Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 45ae3ca43e165b355fb4c605139afda2cc25c4e6..182b352fa9aaa2b2b0726fe1a73a39d3ecb6dc75 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -10232,9 +10232,9 @@ void Library::InvalidateExportedNamesCaches() { |
} |
-void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { |
- // TODO(iposva): Avoid exponential growth. |
- intptr_t new_dict_size = dict_size * 2; |
+void Library::RehashDictionary(const Array& old_dict, |
+ intptr_t new_dict_size) const { |
+ intptr_t old_dict_size = old_dict.Length() - 1; |
const Array& new_dict = |
Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); |
// Rehash all elements from the original dictionary |
@@ -10242,8 +10242,9 @@ void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { |
Object& entry = Class::Handle(); |
String& entry_name = String::Handle(); |
Object& new_entry = Object::Handle(); |
- for (intptr_t i = 0; i < dict_size; i++) { |
- entry = dict.At(i); |
+ intptr_t used = 0; |
+ for (intptr_t i = 0; i < old_dict_size; i++) { |
+ entry = old_dict.At(i); |
if (!entry.IsNull()) { |
entry_name = entry.DictionaryName(); |
ASSERT(!entry_name.IsNull()); |
@@ -10255,10 +10256,12 @@ void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { |
new_entry = new_dict.At(index); |
} |
new_dict.SetAt(index, entry); |
+ used++; |
} |
} |
- // Copy used count. |
- new_entry = dict.At(dict_size); |
+ // Set used count. |
+ ASSERT(used < new_dict_size); // Need at least one empty slot. |
+ new_entry = Smi::New(used); |
new_dict.SetAt(new_dict_size, new_entry); |
// Remember the new dictionary now. |
StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); |
@@ -10292,7 +10295,8 @@ void Library::AddObject(const Object& obj, const String& name) const { |
// Rehash if symbol_table is 75% full. |
if (used_elements > ((dict_size / 4) * 3)) { |
- GrowDictionary(dict, dict_size); |
+ // TODO(iposva): Avoid exponential growth. |
+ RehashDictionary(dict, 2 * dict_size); |
} |
// Invalidate the cache of loaded scripts. |
@@ -10384,55 +10388,6 @@ void Library::ReplaceObject(const Object& obj, const String& name) const { |
} |
-bool Library::RemoveObject(const Object& obj, const String& name) const { |
- Thread* thread = Thread::Current(); |
- ASSERT(thread->IsMutatorThread()); |
- Zone* zone = thread->zone(); |
- Object& entry = Object::Handle(zone); |
- |
- intptr_t index; |
- entry = LookupEntry(name, &index); |
- if (entry.raw() != obj.raw()) { |
- return false; |
- } |
- |
- const Array& dict = Array::Handle(zone, dictionary()); |
- dict.SetAt(index, Object::null_object()); |
- intptr_t dict_size = dict.Length() - 1; |
- |
- // Fix any downstream collisions. |
- String& key = String::Handle(zone); |
- for (;;) { |
- index = (index + 1) % dict_size; |
- entry = dict.At(index); |
- |
- if (entry.IsNull()) break; |
- |
- key = entry.DictionaryName(); |
- intptr_t new_index = key.Hash() % dict_size; |
- while ((dict.At(new_index) != entry.raw()) && |
- (dict.At(new_index) != Object::null())) { |
- new_index = (new_index + 1) % dict_size; |
- } |
- |
- if (index != new_index) { |
- ASSERT(dict.At(new_index) == Object::null()); |
- dict.SetAt(new_index, entry); |
- dict.SetAt(index, Object::null_object()); |
- } |
- } |
- |
- // Update used count. |
- intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1; |
- dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements))); |
- |
- ClearResolvedNamesCache(); |
- InvalidateExportedNamesCaches(); |
- |
- return true; |
-} |
- |
- |
void Library::AddClass(const Class& cls) const { |
ASSERT(!Compiler::IsBackgroundCompilation()); |
const String& class_name = String::Handle(cls.Name()); |
@@ -10791,10 +10746,13 @@ bool Library::ImportsCorelib() const { |
} |
-void Library::DropDependencies() const { |
+void Library::DropDependenciesAndCaches() const { |
StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); |
StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); |
StoreNonPointer(&raw_ptr()->num_imports_, 0); |
+ StorePointer(&raw_ptr()->resolved_names_, Array::null()); |
+ StorePointer(&raw_ptr()->exported_names_, Array::null()); |
+ StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
} |