Commit 58ead42b authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[explicit isolates] Make IsKey and IsLive use ReadOnlyRoots

Converts the Shape functions IsKey and IsLive to take ReadOnlyRoots
rather Isolate. This allows HashTableBase::FindEntry and
ObjectHashTableBase::Lookup to also take ReadOnlyRoots rather than
Isolate.

Bug: v8:7786
Change-Id: I37efea1d20139f394d6365569438755cb8fc44c4
Reviewed-on: https://chromium-review.googlesource.com/1133391Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54390}
parent 770ace07
...@@ -5452,10 +5452,11 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -5452,10 +5452,11 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<NameDictionary>(from->property_dictionary(), isolate()); Handle<NameDictionary>(from->property_dictionary(), isolate());
Handle<FixedArray> key_indices = Handle<FixedArray> key_indices =
NameDictionary::IterationIndices(properties); NameDictionary::IterationIndices(properties);
ReadOnlyRoots roots(isolate());
for (int i = 0; i < key_indices->length(); i++) { for (int i = 0; i < key_indices->length(); i++) {
int key_index = Smi::ToInt(key_indices->get(i)); int key_index = Smi::ToInt(key_indices->get(i));
Object* raw_key = properties->KeyAt(key_index); Object* raw_key = properties->KeyAt(key_index);
DCHECK(properties->IsKey(isolate(), raw_key)); DCHECK(properties->IsKey(roots, raw_key));
DCHECK(raw_key->IsName()); DCHECK(raw_key->IsName());
// If the property is already there we skip it. // If the property is already there we skip it.
Handle<Name> key(Name::cast(raw_key), isolate()); Handle<Name> key(Name::cast(raw_key), isolate());
......
...@@ -651,9 +651,10 @@ uint32_t EstimateElementCount(Isolate* isolate, Handle<JSArray> array) { ...@@ -651,9 +651,10 @@ uint32_t EstimateElementCount(Isolate* isolate, Handle<JSArray> array) {
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
NumberDictionary* dictionary = NumberDictionary::cast(array->elements()); NumberDictionary* dictionary = NumberDictionary::cast(array->elements());
int capacity = dictionary->Capacity(); int capacity = dictionary->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* key = dictionary->KeyAt(i); Object* key = dictionary->KeyAt(i);
if (dictionary->IsKey(isolate, key)) { if (dictionary->IsKey(roots, key)) {
element_count++; element_count++;
} }
} }
...@@ -718,9 +719,10 @@ void CollectElementIndices(Isolate* isolate, Handle<JSObject> object, ...@@ -718,9 +719,10 @@ void CollectElementIndices(Isolate* isolate, Handle<JSObject> object,
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary* dict = NumberDictionary::cast(object->elements()); NumberDictionary* dict = NumberDictionary::cast(object->elements());
uint32_t capacity = dict->Capacity(); uint32_t capacity = dict->Capacity();
ReadOnlyRoots roots(isolate);
FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, { FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, {
Object* k = dict->KeyAt(j); Object* k = dict->KeyAt(j);
if (!dict->IsKey(isolate, k)) continue; if (!dict->IsKey(roots, k)) continue;
DCHECK(k->IsNumber()); DCHECK(k->IsNumber());
uint32_t index = static_cast<uint32_t>(k->Number()); uint32_t index = static_cast<uint32_t>(k->Number());
if (index < range) { if (index < range) {
......
...@@ -434,7 +434,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo( ...@@ -434,7 +434,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
isolate()); isolate());
Handle<Cell> cell( Handle<Cell> cell(
Cell::cast(module_namespace->module()->exports()->Lookup( Cell::cast(module_namespace->module()->exports()->Lookup(
isolate(), name, Smi::ToInt(name->GetHash()))), ReadOnlyRoots(isolate()), name,
Smi::ToInt(name->GetHash()))),
isolate()); isolate());
if (cell->value()->IsTheHole(isolate())) { if (cell->value()->IsTheHole(isolate())) {
// This module has not been fully initialized yet. // This module has not been fully initialized yet.
......
...@@ -1432,13 +1432,14 @@ class DictionaryElementsAccessor ...@@ -1432,13 +1432,14 @@ class DictionaryElementsAccessor
CHECK(array->length()->ToArrayLength(&old_length)); CHECK(array->length()->ToArrayLength(&old_length));
{ {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
ReadOnlyRoots roots(isolate);
if (length < old_length) { if (length < old_length) {
if (dict->requires_slow_elements()) { if (dict->requires_slow_elements()) {
// Find last non-deletable element in range of elements to be // Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly. // deleted and adjust range accordingly.
for (int entry = 0; entry < capacity; entry++) { for (int entry = 0; entry < capacity; entry++) {
Object* index = dict->KeyAt(entry); Object* index = dict->KeyAt(entry);
if (dict->IsKey(isolate, index)) { if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index->Number()); uint32_t number = static_cast<uint32_t>(index->Number());
if (length <= number && number < old_length) { if (length <= number && number < old_length) {
PropertyDetails details = dict->DetailsAt(entry); PropertyDetails details = dict->DetailsAt(entry);
...@@ -1456,7 +1457,7 @@ class DictionaryElementsAccessor ...@@ -1456,7 +1457,7 @@ class DictionaryElementsAccessor
int removed_entries = 0; int removed_entries = 0;
for (int entry = 0; entry < capacity; entry++) { for (int entry = 0; entry < capacity; entry++) {
Object* index = dict->KeyAt(entry); Object* index = dict->KeyAt(entry);
if (dict->IsKey(isolate, index)) { if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index->Number()); uint32_t number = static_cast<uint32_t>(index->Number());
if (length <= number && number < old_length) { if (length <= number && number < old_length) {
dict->ClearEntry(entry); dict->ClearEntry(entry);
...@@ -1497,9 +1498,10 @@ class DictionaryElementsAccessor ...@@ -1497,9 +1498,10 @@ class DictionaryElementsAccessor
Handle<NumberDictionary> source_dict( Handle<NumberDictionary> source_dict(
NumberDictionary::cast(receiver->elements()), isolate); NumberDictionary::cast(receiver->elements()), isolate);
int entry_count = source_dict->Capacity(); int entry_count = source_dict->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < entry_count; i++) { for (int i = 0; i < entry_count; i++) {
Object* key = source_dict->KeyAt(i); Object* key = source_dict->KeyAt(i);
if (!source_dict->ToKey(isolate, i, &key)) continue; if (!source_dict->ToKey(roots, i, &key)) continue;
uint64_t key_value = NumberToInt64(key); uint64_t key_value = NumberToInt64(key);
if (key_value >= start && key_value < end) { if (key_value >= start && key_value < end) {
Handle<NumberDictionary> dest_dict( Handle<NumberDictionary> dest_dict(
...@@ -1528,10 +1530,10 @@ class DictionaryElementsAccessor ...@@ -1528,10 +1530,10 @@ class DictionaryElementsAccessor
NumberDictionary* dict = NumberDictionary::cast(backing_store); NumberDictionary* dict = NumberDictionary::cast(backing_store);
if (!dict->requires_slow_elements()) return false; if (!dict->requires_slow_elements()) return false;
int capacity = dict->Capacity(); int capacity = dict->Capacity();
Isolate* isolate = holder->GetIsolate(); ReadOnlyRoots roots = holder->GetReadOnlyRoots();
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i); Object* key = dict->KeyAt(i);
if (!dict->IsKey(isolate, key)) continue; if (!dict->IsKey(roots, key)) continue;
PropertyDetails details = dict->DetailsAt(i); PropertyDetails details = dict->DetailsAt(i);
if (details.kind() == kAccessor) return true; if (details.kind() == kAccessor) return true;
} }
...@@ -1644,7 +1646,7 @@ class DictionaryElementsAccessor ...@@ -1644,7 +1646,7 @@ class DictionaryElementsAccessor
int entry, PropertyFilter filter) { int entry, PropertyFilter filter) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Object* raw_key = dictionary->KeyAt(entry); Object* raw_key = dictionary->KeyAt(entry);
if (!dictionary->IsKey(isolate, raw_key)) return kMaxUInt32; if (!dictionary->IsKey(ReadOnlyRoots(isolate), raw_key)) return kMaxUInt32;
return FilterKey(dictionary, entry, raw_key, filter); return FilterKey(dictionary, entry, raw_key, filter);
} }
...@@ -1660,9 +1662,10 @@ class DictionaryElementsAccessor ...@@ -1660,9 +1662,10 @@ class DictionaryElementsAccessor
GetMaxNumberOfEntries(*object, *backing_store)); GetMaxNumberOfEntries(*object, *backing_store));
int insertion_index = 0; int insertion_index = 0;
PropertyFilter filter = keys->filter(); PropertyFilter filter = keys->filter();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* raw_key = dictionary->KeyAt(i); Object* raw_key = dictionary->KeyAt(i);
if (!dictionary->IsKey(isolate, raw_key)) continue; if (!dictionary->IsKey(roots, raw_key)) continue;
uint32_t key = FilterKey(dictionary, i, raw_key, filter); uint32_t key = FilterKey(dictionary, i, raw_key, filter);
if (key == kMaxUInt32) { if (key == kMaxUInt32) {
keys->AddShadowingKey(raw_key); keys->AddShadowingKey(raw_key);
...@@ -1706,9 +1709,10 @@ class DictionaryElementsAccessor ...@@ -1706,9 +1709,10 @@ class DictionaryElementsAccessor
Handle<NumberDictionary> dictionary( Handle<NumberDictionary> dictionary(
NumberDictionary::cast(receiver->elements()), isolate); NumberDictionary::cast(receiver->elements()), isolate);
int capacity = dictionary->Capacity(); int capacity = dictionary->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* k = dictionary->KeyAt(i); Object* k = dictionary->KeyAt(i);
if (!dictionary->IsKey(isolate, k)) continue; if (!dictionary->IsKey(roots, k)) continue;
Object* value = dictionary->ValueAt(i); Object* value = dictionary->ValueAt(i);
DCHECK(!value->IsTheHole(isolate)); DCHECK(!value->IsTheHole(isolate));
DCHECK(!value->IsAccessorPair()); DCHECK(!value->IsAccessorPair());
...@@ -1901,7 +1905,7 @@ class DictionaryElementsAccessor ...@@ -1901,7 +1905,7 @@ class DictionaryElementsAccessor
#if DEBUG #if DEBUG
DCHECK_EQ(holder->map()->elements_kind(), DICTIONARY_ELEMENTS); DCHECK_EQ(holder->map()->elements_kind(), DICTIONARY_ELEMENTS);
if (!FLAG_enable_slow_asserts) return; if (!FLAG_enable_slow_asserts) return;
Isolate* isolate = holder->GetIsolate(); ReadOnlyRoots roots = holder->GetReadOnlyRoots();
NumberDictionary* dictionary = NumberDictionary::cast(holder->elements()); NumberDictionary* dictionary = NumberDictionary::cast(holder->elements());
// Validate the requires_slow_elements and max_number_key values. // Validate the requires_slow_elements and max_number_key values.
int capacity = dictionary->Capacity(); int capacity = dictionary->Capacity();
...@@ -1909,7 +1913,7 @@ class DictionaryElementsAccessor ...@@ -1909,7 +1913,7 @@ class DictionaryElementsAccessor
int max_key = 0; int max_key = 0;
for (int i = 0; i < capacity; ++i) { for (int i = 0; i < capacity; ++i) {
Object* k; Object* k;
if (!dictionary->ToKey(isolate, i, &k)) continue; if (!dictionary->ToKey(roots, i, &k)) continue;
DCHECK_LE(0.0, k->Number()); DCHECK_LE(0.0, k->Number());
if (k->Number() > NumberDictionary::kRequiresSlowElementsLimit) { if (k->Number() > NumberDictionary::kRequiresSlowElementsLimit) {
requires_slow_elements = true; requires_slow_elements = true;
......
...@@ -804,7 +804,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { ...@@ -804,7 +804,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<ObjectHashTable> exports( Handle<ObjectHashTable> exports(
Handle<JSModuleNamespace>::cast(holder)->module()->exports(), Handle<JSModuleNamespace>::cast(holder)->module()->exports(),
isolate()); isolate());
int entry = exports->FindEntry(isolate(), lookup->name(), int entry = exports->FindEntry(roots, lookup->name(),
Smi::ToInt(lookup->name()->GetHash())); Smi::ToInt(lookup->name()->GetHash()));
// We found the accessor, so the entry must exist. // We found the accessor, so the entry must exist.
DCHECK_NE(entry, ObjectHashTable::kNotFound); DCHECK_NE(entry, ObjectHashTable::kNotFound);
......
...@@ -3186,15 +3186,13 @@ PropertyCell* GlobalDictionary::CellAt(int entry) { ...@@ -3186,15 +3186,13 @@ PropertyCell* GlobalDictionary::CellAt(int entry) {
return PropertyCell::cast(KeyAt(entry)); return PropertyCell::cast(KeyAt(entry));
} }
bool GlobalDictionaryShape::IsLive(Isolate* isolate, Object* k) { bool GlobalDictionaryShape::IsLive(ReadOnlyRoots roots, Object* k) {
ReadOnlyRoots roots(isolate);
DCHECK_NE(roots.the_hole_value(), k); DCHECK_NE(roots.the_hole_value(), k);
return k != roots.undefined_value(); return k != roots.undefined_value();
} }
bool GlobalDictionaryShape::IsKey(Isolate* isolate, Object* k) { bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object* k) {
return IsLive(isolate, k) && return IsLive(roots, k) && !PropertyCell::cast(k)->value()->IsTheHole(roots);
!PropertyCell::cast(k)->value()->IsTheHole(isolate);
} }
Name* GlobalDictionary::NameAt(int entry) { return CellAt(entry)->name(); } Name* GlobalDictionary::NameAt(int entry) { return CellAt(entry)->name(); }
......
This diff is collapsed.
...@@ -215,8 +215,8 @@ class GlobalDictionaryShape : public NameDictionaryShape { ...@@ -215,8 +215,8 @@ class GlobalDictionaryShape : public NameDictionaryShape {
PropertyDetails value); PropertyDetails value);
static inline Object* Unwrap(Object* key); static inline Object* Unwrap(Object* key);
static inline bool IsKey(Isolate* isolate, Object* k); static inline bool IsKey(ReadOnlyRoots roots, Object* k);
static inline bool IsLive(Isolate* isolate, Object* key); static inline bool IsLive(ReadOnlyRoots roots, Object* key);
static inline int GetMapRootIndex(); static inline int GetMapRootIndex();
}; };
......
...@@ -69,18 +69,17 @@ int HashTable<Derived, Shape>::FindEntry(Key key) { ...@@ -69,18 +69,17 @@ int HashTable<Derived, Shape>::FindEntry(Key key) {
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) { int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) {
return FindEntry(isolate, key, Shape::Hash(isolate, key)); return FindEntry(ReadOnlyRoots(isolate), key, Shape::Hash(isolate, key));
} }
// Find entry for key otherwise return kNotFound. // Find entry for key otherwise return kNotFound.
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key, int HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
int32_t hash) { int32_t hash) {
uint32_t capacity = Capacity(); uint32_t capacity = Capacity();
uint32_t entry = FirstProbe(hash, capacity); uint32_t entry = FirstProbe(hash, capacity);
uint32_t count = 1; uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full. // EnsureCapacity will guarantee the hash table is never full.
ReadOnlyRoots roots(isolate);
Object* undefined = roots.undefined_value(); Object* undefined = roots.undefined_value();
Object* the_hole = roots.the_hole_value(); Object* the_hole = roots.the_hole_value();
USE(the_hole); USE(the_hole);
...@@ -98,27 +97,26 @@ int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key, ...@@ -98,27 +97,26 @@ int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::IsKey(Isolate* isolate, Object* k) { bool HashTable<Derived, Shape>::IsKey(ReadOnlyRoots roots, Object* k) {
return Shape::IsKey(isolate, k); return Shape::IsKey(roots, k);
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, int entry, bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry,
Object** out_k) { Object** out_k) {
Object* k = KeyAt(entry); Object* k = KeyAt(entry);
if (!IsKey(isolate, k)) return false; if (!IsKey(roots, k)) return false;
*out_k = Shape::Unwrap(k); *out_k = Shape::Unwrap(k);
return true; return true;
} }
template <typename KeyT> template <typename KeyT>
bool BaseShape<KeyT>::IsKey(Isolate* isolate, Object* key) { bool BaseShape<KeyT>::IsKey(ReadOnlyRoots roots, Object* key) {
return IsLive(isolate, key); return IsLive(roots, key);
} }
template <typename KeyT> template <typename KeyT>
bool BaseShape<KeyT>::IsLive(Isolate* isolate, Object* k) { bool BaseShape<KeyT>::IsLive(ReadOnlyRoots roots, Object* k) {
ReadOnlyRoots roots(isolate);
return k != roots.the_hole_value() && k != roots.undefined_value(); return k != roots.the_hole_value() && k != roots.undefined_value();
} }
...@@ -136,13 +134,13 @@ const HashTable<Derived, Shape>* HashTable<Derived, Shape>::cast( ...@@ -136,13 +134,13 @@ const HashTable<Derived, Shape>* HashTable<Derived, Shape>::cast(
} }
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) { bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) {
return FindEntry(isolate, key, hash) != kNotFound; return FindEntry(ReadOnlyRoots(isolate), key, hash) != kNotFound;
} }
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) { bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) {
Object* hash = key->GetHash(); Object* hash = key->GetHash();
if (!hash->IsSmi()) return false; if (!hash->IsSmi()) return false;
return FindEntry(isolate, key, Smi::ToInt(hash)) != kNotFound; return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)) != kNotFound;
} }
} // namespace internal } // namespace internal
......
...@@ -58,8 +58,8 @@ class BaseShape { ...@@ -58,8 +58,8 @@ class BaseShape {
static inline int GetMapRootIndex(); static inline int GetMapRootIndex();
static const bool kNeedsHoleCheck = true; static const bool kNeedsHoleCheck = true;
static Object* Unwrap(Object* key) { return key; } static Object* Unwrap(Object* key) { return key; }
static inline bool IsKey(Isolate* isolate, Object* key); static inline bool IsKey(ReadOnlyRoots roots, Object* key);
static inline bool IsLive(Isolate* isolate, Object* key); static inline bool IsLive(ReadOnlyRoots roots, Object* key);
}; };
class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) { class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
...@@ -145,7 +145,7 @@ class HashTable : public HashTableBase { ...@@ -145,7 +145,7 @@ class HashTable : public HashTableBase {
// Find entry for key otherwise return kNotFound. // Find entry for key otherwise return kNotFound.
inline int FindEntry(Key key); inline int FindEntry(Key key);
inline int FindEntry(Isolate* isolate, Key key, int32_t hash); inline int FindEntry(ReadOnlyRoots roots, Key key, int32_t hash);
int FindEntry(Isolate* isolate, Key key); int FindEntry(Isolate* isolate, Key key);
// Rehashes the table in-place. // Rehashes the table in-place.
...@@ -153,9 +153,9 @@ class HashTable : public HashTableBase { ...@@ -153,9 +153,9 @@ class HashTable : public HashTableBase {
// Tells whether k is a real key. The hole and undefined are not allowed // Tells whether k is a real key. The hole and undefined are not allowed
// as keys and can be used to indicate missing or deleted elements. // as keys and can be used to indicate missing or deleted elements.
static bool IsKey(Isolate* isolate, Object* k); static bool IsKey(ReadOnlyRoots roots, Object* k);
inline bool ToKey(Isolate* isolate, int entry, Object** out_k); inline bool ToKey(ReadOnlyRoots roots, int entry, Object** out_k);
// Returns the key at entry. // Returns the key at entry.
Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); } Object* KeyAt(int entry) { return get(EntryToIndex(entry) + kEntryKeyIndex); }
...@@ -276,7 +276,7 @@ class ObjectHashTableBase : public HashTable<Derived, Shape> { ...@@ -276,7 +276,7 @@ class ObjectHashTableBase : public HashTable<Derived, Shape> {
// returned in case the key is not present. // returned in case the key is not present.
Object* Lookup(Handle<Object> key); Object* Lookup(Handle<Object> key);
Object* Lookup(Handle<Object> key, int32_t hash); Object* Lookup(Handle<Object> key, int32_t hash);
Object* Lookup(Isolate* isolate, Handle<Object> key, int32_t hash); Object* Lookup(ReadOnlyRoots roots, Handle<Object> key, int32_t hash);
// Returns the value at entry. // Returns the value at entry.
Object* ValueAt(int entry); Object* ValueAt(int entry);
......
...@@ -778,12 +778,13 @@ void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone, ...@@ -778,12 +778,13 @@ void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone,
// TODO(neis): Only allocate more_exports if there are star exports. // TODO(neis): Only allocate more_exports if there are star exports.
// Maybe split special_exports into indirect_exports and star_exports. // Maybe split special_exports into indirect_exports and star_exports.
ReadOnlyRoots roots(isolate);
Handle<FixedArray> special_exports(module->info()->special_exports(), Handle<FixedArray> special_exports(module->info()->special_exports(),
isolate); isolate);
for (int i = 0, n = special_exports->length(); i < n; ++i) { for (int i = 0, n = special_exports->length(); i < n; ++i) {
Handle<ModuleInfoEntry> entry( Handle<ModuleInfoEntry> entry(
ModuleInfoEntry::cast(special_exports->get(i)), isolate); ModuleInfoEntry::cast(special_exports->get(i)), isolate);
if (!entry->export_name()->IsUndefined(isolate)) { if (!entry->export_name()->IsUndefined(roots)) {
continue; // Indirect export. continue; // Indirect export.
} }
...@@ -802,24 +803,24 @@ void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone, ...@@ -802,24 +803,24 @@ void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone,
isolate); isolate);
for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) { for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) {
Object* key; Object* key;
if (!requested_exports->ToKey(isolate, i, &key)) continue; if (!requested_exports->ToKey(roots, i, &key)) continue;
Handle<String> name(String::cast(key), isolate); Handle<String> name(String::cast(key), isolate);
if (name->Equals(ReadOnlyRoots(isolate).default_string())) continue; if (name->Equals(roots.default_string())) continue;
if (!exports->Lookup(name)->IsTheHole(isolate)) continue; if (!exports->Lookup(name)->IsTheHole(roots)) continue;
Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate); Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(i)), isolate);
auto insert_result = more_exports.insert(std::make_pair(name, cell)); auto insert_result = more_exports.insert(std::make_pair(name, cell));
if (!insert_result.second) { if (!insert_result.second) {
auto it = insert_result.first; auto it = insert_result.first;
if (*it->second == *cell || it->second->IsUndefined(isolate)) { if (*it->second == *cell || it->second->IsUndefined(roots)) {
// We already recorded this mapping before, or the name is already // We already recorded this mapping before, or the name is already
// known to be ambiguous. In either case, there's nothing to do. // known to be ambiguous. In either case, there's nothing to do.
} else { } else {
DCHECK(it->second->IsCell()); DCHECK(it->second->IsCell());
// Different star exports provide different cells for this name, hence // Different star exports provide different cells for this name, hence
// mark the name as ambiguous. // mark the name as ambiguous.
it->second = isolate->factory()->undefined_value(); it->second = roots.undefined_value_handle();
} }
} }
} }
...@@ -848,7 +849,8 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate, ...@@ -848,7 +849,8 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate, Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
Handle<Module> module) { Handle<Module> module) {
Handle<HeapObject> object(module->module_namespace(), isolate); Handle<HeapObject> object(module->module_namespace(), isolate);
if (!object->IsUndefined(isolate)) { ReadOnlyRoots roots(isolate);
if (!object->IsUndefined(roots)) {
// Namespace object already exists. // Namespace object already exists.
return Handle<JSModuleNamespace>::cast(object); return Handle<JSModuleNamespace>::cast(object);
} }
...@@ -862,7 +864,7 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate, ...@@ -862,7 +864,7 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
names.reserve(exports->NumberOfElements()); names.reserve(exports->NumberOfElements());
for (int i = 0, n = exports->Capacity(); i < n; ++i) { for (int i = 0, n = exports->Capacity(); i < n; ++i) {
Object* key; Object* key;
if (!exports->ToKey(isolate, i, &key)) continue; if (!exports->ToKey(roots, i, &key)) continue;
names.push_back(handle(String::cast(key), isolate)); names.push_back(handle(String::cast(key), isolate));
} }
DCHECK_EQ(static_cast<int>(names.size()), exports->NumberOfElements()); DCHECK_EQ(static_cast<int>(names.size()), exports->NumberOfElements());
......
...@@ -1431,8 +1431,9 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { ...@@ -1431,8 +1431,9 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
GlobalDictionary* dictionary = GlobalDictionary* dictionary =
JSGlobalObject::cast(js_obj)->global_dictionary(); JSGlobalObject::cast(js_obj)->global_dictionary();
int length = dictionary->Capacity(); int length = dictionary->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
if (dictionary->IsKey(isolate, dictionary->KeyAt(i))) { if (dictionary->IsKey(roots, dictionary->KeyAt(i))) {
PropertyCell* cell = dictionary->CellAt(i); PropertyCell* cell = dictionary->CellAt(i);
Name* name = cell->name(); Name* name = cell->name();
Object* value = cell->value(); Object* value = cell->value();
...@@ -1444,9 +1445,10 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { ...@@ -1444,9 +1445,10 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
} else { } else {
NameDictionary* dictionary = js_obj->property_dictionary(); NameDictionary* dictionary = js_obj->property_dictionary();
int length = dictionary->Capacity(); int length = dictionary->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i); Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(isolate, k)) { if (dictionary->IsKey(roots, k)) {
Object* value = dictionary->ValueAt(i); Object* value = dictionary->ValueAt(i);
PropertyDetails details = dictionary->DetailsAt(i); PropertyDetails details = dictionary->DetailsAt(i);
SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
...@@ -1476,14 +1478,14 @@ void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry, ...@@ -1476,14 +1478,14 @@ void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry,
void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) { void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
Isolate* isolate = js_obj->GetIsolate(); ReadOnlyRoots roots = js_obj->GetReadOnlyRoots();
if (js_obj->HasObjectElements()) { if (js_obj->HasObjectElements()) {
FixedArray* elements = FixedArray::cast(js_obj->elements()); FixedArray* elements = FixedArray::cast(js_obj->elements());
int length = js_obj->IsJSArray() int length = js_obj->IsJSArray()
? Smi::ToInt(JSArray::cast(js_obj)->length()) ? Smi::ToInt(JSArray::cast(js_obj)->length())
: elements->length(); : elements->length();
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
if (!elements->get(i)->IsTheHole(isolate)) { if (!elements->get(i)->IsTheHole(roots)) {
SetElementReference(js_obj, entry, i, elements->get(i)); SetElementReference(js_obj, entry, i, elements->get(i));
} }
} }
...@@ -1492,7 +1494,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) { ...@@ -1492,7 +1494,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj, int entry) {
int length = dictionary->Capacity(); int length = dictionary->Capacity();
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
Object* k = dictionary->KeyAt(i); Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(isolate, k)) { if (dictionary->IsKey(roots, k)) {
DCHECK(k->IsNumber()); DCHECK(k->IsNumber());
uint32_t index = static_cast<uint32_t>(k->Number()); uint32_t index = static_cast<uint32_t>(k->Number());
SetElementReference(js_obj, entry, index, dictionary->ValueAt(i)); SetElementReference(js_obj, entry, index, dictionary->ValueAt(i));
......
...@@ -228,9 +228,10 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary, ...@@ -228,9 +228,10 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
// Replace all indices with proper methods. // Replace all indices with proper methods.
int capacity = dictionary->Capacity(); int capacity = dictionary->Capacity();
ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* maybe_key = dictionary->KeyAt(i); Object* maybe_key = dictionary->KeyAt(i);
if (!Dictionary::IsKey(isolate, maybe_key)) continue; if (!Dictionary::IsKey(roots, maybe_key)) continue;
if (install_name_accessor && *install_name_accessor && if (install_name_accessor && *install_name_accessor &&
(maybe_key == *name_string)) { (maybe_key == *name_string)) {
*install_name_accessor = false; *install_name_accessor = false;
......
...@@ -98,7 +98,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { ...@@ -98,7 +98,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
#ifdef DEBUG #ifdef DEBUG
DCHECK(key->IsJSReceiver()); DCHECK(key->IsJSReceiver());
DCHECK(EphemeronHashTableShape::IsLive(isolate, *key)); DCHECK(EphemeronHashTableShape::IsLive(ReadOnlyRoots(isolate), *key));
Handle<EphemeronHashTable> table( Handle<EphemeronHashTable> table(
EphemeronHashTable::cast(weak_collection->table()), isolate); EphemeronHashTable::cast(weak_collection->table()), isolate);
// Should only be called when shrinking the table is necessary. See // Should only be called when shrinking the table is necessary. See
...@@ -130,7 +130,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { ...@@ -130,7 +130,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
#ifdef DEBUG #ifdef DEBUG
DCHECK(key->IsJSReceiver()); DCHECK(key->IsJSReceiver());
DCHECK(EphemeronHashTableShape::IsLive(isolate, *key)); DCHECK(EphemeronHashTableShape::IsLive(ReadOnlyRoots(isolate), *key));
Handle<EphemeronHashTable> table( Handle<EphemeronHashTable> table(
EphemeronHashTable::cast(weak_collection->table()), isolate); EphemeronHashTable::cast(weak_collection->table()), isolate);
// Should only be called when rehashing or resizing the table is necessary. // Should only be called when rehashing or resizing the table is necessary.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment