Commit 3ead1897 authored by yangguo's avatar yangguo Committed by Commit bot

Keep track of script objects in a weak fixed array.

We need this for the debugger and for future changes that need to
find all shared function infos (through scripts).

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/1297273005

Cr-Commit-Position: refs/heads/master@{#30264}
parent 98a0fe0f
......@@ -40,7 +40,6 @@ Debug::Debug(Isolate* isolate)
in_debug_event_listener_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
script_cache_(NULL),
debug_info_list_(NULL),
isolate_(isolate) {
ThreadInit();
......@@ -354,66 +353,6 @@ int Debug::ArchiveSpacePerThread() {
}
ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) {
Heap* heap = isolate_->heap();
HandleScope scope(isolate_);
DCHECK(isolate_->debug()->is_active());
// Perform a GC to get rid of all unreferenced scripts.
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
// Scan heap for Script objects.
List<Handle<Script> > scripts;
{
HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
DisallowHeapAllocation no_allocation;
for (HeapObject* obj = iterator.next(); obj != NULL;
obj = iterator.next()) {
if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
scripts.Add(Handle<Script>(Script::cast(obj)));
}
}
}
GlobalHandles* global_handles = isolate_->global_handles();
table_ = Handle<WeakValueHashTable>::cast(global_handles->Create(
Object::cast(*WeakValueHashTable::New(isolate_, scripts.length()))));
for (int i = 0; i < scripts.length(); i++) Add(scripts[i]);
}
void ScriptCache::Add(Handle<Script> script) {
HandleScope scope(isolate_);
Handle<Smi> id(script->id(), isolate_);
#ifdef DEBUG
Handle<Object> lookup(table_->LookupWeak(id), isolate_);
if (!lookup->IsTheHole()) {
Handle<Script> found = Handle<Script>::cast(lookup);
DCHECK(script->id() == found->id());
DCHECK(!script->name()->IsString() ||
String::cast(script->name())->Equals(String::cast(found->name())));
}
#endif
Handle<WeakValueHashTable> new_table =
WeakValueHashTable::PutWeak(table_, id, script);
if (new_table.is_identical_to(table_)) return;
GlobalHandles* global_handles = isolate_->global_handles();
global_handles->Destroy(Handle<Object>::cast(table_).location());
table_ = Handle<WeakValueHashTable>::cast(
global_handles->Create(Object::cast(*new_table)));
}
ScriptCache::~ScriptCache() {
isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location());
table_ = Handle<WeakValueHashTable>();
}
DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
// Globalize the request debug info object and make it weak.
GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
......@@ -466,12 +405,6 @@ void Debug::Unload() {
// Return debugger is not loaded.
if (!is_loaded()) return;
// Clear the script cache.
if (script_cache_ != NULL) {
delete script_cache_;
script_cache_ = NULL;
}
// Clear debugger context global handle.
GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
debug_context_ = Handle<Context>();
......@@ -1675,17 +1608,24 @@ void Debug::ClearMirrorCache() {
Handle<FixedArray> Debug::GetLoadedScripts() {
// Create and fill the script cache when the loaded scripts is requested for
// the first time.
if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
// Perform GC to get unreferenced scripts evicted from the cache before
// returning the content.
isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
"Debug::GetLoadedScripts");
// Get the scripts from the cache.
return script_cache_->GetScripts();
Factory* factory = isolate_->factory();
if (!factory->script_list()->IsWeakFixedArray()) {
return factory->empty_fixed_array();
}
Handle<WeakFixedArray> array =
Handle<WeakFixedArray>::cast(factory->script_list());
Handle<FixedArray> results = factory->NewFixedArray(array->Length());
int length = 0;
for (int i = 0; i < array->Length(); ++i) {
Object* item = array->Get(i);
if (item->IsScript() && Script::cast(item)->HasValidSource()) {
results->set(length++, item);
}
}
results->Shrink(length);
return results;
}
......@@ -1937,9 +1877,6 @@ void Debug::OnBeforeCompile(Handle<Script> script) {
// Handle debugger actions when a new script is compiled.
void Debug::OnAfterCompile(Handle<Script> script) {
// Add the newly compiled script to the script cache.
if (script_cache_ != NULL) script_cache_->Add(script);
if (ignore_events()) return;
if (in_debug_scope()) {
......
......@@ -186,29 +186,6 @@ class BreakLocation {
};
// Cache of all script objects in the heap. When a script is added a weak handle
// to it is created and that weak handle is stored in the cache. The weak handle
// callback takes care of removing the script from the cache. The key used in
// the cache is the script id.
class ScriptCache {
public:
explicit ScriptCache(Isolate* isolate);
~ScriptCache();
// Add script to the cache.
void Add(Handle<Script> script);
// Return the scripts in the cache.
Handle<FixedArray> GetScripts() {
return WeakValueHashTable::GetWeakValues(table_);
}
private:
Isolate* isolate_;
Handle<WeakValueHashTable> table_;
};
// Linked list holding debug info objects. The debug info objects are kept as
// weak handles to avoid a debug info object to keep a function alive.
class DebugInfoListNode {
......@@ -622,7 +599,6 @@ class Debug {
bool break_on_exception_;
bool break_on_uncaught_exception_;
ScriptCache* script_cache_; // Cache of all scripts in the heap.
DebugInfoListNode* debug_info_list_; // List of active debug info objects.
// Storage location for jump when exiting debug break calls.
......
......@@ -848,6 +848,7 @@ Handle<Script> Factory::NewScript(Handle<String> source) {
script->set_shared_function_infos(Smi::FromInt(0));
script->set_flags(Smi::FromInt(0));
heap->set_script_list(*WeakFixedArray::Add(script_list(), script));
return script;
}
......
......@@ -3347,6 +3347,8 @@ void Heap::CreateInitialObjects() {
*WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY,
TENURED));
set_script_list(Smi::FromInt(0));
Handle<SeededNumberDictionary> slow_element_dictionary =
SeededNumberDictionary::New(isolate(), 0, TENURED);
slow_element_dictionary->set_requires_slow_elements();
......@@ -3415,6 +3417,7 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
case kPolymorphicCodeCacheRootIndex:
case kEmptyScriptRootIndex:
case kSymbolRegistryRootIndex:
case kScriptListRootIndex:
case kMaterializedObjectsRootIndex:
case kAllocationSitesScratchpadRootIndex:
case kMicrotaskQueueRootIndex:
......
......@@ -170,6 +170,7 @@ namespace internal {
V(Cell, undefined_cell, UndefinedCell) \
V(JSObject, observation_state, ObservationState) \
V(Object, symbol_registry, SymbolRegistry) \
V(Object, script_list, ScriptList) \
V(SeededNumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \
V(FixedArray, materialized_objects, MaterializedObjects) \
......
......@@ -877,9 +877,6 @@ bool Object::IsWeakHashTable() const {
}
bool Object::IsWeakValueHashTable() const { return IsHashTable(); }
bool Object::IsDictionary() const {
return IsHashTable() &&
this != HeapObject::cast(this)->GetHeap()->string_table();
......@@ -3319,7 +3316,6 @@ CAST_ACCESSOR(UnseededNumberDictionary)
CAST_ACCESSOR(WeakCell)
CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakHashTable)
CAST_ACCESSOR(WeakValueHashTable)
// static
......
......@@ -14837,49 +14837,6 @@ void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell,
}
#ifdef DEBUG
Object* WeakValueHashTable::LookupWeak(Handle<Object> key) {
Object* value = Lookup(key);
if (value->IsWeakCell() && !WeakCell::cast(value)->cleared()) {
value = WeakCell::cast(value)->value();
}
return value;
}
#endif // DEBUG
Handle<WeakValueHashTable> WeakValueHashTable::PutWeak(
Handle<WeakValueHashTable> table, Handle<Object> key,
Handle<HeapObject> value) {
Handle<WeakCell> cell = value->GetIsolate()->factory()->NewWeakCell(value);
return Handle<WeakValueHashTable>::cast(
Put(Handle<ObjectHashTable>::cast(table), key, cell));
}
Handle<FixedArray> WeakValueHashTable::GetWeakValues(
Handle<WeakValueHashTable> table) {
Isolate* isolate = table->GetIsolate();
uint32_t capacity = table->Capacity();
Handle<FixedArray> results = isolate->factory()->NewFixedArray(capacity);
int length = 0;
for (uint32_t i = 0; i < capacity; i++) {
uint32_t key_index = table->EntryToIndex(i);
Object* key = table->get(key_index);
if (!table->IsKey(key)) continue;
uint32_t value_index = table->EntryToValueIndex(i);
WeakCell* value_cell = WeakCell::cast(table->get(value_index));
if (value_cell->cleared()) {
table->RemoveEntry(i);
} else {
results->set(length++, value_cell->value());
}
}
results->Shrink(length);
return results;
}
template<class Derived, class Iterator, int entrysize>
Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
Isolate* isolate, int capacity, PretenureFlag pretenure) {
......
......@@ -991,7 +991,6 @@ template <class C> inline bool Is(Object* obj);
V(WeakCell) \
V(ObjectHashTable) \
V(WeakHashTable) \
V(WeakValueHashTable) \
V(OrderedHashTable)
// Object is the abstract superclass for all classes in the
......@@ -3742,26 +3741,6 @@ class WeakHashTable: public HashTable<WeakHashTable,
};
class WeakValueHashTable : public ObjectHashTable {
public:
DECLARE_CAST(WeakValueHashTable)
#ifdef DEBUG
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
Object* LookupWeak(Handle<Object> key);
#endif // DEBUG
// Adds (or overwrites) the value associated with the given key. Mapping a
// key to the hole value causes removal of the whole entry.
MUST_USE_RESULT static Handle<WeakValueHashTable> PutWeak(
Handle<WeakValueHashTable> table, Handle<Object> key,
Handle<HeapObject> value);
static Handle<FixedArray> GetWeakValues(Handle<WeakValueHashTable> table);
};
// ScopeInfo represents information about different scopes of a source
// program and the allocation of the scope's variables. Scope information
// is stored in a compressed form in ScopeInfo objects and is used
......
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