| Index: runtime/vm/compiler.cc
|
| diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
|
| index de8560e7ec3192ae47152bb054316a241ed404c8..d568a9645ca7f915e1cd06fe528c43678be29f26 100644
|
| --- a/runtime/vm/compiler.cc
|
| +++ b/runtime/vm/compiler.cc
|
| @@ -812,6 +812,12 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
|
| flow_graph->deoptimize_dependent_code());
|
| } else {
|
| for (intptr_t i = 0;
|
| + i < flow_graph->deoptimize_dependent_code().length();
|
| + i++) {
|
| + const Field* field = flow_graph->deoptimize_dependent_code()[i];
|
| + field->DeoptimizeDependentCode();
|
| + }
|
| + for (intptr_t i = 0;
|
| i < thread->cha()->leaf_classes().length();
|
| ++i) {
|
| thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
|
| @@ -822,12 +828,6 @@ static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
|
| const Field* field = (*flow_graph->guarded_fields())[i];
|
| field->RegisterDependentCode(code);
|
| }
|
| - for (intptr_t i = 0;
|
| - i < flow_graph->deoptimize_dependent_code().length();
|
| - i++) {
|
| - const Field* field = flow_graph->deoptimize_dependent_code()[i];
|
| - field->DeoptimizeDependentCode();
|
| - }
|
| }
|
| }
|
| } else { // not optimized.
|
| @@ -1820,10 +1820,11 @@ void BackgroundCompiler::AddResult(const BackgroundCompilationResult& result) {
|
| MonitorLocker ml(queue_monitor_);
|
| // Reuse the input QueueElement to return the result.
|
| QueueElement* qelem = function_queue()->Remove();
|
| - if (result.IsValid()) {
|
| - qelem->SetFromResult(result);
|
| - result_queue()->Add(qelem);
|
| - }
|
| + // Always add result, even if it is invalid, since the queue element is
|
| + // deleted in the mutator thread and potential field based deoptimizations
|
| + // (carried in the result) still must be done.
|
| + qelem->SetFromResult(result);
|
| + result_queue()->Add(qelem);
|
| }
|
|
|
|
|
| @@ -1845,13 +1846,20 @@ void BackgroundCompiler::InstallGeneratedCode() {
|
| Function& function = Function::Handle();
|
| while (result_queue()->Peek() != NULL) {
|
| BackgroundCompilationResult result;
|
| - QueueElement* elem = result_queue()->Remove();
|
| - ASSERT(elem != NULL);
|
| - result.SetFromQElement(elem);
|
| - delete elem;
|
| + QueueElement* qelem = result_queue()->Remove();
|
| + ASSERT(qelem != NULL);
|
| + result.SetFromQElement(qelem);
|
| + delete qelem;
|
|
|
| const Code& code = result.result_code();
|
| function ^= code.owner();
|
| + Field& field = Field::Handle();
|
| + // Always execute necessary deoptimizations, even if the result is invalid.
|
| + for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length();
|
| + i++) {
|
| + field ^= result.deoptimize_dependent_fields().At(i);
|
| + field.DeoptimizeDependentCode();
|
| + }
|
| if (result.IsValid()) {
|
| function.InstallOptimizedCode(result.result_code(), false /* not OSR */);
|
| // Install leaf classes and fields dependencies.
|
| @@ -1860,16 +1868,10 @@ void BackgroundCompiler::InstallGeneratedCode() {
|
| cls ^= result.leaf_classes().At(i);
|
| cls.RegisterCHACode(code);
|
| }
|
| - Field& field = Field::Handle();
|
| for (intptr_t i = 0; i < result.guarded_fields().Length(); i++) {
|
| field ^= result.guarded_fields().At(i);
|
| field.RegisterDependentCode(code);
|
| }
|
| - for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length();
|
| - i++) {
|
| - field ^= result.deoptimize_dependent_fields().At(i);
|
| - field.DeoptimizeDependentCode();
|
| - }
|
| } else if (FLAG_trace_compiler) {
|
| THR_Print("Drop code generated in the background compiler:\n");
|
| result.PrintValidity();
|
|
|