OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/become.h" | 10 #include "vm/become.h" |
(...skipping 10214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10225 Isolate::Current()->object_store()->libraries()); | 10225 Isolate::Current()->object_store()->libraries()); |
10226 Library& lib = Library::Handle(); | 10226 Library& lib = Library::Handle(); |
10227 intptr_t num_libs = libs.Length(); | 10227 intptr_t num_libs = libs.Length(); |
10228 for (intptr_t i = 0; i < num_libs; i++) { | 10228 for (intptr_t i = 0; i < num_libs; i++) { |
10229 lib ^= libs.At(i); | 10229 lib ^= libs.At(i); |
10230 lib.ClearExportedNamesCache(); | 10230 lib.ClearExportedNamesCache(); |
10231 } | 10231 } |
10232 } | 10232 } |
10233 | 10233 |
10234 | 10234 |
10235 void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { | 10235 void Library::RehashDictionary(const Array& old_dict, |
10236 // TODO(iposva): Avoid exponential growth. | 10236 intptr_t new_dict_size) const { |
10237 intptr_t new_dict_size = dict_size * 2; | 10237 intptr_t old_dict_size = old_dict.Length() - 1; |
10238 const Array& new_dict = | 10238 const Array& new_dict = |
10239 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); | 10239 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); |
10240 // Rehash all elements from the original dictionary | 10240 // Rehash all elements from the original dictionary |
10241 // to the newly allocated array. | 10241 // to the newly allocated array. |
10242 Object& entry = Class::Handle(); | 10242 Object& entry = Class::Handle(); |
10243 String& entry_name = String::Handle(); | 10243 String& entry_name = String::Handle(); |
10244 Object& new_entry = Object::Handle(); | 10244 Object& new_entry = Object::Handle(); |
10245 for (intptr_t i = 0; i < dict_size; i++) { | 10245 intptr_t used = 0; |
10246 entry = dict.At(i); | 10246 for (intptr_t i = 0; i < old_dict_size; i++) { |
| 10247 entry = old_dict.At(i); |
10247 if (!entry.IsNull()) { | 10248 if (!entry.IsNull()) { |
10248 entry_name = entry.DictionaryName(); | 10249 entry_name = entry.DictionaryName(); |
10249 ASSERT(!entry_name.IsNull()); | 10250 ASSERT(!entry_name.IsNull()); |
10250 const intptr_t hash = entry_name.Hash(); | 10251 const intptr_t hash = entry_name.Hash(); |
10251 intptr_t index = hash % new_dict_size; | 10252 intptr_t index = hash % new_dict_size; |
10252 new_entry = new_dict.At(index); | 10253 new_entry = new_dict.At(index); |
10253 while (!new_entry.IsNull()) { | 10254 while (!new_entry.IsNull()) { |
10254 index = (index + 1) % new_dict_size; // Move to next element. | 10255 index = (index + 1) % new_dict_size; // Move to next element. |
10255 new_entry = new_dict.At(index); | 10256 new_entry = new_dict.At(index); |
10256 } | 10257 } |
10257 new_dict.SetAt(index, entry); | 10258 new_dict.SetAt(index, entry); |
| 10259 used++; |
10258 } | 10260 } |
10259 } | 10261 } |
10260 // Copy used count. | 10262 // Set used count. |
10261 new_entry = dict.At(dict_size); | 10263 ASSERT(used < new_dict_size); // Need at least one empty slot. |
| 10264 new_entry = Smi::New(used); |
10262 new_dict.SetAt(new_dict_size, new_entry); | 10265 new_dict.SetAt(new_dict_size, new_entry); |
10263 // Remember the new dictionary now. | 10266 // Remember the new dictionary now. |
10264 StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); | 10267 StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); |
10265 } | 10268 } |
10266 | 10269 |
10267 | 10270 |
10268 void Library::AddObject(const Object& obj, const String& name) const { | 10271 void Library::AddObject(const Object& obj, const String& name) const { |
10269 ASSERT(Thread::Current()->IsMutatorThread()); | 10272 ASSERT(Thread::Current()->IsMutatorThread()); |
10270 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || | 10273 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || |
10271 obj.IsLibraryPrefix()); | 10274 obj.IsLibraryPrefix()); |
(...skipping 13 matching lines...) Expand all Loading... |
10285 | 10288 |
10286 // Insert the object at the empty slot. | 10289 // Insert the object at the empty slot. |
10287 dict.SetAt(index, obj); | 10290 dict.SetAt(index, obj); |
10288 // One more element added. | 10291 // One more element added. |
10289 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) + 1; | 10292 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) + 1; |
10290 const Smi& used = Smi::Handle(Smi::New(used_elements)); | 10293 const Smi& used = Smi::Handle(Smi::New(used_elements)); |
10291 dict.SetAt(dict_size, used); // Update used count. | 10294 dict.SetAt(dict_size, used); // Update used count. |
10292 | 10295 |
10293 // Rehash if symbol_table is 75% full. | 10296 // Rehash if symbol_table is 75% full. |
10294 if (used_elements > ((dict_size / 4) * 3)) { | 10297 if (used_elements > ((dict_size / 4) * 3)) { |
10295 GrowDictionary(dict, dict_size); | 10298 // TODO(iposva): Avoid exponential growth. |
| 10299 RehashDictionary(dict, 2 * dict_size); |
10296 } | 10300 } |
10297 | 10301 |
10298 // Invalidate the cache of loaded scripts. | 10302 // Invalidate the cache of loaded scripts. |
10299 if (loaded_scripts() != Array::null()) { | 10303 if (loaded_scripts() != Array::null()) { |
10300 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 10304 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
10301 } | 10305 } |
10302 } | 10306 } |
10303 | 10307 |
10304 | 10308 |
10305 // Lookup a name in the library's re-export namespace. | 10309 // Lookup a name in the library's re-export namespace. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10377 ASSERT(LookupLocalObject(name) != Object::null()); | 10381 ASSERT(LookupLocalObject(name) != Object::null()); |
10378 | 10382 |
10379 intptr_t index; | 10383 intptr_t index; |
10380 LookupEntry(name, &index); | 10384 LookupEntry(name, &index); |
10381 // The value is guaranteed to be found. | 10385 // The value is guaranteed to be found. |
10382 const Array& dict = Array::Handle(dictionary()); | 10386 const Array& dict = Array::Handle(dictionary()); |
10383 dict.SetAt(index, obj); | 10387 dict.SetAt(index, obj); |
10384 } | 10388 } |
10385 | 10389 |
10386 | 10390 |
10387 bool Library::RemoveObject(const Object& obj, const String& name) const { | |
10388 Thread* thread = Thread::Current(); | |
10389 ASSERT(thread->IsMutatorThread()); | |
10390 Zone* zone = thread->zone(); | |
10391 Object& entry = Object::Handle(zone); | |
10392 | |
10393 intptr_t index; | |
10394 entry = LookupEntry(name, &index); | |
10395 if (entry.raw() != obj.raw()) { | |
10396 return false; | |
10397 } | |
10398 | |
10399 const Array& dict = Array::Handle(zone, dictionary()); | |
10400 dict.SetAt(index, Object::null_object()); | |
10401 intptr_t dict_size = dict.Length() - 1; | |
10402 | |
10403 // Fix any downstream collisions. | |
10404 String& key = String::Handle(zone); | |
10405 for (;;) { | |
10406 index = (index + 1) % dict_size; | |
10407 entry = dict.At(index); | |
10408 | |
10409 if (entry.IsNull()) break; | |
10410 | |
10411 key = entry.DictionaryName(); | |
10412 intptr_t new_index = key.Hash() % dict_size; | |
10413 while ((dict.At(new_index) != entry.raw()) && | |
10414 (dict.At(new_index) != Object::null())) { | |
10415 new_index = (new_index + 1) % dict_size; | |
10416 } | |
10417 | |
10418 if (index != new_index) { | |
10419 ASSERT(dict.At(new_index) == Object::null()); | |
10420 dict.SetAt(new_index, entry); | |
10421 dict.SetAt(index, Object::null_object()); | |
10422 } | |
10423 } | |
10424 | |
10425 // Update used count. | |
10426 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1; | |
10427 dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements))); | |
10428 | |
10429 ClearResolvedNamesCache(); | |
10430 InvalidateExportedNamesCaches(); | |
10431 | |
10432 return true; | |
10433 } | |
10434 | |
10435 | |
10436 void Library::AddClass(const Class& cls) const { | 10391 void Library::AddClass(const Class& cls) const { |
10437 ASSERT(!Compiler::IsBackgroundCompilation()); | 10392 ASSERT(!Compiler::IsBackgroundCompilation()); |
10438 const String& class_name = String::Handle(cls.Name()); | 10393 const String& class_name = String::Handle(cls.Name()); |
10439 AddObject(cls, class_name); | 10394 AddObject(cls, class_name); |
10440 // Link class to this library. | 10395 // Link class to this library. |
10441 cls.set_library(*this); | 10396 cls.set_library(*this); |
10442 InvalidateResolvedName(class_name); | 10397 InvalidateResolvedName(class_name); |
10443 } | 10398 } |
10444 | 10399 |
10445 | 10400 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10784 imported = prefix.GetLibrary(i); | 10739 imported = prefix.GetLibrary(i); |
10785 if (imported.IsCoreLibrary()) { | 10740 if (imported.IsCoreLibrary()) { |
10786 return true; | 10741 return true; |
10787 } | 10742 } |
10788 } | 10743 } |
10789 } | 10744 } |
10790 return false; | 10745 return false; |
10791 } | 10746 } |
10792 | 10747 |
10793 | 10748 |
10794 void Library::DropDependencies() const { | 10749 void Library::DropDependenciesAndCaches() const { |
10795 StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); | 10750 StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); |
10796 StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); | 10751 StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); |
10797 StoreNonPointer(&raw_ptr()->num_imports_, 0); | 10752 StoreNonPointer(&raw_ptr()->num_imports_, 0); |
| 10753 StorePointer(&raw_ptr()->resolved_names_, Array::null()); |
| 10754 StorePointer(&raw_ptr()->exported_names_, Array::null()); |
| 10755 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
10798 } | 10756 } |
10799 | 10757 |
10800 | 10758 |
10801 void Library::AddImport(const Namespace& ns) const { | 10759 void Library::AddImport(const Namespace& ns) const { |
10802 Array& imports = Array::Handle(this->imports()); | 10760 Array& imports = Array::Handle(this->imports()); |
10803 intptr_t capacity = imports.Length(); | 10761 intptr_t capacity = imports.Length(); |
10804 if (num_imports() == capacity) { | 10762 if (num_imports() == capacity) { |
10805 capacity = capacity + kImportsCapacityIncrement; | 10763 capacity = capacity + kImportsCapacityIncrement; |
10806 imports = Array::Grow(imports, capacity); | 10764 imports = Array::Grow(imports, capacity); |
10807 StorePointer(&raw_ptr()->imports_, imports.raw()); | 10765 StorePointer(&raw_ptr()->imports_, imports.raw()); |
(...skipping 12375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23183 return UserTag::null(); | 23141 return UserTag::null(); |
23184 } | 23142 } |
23185 | 23143 |
23186 | 23144 |
23187 const char* UserTag::ToCString() const { | 23145 const char* UserTag::ToCString() const { |
23188 const String& tag_label = String::Handle(label()); | 23146 const String& tag_label = String::Handle(label()); |
23189 return tag_label.ToCString(); | 23147 return tag_label.ToCString(); |
23190 } | 23148 } |
23191 | 23149 |
23192 } // namespace dart | 23150 } // namespace dart |
OLD | NEW |