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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 "Huge method cutoff in unoptimized code size (in bytes)."); | 50 "Huge method cutoff in unoptimized code size (in bytes)."); |
51 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, | 51 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, |
52 "Huge method cutoff in tokens: Disables optimizations for huge methods."); | 52 "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
53 DEFINE_FLAG(bool, overlap_type_arguments, true, | 53 DEFINE_FLAG(bool, overlap_type_arguments, true, |
54 "When possible, partially or fully overlap the type arguments of a type " | 54 "When possible, partially or fully overlap the type arguments of a type " |
55 "with the type arguments of its super type."); | 55 "with the type arguments of its super type."); |
56 DEFINE_FLAG(bool, show_internal_names, false, | 56 DEFINE_FLAG(bool, show_internal_names, false, |
57 "Show names of internal classes (e.g. \"OneByteString\") in error messages " | 57 "Show names of internal classes (e.g. \"OneByteString\") in error messages " |
58 "instead of showing the corresponding interface names (e.g. \"String\")"); | 58 "instead of showing the corresponding interface names (e.g. \"String\")"); |
59 DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache"); | 59 DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache"); |
| 60 DEFINE_FLAG(bool, use_exp_cache, true, "Use library exported name cache"); |
60 DEFINE_FLAG(bool, ignore_patch_signature_mismatch, false, | 61 DEFINE_FLAG(bool, ignore_patch_signature_mismatch, false, |
61 "Ignore patch file member signature mismatch."); | 62 "Ignore patch file member signature mismatch."); |
62 | 63 |
63 DECLARE_FLAG(bool, show_invisible_frames); | 64 DECLARE_FLAG(bool, show_invisible_frames); |
64 DECLARE_FLAG(bool, trace_deoptimization); | 65 DECLARE_FLAG(bool, trace_deoptimization); |
65 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 66 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
66 DECLARE_FLAG(bool, write_protect_code); | 67 DECLARE_FLAG(bool, write_protect_code); |
67 DECLARE_FLAG(bool, support_externalizable_strings); | 68 DECLARE_FLAG(bool, support_externalizable_strings); |
68 | 69 |
69 | 70 |
(...skipping 9621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9691 #endif | 9692 #endif |
9692 return present; | 9693 return present; |
9693 } | 9694 } |
9694 | 9695 |
9695 | 9696 |
9696 // Add a name to the resolved name cache. This name resolves to the | 9697 // Add a name to the resolved name cache. This name resolves to the |
9697 // given object in this library scope. obj may be null, which means | 9698 // given object in this library scope. obj may be null, which means |
9698 // the name does not resolve to anything in this library scope. | 9699 // the name does not resolve to anything in this library scope. |
9699 void Library::AddToResolvedNamesCache(const String& name, | 9700 void Library::AddToResolvedNamesCache(const String& name, |
9700 const Object& obj) const { | 9701 const Object& obj) const { |
9701 ASSERT(!Compiler::IsBackgroundCompilation()); | 9702 if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { |
9702 if (!FLAG_use_lib_cache) { | |
9703 return; | 9703 return; |
9704 } | 9704 } |
9705 ResolvedNamesMap cache(resolved_names()); | 9705 ResolvedNamesMap cache(resolved_names()); |
9706 cache.UpdateOrInsert(name, obj); | 9706 cache.UpdateOrInsert(name, obj); |
9707 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); | 9707 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); |
9708 } | 9708 } |
9709 | 9709 |
9710 | 9710 |
| 9711 bool Library::LookupExportedNamesCache(const String& name, |
| 9712 Object* obj) const { |
| 9713 ASSERT(FLAG_use_exp_cache); |
| 9714 if (exported_names() == Array::null()) { |
| 9715 return false; |
| 9716 } |
| 9717 ResolvedNamesMap cache(exported_names()); |
| 9718 bool present = false; |
| 9719 *obj = cache.GetOrNull(name, &present); |
| 9720 // Mutator compiler thread may add entries and therefore |
| 9721 // change 'exported_names()' while running a background compilation; |
| 9722 // do not ASSERT that 'exported_names()' has not changed. |
| 9723 #if defined(DEBUG) |
| 9724 if (Thread::Current()->IsMutatorThread()) { |
| 9725 ASSERT(cache.Release().raw() == exported_names()); |
| 9726 } else { |
| 9727 // Release must be called in debug mode. |
| 9728 cache.Release(); |
| 9729 } |
| 9730 #endif |
| 9731 return present; |
| 9732 } |
| 9733 |
| 9734 void Library::AddToExportedNamesCache(const String& name, |
| 9735 const Object& obj) const { |
| 9736 if (!FLAG_use_exp_cache || Compiler::IsBackgroundCompilation()) { |
| 9737 return; |
| 9738 } |
| 9739 if (exported_names() == Array::null()) { |
| 9740 AllocateExportedNamesCache(); |
| 9741 } |
| 9742 ResolvedNamesMap cache(exported_names()); |
| 9743 cache.UpdateOrInsert(name, obj); |
| 9744 StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); |
| 9745 } |
| 9746 |
| 9747 |
9711 void Library::InvalidateResolvedName(const String& name) const { | 9748 void Library::InvalidateResolvedName(const String& name) const { |
9712 Object& entry = Object::Handle(); | 9749 Thread* thread = Thread::Current(); |
| 9750 Zone* zone = thread->zone(); |
| 9751 Object& entry = Object::Handle(zone); |
9713 if (LookupResolvedNamesCache(name, &entry)) { | 9752 if (LookupResolvedNamesCache(name, &entry)) { |
9714 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. | 9753 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. |
9715 InvalidateResolvedNamesCache(); | 9754 InvalidateResolvedNamesCache(); |
9716 } | 9755 } |
| 9756 // When a new name is added to a library, we need to invalidate all |
| 9757 // caches that contain an entry for this name. If the name was previously |
| 9758 // looked up but could not be resolved, the cache contains a null entry. |
| 9759 GrowableObjectArray& libs = GrowableObjectArray::Handle( |
| 9760 zone, thread->isolate()->object_store()->libraries()); |
| 9761 Library& lib = Library::Handle(zone); |
| 9762 intptr_t num_libs = libs.Length(); |
| 9763 for (intptr_t i = 0; i < num_libs; i++) { |
| 9764 lib ^= libs.At(i); |
| 9765 if (LookupExportedNamesCache(name, &entry)) { |
| 9766 InitExportedNamesCache(); |
| 9767 } |
| 9768 } |
9717 } | 9769 } |
9718 | 9770 |
9719 | 9771 |
9720 void Library::InvalidateResolvedNamesCache() const { | 9772 void Library::InvalidateResolvedNamesCache() const { |
9721 const intptr_t kInvalidatedCacheSize = 16; | 9773 const intptr_t kInvalidatedCacheSize = 16; |
9722 InitResolvedNamesCache(kInvalidatedCacheSize); | 9774 InitResolvedNamesCache(kInvalidatedCacheSize); |
9723 } | 9775 } |
9724 | 9776 |
9725 | 9777 |
| 9778 // Invalidate all exported names caches in the isolate. |
| 9779 void Library::InvalidateExportedNamesCaches() { |
| 9780 GrowableObjectArray& libs = GrowableObjectArray::Handle( |
| 9781 Isolate::Current()->object_store()->libraries()); |
| 9782 Library& lib = Library::Handle(); |
| 9783 intptr_t num_libs = libs.Length(); |
| 9784 for (intptr_t i = 0; i < num_libs; i++) { |
| 9785 lib ^= libs.At(i); |
| 9786 lib.InitExportedNamesCache(); |
| 9787 } |
| 9788 } |
| 9789 |
| 9790 |
9726 void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { | 9791 void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { |
9727 // TODO(iposva): Avoid exponential growth. | 9792 // TODO(iposva): Avoid exponential growth. |
9728 intptr_t new_dict_size = dict_size * 2; | 9793 intptr_t new_dict_size = dict_size * 2; |
9729 const Array& new_dict = | 9794 const Array& new_dict = |
9730 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); | 9795 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); |
9731 // Rehash all elements from the original dictionary | 9796 // Rehash all elements from the original dictionary |
9732 // to the newly allocated array. | 9797 // to the newly allocated array. |
9733 Object& entry = Class::Handle(); | 9798 Object& entry = Class::Handle(); |
9734 String& entry_name = String::Handle(); | 9799 String& entry_name = String::Handle(); |
9735 Object& new_entry = Object::Handle(); | 9800 Object& new_entry = Object::Handle(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9791 // Invalidate the cache of loaded scripts. | 9856 // Invalidate the cache of loaded scripts. |
9792 if (loaded_scripts() != Array::null()) { | 9857 if (loaded_scripts() != Array::null()) { |
9793 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 9858 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
9794 } | 9859 } |
9795 } | 9860 } |
9796 | 9861 |
9797 | 9862 |
9798 // Lookup a name in the library's re-export namespace. | 9863 // Lookup a name in the library's re-export namespace. |
9799 // This lookup can occur from two different threads: background compiler and | 9864 // This lookup can occur from two different threads: background compiler and |
9800 // mutator thread. | 9865 // mutator thread. |
9801 RawObject* Library::LookupReExport(const String& name) const { | 9866 RawObject* Library::LookupReExport(const String& name, |
9802 if (HasExports()) { | 9867 ZoneGrowableArray<intptr_t>* trail) const { |
9803 const bool is_background_compiler = Compiler::IsBackgroundCompilation(); | 9868 if (!HasExports()) { |
9804 Array& exports = Array::Handle(); | 9869 return Object::null(); |
9805 if (is_background_compiler) { | 9870 } |
9806 exports = this->exports2(); | 9871 |
9807 // Break potential export cycle while looking up name. | 9872 if (trail == NULL) { |
9808 StorePointer(&raw_ptr()->exports2_, Object::empty_array().raw()); | 9873 trail = new ZoneGrowableArray<intptr_t>(); |
9809 } else { | 9874 } |
9810 exports = this->exports(); | 9875 Object& obj = Object::Handle(); |
9811 // Break potential export cycle while looking up name. | 9876 if (FLAG_use_exp_cache && LookupExportedNamesCache(name, &obj)) { |
9812 StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); | 9877 return obj.raw(); |
9813 } | 9878 } |
9814 Namespace& ns = Namespace::Handle(); | 9879 |
9815 Object& obj = Object::Handle(); | 9880 const intptr_t lib_id = this->index(); |
9816 for (int i = 0; i < exports.Length(); i++) { | 9881 ASSERT(lib_id >= 0); // We use -1 to indicate that a cycle was found. |
9817 ns ^= exports.At(i); | 9882 trail->Add(lib_id); |
9818 obj = ns.Lookup(name); | 9883 const Array& exports = Array::Handle(this->exports()); |
9819 if (!obj.IsNull()) { | 9884 Namespace& ns = Namespace::Handle(); |
9820 // The Lookup call above may return a setter x= when we are looking | 9885 for (int i = 0; i < exports.Length(); i++) { |
9821 // for the name x. Make sure we only return when a matching name | 9886 ns ^= exports.At(i); |
9822 // is found. | 9887 obj = ns.Lookup(name, trail); |
9823 String& obj_name = String::Handle(obj.DictionaryName()); | 9888 if (!obj.IsNull()) { |
9824 if (Field::IsSetterName(obj_name) == Field::IsSetterName(name)) { | 9889 // The Lookup call above may return a setter x= when we are looking |
9825 break; | 9890 // for the name x. Make sure we only return when a matching name |
9826 } | 9891 // is found. |
| 9892 String& obj_name = String::Handle(obj.DictionaryName()); |
| 9893 if (Field::IsSetterName(obj_name) == Field::IsSetterName(name)) { |
| 9894 break; |
9827 } | 9895 } |
9828 } | 9896 } |
9829 if (is_background_compiler) { | |
9830 StorePointer(&raw_ptr()->exports2_, exports.raw()); | |
9831 } else { | |
9832 StorePointer(&raw_ptr()->exports_, exports.raw()); | |
9833 } | |
9834 return obj.raw(); | |
9835 } | 9897 } |
9836 return Object::null(); | 9898 bool in_cycle = (trail->RemoveLast() < 0); |
| 9899 if (FLAG_use_exp_cache && |
| 9900 !in_cycle && |
| 9901 !Compiler::IsBackgroundCompilation()) { |
| 9902 AddToExportedNamesCache(name, obj); |
| 9903 } |
| 9904 return obj.raw(); |
9837 } | 9905 } |
9838 | 9906 |
9839 | 9907 |
9840 RawObject* Library::LookupEntry(const String& name, intptr_t *index) const { | 9908 RawObject* Library::LookupEntry(const String& name, intptr_t *index) const { |
9841 Thread* thread = Thread::Current(); | 9909 Thread* thread = Thread::Current(); |
9842 REUSABLE_ARRAY_HANDLESCOPE(thread); | 9910 REUSABLE_ARRAY_HANDLESCOPE(thread); |
9843 REUSABLE_OBJECT_HANDLESCOPE(thread); | 9911 REUSABLE_OBJECT_HANDLESCOPE(thread); |
9844 REUSABLE_STRING_HANDLESCOPE(thread); | 9912 REUSABLE_STRING_HANDLESCOPE(thread); |
9845 Array& dict = thread->ArrayHandle(); | 9913 Array& dict = thread->ArrayHandle(); |
9846 dict ^= dictionary(); | 9914 dict ^= dictionary(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9912 dict.SetAt(new_index, entry); | 9980 dict.SetAt(new_index, entry); |
9913 dict.SetAt(index, Object::null_object()); | 9981 dict.SetAt(index, Object::null_object()); |
9914 } | 9982 } |
9915 } | 9983 } |
9916 | 9984 |
9917 // Update used count. | 9985 // Update used count. |
9918 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1; | 9986 intptr_t used_elements = Smi::Value(Smi::RawCast(dict.At(dict_size))) - 1; |
9919 dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements))); | 9987 dict.SetAt(dict_size, Smi::Handle(zone, Smi::New(used_elements))); |
9920 | 9988 |
9921 InvalidateResolvedNamesCache(); | 9989 InvalidateResolvedNamesCache(); |
| 9990 InvalidateExportedNamesCaches(); |
9922 | 9991 |
9923 return true; | 9992 return true; |
9924 } | 9993 } |
9925 | 9994 |
9926 | 9995 |
9927 void Library::AddClass(const Class& cls) const { | 9996 void Library::AddClass(const Class& cls) const { |
9928 ASSERT(!Compiler::IsBackgroundCompilation()); | 9997 ASSERT(!Compiler::IsBackgroundCompilation()); |
9929 const String& class_name = String::Handle(cls.Name()); | 9998 const String& class_name = String::Handle(cls.Name()); |
9930 AddObject(cls, class_name); | 9999 AddObject(cls, class_name); |
9931 // Link class to this library. | 10000 // Link class to this library. |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10278 } | 10347 } |
10279 } | 10348 } |
10280 } | 10349 } |
10281 return false; | 10350 return false; |
10282 } | 10351 } |
10283 | 10352 |
10284 | 10353 |
10285 void Library::DropDependencies() const { | 10354 void Library::DropDependencies() const { |
10286 StorePointer(&raw_ptr()->imports_, Array::null()); | 10355 StorePointer(&raw_ptr()->imports_, Array::null()); |
10287 StorePointer(&raw_ptr()->exports_, Array::null()); | 10356 StorePointer(&raw_ptr()->exports_, Array::null()); |
10288 StorePointer(&raw_ptr()->exports2_, Array::null()); | |
10289 } | 10357 } |
10290 | 10358 |
10291 | 10359 |
10292 void Library::AddImport(const Namespace& ns) const { | 10360 void Library::AddImport(const Namespace& ns) const { |
10293 Array& imports = Array::Handle(this->imports()); | 10361 Array& imports = Array::Handle(this->imports()); |
10294 intptr_t capacity = imports.Length(); | 10362 intptr_t capacity = imports.Length(); |
10295 if (num_imports() == capacity) { | 10363 if (num_imports() == capacity) { |
10296 capacity = capacity + kImportsCapacityIncrement; | 10364 capacity = capacity + kImportsCapacityIncrement; |
10297 imports = Array::Grow(imports, capacity); | 10365 imports = Array::Grow(imports, capacity); |
10298 StorePointer(&raw_ptr()->imports_, imports.raw()); | 10366 StorePointer(&raw_ptr()->imports_, imports.raw()); |
(...skipping 12 matching lines...) Expand all Loading... |
10311 | 10379 |
10312 | 10380 |
10313 // We add one namespace at a time to the exports array and don't | 10381 // We add one namespace at a time to the exports array and don't |
10314 // pre-allocate any unused capacity. The assumption is that | 10382 // pre-allocate any unused capacity. The assumption is that |
10315 // re-exports are quite rare. | 10383 // re-exports are quite rare. |
10316 void Library::AddExport(const Namespace& ns) const { | 10384 void Library::AddExport(const Namespace& ns) const { |
10317 Array &exports = Array::Handle(this->exports()); | 10385 Array &exports = Array::Handle(this->exports()); |
10318 intptr_t num_exports = exports.Length(); | 10386 intptr_t num_exports = exports.Length(); |
10319 exports = Array::Grow(exports, num_exports + 1); | 10387 exports = Array::Grow(exports, num_exports + 1); |
10320 StorePointer(&raw_ptr()->exports_, exports.raw()); | 10388 StorePointer(&raw_ptr()->exports_, exports.raw()); |
10321 StorePointer(&raw_ptr()->exports2_, exports.raw()); | |
10322 exports.SetAt(num_exports, ns); | 10389 exports.SetAt(num_exports, ns); |
10323 } | 10390 } |
10324 | 10391 |
10325 | 10392 |
10326 static RawArray* NewDictionary(intptr_t initial_size) { | 10393 static RawArray* NewDictionary(intptr_t initial_size) { |
10327 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); | 10394 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); |
10328 // The last element of the dictionary specifies the number of in use slots. | 10395 // The last element of the dictionary specifies the number of in use slots. |
10329 dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); | 10396 dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); |
10330 return dict.raw(); | 10397 return dict.raw(); |
10331 } | 10398 } |
10332 | 10399 |
10333 | 10400 |
10334 void Library::InitResolvedNamesCache(intptr_t size, | 10401 void Library::InitResolvedNamesCache(intptr_t size, |
10335 SnapshotReader* reader) const { | 10402 SnapshotReader* reader) const { |
10336 ASSERT(Thread::Current()->IsMutatorThread()); | 10403 ASSERT(Thread::Current()->IsMutatorThread()); |
10337 if (reader == NULL) { | 10404 if (reader == NULL) { |
10338 StorePointer(&raw_ptr()->resolved_names_, | 10405 StorePointer(&raw_ptr()->resolved_names_, |
10339 HashTables::New<ResolvedNamesMap>(size)); | 10406 HashTables::New<ResolvedNamesMap>(size)); |
10340 } else { | 10407 } else { |
10341 intptr_t len = ResolvedNamesMap::ArrayLengthForNumOccupied(size); | 10408 intptr_t len = ResolvedNamesMap::ArrayLengthForNumOccupied(size); |
10342 *reader->ArrayHandle() ^= reader->NewArray(len); | 10409 *reader->ArrayHandle() ^= reader->NewArray(len); |
10343 StorePointer(&raw_ptr()->resolved_names_, | 10410 StorePointer(&raw_ptr()->resolved_names_, |
10344 HashTables::New<ResolvedNamesMap>(*reader->ArrayHandle())); | 10411 HashTables::New<ResolvedNamesMap>(*reader->ArrayHandle())); |
10345 } | 10412 } |
10346 } | 10413 } |
10347 | 10414 |
10348 | 10415 |
| 10416 void Library::AllocateExportedNamesCache() const { |
| 10417 StorePointer(&raw_ptr()->exported_names_, |
| 10418 HashTables::New<ResolvedNamesMap>(16)); |
| 10419 } |
| 10420 |
| 10421 |
| 10422 void Library::InitExportedNamesCache() const { |
| 10423 if (exported_names() != Array::null()) { |
| 10424 StorePointer(&raw_ptr()->exported_names_, |
| 10425 HashTables::New<ResolvedNamesMap>(16)); |
| 10426 } |
| 10427 } |
| 10428 |
| 10429 |
10349 void Library::InitClassDictionary() const { | 10430 void Library::InitClassDictionary() const { |
10350 // TODO(iposva): Find reasonable initial size. | 10431 // TODO(iposva): Find reasonable initial size. |
10351 const int kInitialElementCount = 16; | 10432 const int kInitialElementCount = 16; |
10352 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); | 10433 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); |
10353 } | 10434 } |
10354 | 10435 |
10355 | 10436 |
10356 void Library::InitImportList() const { | 10437 void Library::InitImportList() const { |
10357 const Array& imports = | 10438 const Array& imports = |
10358 Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); | 10439 Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); |
(...skipping 14 matching lines...) Expand all Loading... |
10373 RawLibrary* Library::NewLibraryHelper(const String& url, | 10454 RawLibrary* Library::NewLibraryHelper(const String& url, |
10374 bool import_core_lib) { | 10455 bool import_core_lib) { |
10375 Thread* thread = Thread::Current(); | 10456 Thread* thread = Thread::Current(); |
10376 Zone* zone = thread->zone(); | 10457 Zone* zone = thread->zone(); |
10377 ASSERT(thread->IsMutatorThread()); | 10458 ASSERT(thread->IsMutatorThread()); |
10378 const Library& result = Library::Handle(zone, Library::New()); | 10459 const Library& result = Library::Handle(zone, Library::New()); |
10379 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw()); | 10460 result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw()); |
10380 result.StorePointer(&result.raw_ptr()->url_, url.raw()); | 10461 result.StorePointer(&result.raw_ptr()->url_, url.raw()); |
10381 result.StorePointer(&result.raw_ptr()->resolved_names_, | 10462 result.StorePointer(&result.raw_ptr()->resolved_names_, |
10382 Object::empty_array().raw()); | 10463 Object::empty_array().raw()); |
| 10464 result.StorePointer(&result.raw_ptr()->exported_names_, |
| 10465 Array::null()); |
10383 result.StorePointer(&result.raw_ptr()->dictionary_, | 10466 result.StorePointer(&result.raw_ptr()->dictionary_, |
10384 Object::empty_array().raw()); | 10467 Object::empty_array().raw()); |
10385 result.StorePointer(&result.raw_ptr()->metadata_, | 10468 result.StorePointer(&result.raw_ptr()->metadata_, |
10386 GrowableObjectArray::New(4, Heap::kOld)); | 10469 GrowableObjectArray::New(4, Heap::kOld)); |
10387 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null()); | 10470 result.StorePointer(&result.raw_ptr()->toplevel_class_, Class::null()); |
10388 result.StorePointer(&result.raw_ptr()->patch_classes_, | 10471 result.StorePointer(&result.raw_ptr()->patch_classes_, |
10389 GrowableObjectArray::New(Object::empty_array(), | 10472 GrowableObjectArray::New(Object::empty_array(), |
10390 Heap::kOld)); | 10473 Heap::kOld)); |
10391 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw()); | 10474 result.StorePointer(&result.raw_ptr()->imports_, Object::empty_array().raw()); |
10392 result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw()); | 10475 result.StorePointer(&result.raw_ptr()->exports_, Object::empty_array().raw()); |
10393 result.StorePointer(&result.raw_ptr()->exports2_, | |
10394 Object::empty_array().raw()); | |
10395 result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null()); | 10476 result.StorePointer(&result.raw_ptr()->loaded_scripts_, Array::null()); |
10396 result.StorePointer(&result.raw_ptr()->load_error_, Instance::null()); | 10477 result.StorePointer(&result.raw_ptr()->load_error_, Instance::null()); |
10397 result.set_native_entry_resolver(NULL); | 10478 result.set_native_entry_resolver(NULL); |
10398 result.set_native_entry_symbol_resolver(NULL); | 10479 result.set_native_entry_symbol_resolver(NULL); |
10399 result.set_is_in_fullsnapshot(false); | 10480 result.set_is_in_fullsnapshot(false); |
10400 result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true); | 10481 result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true); |
10401 result.set_debuggable(false); | 10482 result.set_debuggable(false); |
10402 result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme())); | 10483 result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme())); |
10403 result.StoreNonPointer(&result.raw_ptr()->load_state_, | 10484 result.StoreNonPointer(&result.raw_ptr()->load_state_, |
10404 RawLibrary::kAllocated); | 10485 RawLibrary::kAllocated); |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11106 // contained in the list, so it is hidden. | 11187 // contained in the list, so it is hidden. |
11107 return true; | 11188 return true; |
11108 } | 11189 } |
11109 // The name is not filtered out. | 11190 // The name is not filtered out. |
11110 return false; | 11191 return false; |
11111 } | 11192 } |
11112 | 11193 |
11113 | 11194 |
11114 // Look up object with given name in library and filter out hidden | 11195 // Look up object with given name in library and filter out hidden |
11115 // names. Also look up getters and setters. | 11196 // names. Also look up getters and setters. |
11116 RawObject* Namespace::Lookup(const String& name) const { | 11197 RawObject* Namespace::Lookup(const String& name, |
| 11198 ZoneGrowableArray<intptr_t>* trail) const { |
11117 Zone* zone = Thread::Current()->zone(); | 11199 Zone* zone = Thread::Current()->zone(); |
11118 const Library& lib = Library::Handle(zone, library()); | 11200 const Library& lib = Library::Handle(zone, library()); |
| 11201 |
| 11202 if (trail != NULL) { |
| 11203 // Look for cycle in reexport graph. |
| 11204 for (int i = 0; i < trail->length(); i++) { |
| 11205 if (trail->At(i) == lib.index()) { |
| 11206 for (int j = i+1; j < trail->length(); j++) { |
| 11207 (*trail)[j] = -1; |
| 11208 } |
| 11209 return Object::null(); |
| 11210 } |
| 11211 } |
| 11212 } |
| 11213 |
11119 intptr_t ignore = 0; | 11214 intptr_t ignore = 0; |
11120 | |
11121 // Lookup the name in the library's symbols. | 11215 // Lookup the name in the library's symbols. |
11122 Object& obj = Object::Handle(zone, lib.LookupEntry(name, &ignore)); | 11216 Object& obj = Object::Handle(zone, lib.LookupEntry(name, &ignore)); |
11123 if (!Field::IsGetterName(name) && | 11217 if (!Field::IsGetterName(name) && |
11124 !Field::IsSetterName(name) && | 11218 !Field::IsSetterName(name) && |
11125 (obj.IsNull() || obj.IsLibraryPrefix())) { | 11219 (obj.IsNull() || obj.IsLibraryPrefix())) { |
11126 String& accessor_name = String::Handle(zone); | 11220 String& accessor_name = String::Handle(zone); |
11127 accessor_name ^= Field::LookupGetterSymbol(name); | 11221 accessor_name ^= Field::LookupGetterSymbol(name); |
11128 if (!accessor_name.IsNull()) { | 11222 if (!accessor_name.IsNull()) { |
11129 obj = lib.LookupEntry(accessor_name, &ignore); | 11223 obj = lib.LookupEntry(accessor_name, &ignore); |
11130 } | 11224 } |
11131 if (obj.IsNull()) { | 11225 if (obj.IsNull()) { |
11132 accessor_name ^= Field::LookupSetterSymbol(name); | 11226 accessor_name ^= Field::LookupSetterSymbol(name); |
11133 if (!accessor_name.IsNull()) { | 11227 if (!accessor_name.IsNull()) { |
11134 obj = lib.LookupEntry(accessor_name, &ignore); | 11228 obj = lib.LookupEntry(accessor_name, &ignore); |
11135 } | 11229 } |
11136 } | 11230 } |
11137 } | 11231 } |
11138 | 11232 |
11139 // Library prefixes are not exported. | 11233 // Library prefixes are not exported. |
11140 if (obj.IsNull() || obj.IsLibraryPrefix()) { | 11234 if (obj.IsNull() || obj.IsLibraryPrefix()) { |
11141 // Lookup in the re-exported symbols. | 11235 // Lookup in the re-exported symbols. |
11142 obj = lib.LookupReExport(name); | 11236 obj = lib.LookupReExport(name, trail); |
11143 if (obj.IsNull() && !Field::IsSetterName(name)) { | 11237 if (obj.IsNull() && !Field::IsSetterName(name)) { |
11144 // LookupReExport() only returns objects that match the given name. | 11238 // LookupReExport() only returns objects that match the given name. |
11145 // If there is no field/func/getter, try finding a setter. | 11239 // If there is no field/func/getter, try finding a setter. |
11146 const String& setter_name = | 11240 const String& setter_name = |
11147 String::Handle(zone, Field::LookupSetterSymbol(name)); | 11241 String::Handle(zone, Field::LookupSetterSymbol(name)); |
11148 if (!setter_name.IsNull()) { | 11242 if (!setter_name.IsNull()) { |
11149 obj = lib.LookupReExport(setter_name); | 11243 obj = lib.LookupReExport(setter_name, trail); |
11150 } | 11244 } |
11151 } | 11245 } |
11152 } | 11246 } |
11153 if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { | 11247 if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { |
11154 return Object::null(); | 11248 return Object::null(); |
11155 } | 11249 } |
11156 return obj.raw(); | 11250 return obj.raw(); |
11157 } | 11251 } |
11158 | 11252 |
11159 | 11253 |
(...skipping 11028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22188 return UserTag::null(); | 22282 return UserTag::null(); |
22189 } | 22283 } |
22190 | 22284 |
22191 | 22285 |
22192 const char* UserTag::ToCString() const { | 22286 const char* UserTag::ToCString() const { |
22193 const String& tag_label = String::Handle(label()); | 22287 const String& tag_label = String::Handle(label()); |
22194 return tag_label.ToCString(); | 22288 return tag_label.ToCString(); |
22195 } | 22289 } |
22196 | 22290 |
22197 } // namespace dart | 22291 } // namespace dart |
OLD | NEW |