Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/precompiler.h" | 5 #include "vm/precompiler.h" |
| 6 | 6 |
| 7 #include "vm/cha.h" | |
| 7 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 8 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/hash_table.h" | |
| 9 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
| 10 #include "vm/log.h" | 12 #include "vm/log.h" |
| 11 #include "vm/longjump.h" | 13 #include "vm/longjump.h" |
| 12 #include "vm/object.h" | 14 #include "vm/object.h" |
| 13 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 14 #include "vm/resolver.h" | 16 #include "vm/resolver.h" |
| 15 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 16 | 18 |
| 17 namespace dart { | 19 namespace dart { |
| 18 | 20 |
| 19 | 21 |
| 20 #define T (thread()) | 22 #define T (thread()) |
| 21 #define I (isolate()) | 23 #define I (isolate()) |
| 22 #define Z (zone()) | 24 #define Z (zone()) |
| 23 | 25 |
| 24 | 26 |
| 27 DEFINE_FLAG(bool, collect_dynamic_function_names, false, | |
| 28 "In precompilation collects all dynamic function names in order to" | |
| 29 " identify unique targets"); | |
| 25 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); | 30 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); |
| 26 | 31 |
| 27 | 32 |
| 28 static void Jump(const Error& error) { | 33 static void Jump(const Error& error) { |
| 29 Thread::Current()->long_jump_base()->Jump(1, error); | 34 Thread::Current()->long_jump_base()->Jump(1, error); |
| 30 } | 35 } |
| 31 | 36 |
| 32 | 37 |
| 33 RawError* Precompiler::CompileAll( | 38 RawError* Precompiler::CompileAll( |
| 34 Dart_QualifiedFunctionName embedder_entry_points[], | 39 Dart_QualifiedFunctionName embedder_entry_points[], |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 // - field initializers | 95 // - field initializers |
| 91 // - invoke-field-dispatchers | 96 // - invoke-field-dispatchers |
| 92 // - method-extractors | 97 // - method-extractors |
| 93 // that are needed in early iterations but optimized away in later | 98 // that are needed in early iterations but optimized away in later |
| 94 // iterations. | 99 // iterations. |
| 95 ClearAllCode(); | 100 ClearAllCode(); |
| 96 | 101 |
| 97 // Start with the allocations and invocations that happen from C++. | 102 // Start with the allocations and invocations that happen from C++. |
| 98 AddRoots(embedder_entry_points); | 103 AddRoots(embedder_entry_points); |
| 99 | 104 |
| 105 CollectDynamicFunctionNames(); | |
| 106 | |
| 100 // Compile newly found targets and add their callees until we reach a fixed | 107 // Compile newly found targets and add their callees until we reach a fixed |
| 101 // point. | 108 // point. |
| 102 Iterate(); | 109 Iterate(); |
| 103 } | 110 } |
| 104 | 111 |
| 105 DropUncompiledFunctions(); | 112 DropUncompiledFunctions(); |
| 106 | 113 |
| 107 // TODO(rmacnak): DropEmptyClasses(); | 114 // TODO(rmacnak): DropEmptyClasses(); |
| 108 | 115 |
| 109 BindStaticCalls(); | 116 BindStaticCalls(); |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 function2 = function.GetMethodExtractor(selector2); | 708 function2 = function.GetMethodExtractor(selector2); |
| 702 AddFunction(function2); | 709 AddFunction(function2); |
| 703 } | 710 } |
| 704 } | 711 } |
| 705 } | 712 } |
| 706 } | 713 } |
| 707 } | 714 } |
| 708 } | 715 } |
| 709 | 716 |
| 710 | 717 |
| 718 class NameFunctionsTraits { | |
| 719 public: | |
| 720 static bool IsMatch(const Object& a, const Object& b) { | |
| 721 return a.IsString() && b.IsString() && | |
| 722 String::Cast(a).Equals(String::Cast(b)); | |
| 723 } | |
| 724 static uword Hash(const Object& obj) { | |
| 725 return String::Cast(obj).Hash(); | |
| 726 } | |
| 727 static RawObject* NewKey(const String& str) { | |
| 728 return str.raw(); | |
| 729 } | |
| 730 }; | |
| 731 | |
| 732 typedef UnorderedHashMap<NameFunctionsTraits> Table; | |
| 733 | |
| 734 | |
| 735 class FunctionsTraits { | |
| 736 public: | |
| 737 static bool IsMatch(const Object& a, const Object& b) { | |
| 738 Zone* zone = Thread::Current()->zone(); | |
| 739 String& a_s = String::Handle(zone); | |
| 740 String& b_s = String::Handle(zone); | |
| 741 a_s = a.IsFunction() ? Function::Cast(a).name() : String::Cast(a).raw(); | |
| 742 b_s = b.IsFunction() ? Function::Cast(b).name() : String::Cast(b).raw(); | |
| 743 ASSERT(a_s.IsSymbol() && b_s.IsSymbol()); | |
| 744 return a_s.raw() == b_s.raw(); | |
| 745 } | |
| 746 static uword Hash(const Object& obj) { | |
| 747 if (obj.IsFunction()) { | |
| 748 return String::Handle(Function::Cast(obj).name()).Hash(); | |
| 749 } else { | |
| 750 ASSERT(String::Cast(obj).IsSymbol()); | |
| 751 return String::Cast(obj).Hash(); | |
| 752 } | |
| 753 } | |
| 754 static RawObject* NewKey(const Function& function) { | |
| 755 return function.raw(); | |
| 756 } | |
| 757 }; | |
| 758 | |
| 759 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; | |
| 760 | |
| 761 | |
| 762 void Precompiler::CollectDynamicFunctionNames() { | |
| 763 if (!FLAG_collect_dynamic_function_names) { | |
| 764 return; | |
| 765 } | |
| 766 Library& lib = Library::Handle(Z); | |
| 767 Class& cls = Class::Handle(Z); | |
| 768 Array& functions = Array::Handle(Z); | |
| 769 Function& function = Function::Handle(Z); | |
| 770 String& fname = String::Handle(Z); | |
| 771 Array& farray = Array::Handle(Z); | |
| 772 | |
| 773 Table table(HashTables::New<Table>(100)); | |
| 774 for (intptr_t i = 0; i < libraries_.Length(); i++) { | |
| 775 lib ^= libraries_.At(i); | |
| 776 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | |
| 777 while (it.HasNext()) { | |
| 778 cls = it.GetNextClass(); | |
| 779 if (cls.IsDynamicClass()) { | |
| 780 continue; // class 'dynamic' is in the read-only VM isolate. | |
| 781 } | |
| 782 functions = cls.functions(); | |
| 783 for (intptr_t j = 0; j < functions.Length(); j++) { | |
| 784 function ^= functions.At(j); | |
| 785 if (function.IsDynamicFunction()) { | |
|
rmacnak
2015/12/03 00:34:34
Regular methods need to be added under their gette
srdjan
2015/12/04 17:14:25
Thanks, good catch. Fixed and also added checks (h
| |
| 786 fname = function.name(); | |
| 787 farray ^= table.InsertNewOrGetValue(fname, Array::empty_array()); | |
| 788 farray = Array::Grow(farray, farray.Length() + 1); | |
| 789 farray.SetAt(farray.Length() - 1, function); | |
| 790 table.UpdateValue(fname, farray); | |
| 791 } | |
| 792 } | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 // Locate all entries with one function only, and which owner is neither | |
| 797 // subclassed nor implemented. | |
| 798 Table::Iterator iter(&table); | |
| 799 String& key = String::Handle(Z); | |
| 800 UniqueFunctionsSet functions_set(HashTables::New<UniqueFunctionsSet>(20)); | |
| 801 while (iter.MoveNext()) { | |
| 802 intptr_t curr_key = iter.Current(); | |
| 803 key ^= table.GetKey(curr_key); | |
| 804 farray ^= table.GetOrNull(key); | |
| 805 ASSERT(!farray.IsNull()); | |
| 806 if (farray.Length() == 1) { | |
| 807 function ^= farray.At(0); | |
| 808 cls = function.Owner(); | |
| 809 if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) { | |
| 810 functions_set.Insert(function); | |
| 811 } | |
| 812 } | |
| 813 } | |
| 814 | |
| 815 isolate()->object_store()->set_unique_dynamic_targets( | |
| 816 functions_set.Release()); | |
| 817 table.Release(); | |
| 818 } | |
| 819 | |
| 820 | |
| 821 void Precompiler::GetUniqueDynamicTarget(Isolate* isolate, | |
| 822 const String& fname, | |
| 823 Object* function) { | |
| 824 UniqueFunctionsSet functions_set( | |
| 825 isolate->object_store()->unique_dynamic_targets()); | |
| 826 ASSERT(fname.IsSymbol()); | |
| 827 *function = functions_set.GetOrNull(fname); | |
| 828 ASSERT(functions_set.Release().raw() == | |
| 829 isolate->object_store()->unique_dynamic_targets()); | |
| 830 } | |
| 831 | |
| 832 | |
| 711 void Precompiler::DropUncompiledFunctions() { | 833 void Precompiler::DropUncompiledFunctions() { |
| 712 Library& lib = Library::Handle(Z); | 834 Library& lib = Library::Handle(Z); |
| 713 Class& cls = Class::Handle(Z); | 835 Class& cls = Class::Handle(Z); |
| 714 Array& functions = Array::Handle(Z); | 836 Array& functions = Array::Handle(Z); |
| 715 Function& function = Function::Handle(Z); | 837 Function& function = Function::Handle(Z); |
| 716 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | 838 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); |
| 717 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 839 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
| 718 | 840 |
| 719 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 841 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 720 lib ^= libraries_.At(i); | 842 lib ^= libraries_.At(i); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 957 cls = it.GetNextClass(); | 1079 cls = it.GetNextClass(); |
| 958 if (cls.IsDynamicClass()) { | 1080 if (cls.IsDynamicClass()) { |
| 959 continue; // class 'dynamic' is in the read-only VM isolate. | 1081 continue; // class 'dynamic' is in the read-only VM isolate. |
| 960 } | 1082 } |
| 961 cls.set_is_allocated(false); | 1083 cls.set_is_allocated(false); |
| 962 } | 1084 } |
| 963 } | 1085 } |
| 964 } | 1086 } |
| 965 | 1087 |
| 966 } // namespace dart | 1088 } // namespace dart |
| OLD | NEW |