| 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());
|
| }
|
| }
|
| }
|
|
|