Index: runtime/vm/bootstrap.cc |
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc |
index ed97340f8e254946e1a2e7c78c499f3319702664..965f40a824510013e808d5d598edf6a39114bd8c 100644 |
--- a/runtime/vm/bootstrap.cc |
+++ b/runtime/vm/bootstrap.cc |
@@ -10,24 +10,21 @@ |
#include "vm/class_finalizer.h" |
#include "vm/compiler.h" |
#include "vm/dart_api_impl.h" |
+#include "vm/kernel.h" |
+#include "vm/kernel_reader.h" |
#include "vm/object.h" |
#include "vm/object_store.h" |
#include "vm/symbols.h" |
namespace dart { |
-#define INIT_LIBRARY(index, name, source, patch) \ |
- { index, \ |
- "dart:"#name, source, \ |
- "dart:"#name"-patch", patch } \ |
- |
-typedef struct { |
- ObjectStore::BootstrapLibraryId index_; |
- const char* uri_; |
- const char** source_paths_; |
- const char* patch_uri_; |
- const char** patch_paths_; |
-} bootstrap_lib_props; |
+struct BootstrapLibProps { |
+ ObjectStore::BootstrapLibraryId index; |
+ const char* uri; |
+ const char** source_paths; |
+ const char* patch_uri; |
+ const char** patch_paths; |
+}; |
enum { |
@@ -38,81 +35,36 @@ enum { |
}; |
-static bootstrap_lib_props bootstrap_libraries[] = { |
- INIT_LIBRARY(ObjectStore::kCore, |
- core, |
- Bootstrap::core_source_paths_, |
- Bootstrap::core_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kAsync, |
- async, |
- Bootstrap::async_source_paths_, |
- Bootstrap::async_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kConvert, |
- convert, |
- Bootstrap::convert_source_paths_, |
- Bootstrap::convert_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kCollection, |
- collection, |
- Bootstrap::collection_source_paths_, |
- Bootstrap::collection_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kDeveloper, |
- developer, |
- Bootstrap::developer_source_paths_, |
- Bootstrap::developer_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kInternal, |
- _internal, |
- Bootstrap::_internal_source_paths_, |
- Bootstrap::_internal_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kIsolate, |
- isolate, |
- Bootstrap::isolate_source_paths_, |
- Bootstrap::isolate_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kMath, |
- math, |
- Bootstrap::math_source_paths_, |
- Bootstrap::math_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kMirrors, |
- mirrors, |
- Bootstrap::mirrors_source_paths_, |
- Bootstrap::mirrors_patch_paths_), |
- INIT_LIBRARY(ObjectStore::kProfiler, |
- profiler, |
- Bootstrap::profiler_source_paths_, |
- NULL), |
- INIT_LIBRARY(ObjectStore::kTypedData, |
- typed_data, |
- Bootstrap::typed_data_source_paths_, |
- NULL), |
- INIT_LIBRARY(ObjectStore::kVMService, |
- _vmservice, |
- Bootstrap::_vmservice_source_paths_, |
- Bootstrap::_vmservice_patch_paths_), |
- { ObjectStore::kNone, NULL, NULL, NULL, NULL } |
+const char** Bootstrap::profiler_patch_paths_ = NULL; |
+const char** Bootstrap::typed_data_patch_paths_ = NULL; |
+ |
+ |
+#define MAKE_PROPERTIES(CamelName, hacker_name) \ |
Florian Schneider
2016/11/08 20:41:39
I do like reducing boilerplate code, but I don't l
Vyacheslav Egorov (Google)
2016/11/09 14:43:16
Moved to a separate CL: https://codereview.chromiu
|
+ { ObjectStore::k##CamelName, \ |
+ "dart:" #hacker_name, \ |
Florian Schneider
2016/11/08 20:41:39
What's a hacker_name? Why not just use "name"?
Vyacheslav Egorov (Google)
2016/11/09 14:43:16
I guess hacker_name is name_with_underscores. Rena
Kevin Millikin (Google)
2016/11/09 15:17:32
Because the other parameter is also a name.
|
+ Bootstrap::hacker_name##_source_paths_, \ |
+ "dart:" #hacker_name "-patch", \ |
+ Bootstrap::hacker_name##_patch_paths_ \ |
+ }, |
+ |
+static BootstrapLibProps bootstrap_libraries[] = { |
Florian Schneider
2016/11/08 20:41:39
static const?
Vyacheslav Egorov (Google)
2016/11/09 14:43:16
Done.
|
+ FOR_EACH_BOOTSTRAP_LIBRARY(MAKE_PROPERTIES) |
}; |
+#undef MAKE_PROPERTIES |
-static RawString* GetLibrarySource(const Library& lib, |
- const String& uri, |
- bool patch) { |
- // First check if this is a valid bootstrap library and find it's index |
- // in the 'bootstrap_libraries' table above. |
- intptr_t index; |
- const String& lib_uri = String::Handle(lib.url()); |
- for (index = 0; |
- bootstrap_libraries[index].index_ != ObjectStore::kNone; |
- ++index) { |
- if (lib_uri.Equals(bootstrap_libraries[index].uri_)) { |
- break; |
- } |
- } |
- if (bootstrap_libraries[index].index_ == ObjectStore::kNone) { |
- return String::null(); // Library is not a bootstrap library. |
- } |
+ |
+static const intptr_t kBootstrapLibraryCount = ARRAY_SIZE(bootstrap_libraries); |
+ |
+ |
+static RawString* GetLibrarySourceByIndex(intptr_t index, |
+ const String& uri, |
+ bool patch) { |
+ ASSERT(index >= 0 && index < kBootstrapLibraryCount); |
// Try to read the source using the path specified for the uri. |
- const char** source_paths = patch ? |
- bootstrap_libraries[index].patch_paths_ : |
- bootstrap_libraries[index].source_paths_; |
+ const char** source_paths = patch ? bootstrap_libraries[index].patch_paths |
+ : bootstrap_libraries[index].source_paths; |
if (source_paths == NULL) { |
return String::null(); // No path mapping information exists for library. |
} |
@@ -157,6 +109,26 @@ static RawString* GetLibrarySource(const Library& lib, |
} |
+static RawString* GetLibrarySource(const Library& lib, |
+ const String& uri, |
+ bool patch) { |
+ // First check if this is a valid bootstrap library and find its index in |
+ // the 'bootstrap_libraries' table above. |
+ intptr_t index; |
+ const String& lib_uri = String::Handle(lib.url()); |
+ for (index = 0; index < kBootstrapLibraryCount; ++index) { |
+ if (lib_uri.Equals(bootstrap_libraries[index].uri)) { |
+ break; |
+ } |
+ } |
+ if (index == kBootstrapLibraryCount) { |
+ return String::null(); // The library is not a bootstrap library. |
+ } |
+ |
+ return GetLibrarySourceByIndex(index, uri, patch); |
+} |
+ |
+ |
static RawError* Compile(const Library& library, const Script& script) { |
bool update_lib_status = (script.kind() == RawScript::kScriptTag || |
script.kind() == RawScript::kLibraryTag); |
@@ -240,10 +212,15 @@ static Dart_Handle BootstrapLibraryTagHandler(Dart_LibraryTag tag, |
} |
-static RawError* LoadPatchFiles(Zone* zone, |
+static RawError* LoadPatchFiles(Thread* thread, |
const Library& lib, |
- const String& patch_uri, |
- const char** patch_files) { |
+ intptr_t index) { |
+ const char** patch_files = bootstrap_libraries[index].patch_paths; |
+ if (patch_files == NULL) return Error::null(); |
+ |
+ Zone* zone = thread->zone(); |
+ String& patch_uri = String::Handle( |
+ zone, Symbols::New(thread, bootstrap_libraries[index].patch_uri)); |
String& patch_file_uri = String::Handle(zone); |
String& source = String::Handle(zone); |
Script& script = Script::Handle(zone); |
@@ -253,7 +230,7 @@ static RawError* LoadPatchFiles(Zone* zone, |
strings.SetAt(1, Symbols::Slash()); |
for (intptr_t j = 0; patch_files[j] != NULL; j += kPathsEntryLength) { |
patch_file_uri = String::New(patch_files[j + kPathsUriOffset]); |
- source = GetLibrarySource(lib, patch_file_uri, true); |
+ source = GetLibrarySourceByIndex(index, patch_file_uri, true); |
if (source.IsNull()) { |
const String& message = String::Handle( |
String::NewFormatted("Unable to find dart patch source for %s", |
@@ -273,57 +250,46 @@ static RawError* LoadPatchFiles(Zone* zone, |
} |
-RawError* Bootstrap::LoadandCompileScripts() { |
- Thread* thread = Thread::Current(); |
+static void Finish(Thread* thread, bool from_kernel) { |
+ Bootstrap::SetupNativeResolver(); |
+ if (!ClassFinalizer::ProcessPendingClasses(from_kernel)) { |
+ FATAL("Error in class finalization during bootstrapping."); |
+ } |
+ |
+ // Eagerly compile the _Closure class as it is the class of all closure |
+ // instances. This allows us to just finalize function types without going |
+ // through the hoops of trying to compile their scope class. |
+ ObjectStore* object_store = thread->isolate()->object_store(); |
+ Class& cls = Class::Handle(thread->zone(), object_store->closure_class()); |
+ Compiler::CompileClass(cls); |
+ // Eagerly compile Bool class, bool constants are used from within compiler. |
+ cls = object_store->bool_class(); |
+ Compiler::CompileClass(cls); |
+} |
+ |
+ |
+static RawError* BootstrapFromSource(Thread* thread) { |
Isolate* isolate = thread->isolate(); |
Zone* zone = thread->zone(); |
String& uri = String::Handle(zone); |
- String& patch_uri = String::Handle(zone); |
String& source = String::Handle(zone); |
Script& script = Script::Handle(zone); |
Library& lib = Library::Handle(zone); |
Error& error = Error::Handle(zone); |
- Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); |
// Set the library tag handler for the isolate to the bootstrap |
// library tag handler so that we can load all the bootstrap libraries. |
+ Dart_LibraryTagHandler saved_tag_handler = isolate->library_tag_handler(); |
isolate->set_library_tag_handler(BootstrapLibraryTagHandler); |
- HANDLESCOPE(thread); |
- |
- // Create library objects for all the bootstrap libraries. |
- for (intptr_t i = 0; |
- bootstrap_libraries[i].index_ != ObjectStore::kNone; |
- ++i) { |
-#ifdef PRODUCT |
- if (bootstrap_libraries[i].index_ == ObjectStore::kMirrors) { |
- continue; |
- } |
-#endif // !PRODUCT |
- uri = Symbols::New(thread, bootstrap_libraries[i].uri_); |
- lib = Library::LookupLibrary(thread, uri); |
- if (lib.IsNull()) { |
- lib = Library::NewLibraryHelper(uri, false); |
- lib.SetLoadRequested(); |
- lib.Register(thread); |
- } |
- isolate->object_store()->set_bootstrap_library( |
- bootstrap_libraries[i].index_, lib); |
- } |
- |
// Load, compile and patch bootstrap libraries. |
- for (intptr_t i = 0; |
- bootstrap_libraries[i].index_ != ObjectStore::kNone; |
- ++i) { |
-#ifdef PRODUCT |
- if (bootstrap_libraries[i].index_ == ObjectStore::kMirrors) { |
- continue; |
- } |
-#endif // PRODUCT |
- uri = Symbols::New(thread, bootstrap_libraries[i].uri_); |
- lib = Library::LookupLibrary(thread, uri); |
+ for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) { |
+ ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index; |
+ uri = Symbols::New(thread, bootstrap_libraries[i].uri); |
+ lib = isolate->object_store()->bootstrap_library(id); |
ASSERT(!lib.IsNull()); |
- source = GetLibrarySource(lib, uri, false); |
+ ASSERT(lib.raw() == Library::LookupLibrary(thread, uri)); |
+ source = GetLibrarySourceByIndex(i, uri, false); |
if (source.IsNull()) { |
const String& message = String::Handle( |
String::NewFormatted("Unable to find dart source for %s", |
@@ -337,36 +303,97 @@ RawError* Bootstrap::LoadandCompileScripts() { |
break; |
} |
// If a patch exists, load and patch the script. |
- if (bootstrap_libraries[i].patch_paths_ != NULL) { |
- patch_uri = Symbols::New(thread, bootstrap_libraries[i].patch_uri_); |
- error = LoadPatchFiles(zone, |
- lib, |
- patch_uri, |
- bootstrap_libraries[i].patch_paths_); |
- if (!error.IsNull()) { |
- break; |
- } |
+ error = LoadPatchFiles(thread, lib, i); |
+ if (!error.IsNull()) { |
+ break; |
} |
} |
+ |
if (error.IsNull()) { |
- SetupNativeResolver(); |
- ClassFinalizer::ProcessPendingClasses(); |
- |
- // Eagerly compile the _Closure class as it is the class of all closure |
- // instances. This allows us to just finalize function types |
- // without going through the hoops of trying to compile their scope class. |
- Class& cls = |
- Class::Handle(zone, isolate->object_store()->closure_class()); |
- Compiler::CompileClass(cls); |
- // Eagerly compile Bool class, bool constants are used from within compiler. |
- cls = isolate->object_store()->bool_class(); |
- Compiler::CompileClass(cls); |
+ Finish(thread, /*from_kernel=*/false); |
} |
- |
// Restore the library tag handler for the isolate. |
isolate->set_library_tag_handler(saved_tag_handler); |
return error.raw(); |
} |
+ |
+static RawError* BootstrapFromKernel(Thread* thread, |
+ const uint8_t* buffer, |
+ intptr_t buffer_size) { |
+ Zone* zone = thread->zone(); |
+ kernel::Program* program = |
+ ReadPrecompiledKernelFromBuffer(buffer, buffer_size); |
+ if (program == NULL) { |
+ const String& message = |
+ String::Handle(zone, String::New("Failed to read Kernel file")); |
+ return ApiError::New(message); |
+ } |
+ |
+ Isolate* isolate = thread->isolate(); |
+ // Mark the already-pending classes. This mark bit will be used to avoid |
+ // adding classes to the list more than once. |
+ GrowableObjectArray& pending_classes = GrowableObjectArray::Handle( |
+ zone, isolate->object_store()->pending_classes()); |
+ dart::Class& pending = dart::Class::Handle(zone); |
+ for (intptr_t i = 0; i < pending_classes.Length(); ++i) { |
+ pending ^= pending_classes.At(i); |
+ pending.set_is_marked_for_parsing(); |
+ } |
+ |
+ Library& library = Library::Handle(zone); |
+ String& dart_name = String::Handle(zone); |
+ String& kernel_name = String::Handle(zone); |
+ kernel::KernelReader reader(NULL, -1, true); |
+ for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) { |
+ ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index; |
+ library = isolate->object_store()->bootstrap_library(id); |
+ dart_name = library.url(); |
+ for (intptr_t j = 0; j < program->libraries().length(); ++j) { |
+ kernel::Library* kernel_library = program->libraries()[j]; |
+ kernel::String* uri = kernel_library->import_uri(); |
+ kernel_name = Symbols::FromUTF8(thread, uri->buffer(), uri->size()); |
+ if (kernel_name.Equals(dart_name)) { |
+ reader.ReadLibrary(kernel_library); |
+ library.SetLoaded(); |
+ break; |
+ } |
+ } |
+ } |
+ |
+ Finish(thread, /*from_kernel=*/true); |
+ return Error::null(); |
+} |
+ |
+ |
+RawError* Bootstrap::DoBootstrapping(const uint8_t* kernel_buffer, |
+ intptr_t kernel_buffer_length) { |
+ Thread* thread = Thread::Current(); |
+ Isolate* isolate = thread->isolate(); |
+ Zone* zone = thread->zone(); |
+ String& uri = String::Handle(zone); |
+ Library& lib = Library::Handle(zone); |
+ |
+ HANDLESCOPE(thread); |
+ |
+ // Ensure there are library objects for all the bootstrap libraries. |
+ for (intptr_t i = 0; i < kBootstrapLibraryCount; ++i) { |
+ ObjectStore::BootstrapLibraryId id = bootstrap_libraries[i].index; |
+ uri = Symbols::New(thread, bootstrap_libraries[i].uri); |
+ lib = isolate->object_store()->bootstrap_library(id); |
+ ASSERT(lib.raw() == Library::LookupLibrary(thread, uri)); |
+ if (lib.IsNull()) { |
+ lib = Library::NewLibraryHelper(uri, false); |
+ lib.SetLoadRequested(); |
+ lib.Register(thread); |
+ isolate->object_store()->set_bootstrap_library(id, lib); |
+ } |
+ } |
+ |
+ return (kernel_buffer == NULL) |
+ ? BootstrapFromSource(thread) |
+ : BootstrapFromKernel(thread, kernel_buffer, kernel_buffer_length); |
+} |
+ |
} // namespace dart |