[objects] Pass isolate to HashTable accesses

Change-Id: I90612ae0e54b46e7147d9a3392783f56da598b2b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2287499
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68750}
This commit is contained in:
Leszek Swirski 2020-07-09 09:32:19 +02:00 committed by Commit Bot
parent a1b752a7a7
commit 8377214ae8
16 changed files with 163 additions and 111 deletions

View File

@ -428,10 +428,9 @@ PropertyAccessInfo AccessInfoFactory::ComputeAccessorDescriptorAccessInfo(
isolate());
Handle<JSModuleNamespace> module_namespace(
JSModuleNamespace::cast(proto_info->module_namespace()), isolate());
Handle<Cell> cell(
Cell::cast(module_namespace->module().exports().Lookup(
ReadOnlyRoots(isolate()), name, Smi::ToInt(name->GetHash()))),
isolate());
Handle<Cell> cell(Cell::cast(module_namespace->module().exports().Lookup(
isolate(), name, Smi::ToInt(name->GetHash()))),
isolate());
if (cell->value().IsTheHole(isolate())) {
// This module has not been fully initialized yet.
return PropertyAccessInfo::Invalid(zone());

View File

@ -5,10 +5,10 @@
#ifndef V8_EXECUTION_ISOLATE_UTILS_INL_H_
#define V8_EXECUTION_ISOLATE_UTILS_INL_H_
#include "src/execution/isolate-utils.h"
#include "src/common/ptr-compr-inl.h"
#include "src/execution/isolate-utils.h"
#include "src/execution/isolate.h"
#include "src/execution/local-isolate-wrapper.h"
#include "src/heap/heap-write-barrier-inl.h"
namespace v8 {
@ -22,6 +22,31 @@ inline const Isolate* GetIsolateForPtrCompr(HeapObject object) {
#endif // V8_COMPRESS_POINTERS
}
inline const Isolate* GetIsolateForPtrCompr(const Isolate* isolate) {
#ifdef V8_COMPRESS_POINTERS
return isolate;
#else
return nullptr;
#endif // V8_COMPRESS_POINTERS
}
inline const Isolate* GetIsolateForPtrCompr(const OffThreadIsolate* isolate) {
#ifdef V8_COMPRESS_POINTERS
return isolate->GetIsolateForPtrCompr();
#else
return nullptr;
#endif // V8_COMPRESS_POINTERS
}
inline const Isolate* GetIsolateForPtrCompr(LocalIsolateWrapper isolate) {
#ifdef V8_COMPRESS_POINTERS
return isolate.is_main_thread() ? isolate.main_thread()
: GetIsolateForPtrCompr(isolate.off_thread());
#else
return nullptr;
#endif // V8_COMPRESS_POINTERS
}
V8_INLINE Heap* GetHeapFromWritableObject(HeapObject object) {
// Avoid using the below GetIsolateFromWritableObject because we want to be
// able to get the heap, but not the isolate, for off-thread objects.

View File

@ -89,6 +89,8 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
inline ReadOnlyHeap* read_only_heap();
inline Object root(RootIndex index);
const Isolate* GetIsolateForPtrCompr() const { return isolate_; }
v8::internal::OffThreadFactory* factory() {
// Upcast to the privately inherited base-class using c-style casts to avoid
// undefined behavior (as static_cast cannot cast across private bases).

View File

@ -16,7 +16,7 @@ namespace internal {
ReadOnlyRoots ReadOnlyHeap::GetReadOnlyRoots(HeapObject object) {
#ifdef V8_COMPRESS_POINTERS
const Isolate* isolate = GetIsolateForPtrCompr(object);
return ReadOnlyRoots(isolate);
return ReadOnlyRoots(const_cast<Isolate*>(isolate));
#else
#ifdef V8_SHARED_RO_HEAP
// This fails if we are creating heap objects and the roots haven't yet been

View File

@ -828,8 +828,9 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<ObjectHashTable> exports(
Handle<JSModuleNamespace>::cast(holder)->module().exports(),
isolate());
InternalIndex entry = exports->FindEntry(
roots, lookup->name(), Smi::ToInt(lookup->name()->GetHash()));
InternalIndex entry =
exports->FindEntry(isolate(), roots, lookup->name(),
Smi::ToInt(lookup->name()->GetHash()));
// We found the accessor, so the entry must exist.
DCHECK(entry.is_found());
int index = ObjectHashTable::EntryToValueIndex(entry);

View File

@ -1365,7 +1365,7 @@ class DictionaryElementsAccessor
// Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly.
for (InternalIndex entry : dict->IterateEntries()) {
Object index = dict->KeyAt(entry);
Object index = dict->KeyAt(isolate, entry);
if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index.Number());
if (length <= number && number < old_length) {
@ -1383,7 +1383,7 @@ class DictionaryElementsAccessor
// Remove elements that should be deleted.
int removed_entries = 0;
for (InternalIndex entry : dict->IterateEntries()) {
Object index = dict->KeyAt(entry);
Object index = dict->KeyAt(isolate, entry);
if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index.Number());
if (length <= number && number < old_length) {
@ -1423,9 +1423,10 @@ class DictionaryElementsAccessor
DisallowHeapAllocation no_gc;
NumberDictionary dict = NumberDictionary::cast(backing_store);
if (!dict.requires_slow_elements()) return false;
ReadOnlyRoots roots = holder.GetReadOnlyRoots();
const Isolate* isolate = GetIsolateForPtrCompr(holder);
ReadOnlyRoots roots = holder.GetReadOnlyRoots(isolate);
for (InternalIndex i : dict.IterateEntries()) {
Object key = dict.KeyAt(i);
Object key = dict.KeyAt(isolate, i);
if (!dict.IsKey(roots, key)) continue;
PropertyDetails details = dict.DetailsAt(i);
if (details.kind() == kAccessor) return true;
@ -1488,7 +1489,7 @@ class DictionaryElementsAccessor
InternalIndex entry) {
DisallowHeapAllocation no_gc;
NumberDictionary dict = NumberDictionary::cast(store);
Object index = dict.KeyAt(entry);
Object index = dict.KeyAt(isolate, entry);
return !index.IsTheHole(isolate);
}
@ -1535,7 +1536,7 @@ class DictionaryElementsAccessor
InternalIndex entry,
PropertyFilter filter) {
DisallowHeapAllocation no_gc;
Object raw_key = dictionary->KeyAt(entry);
Object raw_key = dictionary->KeyAt(isolate, entry);
if (!dictionary->IsKey(ReadOnlyRoots(isolate), raw_key)) return kMaxUInt32;
return FilterKey(dictionary, entry, raw_key, filter);
}
@ -1554,7 +1555,7 @@ class DictionaryElementsAccessor
ReadOnlyRoots roots(isolate);
for (InternalIndex i : dictionary->IterateEntries()) {
AllowHeapAllocation allow_gc;
Object raw_key = dictionary->KeyAt(i);
Object raw_key = dictionary->KeyAt(isolate, i);
if (!dictionary->IsKey(roots, raw_key)) continue;
uint32_t key = FilterKey(dictionary, i, raw_key, filter);
if (key == kMaxUInt32) {
@ -1601,9 +1602,9 @@ class DictionaryElementsAccessor
NumberDictionary::cast(receiver->elements()), isolate);
ReadOnlyRoots roots(isolate);
for (InternalIndex i : dictionary->IterateEntries()) {
Object k = dictionary->KeyAt(i);
Object k = dictionary->KeyAt(isolate, i);
if (!dictionary->IsKey(roots, k)) continue;
Object value = dictionary->ValueAt(i);
Object value = dictionary->ValueAt(isolate, i);
DCHECK(!value.IsTheHole(isolate));
DCHECK(!value.IsAccessorPair());
DCHECK(!value.IsAccessorInfo());
@ -1624,7 +1625,7 @@ class DictionaryElementsAccessor
// must be accessed in order via the slow path.
bool found = false;
for (InternalIndex i : dictionary.IterateEntries()) {
Object k = dictionary.KeyAt(i);
Object k = dictionary.KeyAt(isolate, i);
if (k == the_hole) continue;
if (k == undefined) continue;
@ -1638,7 +1639,7 @@ class DictionaryElementsAccessor
// access getters out of order
return false;
} else if (!found) {
Object element_k = dictionary.ValueAt(i);
Object element_k = dictionary.ValueAt(isolate, i);
if (value->SameValueZero(element_k)) found = true;
}
}

View File

@ -5,11 +5,10 @@
#ifndef V8_OBJECTS_HASH_TABLE_INL_H_
#define V8_OBJECTS_HASH_TABLE_INL_H_
#include "src/objects/hash-table.h"
#include "src/execution/isolate-utils-inl.h"
#include "src/heap/heap.h"
#include "src/objects/fixed-array-inl.h"
#include "src/objects/hash-table.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/objects-inl.h"
#include "src/roots/roots-inl.h"
@ -132,19 +131,18 @@ Handle<Map> EphemeronHashTableShape::GetMap(ReadOnlyRoots roots) {
}
template <typename Derived, typename Shape>
InternalIndex HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) {
return FindEntry(ReadOnlyRoots(isolate), key);
}
template <typename Derived, typename Shape>
InternalIndex HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots,
template <typename LocalIsolate>
InternalIndex HashTable<Derived, Shape>::FindEntry(LocalIsolate* isolate,
Key key) {
return FindEntry(roots, key, Shape::Hash(roots, key));
ReadOnlyRoots roots(isolate);
return FindEntry(isolate, roots, key, Shape::Hash(roots, key));
}
// Find entry for key otherwise return kNotFound.
template <typename Derived, typename Shape>
InternalIndex HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
template <typename LocalIsolate>
InternalIndex HashTable<Derived, Shape>::FindEntry(const LocalIsolate* isolate,
ReadOnlyRoots roots, Key key,
int32_t hash) {
uint32_t capacity = Capacity();
InternalIndex entry = FirstProbe(hash, capacity);
@ -154,7 +152,7 @@ InternalIndex HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
Object the_hole = roots.the_hole_value();
USE(the_hole);
while (true) {
Object element = KeyAt(entry);
Object element = KeyAt(isolate, entry);
// Empty entry. Uses raw unchecked accessors because it is called by the
// string table during bootstrapping.
if (element == undefined) break;
@ -176,8 +174,8 @@ bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, InternalIndex entry,
}
template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, InternalIndex entry,
Object* out_k) {
bool HashTable<Derived, Shape>::ToKey(const Isolate* isolate,
InternalIndex entry, Object* out_k) {
Object k = KeyAt(isolate, entry);
if (!IsKey(GetReadOnlyRoots(isolate), k)) return false;
*out_k = Shape::Unwrap(k);
@ -191,9 +189,11 @@ Object HashTable<Derived, Shape>::KeyAt(InternalIndex entry) {
}
template <typename Derived, typename Shape>
Object HashTable<Derived, Shape>::KeyAt(const Isolate* isolate,
template <typename LocalIsolate>
Object HashTable<Derived, Shape>::KeyAt(const LocalIsolate* isolate,
InternalIndex entry) {
return get(isolate, EntryToIndex(entry) + kEntryKeyIndex);
return get(GetIsolateForPtrCompr(isolate),
EntryToIndex(entry) + kEntryKeyIndex);
}
template <typename Derived, typename Shape>
@ -230,13 +230,14 @@ bool BaseShape<KeyT>::IsLive(ReadOnlyRoots roots, Object k) {
}
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) {
return FindEntry(ReadOnlyRoots(isolate), key, hash).is_found();
return FindEntry(isolate, ReadOnlyRoots(isolate), key, hash).is_found();
}
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) {
Object hash = key->GetHash();
if (!hash.IsSmi()) return false;
return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)).is_found();
return FindEntry(isolate, ReadOnlyRoots(isolate), key, Smi::ToInt(hash))
.is_found();
}
bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object other) {

View File

@ -140,12 +140,14 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
void IterateElements(ObjectVisitor* visitor);
// Find entry for key otherwise return kNotFound.
inline InternalIndex FindEntry(ReadOnlyRoots roots, Key key, int32_t hash);
inline InternalIndex FindEntry(ReadOnlyRoots roots, Key key);
inline InternalIndex FindEntry(Isolate* isolate, Key key);
template <typename LocalIsolate>
inline InternalIndex FindEntry(const LocalIsolate* isolate,
ReadOnlyRoots roots, Key key, int32_t hash);
template <typename LocalIsolate>
inline InternalIndex FindEntry(LocalIsolate* isolate, Key key);
// Rehashes the table in-place.
void Rehash(ReadOnlyRoots roots);
void Rehash(const Isolate* isolate);
// Returns 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.
@ -154,11 +156,12 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
}
inline bool ToKey(ReadOnlyRoots roots, InternalIndex entry, Object* out_k);
inline bool ToKey(Isolate* isolate, InternalIndex entry, Object* out_k);
inline bool ToKey(const Isolate* isolate, InternalIndex entry, Object* out_k);
// Returns the key at entry.
inline Object KeyAt(InternalIndex entry);
inline Object KeyAt(const Isolate* isolate, InternalIndex entry);
template <typename LocalIsolate>
inline Object KeyAt(const LocalIsolate* isolate, InternalIndex entry);
static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize;
static const int kEntrySize = Shape::kEntrySize;
@ -210,7 +213,9 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
// Find the entry at which to insert element with the given key that
// has the given hash value.
InternalIndex FindInsertionEntry(uint32_t hash);
InternalIndex FindInsertionEntry(const Isolate* isolate, ReadOnlyRoots roots,
uint32_t hash);
InternalIndex FindInsertionEntry(Isolate* isolate, uint32_t hash);
// Attempt to shrink hash table after removal of key.
V8_WARN_UNUSED_RESULT static Handle<Derived> Shrink(
@ -242,7 +247,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
void Swap(InternalIndex entry1, InternalIndex entry2, WriteBarrierMode mode);
// Rehashes this hash-table into the new table.
void Rehash(ReadOnlyRoots roots, Derived new_table);
void Rehash(const Isolate* isolate, Derived new_table);
OBJECT_CONSTRUCTORS(HashTable, HashTableBase);
};
@ -308,7 +313,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) ObjectHashTableBase
// returned in case the key is not present.
Object Lookup(Handle<Object> key);
Object Lookup(Handle<Object> key, int32_t hash);
Object Lookup(ReadOnlyRoots roots, Handle<Object> key, int32_t hash);
Object Lookup(const Isolate* isolate, Handle<Object> key, int32_t hash);
// Returns the value at entry.
Object ValueAt(InternalIndex entry);

View File

@ -2323,17 +2323,16 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
Handle<GlobalDictionary> dictionary(global_obj->global_dictionary(),
isolate);
InternalIndex entry =
dictionary->FindEntry(ReadOnlyRoots(isolate), name, hash);
ReadOnlyRoots roots(isolate);
InternalIndex entry = dictionary->FindEntry(isolate, roots, name, hash);
if (entry.is_not_found()) {
DCHECK_IMPLIES(global_obj->map().is_prototype_map(),
Map::IsPrototypeChainInvalidated(global_obj->map()));
auto cell = isolate->factory()->NewPropertyCell(name);
cell->set_value(*value);
auto cell_type = value->IsUndefined(isolate)
? PropertyCellType::kUndefined
: PropertyCellType::kConstant;
auto cell_type = value->IsUndefined(roots) ? PropertyCellType::kUndefined
: PropertyCellType::kConstant;
details = details.set_cell_type(cell_type);
value = cell;
dictionary =
@ -3326,7 +3325,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
ReadOnlyRoots roots(isolate);
for (int i = 0; i < instance_descriptor_length; i++) {
InternalIndex index(Smi::ToInt(iteration_order->get(i)));
DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(index)));
DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(isolate, index)));
PropertyKind kind = dictionary->DetailsAt(index).kind();
if (kind == kData) {

View File

@ -133,7 +133,7 @@ void AddToDictionaryTemplate(LocalIsolate* isolate,
int key_index,
ClassBoilerplate::ValueKind value_kind,
Smi value) {
InternalIndex entry = dictionary->FindEntry(ReadOnlyRoots(isolate), key);
InternalIndex entry = dictionary->FindEntry(isolate, key);
if (entry.is_not_found()) {
// Entry not found, add new one.

View File

@ -10,8 +10,6 @@
#include <sstream>
#include <vector>
#include "src/objects/objects-inl.h"
#include "src/api/api-arguments-inl.h"
#include "src/api/api-natives.h"
#include "src/api/api.h"
@ -33,6 +31,8 @@
#include "src/execution/execution.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/isolate-utils-inl.h"
#include "src/execution/isolate-utils.h"
#include "src/execution/microtask-queue.h"
#include "src/execution/off-thread-isolate.h"
#include "src/execution/protectors-inl.h"
@ -69,6 +69,7 @@
#include "src/objects/lookup-inl.h"
#include "src/objects/map-updater.h"
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-details.h"
#include "src/roots/roots.h"
#include "src/utils/identity-map.h"
@ -2359,24 +2360,24 @@ bool HeapObject::CanBeRehashed() const {
}
void HeapObject::RehashBasedOnMap(LocalIsolateWrapper isolate) {
ReadOnlyRoots roots = ReadOnlyRoots(isolate);
const Isolate* ptr_cmp_isolate = GetIsolateForPtrCompr(isolate);
switch (map().instance_type()) {
case HASH_TABLE_TYPE:
UNREACHABLE();
case NAME_DICTIONARY_TYPE:
NameDictionary::cast(*this).Rehash(roots);
NameDictionary::cast(*this).Rehash(ptr_cmp_isolate);
break;
case GLOBAL_DICTIONARY_TYPE:
GlobalDictionary::cast(*this).Rehash(roots);
GlobalDictionary::cast(*this).Rehash(ptr_cmp_isolate);
break;
case NUMBER_DICTIONARY_TYPE:
NumberDictionary::cast(*this).Rehash(roots);
NumberDictionary::cast(*this).Rehash(ptr_cmp_isolate);
break;
case SIMPLE_NUMBER_DICTIONARY_TYPE:
SimpleNumberDictionary::cast(*this).Rehash(roots);
SimpleNumberDictionary::cast(*this).Rehash(ptr_cmp_isolate);
break;
case STRING_TABLE_TYPE:
StringTable::cast(*this).Rehash(roots);
StringTable::cast(*this).Rehash(ptr_cmp_isolate);
break;
case DESCRIPTOR_ARRAY_TYPE:
DCHECK_LE(1, DescriptorArray::cast(*this).number_of_descriptors());
@ -5796,10 +5797,11 @@ bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index) {
template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::Print(std::ostream& os) {
DisallowHeapAllocation no_gc;
ReadOnlyRoots roots = this->GetReadOnlyRoots();
const Isolate* isolate = GetIsolateForPtrCompr(*this);
ReadOnlyRoots roots = this->GetReadOnlyRoots(isolate);
Derived dictionary = Derived::cast(*this);
for (InternalIndex i : dictionary.IterateEntries()) {
Object k = dictionary.KeyAt(i);
Object k = dictionary.KeyAt(isolate, i);
if (!dictionary.ToKey(roots, i, &k)) continue;
os << "\n ";
if (k.IsString()) {
@ -6649,7 +6651,8 @@ Handle<Derived> HashTable<Derived, Shape>::NewInternal(
}
template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
void HashTable<Derived, Shape>::Rehash(const Isolate* isolate,
Derived new_table) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = new_table.GetWriteBarrierMode(no_gc);
@ -6657,19 +6660,21 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
// Copy prefix to new array.
for (int i = kPrefixStartIndex; i < kElementsStartIndex; i++) {
new_table.set(i, get(i), mode);
new_table.set(i, get(isolate, i), mode);
}
// Rehash the elements.
ReadOnlyRoots roots = GetReadOnlyRoots(isolate);
for (InternalIndex i : this->IterateEntries()) {
uint32_t from_index = EntryToIndex(i);
Object k = this->get(from_index);
Object k = this->get(isolate, from_index);
if (!Shape::IsLive(roots, k)) continue;
uint32_t hash = Shape::HashForObject(roots, k);
uint32_t insertion_index = EntryToIndex(new_table.FindInsertionEntry(hash));
new_table.set_key(insertion_index, get(from_index), mode);
uint32_t insertion_index =
EntryToIndex(new_table.FindInsertionEntry(isolate, roots, hash));
new_table.set_key(insertion_index, get(isolate, from_index), mode);
for (int j = 1; j < Shape::kEntrySize; j++) {
new_table.set(insertion_index + j, get(from_index + j), mode);
new_table.set(insertion_index + j, get(isolate, from_index + j), mode);
}
}
new_table.SetNumberOfElements(NumberOfElements());
@ -6711,9 +6716,10 @@ void HashTable<Derived, Shape>::Swap(InternalIndex entry1, InternalIndex entry2,
}
template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
void HashTable<Derived, Shape>::Rehash(const Isolate* isolate) {
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
ReadOnlyRoots roots = GetReadOnlyRoots(isolate);
uint32_t capacity = Capacity();
bool done = false;
for (int probe = 1; !done; probe++) {
@ -6722,7 +6728,7 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
done = true;
for (InternalIndex current(0); current.raw_value() < capacity;
/* {current} is advanced manually below, when appropriate.*/) {
Object current_key = KeyAt(current);
Object current_key = KeyAt(isolate, current);
if (!Shape::IsLive(roots, current_key)) {
++current; // Advance to next entry.
continue;
@ -6732,7 +6738,7 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
++current; // Advance to next entry.
continue;
}
Object target_key = KeyAt(target);
Object target_key = KeyAt(isolate, target);
if (!Shape::IsLive(roots, target_key) ||
EntryForProbe(roots, target_key, probe, target) != target) {
// Put the current element into the correct position.
@ -6752,7 +6758,7 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
HeapObject undefined = roots.undefined_value();
Derived* self = static_cast<Derived*>(this);
for (InternalIndex current : InternalIndex::Range(capacity)) {
if (KeyAt(current) == the_hole) {
if (KeyAt(isolate, current) == the_hole) {
self->set_key(EntryToIndex(current) + kEntryKeyIndex, undefined,
SKIP_WRITE_BARRIER);
}
@ -6778,7 +6784,7 @@ Handle<Derived> HashTable<Derived, Shape>::EnsureCapacity(
isolate, new_nof,
should_pretenure ? AllocationType::kOld : AllocationType::kYoung);
table->Rehash(ReadOnlyRoots(isolate), *new_table);
table->Rehash(GetIsolateForPtrCompr(isolate), *new_table);
return new_table;
}
@ -6825,24 +6831,30 @@ Handle<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
pretenure ? AllocationType::kOld : AllocationType::kYoung,
USE_CUSTOM_MINIMUM_CAPACITY);
table->Rehash(ReadOnlyRoots(isolate), *new_table);
table->Rehash(isolate, *new_table);
return new_table;
}
template <typename Derived, typename Shape>
InternalIndex HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) {
InternalIndex HashTable<Derived, Shape>::FindInsertionEntry(
const Isolate* isolate, ReadOnlyRoots roots, uint32_t hash) {
uint32_t capacity = Capacity();
InternalIndex entry = FirstProbe(hash, capacity);
uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full.
ReadOnlyRoots roots = GetReadOnlyRoots();
while (true) {
if (!Shape::IsLive(roots, KeyAt(entry))) break;
if (!Shape::IsLive(roots, KeyAt(isolate, entry))) break;
entry = NextProbe(entry, count++, capacity);
}
return entry;
}
template <typename Derived, typename Shape>
InternalIndex HashTable<Derived, Shape>::FindInsertionEntry(Isolate* isolate,
uint32_t hash) {
return FindInsertionEntry(isolate, ReadOnlyRoots(isolate), hash);
}
void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
int expected) {
Handle<StringTable> table = isolate->factory()->string_table();
@ -6927,7 +6939,7 @@ Handle<String> StringTable::AddKeyNoResize(Isolate* isolate,
DCHECK(table->FindEntry(isolate, key).is_not_found());
// Add the new string and return it along with the string table.
InternalIndex entry = table->FindInsertionEntry(key->hash());
InternalIndex entry = table->FindInsertionEntry(isolate, key->hash());
table->set(EntryToIndex(entry), *string);
table->ElementAdded();
@ -6984,14 +6996,14 @@ Address LookupString(Isolate* isolate, String string, String source,
}
InternalIndex entry =
table.FindEntry(ReadOnlyRoots(isolate), &key, key.hash());
table.FindEntry(isolate, ReadOnlyRoots(isolate), &key, key.hash());
if (entry.is_not_found()) {
// A string that's not an array index, and not in the string table,
// cannot have been used as a property name before.
return Smi::FromInt(ResultSentinel::kNotFound).ptr();
}
String internalized = String::cast(table.KeyAt(entry));
String internalized = String::cast(table.KeyAt(isolate, entry));
if (FLAG_thin_strings) {
string.MakeThin(isolate, internalized);
}
@ -7043,7 +7055,7 @@ Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
if (!stringset->Has(isolate, name)) {
stringset = EnsureCapacity(isolate, stringset);
uint32_t hash = ShapeT::Hash(ReadOnlyRoots(isolate), *name);
InternalIndex entry = stringset->FindInsertionEntry(hash);
InternalIndex entry = stringset->FindInsertionEntry(isolate, hash);
stringset->set(EntryToIndex(entry), *name);
stringset->ElementAdded();
}
@ -7060,7 +7072,7 @@ Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
int32_t hash = key->GetOrCreateHash(isolate).value();
if (!set->Has(isolate, key, hash)) {
set = EnsureCapacity(isolate, set);
InternalIndex entry = set->FindInsertionEntry(hash);
InternalIndex entry = set->FindInsertionEntry(isolate, hash);
set->set(EntryToIndex(entry), *key);
set->ElementAdded();
}
@ -7256,7 +7268,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
Handle<Object> k = key.AsHandle(isolate);
cache = EnsureCapacity(isolate, cache);
InternalIndex entry = cache->FindInsertionEntry(key.Hash());
InternalIndex entry = cache->FindInsertionEntry(isolate, key.Hash());
cache->set(EntryToIndex(entry), *k);
cache->set(EntryToIndex(entry) + 1, *value);
cache->ElementAdded();
@ -7288,7 +7300,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
}
cache = EnsureCapacity(isolate, cache);
InternalIndex entry = cache->FindInsertionEntry(key.Hash());
InternalIndex entry = cache->FindInsertionEntry(isolate, key.Hash());
Handle<Object> k =
isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
cache->set(EntryToIndex(entry), *k);
@ -7302,7 +7314,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
JSRegExp::Flags flags, Handle<FixedArray> value) {
RegExpKey key(src, flags);
cache = EnsureCapacity(isolate, cache);
InternalIndex entry = cache->FindInsertionEntry(key.Hash());
InternalIndex entry = cache->FindInsertionEntry(isolate, key.Hash());
// We store the value in the key slot, and compare the search key
// to the stored value with a custon IsMatch function during lookups.
cache->set(EntryToIndex(entry), *value);
@ -7384,7 +7396,7 @@ int BaseNameDictionary<Derived, Shape>::NextEnumerationIndex(
for (int i = 0; i < length; i++) {
InternalIndex index(Smi::ToInt(iteration_order->get(i)));
DCHECK(dictionary->IsKey(dictionary->GetReadOnlyRoots(),
dictionary->KeyAt(index)));
dictionary->KeyAt(isolate, index)));
int enum_index = PropertyDetails::kInitialIndex + i;
@ -7465,20 +7477,21 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(LocalIsolate* isolate,
Key key, Handle<Object> value,
PropertyDetails details,
InternalIndex* entry_out) {
uint32_t hash = Shape::Hash(ReadOnlyRoots(isolate), key);
ReadOnlyRoots roots(isolate);
uint32_t hash = Shape::Hash(roots, key);
// Validate that the key is absent.
SLOW_DCHECK(
dictionary->FindEntry(ReadOnlyRoots(isolate), key).is_not_found());
SLOW_DCHECK(dictionary->FindEntry(isolate, key).is_not_found());
// Check whether the dictionary should be extended.
dictionary = Derived::EnsureCapacity(isolate, dictionary);
// Compute the key object.
Handle<Object> k = Shape::AsHandle(isolate, key);
InternalIndex entry = dictionary->FindInsertionEntry(hash);
InternalIndex entry = dictionary->FindInsertionEntry(
GetIsolateForPtrCompr(isolate), roots, hash);
dictionary->SetEntry(entry, *k, *value, details);
DCHECK(dictionary->KeyAt(entry).IsNumber() ||
Shape::Unwrap(dictionary->KeyAt(entry)).IsUniqueName());
DCHECK(dictionary->KeyAt(isolate, entry).IsNumber() ||
Shape::Unwrap(dictionary->KeyAt(isolate, entry)).IsUniqueName());
dictionary->ElementAdded();
if (entry_out) *entry_out = entry;
return dictionary;
@ -7743,13 +7756,14 @@ void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles(
}
template <typename Derived, typename Shape>
Object ObjectHashTableBase<Derived, Shape>::Lookup(ReadOnlyRoots roots,
Object ObjectHashTableBase<Derived, Shape>::Lookup(const Isolate* isolate,
Handle<Object> key,
int32_t hash) {
DisallowHeapAllocation no_gc;
ReadOnlyRoots roots = this->GetReadOnlyRoots(isolate);
DCHECK(this->IsKey(roots, *key));
InternalIndex entry = this->FindEntry(roots, key, hash);
InternalIndex entry = this->FindEntry(isolate, roots, key, hash);
if (entry.is_not_found()) return roots.the_hole_value();
return this->get(Derived::EntryToIndex(entry) + 1);
}
@ -7758,7 +7772,8 @@ template <typename Derived, typename Shape>
Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key) {
DisallowHeapAllocation no_gc;
ReadOnlyRoots roots = this->GetReadOnlyRoots();
const Isolate* isolate = GetIsolateForPtrCompr(*this);
ReadOnlyRoots roots = this->GetReadOnlyRoots(isolate);
DCHECK(this->IsKey(roots, *key));
// If the object does not have an identity hash, it was never used as a key.
@ -7766,13 +7781,13 @@ Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key) {
if (hash.IsUndefined(roots)) {
return roots.the_hole_value();
}
return Lookup(roots, key, Smi::ToInt(hash));
return Lookup(isolate, key, Smi::ToInt(hash));
}
template <typename Derived, typename Shape>
Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key,
int32_t hash) {
return Lookup(this->GetReadOnlyRoots(), key, hash);
return Lookup(GetIsolateForPtrCompr(*this), key, hash);
}
template <typename Derived, typename Shape>
@ -7805,7 +7820,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
DCHECK(table->IsKey(roots, *key));
DCHECK(!value->IsTheHole(roots));
InternalIndex entry = table->FindEntry(roots, key, hash);
InternalIndex entry = table->FindEntry(isolate, roots, key, hash);
// Key is already in table, just overwrite value.
if (entry.is_found()) {
@ -7816,7 +7831,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
// Rehash if more than 33% of the entries are deleted entries.
// TODO(jochen): Consider to shrink the fixed array in place.
if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
table->Rehash(roots);
table->Rehash(isolate);
}
// If we're out of luck, we didn't get a GC recently, and so rehashing
// isn't enough to avoid a crash.
@ -7828,13 +7843,13 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
isolate->heap()->CollectAllGarbage(
Heap::kNoGCFlags, GarbageCollectionReason::kFullHashtable);
}
table->Rehash(roots);
table->Rehash(isolate);
}
}
// Check whether the hash table should be extended.
table = Derived::EnsureCapacity(isolate, table);
table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
table->AddEntry(table->FindInsertionEntry(isolate, hash), *key, *value);
return table;
}
@ -7860,7 +7875,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
ReadOnlyRoots roots = table->GetReadOnlyRoots();
DCHECK(table->IsKey(roots, *key));
InternalIndex entry = table->FindEntry(roots, key, hash);
InternalIndex entry = table->FindEntry(isolate, roots, key, hash);
if (entry.is_not_found()) {
*was_present = false;
return table;

View File

@ -96,7 +96,8 @@ T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Relaxed_Load(const Isolate* isolate,
template <typename LocalIsolate>
T TaggedField<T, kFieldOffset>::Relaxed_Load(const LocalIsolate* isolate,
HeapObject host, int offset) {
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
return T(tagged_to_full(isolate, value));
@ -125,7 +126,8 @@ T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Acquire_Load(const Isolate* isolate,
template <typename LocalIsolate>
T TaggedField<T, kFieldOffset>::Acquire_Load(const LocalIsolate* isolate,
HeapObject host, int offset) {
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
return T(tagged_to_full(isolate, value));

View File

@ -44,14 +44,16 @@ class TaggedField : public AllStatic {
static inline void store(HeapObject host, int offset, T value);
static inline T Relaxed_Load(HeapObject host, int offset = 0);
static inline T Relaxed_Load(const Isolate* isolate, HeapObject host,
template <typename LocalIsolate>
static inline T Relaxed_Load(const LocalIsolate* isolate, HeapObject host,
int offset = 0);
static inline void Relaxed_Store(HeapObject host, T value);
static inline void Relaxed_Store(HeapObject host, int offset, T value);
static inline T Acquire_Load(HeapObject host, int offset = 0);
static inline T Acquire_Load(const Isolate* isolate, HeapObject host,
template <typename LocalIsolate>
static inline T Acquire_Load(const LocalIsolate* isolate, HeapObject host,
int offset = 0);
static inline void Release_Store(HeapObject host, T value);

View File

@ -65,7 +65,7 @@ ReadOnlyRoots::ReadOnlyRoots(Heap* heap)
ReadOnlyRoots::ReadOnlyRoots(OffThreadHeap* heap)
: ReadOnlyRoots(OffThreadIsolate::FromHeap(heap)) {}
ReadOnlyRoots::ReadOnlyRoots(const Isolate* isolate)
ReadOnlyRoots::ReadOnlyRoots(Isolate* isolate)
: read_only_roots_(reinterpret_cast<Address*>(
isolate->roots_table().read_only_roots_begin().address())) {}

View File

@ -529,7 +529,7 @@ class ReadOnlyRoots {
V8_INLINE explicit ReadOnlyRoots(Heap* heap);
V8_INLINE explicit ReadOnlyRoots(OffThreadHeap* heap);
V8_INLINE explicit ReadOnlyRoots(const Isolate* isolate);
V8_INLINE explicit ReadOnlyRoots(Isolate* isolate);
V8_INLINE explicit ReadOnlyRoots(OffThreadIsolate* isolate);
V8_INLINE explicit ReadOnlyRoots(LocalIsolateWrapper wrapper);
V8_INLINE explicit ReadOnlyRoots(LocalHeapWrapper wrapper);

View File

@ -218,7 +218,7 @@ TEST(HashTableRehash) {
for (int i = 0; i < capacity - 1; i++) {
t.insert(InternalIndex(i), i * i, i);
}
t.Rehash(ReadOnlyRoots(isolate));
t.Rehash(isolate);
for (int i = 0; i < capacity - 1; i++) {
CHECK_EQ(i, t.lookup(i * i));
}
@ -231,7 +231,7 @@ TEST(HashTableRehash) {
for (int i = 0; i < capacity / 2; i++) {
t.insert(InternalIndex(i), i * i, i);
}
t.Rehash(ReadOnlyRoots(isolate));
t.Rehash(isolate);
for (int i = 0; i < capacity / 2; i++) {
CHECK_EQ(i, t.lookup(i * i));
}