| Index: runtime/vm/flow_graph_compiler_arm.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_compiler_arm.cc (revision 24893)
|
| +++ runtime/vm/flow_graph_compiler_arm.cc (working copy)
|
| @@ -23,6 +23,7 @@
|
|
|
| DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
|
| DECLARE_FLAG(int, optimization_counter_threshold);
|
| +DECLARE_FLAG(int, reoptimization_counter_threshold);
|
| DECLARE_FLAG(bool, print_ast);
|
| DECLARE_FLAG(bool, print_scopes);
|
| DECLARE_FLAG(bool, enable_type_checks);
|
| @@ -1041,52 +1042,56 @@
|
|
|
| void FlowGraphCompiler::EmitFrameEntry() {
|
| const Function& function = parsed_function().function();
|
| - if (CanOptimizeFunction() && function.is_optimizable()) {
|
| - const bool can_optimize = !is_optimizing() || may_reoptimize();
|
| + if (CanOptimizeFunction() &&
|
| + function.is_optimizable() &&
|
| + (!is_optimizing() || may_reoptimize())) {
|
| const Register function_reg = R6;
|
| - if (can_optimize) {
|
| - // The pool pointer is not setup before entering the Dart frame.
|
|
|
| - // Preserve PP of caller.
|
| - __ mov(R7, ShifterOperand(PP));
|
| + // The pool pointer is not setup before entering the Dart frame.
|
| + // Preserve PP of caller.
|
| + __ mov(R7, ShifterOperand(PP));
|
| + // Temporarily setup pool pointer for this dart function.
|
| + __ LoadPoolPointer();
|
| + // Load function object from object pool.
|
| + __ LoadObject(function_reg, function); // Uses PP.
|
| + // Restore PP of caller.
|
| + __ mov(PP, ShifterOperand(R7));
|
|
|
| - // Temporarily setup pool pointer for this dart function.
|
| - __ LoadPoolPointer();
|
| -
|
| - // Load function object from object pool.
|
| - __ LoadObject(function_reg, function); // Uses PP.
|
| -
|
| - // Restore PP of caller.
|
| - __ mov(PP, ShifterOperand(R7));
|
| - }
|
| // Patch point is after the eventually inlined function object.
|
| AddCurrentDescriptor(PcDescriptors::kEntryPatch,
|
| Isolate::kNoDeoptId,
|
| 0); // No token position.
|
| - if (can_optimize) {
|
| - // Reoptimization of optimized function is triggered by counting in
|
| + intptr_t threshold = FLAG_optimization_counter_threshold;
|
| + __ ldr(R7, FieldAddress(function_reg,
|
| + Function::usage_counter_offset()));
|
| + if (is_optimizing()) {
|
| + // Reoptimization of an optimized function is triggered by counting in
|
| // IC stubs, but not at the entry of the function.
|
| - if (!is_optimizing()) {
|
| - __ ldr(R7, FieldAddress(function_reg,
|
| - Function::usage_counter_offset()));
|
| - __ add(R7, R7, ShifterOperand(1));
|
| - __ str(R7, FieldAddress(function_reg,
|
| - Function::usage_counter_offset()));
|
| - } else {
|
| - __ ldr(R7, FieldAddress(function_reg,
|
| - Function::usage_counter_offset()));
|
| - }
|
| - __ CompareImmediate(R7, FLAG_optimization_counter_threshold);
|
| - ASSERT(function_reg == R6);
|
| - __ Branch(&StubCode::OptimizeFunctionLabel(), GE);
|
| + threshold = FLAG_reoptimization_counter_threshold;
|
| + } else {
|
| + __ add(R7, R7, ShifterOperand(1));
|
| + __ str(R7, FieldAddress(function_reg,
|
| + Function::usage_counter_offset()));
|
| }
|
| - } else {
|
| + __ CompareImmediate(R7, threshold);
|
| + ASSERT(function_reg == R6);
|
| + __ Branch(&StubCode::OptimizeFunctionLabel(), GE);
|
| + } else if (!flow_graph().IsCompiledForOsr()) {
|
| AddCurrentDescriptor(PcDescriptors::kEntryPatch,
|
| Isolate::kNoDeoptId,
|
| 0); // No token position.
|
| }
|
| __ Comment("Enter frame");
|
| - __ EnterDartFrame(StackSize() * kWordSize);
|
| + if (flow_graph().IsCompiledForOsr()) {
|
| + intptr_t extra_slots = StackSize()
|
| + - flow_graph().num_stack_locals()
|
| + - flow_graph().num_copied_params();
|
| + ASSERT(extra_slots >= 0);
|
| + __ EnterOsrFrame(extra_slots * kWordSize);
|
| + } else {
|
| + ASSERT(StackSize() >= 0);
|
| + __ EnterDartFrame(StackSize() * kWordSize);
|
| + }
|
| }
|
|
|
|
|
| @@ -1123,10 +1128,11 @@
|
| if (num_copied_params == 0) {
|
| #ifdef DEBUG
|
| ASSERT(!parsed_function().function().HasOptionalParameters());
|
| - const bool check_arguments = true;
|
| + const bool check_arguments = !flow_graph().IsCompiledForOsr();
|
| #else
|
| const bool check_arguments =
|
| - function.IsClosureFunction() || function.IsNoSuchMethodDispatcher();
|
| + (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) &&
|
| + !flow_graph().IsCompiledForOsr();
|
| #endif
|
| if (check_arguments) {
|
| __ Comment("Check argument count");
|
| @@ -1161,7 +1167,7 @@
|
| }
|
| __ Bind(&correct_num_arguments);
|
| }
|
| - } else {
|
| + } else if (!flow_graph().IsCompiledForOsr()) {
|
| CopyParameters();
|
| }
|
|
|
|
|