Commit c38f52f1 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

Reland [in-place weak refs] Use WeakArrayList in wasm

Now we can remove FixedArrayOfWeakCells (this was the last user).

Previous try: https://chromium-review.googlesource.com/1150170

BUG=v8:7308

Change-Id: Ie924e379ea8bbd797430e3ca591019fe001e78ad
Reviewed-on: https://chromium-review.googlesource.com/1154909Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54928}
parent 897e17a2
......@@ -704,7 +704,7 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() {
RecordSimpleVirtualObjectStats(nullptr, heap_->retained_maps(),
ObjectStats::RETAINED_MAPS_TYPE);
// FixedArrayOfWeakCells.
// WeakArrayList.
RecordSimpleVirtualObjectStats(
nullptr, WeakArrayList::cast(heap_->noscript_shared_function_infos()),
ObjectStats::NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE);
......
......@@ -10366,78 +10366,6 @@ 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) {
......@@ -10449,51 +10377,6 @@ 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) {
......@@ -10580,8 +10463,8 @@ Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
MaybeObjectHandle value) {
int length = array->length();
array = EnsureSpace(isolate, array, length + 1);
// Check that GC didn't remove elements from the array.
DCHECK_EQ(array->length(), length);
// Reload length; GC might have removed elements from the array.
length = array->length();
array->Set(length, *value);
array->set_length(length + 1);
return array;
......
......@@ -107,7 +107,6 @@
// - ScopeInfo
// - ModuleInfo
// - ScriptContextTable
// - FixedArrayOfWeakCells
// - FixedDoubleArray
// - Name
// - String
......@@ -789,7 +788,6 @@ class ZoneForwardList;
V(FixedArray) \
V(FixedArrayBase) \
V(FixedArrayExact) \
V(FixedArrayOfWeakCells) \
V(FixedBigInt64Array) \
V(FixedBigUint64Array) \
V(FixedDoubleArray) \
......@@ -961,7 +959,6 @@ class ZoneForwardList;
V(FeedbackMetadata, FEEDBACK_METADATA_TYPE) \
V(FeedbackVector, FEEDBACK_VECTOR_TYPE) \
V(FixedArrayExact, FIXED_ARRAY_TYPE) \
V(FixedArrayOfWeakCells, FIXED_ARRAY_TYPE) \
V(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE) \
V(Foreign, FOREIGN_TYPE) \
V(FreeSpace, FREE_SPACE_TYPE) \
......
......@@ -24,7 +24,6 @@ CAST_ACCESSOR(FixedArrayBase)
CAST_ACCESSOR(FixedDoubleArray)
CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(TemplateList)
CAST_ACCESSOR(FixedArrayOfWeakCells)
CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakArrayList)
......@@ -297,48 +296,6 @@ 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));
......
......@@ -406,79 +406,6 @@ 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,8 +86,7 @@ ACCESSORS(WasmTableObject, dispatch_tables, FixedArray, kDispatchTablesOffset)
// WasmMemoryObject
ACCESSORS(WasmMemoryObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
SMI_ACCESSORS(WasmMemoryObject, maximum_pages, kMaximumPagesOffset)
OPTIONAL_ACCESSORS(WasmMemoryObject, instances, FixedArrayOfWeakCells,
kInstancesOffset)
OPTIONAL_ACCESSORS(WasmMemoryObject, instances, WeakArrayList, kInstancesOffset)
// WasmGlobalObject
ACCESSORS(WasmGlobalObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
......
......@@ -1019,12 +1019,13 @@ bool WasmMemoryObject::has_full_guard_region(Isolate* isolate) {
void WasmMemoryObject::AddInstance(Isolate* isolate,
Handle<WasmMemoryObject> memory,
Handle<WasmInstanceObject> instance) {
Handle<FixedArrayOfWeakCells> old_instances =
Handle<WeakArrayList> old_instances =
memory->has_instances()
? Handle<FixedArrayOfWeakCells>(memory->instances(), isolate)
: Handle<FixedArrayOfWeakCells>::null();
Handle<FixedArrayOfWeakCells> new_instances =
FixedArrayOfWeakCells::Add(isolate, old_instances, instance);
? 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));
memory->set_instances(*new_instances);
Handle<JSArrayBuffer> buffer(memory->array_buffer(), isolate);
SetInstanceMemory(instance, buffer);
......@@ -1033,7 +1034,7 @@ void WasmMemoryObject::AddInstance(Isolate* isolate,
void WasmMemoryObject::RemoveInstance(Handle<WasmMemoryObject> memory,
Handle<WasmInstanceObject> instance) {
if (memory->has_instances()) {
memory->instances()->Remove(instance);
memory->instances()->RemoveOne(MaybeObjectHandle::Weak(instance));
}
}
......@@ -1059,14 +1060,17 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
}
if (memory_object->has_instances()) {
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);
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());
}
}
}
memory_object->set_array_buffer(*new_buffer);
......
......@@ -34,7 +34,6 @@ using FunctionSig = Signature<ValueType>;
class BreakPoint;
class JSArrayBuffer;
class FixedArrayOfWeakCells;
class SeqOneByteString;
class WasmDebugInfo;
class WasmInstanceObject;
......@@ -284,7 +283,7 @@ class WasmMemoryObject : public JSObject {
DECL_ACCESSORS(array_buffer, JSArrayBuffer)
DECL_INT_ACCESSORS(maximum_pages)
DECL_OPTIONAL_ACCESSORS(instances, FixedArrayOfWeakCells)
DECL_OPTIONAL_ACCESSORS(instances, WeakArrayList)
// Layout description.
#define WASM_MEMORY_OBJECT_FIELDS(V) \
......
......@@ -4773,20 +4773,6 @@ 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;
......
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