Index: src/debug.cc |
diff --git a/src/debug.cc b/src/debug.cc |
index bcff35a7f4d60e1d6c17d7471303699ea2a56a27..df8eab79eb983f61608a54e4fdd1a34ffe414b46 100644 |
--- a/src/debug.cc |
+++ b/src/debug.cc |
@@ -493,8 +493,7 @@ int Debug::ArchiveSpacePerThread() { |
} |
-ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), |
- isolate_(isolate) { |
+ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) { |
Heap* heap = isolate_->heap(); |
HandleScope scope(isolate_); |
@@ -502,92 +501,53 @@ ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), |
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); |
// Scan heap for Script objects. |
- HeapIterator iterator(heap); |
- DisallowHeapAllocation no_allocation; |
- |
- for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
- if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { |
- Add(Handle<Script>(Script::cast(obj))); |
+ 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) { |
- GlobalHandles* global_handles = isolate_->global_handles(); |
- // Create an entry in the hash map for the script. |
- int id = script->id()->value(); |
- HashMap::Entry* entry = |
- HashMap::LookupOrInsert(reinterpret_cast<void*>(id), Hash(id)); |
- if (entry->value != NULL) { |
+ HandleScope scope(isolate_); |
+ Handle<Smi> id(script->id(), isolate_); |
+ |
#ifdef DEBUG |
- // The code deserializer may introduce duplicate Script objects. |
- // Assert that the Script objects with the same id have the same name. |
- Handle<Script> found(reinterpret_cast<Script**>(entry->value)); |
+ 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 |
- return; |
} |
- // Globalize the script object, make it weak and use the location of the |
- // global handle as the value in the hash map. |
- Handle<Script> script_ = |
- Handle<Script>::cast(global_handles->Create(*script)); |
- GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), |
- this, |
- ScriptCache::HandleWeakScript); |
- entry->value = script_.location(); |
-} |
- |
- |
-Handle<FixedArray> ScriptCache::GetScripts() { |
- Factory* factory = isolate_->factory(); |
- Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); |
- int count = 0; |
- for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
- DCHECK(entry->value != NULL); |
- if (entry->value != NULL) { |
- instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
- count++; |
- } |
- } |
- return instances; |
-} |
+#endif |
+ Handle<WeakValueHashTable> new_table = |
+ WeakValueHashTable::PutWeak(table_, id, script); |
-void ScriptCache::Clear() { |
- // Iterate the script cache to get rid of all the weak handles. |
- for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
- DCHECK(entry != NULL); |
- Object** location = reinterpret_cast<Object**>(entry->value); |
- DCHECK((*location)->IsScript()); |
- GlobalHandles::ClearWeakness(location); |
- GlobalHandles::Destroy(location); |
- } |
- // Clear the content of the hash map. |
- HashMap::Clear(); |
+ 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))); |
} |
-void ScriptCache::HandleWeakScript( |
- const v8::WeakCallbackData<v8::Value, void>& data) { |
- // Retrieve the script identifier. |
- Handle<Object> object = Utils::OpenHandle(*data.GetValue()); |
- int id = Handle<Script>::cast(object)->id()->value(); |
- void* key = reinterpret_cast<void*>(id); |
- uint32_t hash = Hash(id); |
- |
- // Remove the corresponding entry from the cache. |
- ScriptCache* script_cache = |
- reinterpret_cast<ScriptCache*>(data.GetParameter()); |
- HashMap::Entry* entry = script_cache->Lookup(key, hash); |
- DCHECK_NOT_NULL(entry); |
- Object** location = reinterpret_cast<Object**>(entry->value); |
- script_cache->Remove(key, hash); |
- |
- // Clear the weak handle. |
- GlobalHandles::Destroy(location); |
+ScriptCache::~ScriptCache() { |
+ isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location()); |
+ table_ = Handle<WeakValueHashTable>(); |
} |