| Index: runtime/vm/precompiler.cc
|
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
|
| index d0c46683b04dd502d763e1194c565f6a36e523cf..6a6148f6162646dee94c86d6a031d59f772a8bc8 100644
|
| --- a/runtime/vm/precompiler.cc
|
| +++ b/runtime/vm/precompiler.cc
|
| @@ -68,19 +68,39 @@ Precompiler::Precompiler(Thread* thread, bool reset_fields) :
|
|
|
| void Precompiler::DoCompileAll(
|
| Dart_QualifiedFunctionName embedder_entry_points[]) {
|
| - ClearAllCode();
|
| + ASSERT(I->compilation_allowed());
|
|
|
| // Make sure class hierarchy is stable before compilation so that CHA
|
| // can be used. Also ensures lookup of entry points won't miss functions
|
| // because their class hasn't been finalized yet.
|
| FinalizeAllClasses();
|
|
|
| - // Start with the allocations and invocations that happen from C++.
|
| - AddRoots(embedder_entry_points);
|
| + const intptr_t kPrecompilerRounds = 1;
|
| + for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
|
| + if (FLAG_trace_precompiler) {
|
| + OS::Print("Precompiler round %" Pd "\n", round);
|
| + }
|
| +
|
| + if (round > 0) {
|
| + ResetPrecompilerState();
|
| + }
|
|
|
| - // Compile newly found targets and add their callees until we reach a fixed
|
| - // point.
|
| - Iterate();
|
| + // TODO(rmacnak): We should be able to do a more thorough job and drop some
|
| + // - implicit static closures
|
| + // - field initializers
|
| + // - invoke-field-dispatchers
|
| + // - method-extractors
|
| + // that are needed in early iterations but optimized away in later
|
| + // iterations.
|
| + ClearAllCode();
|
| +
|
| + // Start with the allocations and invocations that happen from C++.
|
| + AddRoots(embedder_entry_points);
|
| +
|
| + // Compile newly found targets and add their callees until we reach a fixed
|
| + // point.
|
| + Iterate();
|
| + }
|
|
|
| DropUncompiledFunctions();
|
|
|
| @@ -338,6 +358,15 @@ void Precompiler::ProcessFunction(const Function& function) {
|
| if (!error_.IsNull()) {
|
| Jump(error_);
|
| }
|
| + } else {
|
| + if (FLAG_trace_precompiler) {
|
| + // This function was compiled from somewhere other than Precompiler,
|
| + // such as const constructors compiled by the parser.
|
| + THR_Print("Already has code: %s (%" Pd ", %s)\n",
|
| + function.ToLibNamePrefixedQualifiedCString(),
|
| + function.token_pos(),
|
| + Function::KindToCString(function.kind()));
|
| + }
|
| }
|
|
|
| ASSERT(function.HasCode());
|
| @@ -502,14 +531,14 @@ void Precompiler::AddField(const Field& field) {
|
| const bool is_initialized = value.raw() != Object::sentinel().raw();
|
| if (is_initialized && !reset_fields_) return;
|
|
|
| - if (field.HasPrecompiledInitializer()) return;
|
| -
|
| - if (FLAG_trace_precompiler) {
|
| - THR_Print("Precompiling initializer for %s\n", field.ToCString());
|
| + if (!field.HasPrecompiledInitializer()) {
|
| + if (FLAG_trace_precompiler) {
|
| + THR_Print("Precompiling initializer for %s\n", field.ToCString());
|
| + }
|
| + ASSERT(!Dart::IsRunningPrecompiledCode());
|
| + field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
|
| + Compiler::CompileStaticInitializer(field);
|
| }
|
| - ASSERT(!Dart::IsRunningPrecompiledCode());
|
| - field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
|
| - Compiler::CompileStaticInitializer(field);
|
|
|
| const Function& function =
|
| Function::Handle(Z, field.PrecompiledInitializer());
|
| @@ -557,7 +586,7 @@ void Precompiler::AddInstantiatedClass(const Class& cls) {
|
| if (cls.is_allocated()) return;
|
|
|
| class_count_++;
|
| - cls.set_is_allocated();
|
| + cls.set_is_allocated(true);
|
| changed_ = true;
|
|
|
| if (FLAG_trace_precompiler) {
|
| @@ -904,4 +933,30 @@ void Precompiler::FinalizeAllClasses() {
|
| }
|
|
|
|
|
| +void Precompiler::ResetPrecompilerState() {
|
| + changed_ = false;
|
| + function_count_ = 0;
|
| + class_count_ = 0;
|
| + selector_count_ = 0;
|
| + dropped_function_count_ = 0;
|
| + ASSERT(pending_functions_.Length() == 0);
|
| + sent_selectors_.Clear();
|
| + enqueued_functions_.Clear();
|
| +
|
| + Library& lib = Library::Handle(Z);
|
| + Class& cls = Class::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.
|
| + }
|
| + cls.set_is_allocated(false);
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace dart
|
|
|