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

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

Issue 2922913004: Add Dart_Save/LoadCompilationTrace. (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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/compilation_trace.h"
6
7 #include "vm/longjump.h"
8 #include "vm/object_store.h"
9 #include "vm/resolver.h"
10 #include "vm/symbols.h"
11
12 namespace dart {
13
14 CompilationTraceSaver::CompilationTraceSaver(Zone* zone)
15 : buf_(zone, 4 * KB),
16 func_name_(String::Handle(zone)),
17 cls_(Class::Handle(zone)),
18 cls_name_(String::Handle(zone)),
19 lib_(Library::Handle(zone)),
20 uri_(String::Handle(zone)) {}
21
22
23 void CompilationTraceSaver::Visit(const Function& function) {
24 if (!function.HasCode()) {
25 return;
26 }
27
28 func_name_ = function.name();
29 func_name_ = String::RemovePrivateKey(func_name_);
30 cls_ = function.Owner();
31 cls_name_ = cls_.Name();
32 cls_name_ = String::RemovePrivateKey(cls_name_);
33 lib_ = cls_.library();
34 uri_ = lib_.url();
35 buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(),
36 func_name_.ToCString());
37 }
38
39
40 CompilationTraceLoader::CompilationTraceLoader(Thread* thread)
41 : thread_(thread),
42 zone_(thread->zone()),
43 uri_(String::Handle(zone_)),
44 class_name_(String::Handle(zone_)),
45 function_name_(String::Handle(zone_)),
46 function_name2_(String::Handle(zone_)),
47 lib_(Library::Handle(zone_)),
48 cls_(Class::Handle(zone_)),
49 function_(Function::Handle(zone_)),
50 function2_(Function::Handle(zone_)),
51 field_(Field::Handle(zone_)),
52 error_(Object::Handle(zone_)) {}
53
54
55 RawObject* CompilationTraceLoader::CompileTrace(char* buffer) {
56 // First compile functions named in the trace.
57 char* cursor = buffer;
58 while (cursor != NULL) {
59 char* uri = cursor;
60 char* comma1 = strchr(uri, ',');
61 if (comma1 == NULL) break;
62 *comma1 = 0;
63 char* cls_name = comma1 + 1;
64 char* comma2 = strchr(cls_name, ',');
65 if (comma2 == NULL) break;
66 *comma2 = 0;
67 char* func_name = comma2 + 1;
68 char* newline = strchr(func_name, '\n');
69 if (newline == NULL) break;
70 *newline = 0;
71 error_ = CompileTriple(uri, cls_name, func_name);
72 if (error_.IsError()) {
73 return error_.raw();
74 }
75 cursor = newline + 1;
76 }
77
78 // Next, compile common dispatchers. These aren't found with the normal
79 // lookup above because they have irregular lookup that depends on the
80 // arguments descriptor (e.g. call() versus call(x)).
81 const Class& closure_class =
82 Class::Handle(zone_, thread_->isolate()->object_store()->closure_class());
83 Array& arguments_descriptor = Array::Handle(zone_);
84 Function& dispatcher = Function::Handle(zone_);
85 for (intptr_t argc = 1; argc <= 4; argc++) {
86 const intptr_t kTypeArgsLen = 0;
87 arguments_descriptor = ArgumentsDescriptor::New(kTypeArgsLen, argc);
88 dispatcher = closure_class.GetInvocationDispatcher(
89 Symbols::Call(), arguments_descriptor,
90 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */);
91 error_ = CompileFunction(dispatcher);
92 if (error_.IsError()) {
93 return error_.raw();
94 }
95 }
96
97 // Finally, compile closures in all compiled functions.
98 const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle(
99 zone_, thread_->isolate()->object_store()->closure_functions());
100 for (intptr_t i = 0; i < closure_functions.Length(); i++) {
101 function_ ^= closure_functions.At(i);
102 function2_ = function_.parent_function();
103 if (function2_.HasCode()) {
104 error_ = CompileFunction(function_);
105 if (error_.IsError()) {
106 return error_.raw();
107 }
108 }
109 }
110
111 return Object::null();
112 }
113
114
115 RawObject* CompilationTraceLoader::CompileTriple(const char* uri_cstr,
116 const char* cls_cstr,
117 const char* func_cstr) {
118 uri_ = Symbols::New(thread_, uri_cstr);
119 class_name_ = Symbols::New(thread_, cls_cstr);
120 function_name_ = Symbols::New(thread_, func_cstr);
121
122 if (function_name_.Equals("_getMainClosure")) {
123 // The scheme for invoking main relies on compiling _getMainClosure after
124 // synthetically importing the root library.
125 return Object::null();
126 }
127
128 lib_ = Library::LookupLibrary(thread_, uri_);
129 if (lib_.IsNull()) {
130 // Missing library.
131 return Object::null();
132 }
133
134 bool is_getter = Field::IsGetterName(function_name_);
135 bool add_closure = false;
136
137 if (class_name_.Equals(Symbols::TopLevel())) {
138 function_ = lib_.LookupFunctionAllowPrivate(function_name_);
139 field_ = lib_.LookupFieldAllowPrivate(function_name_);
140 if (function_.IsNull() && is_getter) {
141 // Maybe this was a tear off.
142 add_closure = true;
143 function_name2_ = Field::NameFromGetter(function_name_);
144 function_ = lib_.LookupFunctionAllowPrivate(function_name2_);
145 field_ = lib_.LookupFieldAllowPrivate(function_name2_);
146 }
147 } else {
148 cls_ = lib_.SlowLookupClassAllowMultiPartPrivate(class_name_);
149 if (cls_.IsNull()) {
150 // Missing class.
151 return Object::null();
152 }
153
154 error_ = cls_.EnsureIsFinalized(thread_);
155 if (error_.IsError()) {
156 return error_.raw();
157 }
158
159 function_ = cls_.LookupFunctionAllowPrivate(function_name_);
160 field_ = cls_.LookupFieldAllowPrivate(function_name_);
161 if (field_.IsNull() && is_getter) {
162 // Maybe this is a tear off.
163 add_closure = true;
164 function_name2_ = Field::NameFromGetter(function_name_);
165 function_ = cls_.LookupFunctionAllowPrivate(function_name2_);
166 field_ = cls_.LookupFieldAllowPrivate(function_name2_);
167 if (!function_.IsNull() && !function_.is_static()) {
168 // Maybe this was a method extractor.
169 function2_ =
170 Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_);
171 if (!function2_.IsNull()) {
172 error_ = CompileFunction(function2_);
173 if (error_.IsError()) {
174 return error_.raw();
175 }
176 }
177 }
178 }
179 }
180
181 if (!field_.IsNull() && field_.is_const() && field_.is_static() &&
182 (field_.StaticValue() == Object::sentinel().raw())) {
183 error_ = EvaluateInitializer(field_);
184 if (error_.IsError()) {
185 return error_.raw();
186 }
187 }
188
189 if (!function_.IsNull()) {
190 error_ = CompileFunction(function_);
191 if (error_.IsError()) {
192 return error_.raw();
193 }
194 if (add_closure) {
195 function_ = function_.ImplicitClosureFunction();
196 error_ = CompileFunction(function_);
197 if (error_.IsError()) {
198 return error_.raw();
199 }
200 }
201 }
202
203 return Object::null();
204 }
205
206
207 RawObject* CompilationTraceLoader::CompileFunction(const Function& function) {
208 if (function.is_abstract()) {
209 return Object::null();
210 }
211 return Compiler::CompileFunction(thread_, function);
212 }
213
214
215 RawObject* CompilationTraceLoader::EvaluateInitializer(const Field& field) {
216 LongJumpScope jump;
217 if (setjmp(*jump.Set()) == 0) {
218 field_.EvaluateInitializer();
219 } else {
220 Thread* thread = Thread::Current();
221 const Error& error = Error::Handle(thread->sticky_error());
222 thread->clear_sticky_error();
223 return error.raw();
224 }
225 return Object::null();
226 }
227
228 } // 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