Chromium Code Reviews| 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++) { |
|
Florian Schneider
2016/03/04 00:50:25
Would using a subclass of FunctionVisitor work her
rmacnak
2016/03/04 17:33:22
In this case we aren't interested in all of the fu
|
| + 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()); |
| } |
| } |
| } |