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

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

Issue 2823633003: Allow the resolved names cache to be lazily created like the exported names cache. (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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10075 matching lines...) Expand 10 before | Expand all | Expand 10 after
10086 } 10086 }
10087 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } 10087 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); }
10088 }; 10088 };
10089 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap; 10089 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap;
10090 10090
10091 10091
10092 // Returns true if the name is found in the cache, false no cache hit. 10092 // Returns true if the name is found in the cache, false no cache hit.
10093 // obj is set to the cached entry. It may be null, indicating that the 10093 // obj is set to the cached entry. It may be null, indicating that the
10094 // name does not resolve to anything in this library. 10094 // name does not resolve to anything in this library.
10095 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const { 10095 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const {
10096 if (resolved_names() == Array::null()) {
10097 return false;
10098 }
10096 ResolvedNamesMap cache(resolved_names()); 10099 ResolvedNamesMap cache(resolved_names());
10097 bool present = false; 10100 bool present = false;
10098 *obj = cache.GetOrNull(name, &present); 10101 *obj = cache.GetOrNull(name, &present);
10099 // Mutator compiler thread may add entries and therefore 10102 // Mutator compiler thread may add entries and therefore
10100 // change 'resolved_names()' while running a background compilation; 10103 // change 'resolved_names()' while running a background compilation;
10101 // ASSERT that 'resolved_names()' has not changed only in mutator. 10104 // ASSERT that 'resolved_names()' has not changed only in mutator.
10102 #if defined(DEBUG) 10105 #if defined(DEBUG)
10103 if (Thread::Current()->IsMutatorThread()) { 10106 if (Thread::Current()->IsMutatorThread()) {
10104 ASSERT(cache.Release().raw() == resolved_names()); 10107 ASSERT(cache.Release().raw() == resolved_names());
10105 } else { 10108 } else {
10106 // Release must be called in debug mode. 10109 // Release must be called in debug mode.
10107 cache.Release(); 10110 cache.Release();
10108 } 10111 }
10109 #endif 10112 #endif
10110 return present; 10113 return present;
10111 } 10114 }
10112 10115
10113 10116
10114 // Add a name to the resolved name cache. This name resolves to the 10117 // Add a name to the resolved name cache. This name resolves to the
10115 // given object in this library scope. obj may be null, which means 10118 // given object in this library scope. obj may be null, which means
10116 // the name does not resolve to anything in this library scope. 10119 // the name does not resolve to anything in this library scope.
10117 void Library::AddToResolvedNamesCache(const String& name, 10120 void Library::AddToResolvedNamesCache(const String& name,
10118 const Object& obj) const { 10121 const Object& obj) const {
10119 if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { 10122 if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) {
10120 return; 10123 return;
10121 } 10124 }
10125 if (resolved_names() == Array::null()) {
10126 InitResolvedNamesCache();
10127 }
10122 ResolvedNamesMap cache(resolved_names()); 10128 ResolvedNamesMap cache(resolved_names());
10123 cache.UpdateOrInsert(name, obj); 10129 cache.UpdateOrInsert(name, obj);
10124 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); 10130 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw());
10125 } 10131 }
10126 10132
10127 10133
10128 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const { 10134 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const {
10129 ASSERT(FLAG_use_exp_cache); 10135 ASSERT(FLAG_use_exp_cache);
10130 if (exported_names() == Array::null()) { 10136 if (exported_names() == Array::null()) {
10131 return false; 10137 return false;
(...skipping 14 matching lines...) Expand all
10146 #endif 10152 #endif
10147 return present; 10153 return present;
10148 } 10154 }
10149 10155
10150 void Library::AddToExportedNamesCache(const String& name, 10156 void Library::AddToExportedNamesCache(const String& name,
10151 const Object& obj) const { 10157 const Object& obj) const {
10152 if (!FLAG_use_exp_cache || Compiler::IsBackgroundCompilation()) { 10158 if (!FLAG_use_exp_cache || Compiler::IsBackgroundCompilation()) {
10153 return; 10159 return;
10154 } 10160 }
10155 if (exported_names() == Array::null()) { 10161 if (exported_names() == Array::null()) {
10156 AllocateExportedNamesCache(); 10162 InitExportedNamesCache();
10157 } 10163 }
10158 ResolvedNamesMap cache(exported_names()); 10164 ResolvedNamesMap cache(exported_names());
10159 cache.UpdateOrInsert(name, obj); 10165 cache.UpdateOrInsert(name, obj);
10160 StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); 10166 StorePointer(&raw_ptr()->exported_names_, cache.Release().raw());
10161 } 10167 }
10162 10168
10163 10169
10164 void Library::InvalidateResolvedName(const String& name) const { 10170 void Library::InvalidateResolvedName(const String& name) const {
10165 Thread* thread = Thread::Current(); 10171 Thread* thread = Thread::Current();
10166 Zone* zone = thread->zone(); 10172 Zone* zone = thread->zone();
10167 Object& entry = Object::Handle(zone); 10173 Object& entry = Object::Handle(zone);
10168 if (LookupResolvedNamesCache(name, &entry)) { 10174 if (LookupResolvedNamesCache(name, &entry)) {
10169 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. 10175 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'.
10170 InvalidateResolvedNamesCache(); 10176 ClearResolvedNamesCache();
10171 } 10177 }
10172 // When a new name is added to a library, we need to invalidate all 10178 // When a new name is added to a library, we need to invalidate all
10173 // caches that contain an entry for this name. If the name was previously 10179 // caches that contain an entry for this name. If the name was previously
10174 // looked up but could not be resolved, the cache contains a null entry. 10180 // looked up but could not be resolved, the cache contains a null entry.
10175 GrowableObjectArray& libs = GrowableObjectArray::Handle( 10181 GrowableObjectArray& libs = GrowableObjectArray::Handle(
10176 zone, thread->isolate()->object_store()->libraries()); 10182 zone, thread->isolate()->object_store()->libraries());
10177 Library& lib = Library::Handle(zone); 10183 Library& lib = Library::Handle(zone);
10178 intptr_t num_libs = libs.Length(); 10184 intptr_t num_libs = libs.Length();
10179 for (intptr_t i = 0; i < num_libs; i++) { 10185 for (intptr_t i = 0; i < num_libs; i++) {
10180 lib ^= libs.At(i); 10186 lib ^= libs.At(i);
10181 if (lib.LookupExportedNamesCache(name, &entry)) { 10187 if (lib.LookupExportedNamesCache(name, &entry)) {
10182 lib.InitExportedNamesCache(); 10188 lib.ClearExportedNamesCache();
10183 } 10189 }
10184 } 10190 }
10185 } 10191 }
10186 10192
10187 10193
10188 void Library::InvalidateResolvedNamesCache() const {
10189 const intptr_t kInvalidatedCacheSize = 16;
10190 InitResolvedNamesCache(kInvalidatedCacheSize);
10191 }
10192
10193
10194 // Invalidate all exported names caches in the isolate. 10194 // Invalidate all exported names caches in the isolate.
10195 void Library::InvalidateExportedNamesCaches() { 10195 void Library::InvalidateExportedNamesCaches() {
10196 GrowableObjectArray& libs = GrowableObjectArray::Handle( 10196 GrowableObjectArray& libs = GrowableObjectArray::Handle(
10197 Isolate::Current()->object_store()->libraries()); 10197 Isolate::Current()->object_store()->libraries());
10198 Library& lib = Library::Handle(); 10198 Library& lib = Library::Handle();
10199 intptr_t num_libs = libs.Length(); 10199 intptr_t num_libs = libs.Length();
10200 for (intptr_t i = 0; i < num_libs; i++) { 10200 for (intptr_t i = 0; i < num_libs; i++) {
10201 lib ^= libs.At(i); 10201 lib ^= libs.At(i);
10202 lib.InitExportedNamesCache(); 10202 lib.ClearExportedNamesCache();
10203 } 10203 }
10204 } 10204 }
10205 10205
10206 10206
10207 void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { 10207 void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const {
10208 // TODO(iposva): Avoid exponential growth. 10208 // TODO(iposva): Avoid exponential growth.
10209 intptr_t new_dict_size = dict_size * 2; 10209 intptr_t new_dict_size = dict_size * 2;
10210 const Array& new_dict = 10210 const Array& new_dict =
10211 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); 10211 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld));
10212 // Rehash all elements from the original dictionary 10212 // Rehash all elements from the original dictionary
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
10391 ASSERT(dict.At(new_index) == Object::null()); 10391 ASSERT(dict.At(new_index) == Object::null());
10392 dict.SetAt(new_index, entry); 10392 dict.SetAt(new_index, entry);
10393 dict.SetAt(index, Object::null_object()); 10393 dict.SetAt(index, Object::null_object());
10394 } 10394 }
10395 } 10395 }
10396 10396
10397 // Update used count. 10397 // Update used count.
10398 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1; 10398 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1;
10399 dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements))); 10399 dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements)));
10400 10400
10401 InvalidateResolvedNamesCache(); 10401 ClearResolvedNamesCache();
10402 InvalidateExportedNamesCaches(); 10402 InvalidateExportedNamesCaches();
10403 10403
10404 return true; 10404 return true;
10405 } 10405 }
10406 10406
10407 10407
10408 void Library::AddClass(const Class& cls) const { 10408 void Library::AddClass(const Class& cls) const {
10409 ASSERT(!Compiler::IsBackgroundCompilation()); 10409 ASSERT(!Compiler::IsBackgroundCompilation());
10410 const String& class_name = String::Handle(cls.Name()); 10410 const String& class_name = String::Handle(cls.Name());
10411 AddObject(cls, class_name); 10411 AddObject(cls, class_name);
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
10804 10804
10805 10805
10806 static RawArray* NewDictionary(intptr_t initial_size) { 10806 static RawArray* NewDictionary(intptr_t initial_size) {
10807 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); 10807 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld));
10808 // The last element of the dictionary specifies the number of in use slots. 10808 // The last element of the dictionary specifies the number of in use slots.
10809 dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); 10809 dict.SetAt(initial_size, Smi::Handle(Smi::New(0)));
10810 return dict.raw(); 10810 return dict.raw();
10811 } 10811 }
10812 10812
10813 10813
10814 void Library::InitResolvedNamesCache(intptr_t size) const { 10814 void Library::InitResolvedNamesCache() const {
10815 ASSERT(Thread::Current()->IsMutatorThread()); 10815 ASSERT(Thread::Current()->IsMutatorThread());
10816 StorePointer(&raw_ptr()->resolved_names_, 10816 StorePointer(&raw_ptr()->resolved_names_,
10817 HashTables::New<ResolvedNamesMap>(size)); 10817 HashTables::New<ResolvedNamesMap>(64));
10818 } 10818 }
10819 10819
10820 10820
10821 void Library::AllocateExportedNamesCache() const { 10821 void Library::ClearResolvedNamesCache() const {
10822 ASSERT(Thread::Current()->IsMutatorThread());
10823 StorePointer(&raw_ptr()->resolved_names_, Array::null());
10824 }
10825
10826
10827 void Library::InitExportedNamesCache() const {
10822 StorePointer(&raw_ptr()->exported_names_, 10828 StorePointer(&raw_ptr()->exported_names_,
10823 HashTables::New<ResolvedNamesMap>(16)); 10829 HashTables::New<ResolvedNamesMap>(16));
10824 } 10830 }
10825 10831
10826 10832
10827 void Library::InitExportedNamesCache() const { 10833 void Library::ClearExportedNamesCache() const {
10828 if (exported_names() != Array::null()) { 10834 StorePointer(&raw_ptr()->exported_names_, Array::null());
10829 StorePointer(&raw_ptr()->exported_names_,
10830 HashTables::New<ResolvedNamesMap>(16));
10831 }
10832 } 10835 }
10833 10836
10834 10837
10835 void Library::InitClassDictionary() const { 10838 void Library::InitClassDictionary() const {
10836 // TODO(iposva): Find reasonable initial size. 10839 // TODO(iposva): Find reasonable initial size.
10837 const int kInitialElementCount = 16; 10840 const int kInitialElementCount = 16;
10838 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); 10841 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount));
10839 } 10842 }
10840 10843
10841 10844
(...skipping 18 matching lines...) Expand all
10860 Zone* zone = thread->zone(); 10863 Zone* zone = thread->zone();
10861 ASSERT(thread->IsMutatorThread()); 10864 ASSERT(thread->IsMutatorThread());
10862 // Force the url to have a hash code. 10865 // Force the url to have a hash code.
10863 url.Hash(); 10866 url.Hash();
10864 const bool dart_scheme = url.StartsWith(Symbols::DartScheme()); 10867 const bool dart_scheme = url.StartsWith(Symbols::DartScheme());
10865 const bool dart_private_scheme = 10868 const bool dart_private_scheme =
10866 dart_scheme && url.StartsWith(Symbols::DartSchemePrivate()); 10869 dart_scheme && url.StartsWith(Symbols::DartSchemePrivate());
10867 const Library& result = Library::Handle(zone, Library::New()); 10870 const Library& result = Library::Handle(zone, Library::New());
10868 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw()); 10871 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
10869 result.StorePointer(&result.raw_ptr()->url_, url.raw()); 10872 result.StorePointer(&result.raw_ptr()->url_, url.raw());
10870 result.StorePointer(&result.raw_ptr()->resolved_names_, 10873 result.StorePointer(&result.raw_ptr()->resolved_names_, Array::null());
10871 Object::empty_array().raw());
10872 result.StorePointer(&result.raw_ptr()->exported_names_, Array::null()); 10874 result.StorePointer(&result.raw_ptr()->exported_names_, Array::null());
10873 result.StorePointer(&result.raw_ptr()->dictionary_, 10875 result.StorePointer(&result.raw_ptr()->dictionary_,
10874 Object::empty_array().raw()); 10876 Object::empty_array().raw());
10875 result.StorePointer(&result.raw_ptr()->metadata_, 10877 result.StorePointer(&result.raw_ptr()->metadata_,
10876 GrowableObjectArray::New(4, Heap::kOld)); 10878 GrowableObjectArray::New(4, Heap::kOld));
10877 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null()); 10879 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null());
10878 result.StorePointer( 10880 result.StorePointer(
10879 &result.raw_ptr()->patch_classes_, 10881 &result.raw_ptr()->patch_classes_,
10880 GrowableObjectArray::New(Object::empty_array(), Heap::kOld)); 10882 GrowableObjectArray::New(Object::empty_array(), Heap::kOld));
10881 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw()); 10883 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw());
(...skipping 12 matching lines...) Expand all
10894 // frames. 10896 // frames.
10895 result.set_debuggable(FLAG_show_invisible_frames); 10897 result.set_debuggable(FLAG_show_invisible_frames);
10896 } else { 10898 } else {
10897 // Default to debuggable for all other libraries. 10899 // Default to debuggable for all other libraries.
10898 result.set_debuggable(true); 10900 result.set_debuggable(true);
10899 } 10901 }
10900 result.set_is_dart_scheme(dart_scheme); 10902 result.set_is_dart_scheme(dart_scheme);
10901 result.StoreNonPointer(&result.raw_ptr()->load_state_, 10903 result.StoreNonPointer(&result.raw_ptr()->load_state_,
10902 RawLibrary::kAllocated); 10904 RawLibrary::kAllocated);
10903 result.StoreNonPointer(&result.raw_ptr()->index_, -1); 10905 result.StoreNonPointer(&result.raw_ptr()->index_, -1);
10904 const intptr_t kInitialNameCacheSize = 64;
10905 result.InitResolvedNamesCache(kInitialNameCacheSize);
10906 result.InitClassDictionary(); 10906 result.InitClassDictionary();
10907 result.InitImportList(); 10907 result.InitImportList();
10908 result.AllocatePrivateKey(); 10908 result.AllocatePrivateKey();
10909 if (import_core_lib) { 10909 if (import_core_lib) {
10910 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); 10910 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
10911 ASSERT(!core_lib.IsNull()); 10911 ASSERT(!core_lib.IsNull());
10912 const Namespace& ns = Namespace::Handle( 10912 const Namespace& ns = Namespace::Handle(
10913 zone, 10913 zone,
10914 Namespace::New(core_lib, Object::null_array(), Object::null_array())); 10914 Namespace::New(core_lib, Object::null_array(), Object::null_array()));
10915 result.AddImport(ns); 10915 result.AddImport(ns);
(...skipping 12231 matching lines...) Expand 10 before | Expand all | Expand 10 after
23147 return UserTag::null(); 23147 return UserTag::null();
23148 } 23148 }
23149 23149
23150 23150
23151 const char* UserTag::ToCString() const { 23151 const char* UserTag::ToCString() const {
23152 const String& tag_label = String::Handle(label()); 23152 const String& tag_label = String::Handle(label());
23153 return tag_label.ToCString(); 23153 return tag_label.ToCString();
23154 } 23154 }
23155 23155
23156 } // namespace dart 23156 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698