Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: runtime/vm/object.cc

Issue 2823873003: Tree shaker: (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698