| 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 | 
|---|