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

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

Issue 2924013004: core-jit: (Closed)
Patch Set: . Created 3 years, 6 months 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/compilation_trace.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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/compilation_trace.h" 5 #include "vm/compilation_trace.h"
6 6
7 #include "vm/longjump.h" 7 #include "vm/longjump.h"
8 #include "vm/object_store.h" 8 #include "vm/object_store.h"
9 #include "vm/resolver.h" 9 #include "vm/resolver.h"
10 #include "vm/symbols.h" 10 #include "vm/symbols.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 CompilationTraceSaver::CompilationTraceSaver(Zone* zone) 14 CompilationTraceSaver::CompilationTraceSaver(Zone* zone)
15 : buf_(zone, 4 * KB), 15 : buf_(zone, 4 * KB),
16 func_name_(String::Handle(zone)), 16 func_name_(String::Handle(zone)),
17 cls_(Class::Handle(zone)), 17 cls_(Class::Handle(zone)),
18 cls_name_(String::Handle(zone)), 18 cls_name_(String::Handle(zone)),
19 lib_(Library::Handle(zone)), 19 lib_(Library::Handle(zone)),
20 uri_(String::Handle(zone)) {} 20 uri_(String::Handle(zone)) {}
21 21
22 22
23 void CompilationTraceSaver::Visit(const Function& function) { 23 void CompilationTraceSaver::Visit(const Function& function) {
24 if (!function.HasCode()) { 24 if (!function.HasCode()) {
25 return; // Not compiled.
26 }
27 if (function.parent_function() != Function::null()) {
28 // Lookup works poorly for local functions. We compile all local functions
29 // in a compiled function instead.
25 return; 30 return;
26 } 31 }
27 32
28 func_name_ = function.name(); 33 func_name_ = function.name();
29 func_name_ = String::RemovePrivateKey(func_name_); 34 func_name_ = String::RemovePrivateKey(func_name_);
30 cls_ = function.Owner(); 35 cls_ = function.Owner();
31 cls_name_ = cls_.Name(); 36 cls_name_ = cls_.Name();
32 cls_name_ = String::RemovePrivateKey(cls_name_); 37 cls_name_ = String::RemovePrivateKey(cls_name_);
33 lib_ = cls_.library(); 38 lib_ = cls_.library();
34 uri_ = lib_.url(); 39 uri_ = lib_.url();
(...skipping 10 matching lines...) Expand all
45 function_name_(String::Handle(zone_)), 50 function_name_(String::Handle(zone_)),
46 function_name2_(String::Handle(zone_)), 51 function_name2_(String::Handle(zone_)),
47 lib_(Library::Handle(zone_)), 52 lib_(Library::Handle(zone_)),
48 cls_(Class::Handle(zone_)), 53 cls_(Class::Handle(zone_)),
49 function_(Function::Handle(zone_)), 54 function_(Function::Handle(zone_)),
50 function2_(Function::Handle(zone_)), 55 function2_(Function::Handle(zone_)),
51 field_(Field::Handle(zone_)), 56 field_(Field::Handle(zone_)),
52 error_(Object::Handle(zone_)) {} 57 error_(Object::Handle(zone_)) {}
53 58
54 59
55 RawObject* CompilationTraceLoader::CompileTrace(char* buffer) { 60 static char* FindCharacter(char* str, char goal, char* limit) {
61 while (str < limit) {
62 if (*str == goal) {
63 return str;
64 }
65 str++;
66 }
67 return NULL;
68 }
69
70
71 RawObject* CompilationTraceLoader::CompileTrace(uint8_t* buffer,
72 intptr_t size) {
56 // First compile functions named in the trace. 73 // First compile functions named in the trace.
57 char* cursor = buffer; 74 char* cursor = reinterpret_cast<char*>(buffer);
58 while (cursor != NULL) { 75 char* limit = cursor + size;
76 while (cursor < limit) {
59 char* uri = cursor; 77 char* uri = cursor;
60 char* comma1 = strchr(uri, ','); 78 char* comma1 = FindCharacter(uri, ',', limit);
61 if (comma1 == NULL) break; 79 if (comma1 == NULL) {
80 break;
81 }
62 *comma1 = 0; 82 *comma1 = 0;
63 char* cls_name = comma1 + 1; 83 char* cls_name = comma1 + 1;
64 char* comma2 = strchr(cls_name, ','); 84 char* comma2 = FindCharacter(cls_name, ',', limit);
65 if (comma2 == NULL) break; 85 if (comma2 == NULL) {
86 break;
87 }
66 *comma2 = 0; 88 *comma2 = 0;
67 char* func_name = comma2 + 1; 89 char* func_name = comma2 + 1;
68 char* newline = strchr(func_name, '\n'); 90 char* newline = FindCharacter(func_name, '\n', limit);
69 if (newline == NULL) break; 91 if (newline == NULL) {
92 break;
93 }
70 *newline = 0; 94 *newline = 0;
71 error_ = CompileTriple(uri, cls_name, func_name); 95 error_ = CompileTriple(uri, cls_name, func_name);
72 if (error_.IsError()) { 96 if (error_.IsError()) {
73 return error_.raw(); 97 return error_.raw();
74 } 98 }
75 cursor = newline + 1; 99 cursor = newline + 1;
76 } 100 }
77 101
78 // Next, compile common dispatchers. These aren't found with the normal 102 // Next, compile common dispatchers. These aren't found with the normal
79 // lookup above because they have irregular lookup that depends on the 103 // lookup above because they have irregular lookup that depends on the
80 // arguments descriptor (e.g. call() versus call(x)). 104 // arguments descriptor (e.g. call() versus call(x)).
81 const Class& closure_class = 105 const Class& closure_class =
82 Class::Handle(zone_, thread_->isolate()->object_store()->closure_class()); 106 Class::Handle(zone_, thread_->isolate()->object_store()->closure_class());
83 Array& arguments_descriptor = Array::Handle(zone_); 107 Array& arguments_descriptor = Array::Handle(zone_);
84 Function& dispatcher = Function::Handle(zone_); 108 Function& dispatcher = Function::Handle(zone_);
85 for (intptr_t argc = 1; argc <= 4; argc++) { 109 for (intptr_t argc = 1; argc <= 4; argc++) {
86 const intptr_t kTypeArgsLen = 0; 110 const intptr_t kTypeArgsLen = 0;
87 arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc); 111 arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc);
88 dispatcher = closure_class.GetInvocationDispatcher( 112 dispatcher = closure_class.GetInvocationDispatcher(
89 Symbols::Call(), arguments_descriptor, 113 Symbols::Call(), arguments_descriptor,
90 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */); 114 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
91 error_ = CompileFunction(dispatcher); 115 error_ = CompileFunction(dispatcher);
92 if (error_.IsError()) { 116 if (error_.IsError()) {
93 return error_.raw(); 117 return error_.raw();
94 } 118 }
95 } 119 }
96 120
97 // Finally, compile closures in all compiled functions. 121 // Finally, compile closures in all compiled functions. Don't cache the
122 // length since compiling may append to this list.
98 const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle( 123 const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle(
99 zone_, thread_->isolate()->object_store()->closure_functions()); 124 zone_, thread_->isolate()->object_store()->closure_functions());
100 for (intptr_t i = 0; i < closure_functions.Length(); i++) { 125 for (intptr_t i = 0; i < closure_functions.Length(); i++) {
101 function_ ^= closure_functions.At(i); 126 function_ ^= closure_functions.At(i);
102 function2_ = function_.parent_function(); 127 function2_ = function_.parent_function();
103 if (function2_.HasCode()) { 128 if (function2_.HasCode()) {
104 error_ = CompileFunction(function_); 129 error_ = CompileFunction(function_);
105 if (error_.IsError()) { 130 if (error_.IsError()) {
106 return error_.raw(); 131 return error_.raw();
107 } 132 }
108 } 133 }
109 } 134 }
110 135
111 return Object::null(); 136 return Object::null();
112 } 137 }
113 138
114 139
140 // Use a fuzzy match to find the right function to compile. This allows a
141 // compilation trace to remain mostly valid in the face of program changes, and
142 // deals with implicit/dispatcher functions that don't have proper names.
143 // - Ignore private name mangling
144 // - If looking for a getter and we only have the corresponding regular method,
145 // compile the regular method, create its implicit closure and compile that.
146 // - If looking for a regular method and we only have the corresponding getter,
147 // compile the getter, create its method extractor and compile that.
148 // - If looking for a getter and we only have a const field, evaluate the const
149 // field.
115 RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr, 150 RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr,
116 const char* cls_cstr, 151 const char* cls_cstr,
117 const char* func_cstr) { 152 const char* func_cstr) {
118 uri_ = Symbols::New(thread_, uri_cstr); 153 uri_ = Symbols::New(thread_, uri_cstr);
119 class_name_ = Symbols::New(thread_, cls_cstr); 154 class_name_ = Symbols::New(thread_, cls_cstr);
120 function_name_ = Symbols::New(thread_, func_cstr); 155 function_name_ = Symbols::New(thread_, func_cstr);
121 156
122 if (function_name_.Equals("_getMainClosure")) { 157 if (function_name_.Equals("_getMainClosure")) {
123 // The scheme for invoking main relies on compiling _getMainClosure after 158 // The scheme for invoking main relies on compiling _getMainClosure after
124 // synthetically importing the root library. 159 // synthetically importing the root library.
(...skipping 26 matching lines...) Expand all
151 return Object::null(); 186 return Object::null();
152 } 187 }
153 188
154 error_ = cls_.EnsureIsFinalized(thread_); 189 error_ = cls_.EnsureIsFinalized(thread_);
155 if (error_.IsError()) { 190 if (error_.IsError()) {
156 return error_.raw(); 191 return error_.raw();
157 } 192 }
158 193
159 function_ = cls_.LookupFunctionAllowPrivate(function_name_); 194 function_ = cls_.LookupFunctionAllowPrivate(function_name_);
160 field_ = cls_.LookupFieldAllowPrivate(function_name_); 195 field_ = cls_.LookupFieldAllowPrivate(function_name_);
161 if (field_.IsNull() && is_getter) { 196 if (function_.IsNull() && is_getter) {
162 // Maybe this is a tear off. 197 // Maybe this was a tear off.
163 add_closure = true; 198 add_closure = true;
164 function_name2_ = Field::NameFromGetter(function_name_); 199 function_name2_ = Field::NameFromGetter(function_name_);
165 function_ = cls_.LookupFunctionAllowPrivate(function_name2_); 200 function_ = cls_.LookupFunctionAllowPrivate(function_name2_);
166 field_ = cls_.LookupFieldAllowPrivate(function_name2_); 201 field_ = cls_.LookupFieldAllowPrivate(function_name2_);
167 if (!function_.IsNull() && !function_.is_static()) { 202 if (!function_.IsNull() && !function_.is_static()) {
168 // Maybe this was a method extractor. 203 // Maybe this was a method extractor.
169 function2_ = 204 function2_ =
170 Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_); 205 Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_);
171 if (!function2_.IsNull()) { 206 if (!function2_.IsNull()) {
172 error_ = CompileFunction(function2_); 207 error_ = CompileFunction(function2_);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } else { 254 } else {
220 Thread* thread = Thread::Current(); 255 Thread* thread = Thread::Current();
221 const Error& error = Error::Handle(thread->sticky_error()); 256 const Error& error = Error::Handle(thread->sticky_error());
222 thread->clear_sticky_error(); 257 thread->clear_sticky_error();
223 return error.raw(); 258 return error.raw();
224 } 259 }
225 return Object::null(); 260 return Object::null();
226 } 261 }
227 262
228 } // namespace dart 263 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compilation_trace.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698