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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 2485993002: VM: Support bootstrapping core libraries from Kernel binaries instead of source. (Closed)
Patch Set: Done Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/class_finalizer.cc
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 98d74ff073efddae795a4921b18cbceedb87f616..3c5d45848ddd0b4414d591b23d37c04df43b9394 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -118,7 +118,7 @@ static void CollectImmediateSuperInterfaces(const Class& cls,
// Processing ObjectStore::pending_classes_ occurs:
// a) when bootstrap process completes (VerifyBootstrapClasses).
// b) after the user classes are loaded (dart_api).
-bool ClassFinalizer::ProcessPendingClasses() {
+bool ClassFinalizer::ProcessPendingClasses(bool from_kernel) {
Thread* thread = Thread::Current();
NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
"ProcessPendingClasses"));
@@ -150,6 +150,12 @@ bool ClassFinalizer::ProcessPendingClasses() {
for (intptr_t i = 0; i < class_array.Length(); i++) {
cls ^= class_array.At(i);
FinalizeTypesInClass(cls);
+ // Classes compiled from Dart sources are finalized more lazily, classes
+ // compiled from Kernel binaries can be finalized now (and should be,
+ // since we will not revisit them).
+ if (from_kernel) {
+ FinalizeClass(cls);
+ }
}
if (FLAG_print_classes) {
for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -188,7 +194,7 @@ void ClassFinalizer::CollectInterfaces(const Class& cls,
}
-#if defined(DART_NO_SNAPSHOT)
+#if !defined(DART_PRECOMPILED_RUNTIME)
void ClassFinalizer::VerifyBootstrapClasses() {
if (FLAG_trace_class_finalization) {
OS::Print("VerifyBootstrapClasses START.\n");
@@ -254,7 +260,7 @@ void ClassFinalizer::VerifyBootstrapClasses() {
}
Isolate::Current()->heap()->Verify();
}
-#endif // defined(DART_NO_SNAPSHOT).
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
static bool IsLoaded(const Type& type) {
@@ -263,9 +269,15 @@ static bool IsLoaded(const Type& type) {
}
const UnresolvedClass& unresolved_class =
UnresolvedClass::Handle(type.unresolved_class());
- const LibraryPrefix& prefix =
- LibraryPrefix::Handle(unresolved_class.library_prefix());
- return prefix.IsNull() || prefix.is_loaded();
+ const Object& prefix =
+ Object::Handle(unresolved_class.library_or_library_prefix());
+ if (prefix.IsNull()) {
+ return true;
+ } else if (prefix.IsLibraryPrefix()) {
+ return LibraryPrefix::Cast(prefix).is_loaded();
+ } else {
+ return true;
+ }
}
@@ -276,15 +288,19 @@ RawClass* ClassFinalizer::ResolveClass(
const String& class_name = String::Handle(unresolved_class.ident());
Library& lib = Library::Handle();
Class& resolved_class = Class::Handle();
- if (unresolved_class.library_prefix() == LibraryPrefix::null()) {
+ if (unresolved_class.library_or_library_prefix() == Object::null()) {
lib = cls.library();
ASSERT(!lib.IsNull());
resolved_class = lib.LookupClass(class_name);
} else {
- LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
- lib_prefix = unresolved_class.library_prefix();
- ASSERT(!lib_prefix.IsNull());
- resolved_class = lib_prefix.LookupClass(class_name);
+ const Object& prefix =
+ Object::Handle(unresolved_class.library_or_library_prefix());
+
+ if (prefix.IsLibraryPrefix()) {
+ resolved_class = LibraryPrefix::Cast(prefix).LookupClass(class_name);
+ } else {
+ resolved_class = Library::Cast(prefix).LookupClass(class_name);
+ }
}
return resolved_class.raw();
}
@@ -2189,12 +2205,25 @@ void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
const GrowableObjectArray& cloned_funcs =
GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
- CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
-
Array& functions = Array::Handle(zone);
Function& func = Function::Handle(zone);
+
// The parser creates the mixin application class with no functions.
- ASSERT((functions = cls.functions(), functions.Length() == 0));
+ // But the Kernel frontend will generate mixin classes with only
+ // constructors inside them, which forward to the base class constructors.
+ //
+ // => We generate the constructors if they are not already there.
+ functions = cls.functions();
+ if (functions.Length() == 0) {
+ CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
+ } else {
+ for (intptr_t i = 0; i < functions.Length(); i++) {
+ func ^= functions.At(i);
+ ASSERT(func.kernel_function() != 0);
+ cloned_funcs.Add(func);
+ }
+ }
+
// Now clone the functions from the mixin class.
functions = mixin_cls.functions();
const intptr_t num_functions = functions.Length();
@@ -2384,8 +2413,20 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
// if the class is being refinalized because a patch is being applied
// after the class has been finalized then it is ok for the class to have
// functions.
- ASSERT((Array::Handle(cls.functions()).Length() == 0) ||
- cls.is_refinalize_after_patch());
+ //
+ // TODO(kmillikin): This ASSERT will fail when bootstrapping from Kernel
+ // because classes are first created, methods are added, and then classes
+ // are finalized. It is not easy to finalize classes earlier because not
+ // all bootstrap classes have been created yet. It would be possible to
+ // create all classes, delay adding methods, finalize the classes, and then
+ // reprocess all classes to add methods, but that seems unnecessary.
+ // Marking the bootstrap classes as is_refinalize_after_patch seems cute but
+ // it causes other things to fail by violating their assumptions. Reenable
+ // this ASSERT if it's important, remove it if it's just a sanity check and
+ // not required for correctness.
+ //
+ // ASSERT((Array::Handle(cls.functions()).Length() == 0) ||
+ // cls.is_refinalize_after_patch());
}
}

Powered by Google App Engine
This is Rietveld 408576698