From: jarin@chromium.org Date: Thu, 7 Nov 2013 13:09:48 +0000 (+0000) Subject: Proper support for deopt_every_n_times option on the x64 and ARM architectures. X-Git-Tag: upstream/4.7.83~11843 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=363659d7e6359b349fab8a153e5a7f6088640d8c;p=platform%2Fupstream%2Fv8.git Proper support for deopt_every_n_times option on the x64 and ARM architectures. R=danno@chromium.org BUG= Review URL: https://codereview.chromium.org/62293002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17564 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 8eca27d..c6547bef 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()) { diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 14d31c5..a84b569 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -649,7 +649,27 @@ void LCodeGen::DeoptimizeIf(Condition cc, return; } - ASSERT(FLAG_deopt_every_n_times == 0); // Not yet implemented on x64. + if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { + ExternalReference count = ExternalReference::stress_deopt_count(isolate()); + Label no_deopt; + __ pushfq(); + __ push(rax); + Operand count_operand = masm()->ExternalOperand(count, kScratchRegister); + __ movl(rax, count_operand); + __ subl(rax, Immediate(1)); + __ j(not_zero, &no_deopt, Label::kNear); + if (FLAG_trap_on_deopt) __ int3(); + __ movl(rax, Immediate(FLAG_deopt_every_n_times)); + __ movl(count_operand, rax); + __ pop(rax); + __ popfq(); + ASSERT(frame_is_built_); + __ call(entry, RelocInfo::RUNTIME_ENTRY); + __ bind(&no_deopt); + __ movl(count_operand, rax); + __ pop(rax); + __ popfq(); + } if (info()->ShouldTrapOnDeopt()) { Label done;