| 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 |