[objects.h splitting] Move Dictionary and HashTable related leftovers out of objects-inl.h

For this to work, I had to move PropertyCell out of objects.h too, since
otherwise there would be an inl include cycle which makes the code not compile.

BUG=v8:5402,v8:8238

Change-Id: I3233f86b68c1e2fd32d135fcf0bbba8101af8cb2
Reviewed-on: https://chromium-review.googlesource.com/c/1356510
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58004}
This commit is contained in:
Marja Hölttä 2018-11-30 14:09:34 +01:00 committed by Commit Bot
parent 371ba71f82
commit f40638d148
20 changed files with 481 additions and 371 deletions

View File

@ -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",

View File

@ -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 {

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 <typename Derived, typename Shape>
Dictionary<Derived, Shape>::Dictionary(Address ptr)
: HashTable<Derived, Shape>(ptr) {}
template <typename Derived, typename Shape>
BaseNameDictionary<Derived, Shape>::BaseNameDictionary(Address ptr)
: Dictionary<Derived, Shape>(ptr) {}
GlobalDictionary::GlobalDictionary(Address ptr)
: BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>(ptr) {
SLOW_DCHECK(IsGlobalDictionary());
}
NameDictionary::NameDictionary(Address ptr)
: BaseNameDictionary<NameDictionary, NameDictionaryShape>(ptr) {
SLOW_DCHECK(IsNameDictionary());
}
NumberDictionary::NumberDictionary(Address ptr)
: Dictionary<NumberDictionary, NumberDictionaryShape>(ptr) {
SLOW_DCHECK(IsNumberDictionary());
}
SimpleNumberDictionary::SimpleNumberDictionary(Address ptr)
: Dictionary<SimpleNumberDictionary, SimpleNumberDictionaryShape>(ptr) {
SLOW_DCHECK(IsSimpleNumberDictionary());
}
StringTable::StringTable(Address ptr)
: HashTable<StringTable, StringTableShape>(ptr) {
SLOW_DCHECK(IsStringTable());
}
StringSet::StringSet(Address ptr) : HashTable<StringSet, StringSetShape>(ptr) {
SLOW_DCHECK(IsStringSet());
}
template <class Derived, int entrysize>
OrderedHashTable<Derived, entrysize>::OrderedHashTable(Address ptr)
: FixedArray(ptr) {}
OrderedHashSet::OrderedHashSet(Address ptr)
: OrderedHashTable<OrderedHashSet, 1>(ptr) {
SLOW_DCHECK(IsOrderedHashSet());
}
OrderedHashMap::OrderedHashMap(Address ptr)
: OrderedHashTable<OrderedHashMap, 2>(ptr) {
SLOW_DCHECK(IsOrderedHashMap());
}
OrderedNameDictionary::OrderedNameDictionary(Address ptr)
: OrderedHashTable<OrderedNameDictionary, 3>(ptr) {
SLOW_DCHECK(IsOrderedNameDictionary());
}
template <class Derived>
SmallOrderedHashTable<Derived>::SmallOrderedHashTable(Address ptr)
: HeapObjectPtr(ptr) {}
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet,
SmallOrderedHashTable<SmallOrderedHashSet>)
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap,
SmallOrderedHashTable<SmallOrderedHashMap>)
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedNameDictionary,
SmallOrderedHashTable<SmallOrderedNameDictionary>)
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<Object> Oddball::ToNumber(Isolate* isolate, Handle<Oddball> 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<Object> 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<uint32_t>(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 <class Derived>
void SmallOrderedHashTable<Derived>::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<int>(entry_offset), value);
}
// static
Maybe<bool> Object::GreaterThan(Isolate* isolate, Handle<Object> x,
Handle<Object> y) {
@ -1791,157 +1638,6 @@ bool AccessorPair::IsJSAccessor(Object* obj) {
return obj->IsCallable() || obj->IsUndefined();
}
template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::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 <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::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<uint32_t>(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<uint32_t>(other->Number()),
isolate->heap()->HashSeed());
}
Handle<Object> 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<Name> key, Object* other) {
DCHECK(other->IsTheHole() || Name::cast(other)->IsUniqueName());
DCHECK(key->IsUniqueName());
return *key == other;
}
uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle<Name> key) {
return key->Hash();
}
uint32_t NameDictionaryShape::HashForObject(Isolate* isolate, Object* other) {
return Name::cast(other)->Hash();
}
bool GlobalDictionaryShape::IsMatch(Handle<Name> 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<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
Handle<Name> key) {
DCHECK(key->IsUniqueName());
return key;
}
template <typename Dictionary>
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 <typename Dictionary>
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<Object> key, Object* other) {
return key->SameValue(other);
}
uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle<Object> 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<class Derived, class TableType>
Object* OrderedHashTableIterator<Derived, TableType>::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) {

View File

@ -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<PropertyCell> cell,
Handle<Object> 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<PropertyCell> PrepareForValue(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
Handle<Object> value, PropertyDetails details);
static Handle<PropertyCell> InvalidateEntry(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry);
static void SetValueWithInvalidation(Isolate* isolate,
Handle<PropertyCell> cell,
Handle<Object> 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<kNameOffset, kSize, kSize> BodyDescriptor;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
};
// Foreign describes objects pointing from JavaScript to C structures.
class Foreign: public HeapObject {
public:

View File

@ -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 <typename Derived, typename Shape>
Dictionary<Derived, Shape>::Dictionary(Address ptr)
: HashTable<Derived, Shape>(ptr) {}
template <typename Derived, typename Shape>
BaseNameDictionary<Derived, Shape>::BaseNameDictionary(Address ptr)
: Dictionary<Derived, Shape>(ptr) {}
GlobalDictionary::GlobalDictionary(Address ptr)
: BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>(ptr) {
SLOW_DCHECK(IsGlobalDictionary());
}
NameDictionary::NameDictionary(Address ptr)
: BaseNameDictionary<NameDictionary, NameDictionaryShape>(ptr) {
SLOW_DCHECK(IsNameDictionary());
}
NumberDictionary::NumberDictionary(Address ptr)
: Dictionary<NumberDictionary, NumberDictionaryShape>(ptr) {
SLOW_DCHECK(IsNumberDictionary());
}
SimpleNumberDictionary::SimpleNumberDictionary(Address ptr)
: Dictionary<SimpleNumberDictionary, SimpleNumberDictionaryShape>(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<uint32_t>(Smi::ToInt(max_index_object));
return value >> kRequiresSlowElementsTagSize;
}
void NumberDictionary::set_requires_slow_elements() {
set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
}
template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::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 <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::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<uint32_t>(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<uint32_t>(other->Number()),
isolate->heap()->HashSeed());
}
Handle<Object> 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<Name> key, Object* other) {
DCHECK(other->IsTheHole() || Name::cast(other)->IsUniqueName());
DCHECK(key->IsUniqueName());
return *key == other;
}
uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle<Name> key) {
return key->Hash();
}
uint32_t NameDictionaryShape::HashForObject(Isolate* isolate, Object* other) {
return Name::cast(other)->Hash();
}
bool GlobalDictionaryShape::IsMatch(Handle<Name> 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<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
Handle<Name> key) {
DCHECK(key->IsUniqueName());
return key;
}
template <typename Dictionary>
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 <typename Dictionary>
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_

