Keep track of script objects in a weak fixed array.
authoryangguo <yangguo@chromium.org>
Thu, 20 Aug 2015 08:04:41 +0000 (01:04 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 20 Aug 2015 08:04:53 +0000 (08:04 +0000)
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}

src/debug/debug.cc
src/debug/debug.h
src/factory.cc
src/heap/heap.cc
src/heap/heap.h
src/objects-inl.h
src/objects.cc
src/objects.h

index e789def..2bda0a7 100644 (file)
@@ -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()) {
index 4b5b7b7..44ea4fc 100644 (file)
@@ -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.
index db11ebb..a8bd0bf 100644 (file)
@@ -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;
 }
 
index 7a665ae..c19cf94 100644 (file)
@@ -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:
index bcd474a..4f4ec06 100644 (file)
@@ -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)                     \
index b3713b6..933360c 100644 (file)
@@ -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
index 4a18728..841af85 100644 (file)
@@ -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) {
index a136a93..1f5c22c 100644 (file)
@@ -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