Index: runtime/vm/precompiler.cc |
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
index e61e916218cb9abe1876e1b26fdccf377f39076b..b8bfc1898fab8195d08277bfe8bb93f404c7b67d 100644 |
--- a/runtime/vm/precompiler.cc |
+++ b/runtime/vm/precompiler.cc |
@@ -148,6 +148,7 @@ Precompiler::Precompiler(Thread* thread, bool reset_fields) : |
classes_to_retain_(), |
typeargs_to_retain_(), |
types_to_retain_(), |
+ consts_to_retain_(), |
error_(Error::Handle()) { |
} |
@@ -409,6 +410,9 @@ void Precompiler::Iterate() { |
} |
CheckForNewDynamicFunctions(); |
+ if (!changed_) { |
+ TraceConstFunctions(); |
+ } |
} |
} |
@@ -676,6 +680,8 @@ void Precompiler::AddConstObject(const Instance& instance) { |
// argument descriptors. |
if (!instance.IsCanonical()) return; |
+ consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw())); |
+ |
if (cls.NumTypeArguments() > 0) { |
AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); |
} |
@@ -1160,6 +1166,36 @@ void Precompiler::GetUniqueDynamicTarget(Isolate* isolate, |
} |
+void Precompiler::TraceConstFunctions() { |
+ // Compilation of const accessors happens outside of the treeshakers |
+ // queue, so we haven't previously scanned its literal pool. |
+ |
+ Library& lib = Library::Handle(Z); |
+ Class& cls = Class::Handle(Z); |
+ Array& functions = Array::Handle(Z); |
+ Function& function = Function::Handle(Z); |
+ |
+ for (intptr_t i = 0; i < libraries_.Length(); i++) { |
+ lib ^= libraries_.At(i); |
+ ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
+ while (it.HasNext()) { |
+ cls = it.GetNextClass(); |
+ if (cls.IsDynamicClass()) { |
+ continue; // class 'dynamic' is in the read-only VM isolate. |
+ } |
+ |
+ functions = cls.functions(); |
+ for (intptr_t j = 0; j < functions.Length(); j++) { |
+ function ^= functions.At(j); |
+ if (function.is_const() && function.HasCode()) { |
+ AddCalleesOf(function); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+ |
void Precompiler::DropFunctions() { |
Library& lib = Library::Handle(Z); |
Class& cls = Class::Handle(Z); |
@@ -1208,7 +1244,7 @@ void Precompiler::DropFunctions() { |
} |
dropped_function_count_++; |
if (FLAG_trace_precompiler) { |
- THR_Print("Precompilation dropping %s\n", |
+ THR_Print("Dropping function %s\n", |
function.ToLibNamePrefixedQualifiedCString()); |
} |
} |
@@ -1234,7 +1270,7 @@ void Precompiler::DropFunctions() { |
} else { |
dropped_function_count_++; |
if (FLAG_trace_precompiler) { |
- THR_Print("Precompilation dropping %s\n", |
+ THR_Print("Dropping function %s\n", |
function.ToLibNamePrefixedQualifiedCString()); |
} |
} |
@@ -1279,7 +1315,7 @@ void Precompiler::DropFields() { |
} |
dropped_field_count_++; |
if (FLAG_trace_precompiler) { |
- THR_Print("Precompilation dropping %s\n", |
+ THR_Print("Dropping field %s\n", |
field.ToCString()); |
} |
} |
@@ -1390,6 +1426,9 @@ void Precompiler::TraceTypesFromRetainedClasses() { |
Library& lib = Library::Handle(Z); |
Class& cls = Class::Handle(Z); |
Array& members = Array::Handle(Z); |
+ Array& constants = Array::Handle(Z); |
+ GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); |
+ Instance& constant = Instance::Handle(Z); |
for (intptr_t i = 0; i < libraries_.Length(); i++) { |
lib ^= libraries_.At(i); |
@@ -1420,9 +1459,25 @@ void Precompiler::TraceTypesFromRetainedClasses() { |
// them. |
retain = true; |
} |
- members = cls.constants(); |
- if (members.Length() > 0) { |
- // --compile_all? |
+ |
+ constants = cls.constants(); |
+ retained_constants = GrowableObjectArray::New(); |
+ for (intptr_t j = 0; j < constants.Length(); j++) { |
+ constant ^= constants.At(j); |
+ bool retain = consts_to_retain_.Lookup(&constant) != NULL; |
+ if (retain) { |
+ retained_constants.Add(constant); |
+ } |
+ } |
+ if (retained_constants.Length() > 0) { |
+ constants = Array::MakeArray(retained_constants); |
+ cls.set_constants(constants); |
+ } else { |
+ cls.set_constants(Object::empty_array()); |
+ } |
+ |
+ if (constants.Length() > 0) { |
+ ASSERT(retain); // This shouldn't be the reason we keep a class. |
retain = true; |
} |
@@ -1492,7 +1547,7 @@ void Precompiler::DropClasses() { |
dropped_class_count_++; |
if (FLAG_trace_precompiler) { |
- THR_Print("Precompilation dropping %" Pd " %s\n", cid, cls.ToCString()); |
+ THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString()); |
} |
#if defined(DEBUG) |
@@ -1529,7 +1584,7 @@ void Precompiler::DropLibraries() { |
dropped_library_count_++; |
lib.set_index(-1); |
if (FLAG_trace_precompiler) { |
- THR_Print("Precompilation dropping %s\n", lib.ToCString()); |
+ THR_Print("Dropping library %s\n", lib.ToCString()); |
} |
} |
} |