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

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

Issue 1496713002: --collect_dynamic_function_names (default false): find unique virtual function names and use them t… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: g Created 5 years 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/precompiler.h ('k') | no next file » | 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) 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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698