View File

@ -131,6 +131,18 @@ bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) {
return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)) != kNotFound;
}
bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
return key->SameValue(other);
}
uint32_t ObjectHashTableShape::Hash(Isolate* isolate, Handle<Object> key) {
return Smi::ToInt(key->GetHash());
}
uint32_t ObjectHashTableShape::HashForObject(Isolate* isolate, Object* other) {
return Smi::ToInt(other->GetHash());
}
} // namespace internal
} // namespace v8

View File

@ -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 <class Derived, int entrysize>
OrderedHashTable<Derived, entrysize>::OrderedHashTable(Address ptr)
: FixedArray(ptr) {}
OrderedHashSet::OrderedHashSet(Address ptr)
: OrderedHashTable<OrderedHashSet, 1>(ptr) {
SLOW_DCHECK(IsOrderedHashSet());
}
OrderedHashMap::OrderedHashMap(Address ptr)
: OrderedHashTable<OrderedHashMap, 2>(ptr) {
SLOW_DCHECK(IsOrderedHashMap());
}
OrderedNameDictionary::OrderedNameDictionary(Address ptr)
: OrderedHashTable<OrderedNameDictionary, 3>(ptr) {
SLOW_DCHECK(IsOrderedNameDictionary());
}
template <class Derived>
SmallOrderedHashTable<Derived>::SmallOrderedHashTable(Address ptr)
: HeapObjectPtr(ptr) {}
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet,
SmallOrderedHashTable<SmallOrderedHashSet>)
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap,
SmallOrderedHashTable<SmallOrderedHashMap>)
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedNameDictionary,
SmallOrderedHashTable<SmallOrderedNameDictionary>)
RootIndex OrderedHashSet::GetMapRootIndex() {
return RootIndex::kOrderedHashSetMap;
}
@ -114,6 +151,25 @@ inline bool SmallOrderedHashSet::Is(Handle<HeapObject> table) {
inline bool SmallOrderedHashMap::Is(Handle<HeapObject> table) {
return table->IsSmallOrderedHashMap();
}
template <class Derived>
void SmallOrderedHashTable<Derived>::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<int>(entry_offset), value);
}
template <class Derived, class TableType>
Object* OrderedHashTableIterator<Derived, TableType>::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

View File

@ -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_

View File

@ -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<PropertyCell> cell,
Handle<Object> 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<PropertyCell> PrepareForValue(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry,
Handle<Object> value, PropertyDetails details);
static Handle<PropertyCell> InvalidateEntry(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry);
static void SetValueWithInvalidation(Isolate* isolate,
Handle<PropertyCell> cell,
Handle<Object> 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<kNameOffset, kSize, kSize> BodyDescriptor;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PropertyCell);
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_PROPERTY_CELL_H_

View File

@ -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):

View File

@ -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<StringTable, StringTableShape>(ptr) {
SLOW_DCHECK(IsStringTable());
}
StringSet::StringSet(Address ptr) : HashTable<StringSet, StringSetShape>(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<Object> 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_

View File

@ -22,6 +22,7 @@ class Handle;
class Heap;
class Isolate;
class Map;
class PropertyCell;
class String;
class Symbol;
class RootVisitor;