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

[in-place weak refs] Replace Heap::script_list with a WeakArrayList.

BUG=v8:7308

Change-Id: Idd527fc2a2f5bde635441a511e424a83558ab969
Reviewed-on: https://chromium-review.googlesource.com/1143467
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54635}
parent 8d1b5ccf
...@@ -1621,12 +1621,12 @@ Handle<FixedArray> Debug::GetLoadedScripts() { ...@@ -1621,12 +1621,12 @@ Handle<FixedArray> Debug::GetLoadedScripts() {
isolate_->heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask, isolate_->heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
GarbageCollectionReason::kDebugger); GarbageCollectionReason::kDebugger);
Factory* factory = isolate_->factory(); Factory* factory = isolate_->factory();
if (!factory->script_list()->IsFixedArrayOfWeakCells()) { if (!factory->script_list()->IsWeakArrayList()) {
return factory->empty_fixed_array(); return factory->empty_fixed_array();
} }
Handle<FixedArrayOfWeakCells> array = Handle<WeakArrayList> array =
Handle<FixedArrayOfWeakCells>::cast(factory->script_list()); Handle<WeakArrayList>::cast(factory->script_list());
Handle<FixedArray> results = factory->NewFixedArray(array->Length()); Handle<FixedArray> results = factory->NewFixedArray(array->length());
int length = 0; int length = 0;
{ {
Script::Iterator iterator(isolate_); Script::Iterator iterator(isolate_);
......
...@@ -1556,8 +1556,10 @@ Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id, ...@@ -1556,8 +1556,10 @@ Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id,
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
script->set_flags(0); script->set_flags(0);
script->set_host_defined_options(*empty_fixed_array()); script->set_host_defined_options(*empty_fixed_array());
heap->set_script_list( Handle<WeakArrayList> scripts = script_list();
*FixedArrayOfWeakCells::Add(isolate(), script_list(), script)); scripts = WeakArrayList::AddToEnd(isolate(), scripts,
MaybeObjectHandle::Weak(script));
heap->set_script_list(*scripts);
LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id)); LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
return script; return script;
} }
...@@ -1582,8 +1584,10 @@ Handle<Script> Factory::CloneScript(Handle<Script> script) { ...@@ -1582,8 +1584,10 @@ Handle<Script> Factory::CloneScript(Handle<Script> script) {
new_script->set_eval_from_position(script->eval_from_position()); new_script->set_eval_from_position(script->eval_from_position());
new_script->set_flags(script->flags()); new_script->set_flags(script->flags());
new_script->set_host_defined_options(script->host_defined_options()); new_script->set_host_defined_options(script->host_defined_options());
heap->set_script_list( Handle<WeakArrayList> scripts = script_list();
*FixedArrayOfWeakCells::Add(isolate(), script_list(), new_script)); scripts = WeakArrayList::AddToEnd(isolate(), scripts,
MaybeObjectHandle::Weak(new_script));
heap->set_script_list(*scripts);
LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id)); LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
return new_script; return new_script;
} }
......
...@@ -5006,6 +5006,34 @@ void CompactFixedArrayOfWeakCells(Isolate* isolate, Object* object) { ...@@ -5006,6 +5006,34 @@ void CompactFixedArrayOfWeakCells(Isolate* isolate, Object* object) {
array->Compact<FixedArrayOfWeakCells::NullCallback>(isolate); array->Compact<FixedArrayOfWeakCells::NullCallback>(isolate);
} }
} }
Handle<WeakArrayList> CompactWeakArrayList(Heap* heap,
Handle<WeakArrayList> array) {
if (array->length() == 0) {
return array;
}
int new_length = array->CountLiveWeakReferences();
if (new_length == array->length()) {
return array;
}
Handle<WeakArrayList> new_array = WeakArrayList::EnsureSpace(
heap->isolate(),
handle(ReadOnlyRoots(heap).empty_weak_array_list(), heap->isolate()),
new_length);
// Allocation might have caused GC and turned some of the elements into
// cleared weak heap objects. Count the number of live references again and
// fill in the new array.
int copy_to = 0;
for (int i = 0; i < array->length(); i++) {
MaybeObject* element = array->Get(i);
if (element->IsClearedWeakHeapObject()) continue;
new_array->Set(copy_to++, element);
}
new_array->set_length(copy_to);
return new_array;
}
} // anonymous namespace } // anonymous namespace
void Heap::CompactFixedArraysOfWeakCells() { void Heap::CompactFixedArraysOfWeakCells() {
...@@ -5032,8 +5060,12 @@ void Heap::CompactFixedArraysOfWeakCells() { ...@@ -5032,8 +5060,12 @@ void Heap::CompactFixedArraysOfWeakCells() {
// Find known FixedArrayOfWeakCells and compact them. // Find known FixedArrayOfWeakCells and compact them.
CompactFixedArrayOfWeakCells(isolate(), noscript_shared_function_infos()); CompactFixedArrayOfWeakCells(isolate(), noscript_shared_function_infos());
CompactFixedArrayOfWeakCells(isolate(), script_list());
CompactFixedArrayOfWeakCells(isolate(), weak_stack_trace_list()); CompactFixedArrayOfWeakCells(isolate(), weak_stack_trace_list());
// Find known WeakArrayLists and compact them.
Handle<WeakArrayList> scripts(script_list(), isolate());
scripts = CompactWeakArrayList(this, scripts);
set_script_list(*scripts);
} }
void Heap::AddRetainedMap(Handle<Map> map) { void Heap::AddRetainedMap(Handle<Map> map) {
......
...@@ -709,9 +709,9 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() { ...@@ -709,9 +709,9 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() {
nullptr, nullptr,
FixedArrayOfWeakCells::cast(heap_->noscript_shared_function_infos()), FixedArrayOfWeakCells::cast(heap_->noscript_shared_function_infos()),
ObjectStats::NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE); ObjectStats::NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE);
RecordSimpleVirtualObjectStats( RecordSimpleVirtualObjectStats(nullptr,
nullptr, FixedArrayOfWeakCells::cast(heap_->script_list()), WeakArrayList::cast(heap_->script_list()),
ObjectStats::SCRIPT_LIST_TYPE); ObjectStats::SCRIPT_LIST_TYPE);
// HashTable. // HashTable.
RecordHashTableVirtualObjectStats(nullptr, heap_->code_stubs(), RecordHashTableVirtualObjectStats(nullptr, heap_->code_stubs(),
......
...@@ -766,7 +766,7 @@ void Heap::CreateInitialObjects() { ...@@ -766,7 +766,7 @@ void Heap::CreateInitialObjects() {
set_feedback_vectors_for_profiling_tools(roots.undefined_value()); set_feedback_vectors_for_profiling_tools(roots.undefined_value());
set_script_list(Smi::kZero); set_script_list(roots.empty_weak_array_list());
Handle<NumberDictionary> slow_element_dictionary = NumberDictionary::New( Handle<NumberDictionary> slow_element_dictionary = NumberDictionary::New(
isolate(), 1, TENURED_READ_ONLY, USE_CUSTOM_MINIMUM_CAPACITY); isolate(), 1, TENURED_READ_ONLY, USE_CUSTOM_MINIMUM_CAPACITY);
......
...@@ -10567,6 +10567,16 @@ Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate, ...@@ -10567,6 +10567,16 @@ Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate,
return array; return array;
} }
int WeakArrayList::CountLiveWeakReferences() const {
int live_weak_references = 0;
for (int i = 0; i < length(); i++) {
if (Get(i)->IsWeakHeapObject()) {
++live_weak_references;
}
}
return live_weak_references;
}
// static // static
Handle<WeakArrayList> PrototypeUsers::Add(Isolate* isolate, Handle<WeakArrayList> PrototypeUsers::Add(Isolate* isolate,
Handle<WeakArrayList> array, Handle<WeakArrayList> array,
...@@ -10620,14 +10630,7 @@ WeakArrayList* PrototypeUsers::Compact(Handle<WeakArrayList> array, Heap* heap, ...@@ -10620,14 +10630,7 @@ WeakArrayList* PrototypeUsers::Compact(Handle<WeakArrayList> array, Heap* heap,
if (array->length() == 0) { if (array->length() == 0) {
return *array; return *array;
} }
// Count the amount of live references. int new_length = array->CountLiveWeakReferences();
int new_length = kFirstIndex;
for (int i = kFirstIndex; i < array->length(); i++) {
MaybeObject* element = array->Get(i);
if (element->IsSmi()) continue;
if (element->IsClearedWeakHeapObject()) continue;
++new_length;
}
if (new_length == array->length()) { if (new_length == array->length()) {
return *array; return *array;
} }
...@@ -13798,8 +13801,13 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( ...@@ -13798,8 +13801,13 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
Script::Iterator::Iterator(Isolate* isolate) Script::Iterator::Iterator(Isolate* isolate)
: iterator_(isolate->heap()->script_list()) {} : iterator_(isolate->heap()->script_list()) {}
Script* Script::Iterator::Next() {
Script* Script::Iterator::Next() { return iterator_.Next<Script>(); } Object* o = iterator_.Next();
if (o != nullptr) {
return Script::cast(o);
}
return nullptr;
}
SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate, SharedFunctionInfo::ScriptIterator::ScriptIterator(Isolate* isolate,
Script* script) Script* script)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/bigint.h" #include "src/objects/bigint.h"
#include "src/objects/maybe-object-inl.h"
// Has to be the last include (doesn't have include guards): // Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h" #include "src/objects/object-macros.h"
...@@ -286,6 +287,18 @@ MaybeObject** WeakArrayList::data_start() { ...@@ -286,6 +287,18 @@ MaybeObject** WeakArrayList::data_start() {
return HeapObject::RawMaybeWeakField(this, kHeaderSize); return HeapObject::RawMaybeWeakField(this, kHeaderSize);
} }
HeapObject* WeakArrayList::Iterator::Next() {
if (array_ != nullptr) {
while (index_ < array_->length()) {
MaybeObject* item = array_->Get(index_++);
DCHECK(item->IsWeakHeapObject() || item->IsClearedWeakHeapObject());
if (!item->IsClearedWeakHeapObject()) return item->ToWeakHeapObject();
}
array_ = nullptr;
}
return nullptr;
}
Object* FixedArrayOfWeakCells::Get(int index) const { Object* FixedArrayOfWeakCells::Get(int index) const {
Object* raw = FixedArray::cast(this)->get(index + kFirstIndex); Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
if (raw->IsSmi()) return raw; if (raw->IsSmi()) return raw;
......
...@@ -363,11 +363,28 @@ class WeakArrayList : public HeapObject { ...@@ -363,11 +363,28 @@ class WeakArrayList : public HeapObject {
static const int kMaxCapacity = static const int kMaxCapacity =
(FixedArray::kMaxSize - kHeaderSize) / kPointerSize; (FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
protected:
static Handle<WeakArrayList> EnsureSpace(Isolate* isolate, static Handle<WeakArrayList> EnsureSpace(Isolate* isolate,
Handle<WeakArrayList> array, Handle<WeakArrayList> array,
int length); int length);
// Returns the number of non-cleaned weak references in the array.
int CountLiveWeakReferences() const;
class Iterator {
public:
explicit Iterator(WeakArrayList* array) : index_(0), array_(array) {}
inline HeapObject* Next();
private:
int index_;
WeakArrayList* array_;
#ifdef DEBUG
DisallowHeapAllocation no_gc_;
#endif // DEBUG
DISALLOW_COPY_AND_ASSIGN(Iterator);
};
private: private:
static int OffsetOfElementAt(int index) { static int OffsetOfElementAt(int index) {
return kHeaderSize + index * kPointerSize; return kHeaderSize + index * kPointerSize;
......
...@@ -182,7 +182,7 @@ class Script : public Struct, public NeverReadOnlySpaceObject { ...@@ -182,7 +182,7 @@ class Script : public Struct, public NeverReadOnlySpaceObject {
Script* Next(); Script* Next();
private: private:
FixedArrayOfWeakCells::Iterator iterator_; WeakArrayList::Iterator iterator_;
DISALLOW_COPY_AND_ASSIGN(Iterator); DISALLOW_COPY_AND_ASSIGN(Iterator);
}; };
......
...@@ -232,7 +232,7 @@ namespace internal { ...@@ -232,7 +232,7 @@ namespace internal {
V(NameDictionary, public_symbol_table, PublicSymbolTable) \ V(NameDictionary, public_symbol_table, PublicSymbolTable) \
V(NameDictionary, api_symbol_table, ApiSymbolTable) \ V(NameDictionary, api_symbol_table, ApiSymbolTable) \
V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \ V(NameDictionary, api_private_symbol_table, ApiPrivateSymbolTable) \
V(Object, script_list, ScriptList) \ V(WeakArrayList, script_list, ScriptList) \
V(SimpleNumberDictionary, code_stubs, CodeStubs) \ V(SimpleNumberDictionary, code_stubs, CodeStubs) \
V(FixedArray, materialized_objects, MaterializedObjects) \ V(FixedArray, materialized_objects, MaterializedObjects) \
V(FixedArray, microtask_queue, MicrotaskQueue) \ V(FixedArray, microtask_queue, MicrotaskQueue) \
......
...@@ -85,8 +85,9 @@ void ObjectDeserializer::CommitPostProcessedObjects() { ...@@ -85,8 +85,9 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
ScriptEvent(Logger::ScriptEventType::kDeserialize, script->id())); ScriptEvent(Logger::ScriptEventType::kDeserialize, script->id()));
LOG(isolate(), ScriptDetails(*script)); LOG(isolate(), ScriptDetails(*script));
// Add script to list. // Add script to list.
Handle<Object> list = Handle<WeakArrayList> list = factory->script_list();
FixedArrayOfWeakCells::Add(isolate(), factory->script_list(), script); list = WeakArrayList::AddToEnd(isolate(), list,
MaybeObjectHandle::Weak(script));
heap->SetRootScriptList(*list); heap->SetRootScriptList(*list);
} }
} }
......
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