LCOV - code coverage report
Current view: top level - src/objects - hash-table-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 51 61 83.6 %
Date: 2019-04-17 Functions: 31 66 47.0 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_OBJECTS_HASH_TABLE_INL_H_
       6             : #define V8_OBJECTS_HASH_TABLE_INL_H_
       7             : 
       8             : #include "src/objects/hash-table.h"
       9             : 
      10             : #include "src/heap/heap.h"
      11             : #include "src/objects-inl.h"
      12             : #include "src/objects/fixed-array-inl.h"
      13             : #include "src/objects/heap-object-inl.h"
      14             : #include "src/roots-inl.h"
      15             : 
      16             : // Has to be the last include (doesn't have include guards):
      17             : #include "src/objects/object-macros.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : OBJECT_CONSTRUCTORS_IMPL(HashTableBase, FixedArray)
      23             : 
      24             : template <typename Derived, typename Shape>
      25           0 : HashTable<Derived, Shape>::HashTable(Address ptr) : HashTableBase(ptr) {
      26             :   SLOW_DCHECK(IsHashTable());
      27           0 : }
      28             : 
      29             : template <typename Derived, typename Shape>
      30           0 : ObjectHashTableBase<Derived, Shape>::ObjectHashTableBase(Address ptr)
      31           0 :     : HashTable<Derived, Shape>(ptr) {}
      32             : 
      33             : ObjectHashTable::ObjectHashTable(Address ptr)
      34             :     : ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape>(ptr) {
      35             :   SLOW_DCHECK(IsObjectHashTable());
      36             : }
      37             : 
      38             : EphemeronHashTable::EphemeronHashTable(Address ptr)
      39             :     : ObjectHashTableBase<EphemeronHashTable, EphemeronHashTableShape>(ptr) {
      40             :   SLOW_DCHECK(IsEphemeronHashTable());
      41             : }
      42             : 
      43             : ObjectHashSet::ObjectHashSet(Address ptr)
      44             :     : HashTable<ObjectHashSet, ObjectHashSetShape>(ptr) {
      45             :   SLOW_DCHECK(IsObjectHashSet());
      46             : }
      47             : 
      48             : CAST_ACCESSOR(ObjectHashTable)
      49             : CAST_ACCESSOR(EphemeronHashTable)
      50             : CAST_ACCESSOR(ObjectHashSet)
      51             : 
      52        1303 : void EphemeronHashTable::set_key(int index, Object value) {
      53             :   DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
      54             :   DCHECK(IsEphemeronHashTable());
      55             :   DCHECK_GE(index, 0);
      56             :   DCHECK_LT(index, this->length());
      57        1303 :   int offset = kHeaderSize + index * kTaggedSize;
      58        1303 :   RELAXED_WRITE_FIELD(*this, offset, value);
      59        1303 :   EPHEMERON_KEY_WRITE_BARRIER(*this, offset, value);
      60        1303 : }
      61             : 
      62       16972 : void EphemeronHashTable::set_key(int index, Object value,
      63             :                                  WriteBarrierMode mode) {
      64             :   DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
      65             :   DCHECK(IsEphemeronHashTable());
      66             :   DCHECK_GE(index, 0);
      67             :   DCHECK_LT(index, this->length());
      68       16972 :   int offset = kHeaderSize + index * kTaggedSize;
      69       16972 :   RELAXED_WRITE_FIELD(*this, offset, value);
      70       19059 :   CONDITIONAL_EPHEMERON_KEY_WRITE_BARRIER(*this, offset, value, mode);
      71       16972 : }
      72             : 
      73           0 : int HashTableBase::NumberOfElements() const {
      74           0 :   return Smi::ToInt(get(kNumberOfElementsIndex));
      75             : }
      76             : 
      77             : int HashTableBase::NumberOfDeletedElements() const {
      78             :   return Smi::ToInt(get(kNumberOfDeletedElementsIndex));
      79             : }
      80             : 
      81             : int HashTableBase::Capacity() const { return Smi::ToInt(get(kCapacityIndex)); }
      82             : 
      83    33522920 : void HashTableBase::ElementAdded() {
      84    33522920 :   SetNumberOfElements(NumberOfElements() + 1);
      85    33522920 : }
      86             : 
      87      207683 : void HashTableBase::ElementRemoved() {
      88      207683 :   SetNumberOfElements(NumberOfElements() - 1);
      89      207683 :   SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
      90      207683 : }
      91             : 
      92       69009 : void HashTableBase::ElementsRemoved(int n) {
      93       69009 :   SetNumberOfElements(NumberOfElements() - n);
      94       69009 :   SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
      95       69009 : }
      96             : 
      97             : // static
      98             : int HashTableBase::ComputeCapacity(int at_least_space_for) {
      99             :   // Add 50% slack to make slot collisions sufficiently unlikely.
     100             :   // See matching computation in HashTable::HasSufficientCapacityToAdd().
     101             :   // Must be kept in sync with CodeStubAssembler::HashTableComputeCapacity().
     102     1572231 :   int raw_cap = at_least_space_for + (at_least_space_for >> 1);
     103     1572252 :   int capacity = base::bits::RoundUpToPowerOfTwo32(raw_cap);
     104             :   return Max(capacity, kMinCapacity);
     105             : }
     106             : 
     107             : void HashTableBase::SetNumberOfElements(int nof) {
     108             :   set(kNumberOfElementsIndex, Smi::FromInt(nof));
     109             : }
     110             : 
     111             : void HashTableBase::SetNumberOfDeletedElements(int nod) {
     112             :   set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
     113             : }
     114             : 
     115             : template <typename Key>
     116             : RootIndex BaseShape<Key>::GetMapRootIndex() {
     117             :   return RootIndex::kHashTableMap;
     118             : }
     119             : 
     120             : RootIndex EphemeronHashTableShape::GetMapRootIndex() {
     121             :   return RootIndex::kEphemeronHashTableMap;
     122             : }
     123             : 
     124             : template <typename Derived, typename Shape>
     125   201375688 : int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) {
     126   402751380 :   return FindEntry(ReadOnlyRoots(isolate), key, Shape::Hash(isolate, key));
     127             : }
     128             : 
     129             : // Find entry for key otherwise return kNotFound.
     130             : template <typename Derived, typename Shape>
     131   213837578 : int HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
     132             :                                          int32_t hash) {
     133   213837578 :   uint32_t capacity = Capacity();
     134   213837578 :   uint32_t entry = FirstProbe(hash, capacity);
     135             :   uint32_t count = 1;
     136             :   // EnsureCapacity will guarantee the hash table is never full.
     137             :   Object undefined = roots.undefined_value();
     138             :   Object the_hole = roots.the_hole_value();
     139             :   USE(the_hole);
     140   167585423 :   while (true) {
     141   381423001 :     Object element = KeyAt(entry);
     142             :     // Empty entry. Uses raw unchecked accessors because it is called by the
     143             :     // string table during bootstrapping.
     144   381423001 :     if (element == undefined) break;
     145   197762969 :     if (!(Shape::kNeedsHoleCheck && the_hole == element)) {
     146   234507727 :       if (Shape::IsMatch(key, element)) return entry;
     147             :     }
     148   167585423 :     entry = NextProbe(entry, count++, capacity);
     149             :   }
     150             :   return kNotFound;
     151             : }
     152             : 
     153             : template <typename Derived, typename Shape>
     154    15816506 : bool HashTable<Derived, Shape>::IsKey(ReadOnlyRoots roots, Object k) {
     155    15816506 :   return Shape::IsKey(roots, k);
     156             : }
     157             : 
     158             : template <typename Derived, typename Shape>
     159    58370004 : bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry,
     160             :                                       Object* out_k) {
     161             :   Object k = KeyAt(entry);
     162    58370004 :   if (!IsKey(roots, k)) return false;
     163    27421012 :   *out_k = Shape::Unwrap(k);
     164    27421012 :   return true;
     165             : }
     166             : 
     167             : template <typename Derived, typename Shape>
     168           0 : void HashTable<Derived, Shape>::set_key(int index, Object value) {
     169             :   DCHECK(!IsEphemeronHashTable());
     170       69804 :   FixedArray::set(index, value);
     171           0 : }
     172             : 
     173             : template <typename Derived, typename Shape>
     174           0 : void HashTable<Derived, Shape>::set_key(int index, Object value,
     175             :                                         WriteBarrierMode mode) {
     176             :   DCHECK(!IsEphemeronHashTable());
     177    86887529 :   FixedArray::set(index, value, mode);
     178           0 : }
     179             : 
     180             : template <typename KeyT>
     181             : bool BaseShape<KeyT>::IsKey(ReadOnlyRoots roots, Object key) {
     182             :   return IsLive(roots, key);
     183             : }
     184             : 
     185             : template <typename KeyT>
     186             : bool BaseShape<KeyT>::IsLive(ReadOnlyRoots roots, Object k) {
     187  2539481225 :   return k != roots.the_hole_value() && k != roots.undefined_value();
     188             : }
     189             : 
     190             : bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) {
     191      107938 :   return FindEntry(ReadOnlyRoots(isolate), key, hash) != kNotFound;
     192             : }
     193             : 
     194       11457 : bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) {
     195       11457 :   Object hash = key->GetHash();
     196       11457 :   if (!hash->IsSmi()) return false;
     197       10942 :   return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)) != kNotFound;
     198             : }
     199             : 
     200             : bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object other) {
     201      190450 :   return key->SameValue(other);
     202             : }
     203             : 
     204             : uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle<Object> key) {
     205        2000 :   return Smi::ToInt(key->GetHash());
     206             : }
     207             : 
     208             : uint32_t ObjectHashTableShape::HashForObject(ReadOnlyRoots roots,
     209             :                                              Object other) {
     210      452622 :   return Smi::ToInt(other->GetHash());
     211             : }
     212             : 
     213             : }  // namespace internal
     214             : }  // namespace v8
     215             : 
     216             : #include "src/objects/object-macros-undef.h"
     217             : 
     218             : #endif  // V8_OBJECTS_HASH_TABLE_INL_H_

Generated by: LCOV version 1.10