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/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
9 #include "vm/log.h" | 9 #include "vm/log.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 | 22 |
23 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); | 23 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler."); |
24 | 24 |
25 | 25 |
26 static void Jump(const Error& error) { | 26 static void Jump(const Error& error) { |
27 Thread::Current()->long_jump_base()->Jump(1, error); | 27 Thread::Current()->long_jump_base()->Jump(1, error); |
28 } | 28 } |
29 | 29 |
30 | 30 |
31 RawError* Precompiler::CompileAll() { | 31 RawError* Precompiler::CompileAll( |
| 32 Dart_QualifiedFunctionName embedder_entry_points[]) { |
32 LongJumpScope jump; | 33 LongJumpScope jump; |
33 if (setjmp(*jump.Set()) == 0) { | 34 if (setjmp(*jump.Set()) == 0) { |
34 Precompiler precompiler(Thread::Current()); | 35 Precompiler precompiler(Thread::Current()); |
35 precompiler.DoCompileAll(); | 36 precompiler.DoCompileAll(embedder_entry_points); |
36 return Error::null(); | 37 return Error::null(); |
37 } else { | 38 } else { |
38 Isolate* isolate = Isolate::Current(); | 39 Isolate* isolate = Isolate::Current(); |
39 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | 40 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); |
40 isolate->object_store()->clear_sticky_error(); | 41 isolate->object_store()->clear_sticky_error(); |
41 return error.raw(); | 42 return error.raw(); |
42 } | 43 } |
43 } | 44 } |
44 | 45 |
45 | 46 |
46 Precompiler::Precompiler(Thread* thread) : | 47 Precompiler::Precompiler(Thread* thread) : |
47 thread_(thread), | 48 thread_(thread), |
48 zone_(thread->zone()), | 49 zone_(thread->zone()), |
49 isolate_(thread->isolate()), | 50 isolate_(thread->isolate()), |
50 changed_(false), | 51 changed_(false), |
51 function_count_(0), | 52 function_count_(0), |
52 class_count_(0), | 53 class_count_(0), |
53 selector_count_(0), | 54 selector_count_(0), |
54 dropped_function_count_(0), | 55 dropped_function_count_(0), |
55 libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())), | 56 libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())), |
56 pending_functions_(GrowableObjectArray::Handle(Z, | 57 pending_functions_(GrowableObjectArray::Handle(Z, |
57 GrowableObjectArray::New())), | 58 GrowableObjectArray::New())), |
58 collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())), | 59 collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())), |
59 sent_selectors_(Z), | 60 sent_selectors_(Z), |
60 error_(Error::Handle(Z)) { | 61 error_(Error::Handle(Z)) { |
61 } | 62 } |
62 | 63 |
63 | 64 |
64 void Precompiler::DoCompileAll() { | 65 void Precompiler::DoCompileAll( |
| 66 Dart_QualifiedFunctionName embedder_entry_points[]) { |
65 LogBlock lb; | 67 LogBlock lb; |
66 | 68 |
67 // Drop all existing code so we can use the presence of code as an indicator | 69 // Drop all existing code so we can use the presence of code as an indicator |
68 // that we have already looked for the function's callees. | 70 // that we have already looked for the function's callees. |
69 ClearAllCode(); | 71 ClearAllCode(); |
70 | 72 |
71 // Start with the allocations and invocations that happen from C++. | 73 // Start with the allocations and invocations that happen from C++. |
72 AddRoots(); | 74 AddRoots(embedder_entry_points); |
73 | 75 |
74 // TODO(rmacnak): Eagerly add field-invocation functions to all signature | 76 // TODO(rmacnak): Eagerly add field-invocation functions to all signature |
75 // classes so closure calls don't go through the runtime. | 77 // classes so closure calls don't go through the runtime. |
76 | 78 |
77 // Compile newly found targets and add their callees until we reach a fixed | 79 // Compile newly found targets and add their callees until we reach a fixed |
78 // point. | 80 // point. |
79 Iterate(); | 81 Iterate(); |
80 | 82 |
81 CleanUp(); | 83 CleanUp(); |
82 | 84 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 functions = cls.functions(); | 121 functions = cls.functions(); |
120 for (intptr_t i = 0; i < functions.Length(); i++) { | 122 for (intptr_t i = 0; i < functions.Length(); i++) { |
121 function ^= functions.At(i); | 123 function ^= functions.At(i); |
122 function.ClearCode(); | 124 function.ClearCode(); |
123 } | 125 } |
124 } | 126 } |
125 } | 127 } |
126 } | 128 } |
127 | 129 |
128 | 130 |
129 void Precompiler::AddRoots() { | 131 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { |
130 // Note that <rootlibrary>.main is not a root. The appropriate main will be | 132 // Note that <rootlibrary>.main is not a root. The appropriate main will be |
131 // discovered through _getMainClosure. | 133 // discovered through _getMainClosure. |
132 | 134 |
133 AddSelector(Symbols::NoSuchMethod()); | 135 AddSelector(Symbols::NoSuchMethod()); |
134 | 136 |
135 AddSelector(Symbols::Call()); // For speed, not correctness. | 137 AddSelector(Symbols::Call()); // For speed, not correctness. |
136 | 138 |
137 // Allocated from C++. | 139 // Allocated from C++. |
138 static const intptr_t kExternallyAllocatedCids[] = { | 140 static const intptr_t kExternallyAllocatedCids[] = { |
139 kBoolCid, | 141 kBoolCid, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 196 |
195 kIllegalCid | 197 kIllegalCid |
196 }; | 198 }; |
197 | 199 |
198 Class& cls = Class::Handle(Z); | 200 Class& cls = Class::Handle(Z); |
199 for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) { | 201 for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) { |
200 cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]); | 202 cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]); |
201 AddClass(cls); | 203 AddClass(cls); |
202 } | 204 } |
203 | 205 |
204 static const struct { | 206 Dart_QualifiedFunctionName vm_entry_points[] = { |
205 const char* library_; | |
206 const char* class_; | |
207 const char* function_; | |
208 } kExternallyCalled[] = { | |
209 { "dart:_builtin", "::", "_getMainClosure" }, | |
210 { "dart:_builtin", "::", "_getPrintClosure" }, | |
211 { "dart:_builtin", "::", "_getUriBaseClosure" }, | |
212 { "dart:_builtin", "::", "_resolveUri" }, | |
213 { "dart:_builtin", "::", "_setWorkingDirectory" }, | |
214 { "dart:_builtin", "::", "_loadDataAsync" }, | |
215 { "dart:async", "::", "_setScheduleImmediateClosure" }, | 207 { "dart:async", "::", "_setScheduleImmediateClosure" }, |
| 208 { "dart:core", "AbstractClassInstantiationError", |
| 209 "AbstractClassInstantiationError._create" }, |
| 210 { "dart:core", "ArgumentError", "ArgumentError." }, |
| 211 { "dart:core", "AssertionError", "AssertionError." }, |
| 212 { "dart:core", "CyclicInitializationError", |
| 213 "CyclicInitializationError." }, |
| 214 { "dart:core", "FallThroughError", "FallThroughError._create" }, |
| 215 { "dart:core", "FormatException", "FormatException." }, |
| 216 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, |
| 217 { "dart:core", "NullThrownError", "NullThrownError." }, |
| 218 { "dart:core", "OutOfMemoryError", "OutOfMemoryError." }, |
| 219 { "dart:core", "RangeError", "RangeError." }, |
| 220 { "dart:core", "RangeError", "RangeError.range" }, |
| 221 { "dart:core", "StackOverflowError", "StackOverflowError." }, |
| 222 { "dart:core", "UnsupportedError", "UnsupportedError." }, |
| 223 { "dart:core", "_CastError", "_CastError._create" }, |
216 { "dart:core", "_InternalError", "_InternalError." }, | 224 { "dart:core", "_InternalError", "_InternalError." }, |
217 { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" }, | 225 { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" }, |
218 { "dart:io", "::", "_makeUint8ListView" }, | 226 { "dart:core", "_JavascriptCompatibilityError", |
219 { "dart:io", "::", "_makeDatagram" }, | 227 "_JavascriptCompatibilityError." }, |
220 { "dart:io", "::", "_setupHooks" }, | 228 { "dart:core", "_JavascriptIntegerOverflowError", |
221 { "dart:io", "CertificateException", "CertificateException." }, | 229 "_JavascriptIntegerOverflowError." }, |
222 { "dart:io", "HandshakeException", "HandshakeException." }, | 230 { "dart:core", "_TypeError", "_TypeError._create" }, |
223 { "dart:io", "TlsException", "TlsException." }, | 231 { "dart:isolate", "IsolateSpawnException", "IsolateSpawnException." }, |
224 { "dart:io", "X509Certificate", "X509Certificate." }, | 232 { "dart:isolate", "_IsolateUnhandledException", |
225 { "dart:io", "_ExternalBuffer", "set:data" }, | 233 "_IsolateUnhandledException." }, |
226 { "dart:io", "_Platform", "set:_nativeScript" }, | |
227 { "dart:io", "_ProcessStartStatus", "set:_errorCode" }, | |
228 { "dart:io", "_ProcessStartStatus", "set:_errorMessage" }, | |
229 { "dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE" }, | |
230 { "dart:io", "_SecureFilterImpl", "get:SIZE" }, | |
231 { "dart:isolate", "::", "_getIsolateScheduleImmediateClosure" }, | 234 { "dart:isolate", "::", "_getIsolateScheduleImmediateClosure" }, |
| 235 { "dart:isolate", "::", "_setupHooks" }, |
232 { "dart:isolate", "::", "_startMainIsolate" }, | 236 { "dart:isolate", "::", "_startMainIsolate" }, |
233 { "dart:isolate", "::", "_setupHooks" }, | |
234 { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" }, | 237 { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" }, |
235 { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" }, | 238 { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" }, |
236 { "dart:vmservice", "::", "_registerIsolate" }, | 239 { "dart:vmservice", "::", "_registerIsolate" }, |
237 { "dart:vmservice", "::", "boot" }, | 240 { "dart:vmservice", "::", "boot" }, |
238 { "dart:vmservice_io", "::", "_addResource" }, | 241 { NULL, NULL, NULL } // Must be terminated with NULL entries. |
239 { "dart:vmservice_io", "::", "main" }, | |
240 | |
241 // Cf. Exceptions::Create | |
242 { "dart:core", "RangeError", "RangeError." }, | |
243 { "dart:core", "RangeError", "RangeError.range" }, | |
244 { "dart:core", "ArgumentError", "ArgumentError." }, | |
245 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, | |
246 { "dart:core", "FormatException", "FormatException." }, | |
247 { "dart:core", "UnsupportedError", "UnsupportedError." }, | |
248 { "dart:core", "NullThrownError", "NullThrownError." }, | |
249 { "dart:isolate", "IsolateSpawnException", "IsolateSpawnException." }, | |
250 { "dart:isolate", "_IsolateUnhandledException", | |
251 "_IsolateUnhandledException." }, | |
252 { "dart:core", "_JavascriptIntegerOverflowError", | |
253 "_JavascriptIntegerOverflowError." }, | |
254 { "dart:core", "_JavascriptCompatibilityError", | |
255 "_JavascriptCompatibilityError." }, | |
256 { "dart:core", "AssertionError", "AssertionError." }, | |
257 { "dart:core", "_CastError", "_CastError._create" }, | |
258 { "dart:core", "_TypeError", "_TypeError._create" }, | |
259 { "dart:core", "FallThroughError", "FallThroughError._create" }, | |
260 { "dart:core", "AbstractClassInstantiationError", | |
261 "AbstractClassInstantiationError._create" }, | |
262 { "dart:core", "CyclicInitializationError", | |
263 "CyclicInitializationError." }, | |
264 { "dart:core", "StackOverflowError", "StackOverflowError." }, | |
265 { "dart:core", "OutOfMemoryError", "OutOfMemoryError." }, | |
266 { NULL, NULL, NULL } | |
267 }; | 242 }; |
268 | 243 |
| 244 AddEntryPoints(vm_entry_points); |
| 245 AddEntryPoints(embedder_entry_points); |
| 246 } |
| 247 |
| 248 |
| 249 void Precompiler::AddEntryPoints(Dart_QualifiedFunctionName entry_points[]) { |
269 Library& lib = Library::Handle(Z); | 250 Library& lib = Library::Handle(Z); |
| 251 Class& cls = Class::Handle(Z); |
270 Function& func = Function::Handle(Z); | 252 Function& func = Function::Handle(Z); |
271 String& library_name = String::Handle(Z); | 253 String& library_uri = String::Handle(Z); |
272 String& class_name = String::Handle(Z); | 254 String& class_name = String::Handle(Z); |
273 String& function_name = String::Handle(Z); | 255 String& function_name = String::Handle(Z); |
274 for (intptr_t i = 0; kExternallyCalled[i].library_ != NULL; i++) { | |
275 library_name = Symbols::New(kExternallyCalled[i].library_); | |
276 class_name = Symbols::New(kExternallyCalled[i].class_); | |
277 function_name = Symbols::New(kExternallyCalled[i].function_); | |
278 | 256 |
279 lib = Library::LookupLibrary(library_name); | 257 for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) { |
| 258 library_uri = Symbols::New(entry_points[i].library_uri); |
| 259 class_name = Symbols::New(entry_points[i].class_name); |
| 260 function_name = Symbols::New(entry_points[i].function_name); |
| 261 |
| 262 lib = Library::LookupLibrary(library_uri); |
280 if (lib.IsNull()) { | 263 if (lib.IsNull()) { |
281 if (FLAG_trace_precompiler) { | 264 if (FLAG_trace_precompiler) { |
282 THR_Print("WARNING: Missing %s\n", kExternallyCalled[i].library_); | 265 THR_Print("WARNING: Missing %s\n", entry_points[i].library_uri); |
283 } | 266 } |
284 continue; | 267 continue; |
285 } | 268 } |
286 | 269 |
287 if (class_name.raw() == Symbols::TopLevel().raw()) { | 270 if (class_name.raw() == Symbols::TopLevel().raw()) { |
288 func = lib.LookupFunctionAllowPrivate(function_name); | 271 func = lib.LookupFunctionAllowPrivate(function_name); |
289 } else { | 272 } else { |
290 cls = lib.LookupClassAllowPrivate(class_name); | 273 cls = lib.LookupClassAllowPrivate(class_name); |
291 if (cls.IsNull()) { | 274 if (cls.IsNull()) { |
292 if (FLAG_trace_precompiler) { | 275 if (FLAG_trace_precompiler) { |
293 THR_Print("WARNING: Missing %s %s\n", | 276 THR_Print("WARNING: Missing %s %s\n", |
294 kExternallyCalled[i].library_, | 277 entry_points[i].library_uri, |
295 kExternallyCalled[i].class_); | 278 entry_points[i].class_name); |
296 } | 279 } |
297 continue; | 280 continue; |
298 } | 281 } |
299 | 282 |
300 ASSERT(!cls.IsNull()); | 283 ASSERT(!cls.IsNull()); |
301 func = cls.LookupFunctionAllowPrivate(function_name); | 284 func = cls.LookupFunctionAllowPrivate(function_name); |
302 } | 285 } |
303 | 286 |
304 if (func.IsNull()) { | 287 if (func.IsNull()) { |
305 if (FLAG_trace_precompiler) { | 288 if (FLAG_trace_precompiler) { |
306 THR_Print("WARNING: Missing %s %s %s\n", | 289 THR_Print("WARNING: Missing %s %s %s\n", |
307 kExternallyCalled[i].library_, | 290 entry_points[i].library_uri, |
308 kExternallyCalled[i].class_, | 291 entry_points[i].class_name, |
309 kExternallyCalled[i].function_); | 292 entry_points[i].function_name); |
310 } | 293 } |
311 continue; | 294 continue; |
312 } | 295 } |
313 | 296 |
314 AddFunction(func); | 297 AddFunction(func); |
315 } | 298 } |
316 } | 299 } |
317 | 300 |
318 | 301 |
319 void Precompiler::Iterate() { | 302 void Precompiler::Iterate() { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 for (intptr_t j = 0; j < closures.Length(); j++) { | 620 for (intptr_t j = 0; j < closures.Length(); j++) { |
638 function ^= closures.At(j); | 621 function ^= closures.At(j); |
639 ASSERT(function.HasCode()); | 622 ASSERT(function.HasCode()); |
640 } | 623 } |
641 } | 624 } |
642 } | 625 } |
643 } | 626 } |
644 } | 627 } |
645 | 628 |
646 } // namespace dart | 629 } // namespace dart |
OLD | NEW |