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 10075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |