Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 8eca27d77d9427f5c4fa58ae0d58e8cf4956b28c..c6547bef82a3fb434e553852a45598b1830f6f72 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -769,13 +769,39 @@ void LCodeGen::DeoptimizeIf(Condition condition, |
return; |
} |
- ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. |
- if (FLAG_deopt_every_n_times == 1 && |
- !info()->IsStub() && |
- info()->opt_count() == id) { |
- ASSERT(frame_is_built_); |
- __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
- return; |
+ if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { |
+ Register scratch = scratch0(); |
+ ExternalReference count = ExternalReference::stress_deopt_count(isolate()); |
+ |
+ // Store the condition on the stack if necessary |
+ if (condition != al) { |
+ __ mov(scratch, Operand::Zero(), LeaveCC, NegateCondition(condition)); |
+ __ mov(scratch, Operand(1), LeaveCC, condition); |
+ __ push(scratch); |
+ } |
+ |
+ __ push(r1); |
+ __ mov(scratch, Operand(count)); |
+ __ ldr(r1, MemOperand(scratch)); |
+ __ sub(r1, r1, Operand(1), SetCC); |
+ __ movw(r1, FLAG_deopt_every_n_times, eq); |
+ __ str(r1, MemOperand(scratch)); |
+ __ pop(r1); |
+ |
+ if (condition != al) { |
+ // Clean up the stack before the deoptimizer call |
+ __ pop(scratch); |
+ } |
+ |
+ __ Call(entry, RelocInfo::RUNTIME_ENTRY, eq); |
+ |
+ // 'Restore' the condition in a slightly hacky way. (It would be better |
+ // to use 'msr' and 'mrs' instructions here, but they are not supported by |
+ // our ARM simulator). |
+ if (condition != al) { |
+ condition = ne; |
+ __ cmp(scratch, Operand::Zero()); |
+ } |
} |
if (info()->ShouldTrapOnDeopt()) { |