| Index: runtime/vm/intermediate_language_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_ia32.cc (revision 14858)
|
| +++ runtime/vm/intermediate_language_ia32.cc (working copy)
|
| @@ -42,16 +42,35 @@
|
| }
|
|
|
|
|
| +// Attempt optimized compilation at return instruction instead of at the entry.
|
| +// The entry needs to be patchable, no inlined objects are allowed in the area
|
| +// that will be overwritten by the patch instruction: a jump).
|
| 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.
|
| + &StubCode::OptimizeFunctionLabel(),
|
| + PcDescriptors::kOther,
|
| + locs());
|
| + __ Bind(&done);
|
| + }
|
| + } else {
|
| __ LoadObject(func_reg, function);
|
| __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
|
| if (FlowGraphCompiler::CanOptimize() &&
|
| @@ -350,7 +369,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,
|
| @@ -970,7 +995,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,
|
|
|