Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 14798) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -43,15 +43,31 @@ |
| void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + const Function& function = |
| + Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| Register result = locs()->in(0).reg(); |
| Register func_reg = locs()->temp(0).reg(); |
| ASSERT(result == EAX); |
| - if (!compiler->is_optimizing()) { |
| - // Count only in unoptimized code. |
| - // TODO(srdjan): Replace the counting code with a type feedback |
| - // collection and counting stub. |
| - const Function& function = |
| - Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| + if (compiler->is_optimizing()) { |
| + if (compiler->may_reoptimize()) { |
| + // Increment of counter occurs only in optimized IC calls, as they |
| + // can cause reoptimization. |
| + Label done; |
| + __ LoadObject(func_reg, function); |
| + __ cmpl(FieldAddress(func_reg, Function::usage_counter_offset()), |
| + Immediate(FLAG_optimization_counter_threshold)); |
| + __ j(LESS, &done, Assembler::kNearJump); |
| + // Equal (or greater), optimize. Note that counter can reach equality |
| + // only at return instruction. |
| + // The stub call preserves result register (EAX). |
| + ASSERT(func_reg == EDX); |
| + compiler->GenerateCall(0, // no token position. |
|
Kevin Millikin (Google)
2012/11/13 17:56:53
I always have to figure out why we optimize at ret
srdjan
2012/11/13 18:21:39
Done:
// Attempt optimized compilation at return i
|
| + &StubCode::OptimizeFunctionLabel(), |
| + PcDescriptors::kOther, |
| + locs()); |
| + __ Bind(&done); |
| + } |
| + } else { |
| __ LoadObject(func_reg, function); |
| __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
| if (FlowGraphCompiler::CanOptimize() && |
| @@ -346,7 +362,13 @@ |
| ICData& equality_ic_data = ICData::ZoneHandle(); |
| if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| ASSERT(!original_ic_data.IsNull()); |
| - equality_ic_data = original_ic_data.AsUnaryClassChecks(); |
| + if (original_ic_data.NumberOfChecks() == 0) { |
| + // IC call for reoptimization populates original ICData. |
| + equality_ic_data = original_ic_data.raw(); |
| + } else { |
| + // Megamorphic call. |
| + equality_ic_data = original_ic_data.AsUnaryClassChecks(); |
| + } |
| } else { |
| equality_ic_data = ICData::New(compiler->parsed_function().function(), |
| operator_name, |
| @@ -988,7 +1010,13 @@ |
| ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
| ASSERT(!ic_data()->IsNull()); |
| - relational_ic_data = ic_data()->AsUnaryClassChecks(); |
| + if (ic_data()->NumberOfChecks() == 0) { |
| + // IC call for reoptimization populates original ICData. |
| + relational_ic_data = ic_data()->raw(); |
| + } else { |
| + // Megamorphic call. |
| + relational_ic_data = ic_data()->AsUnaryClassChecks(); |
| + } |
| } else { |
| relational_ic_data = ICData::New(compiler->parsed_function().function(), |
| function_name, |