| Index: runtime/vm/intermediate_language_arm.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_arm.cc (revision 24893)
|
| +++ runtime/vm/intermediate_language_arm.cc (working copy)
|
| @@ -24,6 +24,7 @@
|
|
|
| DECLARE_FLAG(int, optimization_counter_threshold);
|
| DECLARE_FLAG(bool, propagate_ic_data);
|
| +DECLARE_FLAG(bool, use_osr);
|
|
|
| // Generic summary for call instructions that have all arguments pushed
|
| // on the stack and return the result in a fixed register R0.
|
| @@ -2051,11 +2052,12 @@
|
|
|
| LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 0;
|
| - const intptr_t kNumTemps = 0;
|
| + const intptr_t kNumTemps = 1;
|
| LocationSummary* summary =
|
| new LocationSummary(kNumInputs,
|
| kNumTemps,
|
| LocationSummary::kCallOnSlowPath);
|
| + summary->set_temp(0, Location::RequiresRegister());
|
| return summary;
|
| }
|
|
|
| @@ -2077,6 +2079,13 @@
|
| instruction_->deopt_id(),
|
| kStackOverflowRuntimeEntry,
|
| instruction_->locs());
|
| +
|
| + if (FLAG_use_osr && !compiler->is_optimizing() && instruction_->in_loop()) {
|
| + // In unoptimized code, record loop stack checks as possible OSR entries.
|
| + compiler->AddCurrentDescriptor(PcDescriptors::kOsrEntry,
|
| + instruction_->deopt_id(),
|
| + 0); // No token position.
|
| + }
|
| compiler->pending_deoptimization_env_ = NULL;
|
| compiler->RestoreLiveRegisters(instruction_->locs());
|
| __ b(exit_label());
|
| @@ -2095,6 +2104,18 @@
|
| __ ldr(IP, Address(IP));
|
| __ cmp(SP, ShifterOperand(IP));
|
| __ b(slow_path->entry_label(), LS);
|
| + if (compiler->CanOSRFunction() && in_loop()) {
|
| + Register temp = locs()->temp(0).reg();
|
| + // In unoptimized code check the usage counter to trigger OSR at loop
|
| + // stack checks. Use progressively higher thresholds for more deeply
|
| + // nested loops to attempt to hit outer loops with OSR when possible.
|
| + __ LoadObject(temp, compiler->parsed_function().function());
|
| + intptr_t threshold =
|
| + FLAG_optimization_counter_threshold * (loop_depth() + 1);
|
| + __ ldr(temp, FieldAddress(temp, Function::usage_counter_offset()));
|
| + __ CompareImmediate(temp, threshold);
|
| + __ b(slow_path->entry_label(), GE);
|
| + }
|
| __ Bind(slow_path->exit_label());
|
| }
|
|
|
|
|