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