diff --git a/BUILD.gn b/BUILD.gn index 34679a6751..5c0bf7ed07 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2283,6 +2283,7 @@ v8_source_set("v8_base") { "src/objects/debug-objects.cc", "src/objects/debug-objects.h", "src/objects/descriptor-array.h", + "src/objects/dictionary-inl.h", "src/objects/dictionary.h", "src/objects/embedder-data-array-inl.h", "src/objects/embedder-data-array.cc", @@ -2377,6 +2378,8 @@ v8_source_set("v8_base") { "src/objects/promise.h", "src/objects/property-array-inl.h", "src/objects/property-array.h", + "src/objects/property-cell-inl.h", + "src/objects/property-cell.h", "src/objects/property-descriptor-object-inl.h", "src/objects/property-descriptor-object.h", "src/objects/prototype-info-inl.h", @@ -2394,6 +2397,7 @@ v8_source_set("v8_base") { "src/objects/stack-frame-info-inl.h", "src/objects/stack-frame-info.h", "src/objects/string-inl.h", + "src/objects/string-table-inl.h", "src/objects/string-table.h", "src/objects/string.h", "src/objects/template-objects.cc", diff --git a/src/api-natives.cc b/src/api-natives.cc index 805756fc93..388d8abe25 100644 --- a/src/api-natives.cc +++ b/src/api-natives.cc @@ -10,6 +10,7 @@ #include "src/message-template.h" #include "src/objects/api-callbacks.h" #include "src/objects/hash-table-inl.h" +#include "src/objects/property-cell.h" #include "src/objects/templates.h" namespace v8 { diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index c1f3f9578f..2347e4762d 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -47,6 +47,7 @@ #include "src/objects/js-segmenter.h" #endif // V8_INTL_SUPPORT #include "src/objects/js-weak-refs.h" +#include "src/objects/property-cell.h" #include "src/objects/slots-inl.h" #include "src/objects/templates.h" #include "src/snapshot/natives.h" diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc index d36f3fdfee..df8104bce9 100644 --- a/src/builtins/builtins-array-gen.cc +++ b/src/builtins/builtins-array-gen.cc @@ -13,6 +13,7 @@ #include "src/frame-constants.h" #include "src/heap/factory-inl.h" #include "src/objects/arguments-inl.h" +#include "src/objects/property-cell.h" namespace v8 { namespace internal { diff --git a/src/builtins/builtins-call-gen.cc b/src/builtins/builtins-call-gen.cc index 4700477bcb..22818184aa 100644 --- a/src/builtins/builtins-call-gen.cc +++ b/src/builtins/builtins-call-gen.cc @@ -10,6 +10,7 @@ #include "src/isolate.h" #include "src/macro-assembler.h" #include "src/objects/arguments.h" +#include "src/objects/property-cell.h" namespace v8 { namespace internal { diff --git a/src/builtins/builtins-string-gen.cc b/src/builtins/builtins-string-gen.cc index 98354f8363..9ca4d05026 100644 --- a/src/builtins/builtins-string-gen.cc +++ b/src/builtins/builtins-string-gen.cc @@ -10,6 +10,7 @@ #include "src/code-factory.h" #include "src/heap/factory-inl.h" #include "src/objects.h" +#include "src/objects/property-cell.h" namespace v8 { namespace internal { diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc index 3f8201e60c..ccdc5e9c30 100644 --- a/src/code-stub-assembler.cc +++ b/src/code-stub-assembler.cc @@ -11,6 +11,7 @@ #include "src/objects/api-callbacks.h" #include "src/objects/descriptor-array.h" #include "src/objects/ordered-hash-table-inl.h" +#include "src/objects/property-cell.h" #include "src/wasm/wasm-objects.h" namespace v8 { diff --git a/src/contexts-inl.h b/src/contexts-inl.h index 328fac74f4..35c4526952 100644 --- a/src/contexts-inl.h +++ b/src/contexts-inl.h @@ -9,6 +9,7 @@ #include "src/heap/heap-write-barrier.h" #include "src/objects-inl.h" +#include "src/objects/dictionary-inl.h" #include "src/objects/fixed-array-inl.h" #include "src/objects/map-inl.h" #include "src/objects/regexp-match-info.h" diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index c1f4e8ce96..b368420427 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -29,6 +29,7 @@ #include "src/objects/api-callbacks-inl.h" #include "src/objects/descriptor-array.h" #include "src/objects/literal-objects-inl.h" +#include "src/objects/property-cell.h" #include "src/objects/scope-info.h" #include "src/objects/script-inl.h" #include "src/profiler/heap-profiler.h" diff --git a/src/layout-descriptor-inl.h b/src/layout-descriptor-inl.h index 0d5db1a9e8..e3584ebd37 100644 --- a/src/layout-descriptor-inl.h +++ b/src/layout-descriptor-inl.h @@ -7,6 +7,7 @@ #include "src/layout-descriptor.h" +#include "src/handles-inl.h" #include "src/objects-inl.h" #include "src/objects/descriptor-array.h" #include "src/objects/smi.h" diff --git a/src/objects-inl.h b/src/objects-inl.h index 917df0d148..77884cf203 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -36,6 +36,7 @@ #include "src/objects/js-proxy-inl.h" #include "src/objects/literal-objects.h" #include "src/objects/maybe-object-inl.h" +#include "src/objects/ordered-hash-table-inl.h" #include "src/objects/regexp-match-info.h" #include "src/objects/scope-info.h" #include "src/objects/slots-inl.h" @@ -431,73 +432,6 @@ ObjectHashSet::ObjectHashSet(Address ptr) SLOW_DCHECK(IsObjectHashSet()); } -template -Dictionary::Dictionary(Address ptr) - : HashTable(ptr) {} - -template -BaseNameDictionary::BaseNameDictionary(Address ptr) - : Dictionary(ptr) {} - -GlobalDictionary::GlobalDictionary(Address ptr) - : BaseNameDictionary(ptr) { - SLOW_DCHECK(IsGlobalDictionary()); -} - -NameDictionary::NameDictionary(Address ptr) - : BaseNameDictionary(ptr) { - SLOW_DCHECK(IsNameDictionary()); -} - -NumberDictionary::NumberDictionary(Address ptr) - : Dictionary(ptr) { - SLOW_DCHECK(IsNumberDictionary()); -} - -SimpleNumberDictionary::SimpleNumberDictionary(Address ptr) - : Dictionary(ptr) { - SLOW_DCHECK(IsSimpleNumberDictionary()); -} - -StringTable::StringTable(Address ptr) - : HashTable(ptr) { - SLOW_DCHECK(IsStringTable()); -} - -StringSet::StringSet(Address ptr) : HashTable(ptr) { - SLOW_DCHECK(IsStringSet()); -} - -template -OrderedHashTable::OrderedHashTable(Address ptr) - : FixedArray(ptr) {} - -OrderedHashSet::OrderedHashSet(Address ptr) - : OrderedHashTable(ptr) { - SLOW_DCHECK(IsOrderedHashSet()); -} - -OrderedHashMap::OrderedHashMap(Address ptr) - : OrderedHashTable(ptr) { - SLOW_DCHECK(IsOrderedHashMap()); -} - -OrderedNameDictionary::OrderedNameDictionary(Address ptr) - : OrderedHashTable(ptr) { - SLOW_DCHECK(IsOrderedNameDictionary()); -} - -template -SmallOrderedHashTable::SmallOrderedHashTable(Address ptr) - : HeapObjectPtr(ptr) {} - -OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet, - SmallOrderedHashTable) -OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap, - SmallOrderedHashTable) -OBJECT_CONSTRUCTORS_IMPL(SmallOrderedNameDictionary, - SmallOrderedHashTable) - OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray) OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray) @@ -526,29 +460,16 @@ CAST_ACCESSOR2(EphemeronHashTable) CAST_ACCESSOR(EnumCache) CAST_ACCESSOR(FeedbackCell) CAST_ACCESSOR(Foreign) -CAST_ACCESSOR2(GlobalDictionary) CAST_ACCESSOR(HeapObject) CAST_ACCESSOR(HeapNumber) CAST_ACCESSOR(MutableHeapNumber) -CAST_ACCESSOR2(OrderedNameDictionary) -CAST_ACCESSOR2(NameDictionary) CAST_ACCESSOR2(NormalizedMapCache) -CAST_ACCESSOR2(NumberDictionary) CAST_ACCESSOR(Object) CAST_ACCESSOR2(ObjectHashSet) CAST_ACCESSOR2(ObjectHashTable) CAST_ACCESSOR(Oddball) -CAST_ACCESSOR2(OrderedHashMap) -CAST_ACCESSOR2(OrderedHashSet) -CAST_ACCESSOR(PropertyCell) CAST_ACCESSOR2(RegExpMatchInfo) CAST_ACCESSOR2(ScopeInfo) -CAST_ACCESSOR2(SimpleNumberDictionary) -CAST_ACCESSOR2(SmallOrderedHashMap) -CAST_ACCESSOR2(SmallOrderedHashSet) -CAST_ACCESSOR2(SmallOrderedNameDictionary) -CAST_ACCESSOR2(StringSet) -CAST_ACCESSOR2(StringTable) CAST_ACCESSOR(Struct) CAST_ACCESSOR(TemplateObjectDescription) CAST_ACCESSOR(Tuple2) @@ -976,19 +897,6 @@ Handle Oddball::ToNumber(Isolate* isolate, Handle input) { ACCESSORS(Cell, value, Object, kValueOffset) ACCESSORS(FeedbackCell, value, HeapObject, kValueOffset) -ACCESSORS2(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) -ACCESSORS2(PropertyCell, name, Name, kNameOffset) -ACCESSORS(PropertyCell, value, Object, kValueOffset) -ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset) - -PropertyDetails PropertyCell::property_details() const { - return PropertyDetails(Smi::cast(property_details_raw())); -} - - -void PropertyCell::set_property_details(PropertyDetails details) { - set_property_details_raw(details.AsSmi()); -} inline bool IsSpecialReceiverInstanceType(InstanceType instance_type) { return instance_type <= LAST_SPECIAL_RECEIVER_TYPE; @@ -1418,58 +1326,6 @@ void DescriptorArray::set(int index, MaybeObject value) { WEAK_WRITE_BARRIER(this, offset(index), value); } -bool StringSetShape::IsMatch(String key, Object* value) { - DCHECK(value->IsString()); - return key->Equals(String::cast(value)); -} - -uint32_t StringSetShape::Hash(Isolate* isolate, String key) { - return key->Hash(); -} - -uint32_t StringSetShape::HashForObject(Isolate* isolate, Object* object) { - return String::cast(object)->Hash(); -} - -StringTableKey::StringTableKey(uint32_t hash_field) - : HashTableKey(hash_field >> Name::kHashShift), hash_field_(hash_field) {} - -void StringTableKey::set_hash_field(uint32_t hash_field) { - hash_field_ = hash_field; - set_hash(hash_field >> Name::kHashShift); -} - -Handle StringTableShape::AsHandle(Isolate* isolate, - StringTableKey* key) { - return key->AsHandle(isolate); -} - -uint32_t StringTableShape::HashForObject(Isolate* isolate, Object* object) { - return String::cast(object)->Hash(); -} - -RootIndex StringTableShape::GetMapRootIndex() { - return RootIndex::kStringTableMap; -} - -bool NumberDictionary::requires_slow_elements() { - Object* max_index_object = get(kMaxNumberKeyIndex); - if (!max_index_object->IsSmi()) return false; - return 0 != (Smi::ToInt(max_index_object) & kRequiresSlowElementsMask); -} - -uint32_t NumberDictionary::max_number_key() { - DCHECK(!requires_slow_elements()); - Object* max_index_object = get(kMaxNumberKeyIndex); - if (!max_index_object->IsSmi()) return 0; - uint32_t value = static_cast(Smi::ToInt(max_index_object)); - return value >> kRequiresSlowElementsTagSize; -} - -void NumberDictionary::set_requires_slow_elements() { - set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); -} - DEFINE_DEOPT_ELEMENT_ACCESSORS2(TranslationByteArray, ByteArray) DEFINE_DEOPT_ELEMENT_ACCESSORS2(InlinedFunctionCount, Smi) DEFINE_DEOPT_ELEMENT_ACCESSORS2(LiteralArray, FixedArray) @@ -1645,15 +1501,6 @@ void Foreign::set_foreign_address(Address value) { WRITE_UINTPTR_FIELD(this, kForeignAddressOffset, value); } -template -void SmallOrderedHashTable::SetDataEntry(int entry, int relative_index, - Object* value) { - DCHECK_NE(kNotFound, entry); - Address entry_offset = GetDataEntryOffset(entry, relative_index); - RELAXED_WRITE_FIELD(this, entry_offset, value); - WRITE_BARRIER(this, static_cast(entry_offset), value); -} - // static Maybe Object::GreaterThan(Isolate* isolate, Handle x, Handle y) { @@ -1791,157 +1638,6 @@ bool AccessorPair::IsJSAccessor(Object* obj) { return obj->IsCallable() || obj->IsUndefined(); } -template -void Dictionary::ClearEntry(Isolate* isolate, int entry) { - Object* the_hole = this->GetReadOnlyRoots().the_hole_value(); - PropertyDetails details = PropertyDetails::Empty(); - Derived::cast(*this)->SetEntry(isolate, entry, the_hole, the_hole, details); -} - -template -void Dictionary::SetEntry(Isolate* isolate, int entry, - Object* key, Object* value, - PropertyDetails details) { - DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3); - DCHECK(!key->IsName() || details.dictionary_index() > 0); - int index = DerivedHashTable::EntryToIndex(entry); - DisallowHeapAllocation no_gc; - WriteBarrierMode mode = this->GetWriteBarrierMode(no_gc); - this->set(index + Derived::kEntryKeyIndex, key, mode); - this->set(index + Derived::kEntryValueIndex, value, mode); - if (Shape::kHasDetails) DetailsAtPut(isolate, entry, details); -} - -Object* GlobalDictionaryShape::Unwrap(Object* object) { - return PropertyCell::cast(object)->name(); -} - -RootIndex GlobalDictionaryShape::GetMapRootIndex() { - return RootIndex::kGlobalDictionaryMap; -} - -Name NameDictionary::NameAt(int entry) { return Name::cast(KeyAt(entry)); } - -RootIndex NameDictionaryShape::GetMapRootIndex() { - return RootIndex::kNameDictionaryMap; -} - -PropertyCell* GlobalDictionary::CellAt(int entry) { - DCHECK(KeyAt(entry)->IsPropertyCell()); - return PropertyCell::cast(KeyAt(entry)); -} - -bool GlobalDictionaryShape::IsLive(ReadOnlyRoots roots, Object* k) { - DCHECK_NE(roots.the_hole_value(), k); - return k != roots.undefined_value(); -} - -bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object* k) { - return IsLive(roots, k) && !PropertyCell::cast(k)->value()->IsTheHole(roots); -} - -Name GlobalDictionary::NameAt(int entry) { return CellAt(entry)->name(); } -Object* GlobalDictionary::ValueAt(int entry) { return CellAt(entry)->value(); } - -void GlobalDictionary::SetEntry(Isolate* isolate, int entry, Object* key, - Object* value, PropertyDetails details) { - DCHECK_EQ(key, PropertyCell::cast(value)->name()); - set(EntryToIndex(entry) + kEntryKeyIndex, value); - DetailsAtPut(isolate, entry, details); -} - -void GlobalDictionary::ValueAtPut(int entry, Object* value) { - set(EntryToIndex(entry), value); -} - -bool NumberDictionaryBaseShape::IsMatch(uint32_t key, Object* other) { - DCHECK(other->IsNumber()); - return key == static_cast(other->Number()); -} - -uint32_t NumberDictionaryBaseShape::Hash(Isolate* isolate, uint32_t key) { - return ComputeSeededHash(key, isolate->heap()->HashSeed()); -} - -uint32_t NumberDictionaryBaseShape::HashForObject(Isolate* isolate, - Object* other) { - DCHECK(other->IsNumber()); - return ComputeSeededHash(static_cast(other->Number()), - isolate->heap()->HashSeed()); -} - -Handle NumberDictionaryBaseShape::AsHandle(Isolate* isolate, - uint32_t key) { - return isolate->factory()->NewNumberFromUint(key); -} - -RootIndex NumberDictionaryShape::GetMapRootIndex() { - return RootIndex::kNumberDictionaryMap; -} - -RootIndex SimpleNumberDictionaryShape::GetMapRootIndex() { - return RootIndex::kSimpleNumberDictionaryMap; -} - -bool NameDictionaryShape::IsMatch(Handle key, Object* other) { - DCHECK(other->IsTheHole() || Name::cast(other)->IsUniqueName()); - DCHECK(key->IsUniqueName()); - return *key == other; -} - -uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle key) { - return key->Hash(); -} - -uint32_t NameDictionaryShape::HashForObject(Isolate* isolate, Object* other) { - return Name::cast(other)->Hash(); -} - -bool GlobalDictionaryShape::IsMatch(Handle key, Object* other) { - DCHECK(PropertyCell::cast(other)->name()->IsUniqueName()); - return *key == PropertyCell::cast(other)->name(); -} - -uint32_t GlobalDictionaryShape::HashForObject(Isolate* isolate, Object* other) { - return PropertyCell::cast(other)->name()->Hash(); -} - -Handle NameDictionaryShape::AsHandle(Isolate* isolate, - Handle key) { - DCHECK(key->IsUniqueName()); - return key; -} - -template -PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary dict, int entry) { - DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). - return dict->CellAt(entry)->property_details(); -} - -template -void GlobalDictionaryShape::DetailsAtPut(Isolate* isolate, Dictionary dict, - int entry, PropertyDetails value) { - DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). - PropertyCell* cell = dict->CellAt(entry); - if (cell->property_details().IsReadOnly() != value.IsReadOnly()) { - cell->dependent_code()->DeoptimizeDependentCodeGroup( - isolate, DependentCode::kPropertyCellChangedGroup); - } - cell->set_property_details(value); -} - -bool ObjectHashTableShape::IsMatch(Handle key, Object* other) { - return key->SameValue(other); -} - -uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle key) { - return Smi::ToInt(key->GetHash()); -} - -uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object* other) { - return Smi::ToInt(other->GetHash()); -} - // static Object* Object::GetSimpleHash(Object* object) { DisallowHeapAllocation no_gc; @@ -2005,16 +1701,6 @@ Relocatable::~Relocatable() { isolate_->set_relocatable_top(prev_); } - -template -Object* OrderedHashTableIterator::CurrentKey() { - TableType table = TableType::cast(this->table()); - int index = Smi::ToInt(this->index()); - Object* key = table->KeyAt(index); - DCHECK(!key->IsTheHole()); - return key; -} - // Predictably converts HeapObject* or Address to uint32 by calculating // offset of the address in respective MemoryChunk. static inline uint32_t ObjectAddressForHashing(void* object) { diff --git a/src/objects.h b/src/objects.h index 9f915ddf87..50185c293e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1559,62 +1559,6 @@ class FeedbackCell : public Struct { DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackCell); }; -class PropertyCell : public HeapObject { - public: - // [name]: the name of the global property. - DECL_ACCESSORS2(name, Name) - // [property_details]: details of the global property. - DECL_ACCESSORS(property_details_raw, Object) - // [value]: value of the global property. - DECL_ACCESSORS(value, Object) - // [dependent_code]: dependent code that depends on the type of the global - // property. - DECL_ACCESSORS2(dependent_code, DependentCode) - - inline PropertyDetails property_details() const; - inline void set_property_details(PropertyDetails details); - - PropertyCellConstantType GetConstantType(); - - // Computes the new type of the cell's contents for the given value, but - // without actually modifying the details. - static PropertyCellType UpdatedType(Isolate* isolate, - Handle cell, - Handle value, - PropertyDetails details); - // Prepares property cell at given entry for receiving given value. - // As a result the old cell could be invalidated and/or dependent code could - // be deoptimized. Returns the prepared property cell. - static Handle PrepareForValue( - Isolate* isolate, Handle dictionary, int entry, - Handle value, PropertyDetails details); - - static Handle InvalidateEntry( - Isolate* isolate, Handle dictionary, int entry); - - static void SetValueWithInvalidation(Isolate* isolate, - Handle cell, - Handle new_value); - - DECL_CAST(PropertyCell) - - // Dispatched behavior. - DECL_PRINTER(PropertyCell) - DECL_VERIFIER(PropertyCell) - - // Layout description. - static const int kDetailsOffset = HeapObject::kHeaderSize; - static const int kNameOffset = kDetailsOffset + kPointerSize; - static const int kValueOffset = kNameOffset + kPointerSize; - static const int kDependentCodeOffset = kValueOffset + kPointerSize; - static const int kSize = kDependentCodeOffset + kPointerSize; - - typedef FixedBodyDescriptor BodyDescriptor; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell); -}; - // Foreign describes objects pointing from JavaScript to C structures. class Foreign: public HeapObject { public: diff --git a/src/objects/dictionary-inl.h b/src/objects/dictionary-inl.h new file mode 100644 index 0000000000..4b6fed59ad --- /dev/null +++ b/src/objects/dictionary-inl.h @@ -0,0 +1,213 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_DICTIONARY_INL_H_ +#define V8_OBJECTS_DICTIONARY_INL_H_ + +#include "src/objects/dictionary.h" + +#include "src/objects/property-cell-inl.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +CAST_ACCESSOR2(GlobalDictionary) +CAST_ACCESSOR2(NameDictionary) +CAST_ACCESSOR2(NumberDictionary) +CAST_ACCESSOR2(SimpleNumberDictionary) + +template +Dictionary::Dictionary(Address ptr) + : HashTable(ptr) {} + +template +BaseNameDictionary::BaseNameDictionary(Address ptr) + : Dictionary(ptr) {} + +GlobalDictionary::GlobalDictionary(Address ptr) + : BaseNameDictionary(ptr) { + SLOW_DCHECK(IsGlobalDictionary()); +} + +NameDictionary::NameDictionary(Address ptr) + : BaseNameDictionary(ptr) { + SLOW_DCHECK(IsNameDictionary()); +} + +NumberDictionary::NumberDictionary(Address ptr) + : Dictionary(ptr) { + SLOW_DCHECK(IsNumberDictionary()); +} + +SimpleNumberDictionary::SimpleNumberDictionary(Address ptr) + : Dictionary(ptr) { + SLOW_DCHECK(IsSimpleNumberDictionary()); +} + +bool NumberDictionary::requires_slow_elements() { + Object* max_index_object = get(kMaxNumberKeyIndex); + if (!max_index_object->IsSmi()) return false; + return 0 != (Smi::ToInt(max_index_object) & kRequiresSlowElementsMask); +} + +uint32_t NumberDictionary::max_number_key() { + DCHECK(!requires_slow_elements()); + Object* max_index_object = get(kMaxNumberKeyIndex); + if (!max_index_object->IsSmi()) return 0; + uint32_t value = static_cast(Smi::ToInt(max_index_object)); + return value >> kRequiresSlowElementsTagSize; +} + +void NumberDictionary::set_requires_slow_elements() { + set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); +} + +template +void Dictionary::ClearEntry(Isolate* isolate, int entry) { + Object* the_hole = this->GetReadOnlyRoots().the_hole_value(); + PropertyDetails details = PropertyDetails::Empty(); + Derived::cast(*this)->SetEntry(isolate, entry, the_hole, the_hole, details); +} + +template +void Dictionary::SetEntry(Isolate* isolate, int entry, + Object* key, Object* value, + PropertyDetails details) { + DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3); + DCHECK(!key->IsName() || details.dictionary_index() > 0); + int index = DerivedHashTable::EntryToIndex(entry); + DisallowHeapAllocation no_gc; + WriteBarrierMode mode = this->GetWriteBarrierMode(no_gc); + this->set(index + Derived::kEntryKeyIndex, key, mode); + this->set(index + Derived::kEntryValueIndex, value, mode); + if (Shape::kHasDetails) DetailsAtPut(isolate, entry, details); +} + +Object* GlobalDictionaryShape::Unwrap(Object* object) { + return PropertyCell::cast(object)->name(); +} + +RootIndex GlobalDictionaryShape::GetMapRootIndex() { + return RootIndex::kGlobalDictionaryMap; +} + +Name NameDictionary::NameAt(int entry) { return Name::cast(KeyAt(entry)); } + +RootIndex NameDictionaryShape::GetMapRootIndex() { + return RootIndex::kNameDictionaryMap; +} + +PropertyCell* GlobalDictionary::CellAt(int entry) { + DCHECK(KeyAt(entry)->IsPropertyCell()); + return PropertyCell::cast(KeyAt(entry)); +} + +bool GlobalDictionaryShape::IsLive(ReadOnlyRoots roots, Object* k) { + DCHECK_NE(roots.the_hole_value(), k); + return k != roots.undefined_value(); +} + +bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object* k) { + return IsLive(roots, k) && !PropertyCell::cast(k)->value()->IsTheHole(roots); +} + +Name GlobalDictionary::NameAt(int entry) { return CellAt(entry)->name(); } +Object* GlobalDictionary::ValueAt(int entry) { return CellAt(entry)->value(); } + +void GlobalDictionary::SetEntry(Isolate* isolate, int entry, Object* key, + Object* value, PropertyDetails details) { + DCHECK_EQ(key, PropertyCell::cast(value)->name()); + set(EntryToIndex(entry) + kEntryKeyIndex, value); + DetailsAtPut(isolate, entry, details); +} + +void GlobalDictionary::ValueAtPut(int entry, Object* value) { + set(EntryToIndex(entry), value); +} + +bool NumberDictionaryBaseShape::IsMatch(uint32_t key, Object* other) { + DCHECK(other->IsNumber()); + return key == static_cast(other->Number()); +} + +uint32_t NumberDictionaryBaseShape::Hash(Isolate* isolate, uint32_t key) { + return ComputeSeededHash(key, isolate->heap()->HashSeed()); +} + +uint32_t NumberDictionaryBaseShape::HashForObject(Isolate* isolate, + Object* other) { + DCHECK(other->IsNumber()); + return ComputeSeededHash(static_cast(other->Number()), + isolate->heap()->HashSeed()); +} + +Handle NumberDictionaryBaseShape::AsHandle(Isolate* isolate, + uint32_t key) { + return isolate->factory()->NewNumberFromUint(key); +} + +RootIndex NumberDictionaryShape::GetMapRootIndex() { + return RootIndex::kNumberDictionaryMap; +} + +RootIndex SimpleNumberDictionaryShape::GetMapRootIndex() { + return RootIndex::kSimpleNumberDictionaryMap; +} + +bool NameDictionaryShape::IsMatch(Handle key, Object* other) { + DCHECK(other->IsTheHole() || Name::cast(other)->IsUniqueName()); + DCHECK(key->IsUniqueName()); + return *key == other; +} + +uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle key) { + return key->Hash(); +} + +uint32_t NameDictionaryShape::HashForObject(Isolate* isolate, Object* other) { + return Name::cast(other)->Hash(); +} + +bool GlobalDictionaryShape::IsMatch(Handle key, Object* other) { + DCHECK(PropertyCell::cast(other)->name()->IsUniqueName()); + return *key == PropertyCell::cast(other)->name(); +} + +uint32_t GlobalDictionaryShape::HashForObject(Isolate* isolate, Object* other) { + return PropertyCell::cast(other)->name()->Hash(); +} + +Handle NameDictionaryShape::AsHandle(Isolate* isolate, + Handle key) { + DCHECK(key->IsUniqueName()); + return key; +} + +template +PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary dict, int entry) { + DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). + return dict->CellAt(entry)->property_details(); +} + +template +void GlobalDictionaryShape::DetailsAtPut(Isolate* isolate, Dictionary dict, + int entry, PropertyDetails value) { + DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). + PropertyCell* cell = dict->CellAt(entry); + if (cell->property_details().IsReadOnly() != value.IsReadOnly()) { + cell->dependent_code()->DeoptimizeDependentCodeGroup( + isolate, DependentCode::kPropertyCellChangedGroup); + } + cell->set_property_details(value); +} + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_DICTIONARY_INL_H_ diff --git a/src/objects/hash-table-inl.h b/src/objects/hash-table-inl.h index 19f7bf9fdf..d094ccccc4 100644 --- a/src/objects/hash-table-inl.h +++ b/src/objects/hash-table-inl.h @@ -131,6 +131,18 @@ bool ObjectHashSet::Has(Isolate* isolate, Handle key) { return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)) != kNotFound; } +bool ObjectHashTableShape::IsMatch(Handle key, Object* other) { + return key->SameValue(other); +} + +uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle key) { + return Smi::ToInt(key->GetHash()); +} + +uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object* other) { + return Smi::ToInt(other->GetHash()); +} + } // namespace internal } // namespace v8 diff --git a/src/objects/ordered-hash-table-inl.h b/src/objects/ordered-hash-table-inl.h index 2ae82472aa..33afa3e0a1 100644 --- a/src/objects/ordered-hash-table-inl.h +++ b/src/objects/ordered-hash-table-inl.h @@ -16,6 +16,43 @@ namespace v8 { namespace internal { +CAST_ACCESSOR2(OrderedNameDictionary) +CAST_ACCESSOR2(SmallOrderedNameDictionary) +CAST_ACCESSOR2(OrderedHashMap) +CAST_ACCESSOR2(OrderedHashSet) +CAST_ACCESSOR2(SmallOrderedHashMap) +CAST_ACCESSOR2(SmallOrderedHashSet) + +template +OrderedHashTable::OrderedHashTable(Address ptr) + : FixedArray(ptr) {} + +OrderedHashSet::OrderedHashSet(Address ptr) + : OrderedHashTable(ptr) { + SLOW_DCHECK(IsOrderedHashSet()); +} + +OrderedHashMap::OrderedHashMap(Address ptr) + : OrderedHashTable(ptr) { + SLOW_DCHECK(IsOrderedHashMap()); +} + +OrderedNameDictionary::OrderedNameDictionary(Address ptr) + : OrderedHashTable(ptr) { + SLOW_DCHECK(IsOrderedNameDictionary()); +} + +template +SmallOrderedHashTable::SmallOrderedHashTable(Address ptr) + : HeapObjectPtr(ptr) {} + +OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet, + SmallOrderedHashTable) +OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap, + SmallOrderedHashTable) +OBJECT_CONSTRUCTORS_IMPL(SmallOrderedNameDictionary, + SmallOrderedHashTable) + RootIndex OrderedHashSet::GetMapRootIndex() { return RootIndex::kOrderedHashSetMap; } @@ -114,6 +151,25 @@ inline bool SmallOrderedHashSet::Is(Handle table) { inline bool SmallOrderedHashMap::Is(Handle table) { return table->IsSmallOrderedHashMap(); } + +template +void SmallOrderedHashTable::SetDataEntry(int entry, int relative_index, + Object* value) { + DCHECK_NE(kNotFound, entry); + Address entry_offset = GetDataEntryOffset(entry, relative_index); + RELAXED_WRITE_FIELD(this, entry_offset, value); + WRITE_BARRIER(this, static_cast(entry_offset), value); +} + +template +Object* OrderedHashTableIterator::CurrentKey() { + TableType table = TableType::cast(this->table()); + int index = Smi::ToInt(this->index()); + Object* key = table->KeyAt(index); + DCHECK(!key->IsTheHole()); + return key; +} + } // namespace internal } // namespace v8 diff --git a/src/objects/property-cell-inl.h b/src/objects/property-cell-inl.h new file mode 100644 index 0000000000..4762885509 --- /dev/null +++ b/src/objects/property-cell-inl.h @@ -0,0 +1,38 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_PROPERTY_CELL_INL_H_ +#define V8_OBJECTS_PROPERTY_CELL_INL_H_ + +#include "src/objects/property-cell.h" + +#include "src/heap/heap-inl.h" +#include "src/objects/code.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +CAST_ACCESSOR(PropertyCell) +ACCESSORS2(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) +ACCESSORS2(PropertyCell, name, Name, kNameOffset) +ACCESSORS(PropertyCell, value, Object, kValueOffset) +ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset) + +PropertyDetails PropertyCell::property_details() const { + return PropertyDetails(Smi::cast(property_details_raw())); +} + +void PropertyCell::set_property_details(PropertyDetails details) { + set_property_details_raw(details.AsSmi()); +} + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_PROPERTY_CELL_INL_H_ diff --git a/src/objects/property-cell.h b/src/objects/property-cell.h new file mode 100644 index 0000000000..6735e6cca0 --- /dev/null +++ b/src/objects/property-cell.h @@ -0,0 +1,77 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_PROPERTY_CELL_H_ +#define V8_OBJECTS_PROPERTY_CELL_H_ + +#include "src/objects.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +class PropertyCell : public HeapObject { + public: + // [name]: the name of the global property. + DECL_ACCESSORS2(name, Name) + // [property_details]: details of the global property. + DECL_ACCESSORS(property_details_raw, Object) + // [value]: value of the global property. + DECL_ACCESSORS(value, Object) + // [dependent_code]: dependent code that depends on the type of the global + // property. + DECL_ACCESSORS2(dependent_code, DependentCode) + + inline PropertyDetails property_details() const; + inline void set_property_details(PropertyDetails details); + + PropertyCellConstantType GetConstantType(); + + // Computes the new type of the cell's contents for the given value, but + // without actually modifying the details. + static PropertyCellType UpdatedType(Isolate* isolate, + Handle cell, + Handle value, + PropertyDetails details); + // Prepares property cell at given entry for receiving given value. + // As a result the old cell could be invalidated and/or dependent code could + // be deoptimized. Returns the prepared property cell. + static Handle PrepareForValue( + Isolate* isolate, Handle dictionary, int entry, + Handle value, PropertyDetails details); + + static Handle InvalidateEntry( + Isolate* isolate, Handle dictionary, int entry); + + static void SetValueWithInvalidation(Isolate* isolate, + Handle cell, + Handle new_value); + + DECL_CAST(PropertyCell) + + // Dispatched behavior. + DECL_PRINTER(PropertyCell) + DECL_VERIFIER(PropertyCell) + + // Layout description. + static const int kDetailsOffset = HeapObject::kHeaderSize; + static const int kNameOffset = kDetailsOffset + kPointerSize; + static const int kValueOffset = kNameOffset + kPointerSize; + static const int kDependentCodeOffset = kValueOffset + kPointerSize; + static const int kSize = kDependentCodeOffset + kPointerSize; + + typedef FixedBodyDescriptor BodyDescriptor; + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell); +}; + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_PROPERTY_CELL_H_ diff --git a/src/objects/string-inl.h b/src/objects/string-inl.h index 25ef30c20d..71cf28903e 100644 --- a/src/objects/string-inl.h +++ b/src/objects/string-inl.h @@ -12,6 +12,7 @@ #include "src/heap/factory.h" #include "src/objects/name-inl.h" #include "src/objects/smi-inl.h" +#include "src/objects/string-table-inl.h" #include "src/string-hasher-inl.h" // Has to be the last include (doesn't have include guards): diff --git a/src/objects/string-table-inl.h b/src/objects/string-table-inl.h new file mode 100644 index 0000000000..d419238f19 --- /dev/null +++ b/src/objects/string-table-inl.h @@ -0,0 +1,69 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_STRING_TABLE_INL_H_ +#define V8_OBJECTS_STRING_TABLE_INL_H_ + +#include "src/objects/string-table.h" + +#include "src/objects/string-inl.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +CAST_ACCESSOR2(StringSet) +CAST_ACCESSOR2(StringTable) + +StringTable::StringTable(Address ptr) + : HashTable(ptr) { + SLOW_DCHECK(IsStringTable()); +} + +StringSet::StringSet(Address ptr) : HashTable(ptr) { + SLOW_DCHECK(IsStringSet()); +} + +bool StringSetShape::IsMatch(String key, Object* value) { + DCHECK(value->IsString()); + return key->Equals(String::cast(value)); +} + +uint32_t StringSetShape::Hash(Isolate* isolate, String key) { + return key->Hash(); +} + +uint32_t StringSetShape::HashForObject(Isolate* isolate, Object* object) { + return String::cast(object)->Hash(); +} + +StringTableKey::StringTableKey(uint32_t hash_field) + : HashTableKey(hash_field >> Name::kHashShift), hash_field_(hash_field) {} + +void StringTableKey::set_hash_field(uint32_t hash_field) { + hash_field_ = hash_field; + set_hash(hash_field >> Name::kHashShift); +} + +Handle StringTableShape::AsHandle(Isolate* isolate, + StringTableKey* key) { + return key->AsHandle(isolate); +} + +uint32_t StringTableShape::HashForObject(Isolate* isolate, Object* object) { + return String::cast(object)->Hash(); +} + +RootIndex StringTableShape::GetMapRootIndex() { + return RootIndex::kStringTableMap; +} + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_STRING_TABLE_INL_H_ diff --git a/src/roots.h b/src/roots.h index ec8f2180fa..a69c324d67 100644 --- a/src/roots.h +++ b/src/roots.h @@ -22,6 +22,7 @@ class Handle; class Heap; class Isolate; class Map; +class PropertyCell; class String; class Symbol; class RootVisitor;