Revert "[in-place weak refs] Use WeakArrayList in wasm"
This reverts commit 13401d2beb
.
Reason for revert: gc stress breakage
Original change's description:
> [in-place weak refs] Use WeakArrayList in wasm
>
> Now we can remove FixedArrayOfWeakCells (this was the last user).
>
> BUG=v8:7308
>
> Change-Id: I7b74f7833288b20d8f4d098a4afce640ea6db823
> Reviewed-on: https://chromium-review.googlesource.com/1150170
> Commit-Queue: Marja Hölttä <marja@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#54776}
TBR=marja@chromium.org,mlippautz@chromium.org,ahaas@chromium.org
Change-Id: I1bc1ad7e27813aeaaf191efdf74b865d676475f5
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7308
Reviewed-on: https://chromium-review.googlesource.com/1154787
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54778}
This commit is contained in:
parent
1bef7d219f
commit
0ad5dda14c
@ -704,7 +704,7 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() {
|
||||
RecordSimpleVirtualObjectStats(nullptr, heap_->retained_maps(),
|
||||
ObjectStats::RETAINED_MAPS_TYPE);
|
||||
|
||||
// WeakArrayList.
|
||||
// FixedArrayOfWeakCells.
|
||||
RecordSimpleVirtualObjectStats(
|
||||
nullptr, WeakArrayList::cast(heap_->noscript_shared_function_infos()),
|
||||
ObjectStats::NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE);
|
||||
|
@ -94,6 +94,7 @@ TYPE_CHECKER(FeedbackCell, FEEDBACK_CELL_TYPE)
|
||||
TYPE_CHECKER(FeedbackMetadata, FEEDBACK_METADATA_TYPE)
|
||||
TYPE_CHECKER(FeedbackVector, FEEDBACK_VECTOR_TYPE)
|
||||
TYPE_CHECKER(FixedArrayExact, FIXED_ARRAY_TYPE)
|
||||
TYPE_CHECKER(FixedArrayOfWeakCells, FIXED_ARRAY_TYPE)
|
||||
TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
|
||||
TYPE_CHECKER(Foreign, FOREIGN_TYPE)
|
||||
TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
|
||||
|
117
src/objects.cc
117
src/objects.cc
@ -10353,6 +10353,78 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
void FixedArrayOfWeakCells::Set(Isolate* isolate,
|
||||
Handle<FixedArrayOfWeakCells> array, int index,
|
||||
Handle<HeapObject> value) {
|
||||
DCHECK(array->IsEmptySlot(index)); // Don't overwrite anything.
|
||||
DCHECK(!value->IsMap());
|
||||
Handle<WeakCell> cell = isolate->factory()->NewWeakCell(value);
|
||||
Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
|
||||
array->set_last_used_index(index);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Handle<FixedArrayOfWeakCells> FixedArrayOfWeakCells::Add(
|
||||
Isolate* isolate, Handle<Object> maybe_array, Handle<HeapObject> value,
|
||||
int* assigned_index) {
|
||||
Handle<FixedArrayOfWeakCells> array =
|
||||
(maybe_array.is_null() || !maybe_array->IsFixedArrayOfWeakCells())
|
||||
? Allocate(isolate, 1, Handle<FixedArrayOfWeakCells>::null())
|
||||
: Handle<FixedArrayOfWeakCells>::cast(maybe_array);
|
||||
// Try to store the new entry if there's room. Optimize for consecutive
|
||||
// accesses.
|
||||
int first_index = array->last_used_index();
|
||||
int length = array->Length();
|
||||
if (length > 0) {
|
||||
for (int i = first_index;;) {
|
||||
if (array->IsEmptySlot((i))) {
|
||||
FixedArrayOfWeakCells::Set(isolate, array, i, value);
|
||||
if (assigned_index != nullptr) *assigned_index = i;
|
||||
return array;
|
||||
}
|
||||
i = (i + 1) % length;
|
||||
if (i == first_index) break;
|
||||
}
|
||||
}
|
||||
|
||||
// No usable slot found, grow the array.
|
||||
int new_length = length == 0 ? 1 : length + (length >> 1) + 4;
|
||||
Handle<FixedArrayOfWeakCells> new_array =
|
||||
Allocate(isolate, new_length, array);
|
||||
FixedArrayOfWeakCells::Set(isolate, new_array, length, value);
|
||||
if (assigned_index != nullptr) *assigned_index = length;
|
||||
return new_array;
|
||||
}
|
||||
|
||||
template <class CompactionCallback>
|
||||
void FixedArrayOfWeakCells::Compact(Isolate* isolate) {
|
||||
FixedArray* array = FixedArray::cast(this);
|
||||
int new_length = kFirstIndex;
|
||||
for (int i = kFirstIndex; i < array->length(); i++) {
|
||||
Object* element = array->get(i);
|
||||
if (element->IsSmi()) continue;
|
||||
if (WeakCell::cast(element)->cleared()) continue;
|
||||
Object* value = WeakCell::cast(element)->value();
|
||||
CompactionCallback::Callback(value, i - kFirstIndex,
|
||||
new_length - kFirstIndex);
|
||||
array->set(new_length++, element);
|
||||
}
|
||||
array->Shrink(isolate, new_length);
|
||||
set_last_used_index(0);
|
||||
}
|
||||
|
||||
void FixedArrayOfWeakCells::Iterator::Reset(Object* maybe_array) {
|
||||
if (maybe_array->IsFixedArrayOfWeakCells()) {
|
||||
list_ = FixedArrayOfWeakCells::cast(maybe_array);
|
||||
index_ = 0;
|
||||
#ifdef DEBUG
|
||||
last_used_index_ = list_->last_used_index();
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
void JSObject::PrototypeRegistryCompactionCallback(HeapObject* value,
|
||||
int old_index,
|
||||
int new_index) {
|
||||
@ -10364,6 +10436,51 @@ void JSObject::PrototypeRegistryCompactionCallback(HeapObject* value,
|
||||
proto_info->set_registry_slot(new_index);
|
||||
}
|
||||
|
||||
template void FixedArrayOfWeakCells::Compact<
|
||||
FixedArrayOfWeakCells::NullCallback>(Isolate* isolate);
|
||||
|
||||
bool FixedArrayOfWeakCells::Remove(Handle<HeapObject> value) {
|
||||
if (Length() == 0) return false;
|
||||
// Optimize for the most recently added element to be removed again.
|
||||
int first_index = last_used_index();
|
||||
for (int i = first_index;;) {
|
||||
if (Get(i) == *value) {
|
||||
Clear(i);
|
||||
// Users of FixedArrayOfWeakCells should make sure that there are no
|
||||
// duplicates.
|
||||
return true;
|
||||
}
|
||||
i = (i + 1) % Length();
|
||||
if (i == first_index) return false;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Handle<FixedArrayOfWeakCells> FixedArrayOfWeakCells::Allocate(
|
||||
Isolate* isolate, int size, Handle<FixedArrayOfWeakCells> initialize_from) {
|
||||
DCHECK_LE(0, size);
|
||||
Handle<FixedArray> result =
|
||||
isolate->factory()->NewUninitializedFixedArray(size + kFirstIndex);
|
||||
int index = 0;
|
||||
if (!initialize_from.is_null()) {
|
||||
DCHECK(initialize_from->Length() <= size);
|
||||
Handle<FixedArray> raw_source = Handle<FixedArray>::cast(initialize_from);
|
||||
// Copy the entries without compacting, since the PrototypeInfo relies on
|
||||
// the index of the entries not to change.
|
||||
while (index < raw_source->length()) {
|
||||
result->set(index, raw_source->get(index));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
while (index < result->length()) {
|
||||
result->set(index, Smi::kZero);
|
||||
index++;
|
||||
}
|
||||
return Handle<FixedArrayOfWeakCells>::cast(result);
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<ArrayList> ArrayList::Add(Isolate* isolate, Handle<ArrayList> array,
|
||||
Handle<Object> obj) {
|
||||
|
@ -106,6 +106,7 @@
|
||||
// - ScopeInfo
|
||||
// - ModuleInfo
|
||||
// - ScriptContextTable
|
||||
// - FixedArrayOfWeakCells
|
||||
// - FixedDoubleArray
|
||||
// - Name
|
||||
// - String
|
||||
@ -788,6 +789,7 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(FixedArray) \
|
||||
V(FixedArrayBase) \
|
||||
V(FixedArrayExact) \
|
||||
V(FixedArrayOfWeakCells) \
|
||||
V(FixedBigInt64Array) \
|
||||
V(FixedBigUint64Array) \
|
||||
V(FixedDoubleArray) \
|
||||
|
@ -24,6 +24,7 @@ CAST_ACCESSOR(FixedArrayBase)
|
||||
CAST_ACCESSOR(FixedDoubleArray)
|
||||
CAST_ACCESSOR(FixedTypedArrayBase)
|
||||
CAST_ACCESSOR(TemplateList)
|
||||
CAST_ACCESSOR(FixedArrayOfWeakCells)
|
||||
CAST_ACCESSOR(WeakFixedArray)
|
||||
CAST_ACCESSOR(WeakArrayList)
|
||||
|
||||
@ -296,6 +297,48 @@ HeapObject* WeakArrayList::Iterator::Next() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Object* FixedArrayOfWeakCells::Get(int index) const {
|
||||
Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
|
||||
if (raw->IsSmi()) return raw;
|
||||
DCHECK(raw->IsWeakCell());
|
||||
return WeakCell::cast(raw)->value();
|
||||
}
|
||||
|
||||
bool FixedArrayOfWeakCells::IsEmptySlot(int index) const {
|
||||
DCHECK(index < Length());
|
||||
return Get(index)->IsSmi();
|
||||
}
|
||||
|
||||
void FixedArrayOfWeakCells::Clear(int index) {
|
||||
FixedArray::cast(this)->set(index + kFirstIndex, Smi::kZero);
|
||||
}
|
||||
|
||||
int FixedArrayOfWeakCells::Length() const {
|
||||
return FixedArray::cast(this)->length() - kFirstIndex;
|
||||
}
|
||||
|
||||
int FixedArrayOfWeakCells::last_used_index() const {
|
||||
return Smi::ToInt(FixedArray::cast(this)->get(kLastUsedIndexIndex));
|
||||
}
|
||||
|
||||
void FixedArrayOfWeakCells::set_last_used_index(int index) {
|
||||
FixedArray::cast(this)->set(kLastUsedIndexIndex, Smi::FromInt(index));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* FixedArrayOfWeakCells::Iterator::Next() {
|
||||
if (list_ != nullptr) {
|
||||
// Assert that list did not change during iteration.
|
||||
DCHECK_EQ(last_used_index_, list_->last_used_index());
|
||||
while (index_ < list_->Length()) {
|
||||
Object* item = list_->Get(index_++);
|
||||
if (item != Empty()) return T::cast(item);
|
||||
}
|
||||
list_ = nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ArrayList::Length() const {
|
||||
if (FixedArray::cast(this)->length() == 0) return 0;
|
||||
return Smi::ToInt(FixedArray::cast(this)->get(kLengthIndex));
|
||||
|
@ -396,6 +396,79 @@ class WeakArrayList : public HeapObject {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(WeakArrayList);
|
||||
};
|
||||
|
||||
// Deprecated. Use WeakFixedArray instead.
|
||||
class FixedArrayOfWeakCells : public FixedArray {
|
||||
public:
|
||||
// If |maybe_array| is not a FixedArrayOfWeakCells, a fresh one will be
|
||||
// allocated. This function does not check if the value exists already,
|
||||
// callers must ensure this themselves if necessary.
|
||||
static Handle<FixedArrayOfWeakCells> Add(Isolate* isolate,
|
||||
Handle<Object> maybe_array,
|
||||
Handle<HeapObject> value,
|
||||
int* assigned_index = nullptr);
|
||||
|
||||
// Returns true if an entry was found and removed.
|
||||
bool Remove(Handle<HeapObject> value);
|
||||
|
||||
class NullCallback {
|
||||
public:
|
||||
static void Callback(Object* value, int old_index, int new_index) {}
|
||||
};
|
||||
|
||||
template <class CompactionCallback>
|
||||
void Compact(Isolate* isolate);
|
||||
|
||||
inline Object* Get(int index) const;
|
||||
inline void Clear(int index);
|
||||
inline int Length() const;
|
||||
|
||||
inline bool IsEmptySlot(int index) const;
|
||||
static Object* Empty() { return Smi::kZero; }
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
explicit Iterator(Object* maybe_array) : list_(nullptr) {
|
||||
Reset(maybe_array);
|
||||
}
|
||||
void Reset(Object* maybe_array);
|
||||
|
||||
template <class T>
|
||||
inline T* Next();
|
||||
|
||||
private:
|
||||
int index_;
|
||||
FixedArrayOfWeakCells* list_;
|
||||
#ifdef DEBUG
|
||||
int last_used_index_;
|
||||
DisallowHeapAllocation no_gc_;
|
||||
#endif // DEBUG
|
||||
DISALLOW_COPY_AND_ASSIGN(Iterator);
|
||||
};
|
||||
|
||||
DECL_CAST(FixedArrayOfWeakCells)
|
||||
|
||||
private:
|
||||
static const int kLastUsedIndexIndex = 0;
|
||||
static const int kFirstIndex = 1;
|
||||
|
||||
static Handle<FixedArrayOfWeakCells> Allocate(
|
||||
Isolate* isolate, int size,
|
||||
Handle<FixedArrayOfWeakCells> initialize_from);
|
||||
|
||||
static void Set(Isolate* isolate, Handle<FixedArrayOfWeakCells> array,
|
||||
int index, Handle<HeapObject> value);
|
||||
inline void clear(int index);
|
||||
|
||||
inline int last_used_index() const;
|
||||
inline void set_last_used_index(int index);
|
||||
|
||||
// Disallow inherited setters.
|
||||
void set(int index, Smi* value);
|
||||
void set(int index, Object* value);
|
||||
void set(int index, Object* value, WriteBarrierMode mode);
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArrayOfWeakCells);
|
||||
};
|
||||
|
||||
// Generic array grows dynamically with O(1) amortized insertion.
|
||||
//
|
||||
// ArrayList is a FixedArray with static convenience methods for adding more
|
||||
|
@ -86,7 +86,8 @@ ACCESSORS(WasmTableObject, dispatch_tables, FixedArray, kDispatchTablesOffset)
|
||||
// WasmMemoryObject
|
||||
ACCESSORS(WasmMemoryObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
|
||||
SMI_ACCESSORS(WasmMemoryObject, maximum_pages, kMaximumPagesOffset)
|
||||
OPTIONAL_ACCESSORS(WasmMemoryObject, instances, WeakArrayList, kInstancesOffset)
|
||||
OPTIONAL_ACCESSORS(WasmMemoryObject, instances, FixedArrayOfWeakCells,
|
||||
kInstancesOffset)
|
||||
|
||||
// WasmGlobalObject
|
||||
ACCESSORS(WasmGlobalObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
|
||||
|
@ -1015,13 +1015,12 @@ bool WasmMemoryObject::has_full_guard_region(Isolate* isolate) {
|
||||
void WasmMemoryObject::AddInstance(Isolate* isolate,
|
||||
Handle<WasmMemoryObject> memory,
|
||||
Handle<WasmInstanceObject> instance) {
|
||||
Handle<WeakArrayList> old_instances =
|
||||
Handle<FixedArrayOfWeakCells> old_instances =
|
||||
memory->has_instances()
|
||||
? Handle<WeakArrayList>(memory->instances(), isolate)
|
||||
: handle(ReadOnlyRoots(isolate->heap()).empty_weak_array_list(),
|
||||
isolate);
|
||||
Handle<WeakArrayList> new_instances = WeakArrayList::AddToEnd(
|
||||
isolate, old_instances, MaybeObjectHandle::Weak(instance));
|
||||
? Handle<FixedArrayOfWeakCells>(memory->instances(), isolate)
|
||||
: Handle<FixedArrayOfWeakCells>::null();
|
||||
Handle<FixedArrayOfWeakCells> new_instances =
|
||||
FixedArrayOfWeakCells::Add(isolate, old_instances, instance);
|
||||
memory->set_instances(*new_instances);
|
||||
Handle<JSArrayBuffer> buffer(memory->array_buffer(), isolate);
|
||||
SetInstanceMemory(instance, buffer);
|
||||
@ -1030,7 +1029,7 @@ void WasmMemoryObject::AddInstance(Isolate* isolate,
|
||||
void WasmMemoryObject::RemoveInstance(Handle<WasmMemoryObject> memory,
|
||||
Handle<WasmInstanceObject> instance) {
|
||||
if (memory->has_instances()) {
|
||||
memory->instances()->RemoveOne(MaybeObjectHandle::Weak(instance));
|
||||
memory->instances()->Remove(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1056,17 +1055,14 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
|
||||
}
|
||||
|
||||
if (memory_object->has_instances()) {
|
||||
Handle<WeakArrayList> instances(memory_object->instances(), isolate);
|
||||
for (int i = 0; i < instances->length(); i++) {
|
||||
MaybeObject* elem = instances->Get(i);
|
||||
HeapObject* heap_object;
|
||||
if (elem->ToWeakHeapObject(&heap_object)) {
|
||||
Handle<WasmInstanceObject> instance(
|
||||
WasmInstanceObject::cast(heap_object), isolate);
|
||||
SetInstanceMemory(instance, new_buffer);
|
||||
} else {
|
||||
DCHECK(elem->IsClearedWeakHeapObject());
|
||||
}
|
||||
Handle<FixedArrayOfWeakCells> instances(memory_object->instances(),
|
||||
isolate);
|
||||
for (int i = 0; i < instances->Length(); i++) {
|
||||
Object* elem = instances->Get(i);
|
||||
if (!elem->IsWasmInstanceObject()) continue;
|
||||
Handle<WasmInstanceObject> instance(WasmInstanceObject::cast(elem),
|
||||
isolate);
|
||||
SetInstanceMemory(instance, new_buffer);
|
||||
}
|
||||
}
|
||||
memory_object->set_array_buffer(*new_buffer);
|
||||
|
@ -34,6 +34,7 @@ using FunctionSig = Signature<ValueType>;
|
||||
|
||||
class BreakPoint;
|
||||
class JSArrayBuffer;
|
||||
class FixedArrayOfWeakCells;
|
||||
class SeqOneByteString;
|
||||
class WasmDebugInfo;
|
||||
class WasmInstanceObject;
|
||||
@ -283,7 +284,7 @@ class WasmMemoryObject : public JSObject {
|
||||
|
||||
DECL_ACCESSORS(array_buffer, JSArrayBuffer)
|
||||
DECL_INT_ACCESSORS(maximum_pages)
|
||||
DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList)
|
||||
DECL_OPTIONAL_ACCESSORS(instances, FixedArrayOfWeakCells)
|
||||
|
||||
// Layout description.
|
||||
#define WASM_MEMORY_OBJECT_FIELDS(V) \
|
||||
|
@ -4773,6 +4773,20 @@ TEST(WritableVsImmortalRoots) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FixedArrayOfWeakCells) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
|
||||
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(1);
|
||||
Handle<FixedArrayOfWeakCells> array =
|
||||
FixedArrayOfWeakCells::Add(isolate, Handle<Object>(), number);
|
||||
array->Remove(number);
|
||||
array->Compact<FixedArrayOfWeakCells::NullCallback>(isolate);
|
||||
FixedArrayOfWeakCells::Add(isolate, array, number);
|
||||
}
|
||||
|
||||
|
||||
TEST(PreprocessStackTrace) {
|
||||
// Do not automatically trigger early GC.
|
||||
FLAG_gc_interval = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user