| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 0d4d805acbed5ab227d64cf2a6fd7c85635ace07..7c162f7f6009e04dde6b57b57fe55ab3d40b8694 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -98,6 +98,38 @@ void LCodeGen::Abort(BailoutReason reason) {
|
| }
|
|
|
|
|
| +void LCodeGen::SaveCallerDoubles() {
|
| + ASSERT(info()->saves_caller_doubles());
|
| + ASSERT(NeedsEagerFrame());
|
| + Comment(";;; Save clobbered callee double registers");
|
| + int count = 0;
|
| + BitVector* doubles = chunk()->allocated_double_registers();
|
| + BitVector::Iterator save_iterator(doubles);
|
| + while (!save_iterator.Done()) {
|
| + __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
|
| + MemOperand(sp, count * kDoubleSize));
|
| + save_iterator.Advance();
|
| + count++;
|
| + }
|
| +}
|
| +
|
| +
|
| +void LCodeGen::RestoreCallerDoubles() {
|
| + ASSERT(info()->saves_caller_doubles());
|
| + ASSERT(NeedsEagerFrame());
|
| + Comment(";;; Restore clobbered callee double registers");
|
| + BitVector* doubles = chunk()->allocated_double_registers();
|
| + BitVector::Iterator save_iterator(doubles);
|
| + int count = 0;
|
| + while (!save_iterator.Done()) {
|
| + __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
|
| + MemOperand(sp, count * kDoubleSize));
|
| + save_iterator.Advance();
|
| + count++;
|
| + }
|
| +}
|
| +
|
| +
|
| bool LCodeGen::GeneratePrologue() {
|
| ASSERT(is_generating());
|
|
|
| @@ -158,16 +190,7 @@ bool LCodeGen::GeneratePrologue() {
|
| }
|
|
|
| if (info()->saves_caller_doubles()) {
|
| - Comment(";;; Save clobbered callee double registers");
|
| - int count = 0;
|
| - BitVector* doubles = chunk()->allocated_double_registers();
|
| - BitVector::Iterator save_iterator(doubles);
|
| - while (!save_iterator.Done()) {
|
| - __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
|
| - MemOperand(sp, count * kDoubleSize));
|
| - save_iterator.Advance();
|
| - count++;
|
| - }
|
| + SaveCallerDoubles();
|
| }
|
|
|
| // Possibly allocate a local context.
|
| @@ -313,6 +336,7 @@ bool LCodeGen::GenerateDeoptJumpTable() {
|
| Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
|
| }
|
| if (deopt_jump_table_[i].needs_frame) {
|
| + ASSERT(!info()->saves_caller_doubles());
|
| __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry)));
|
| if (needs_frame.is_bound()) {
|
| __ b(&needs_frame);
|
| @@ -330,6 +354,10 @@ bool LCodeGen::GenerateDeoptJumpTable() {
|
| __ mov(pc, ip);
|
| }
|
| } else {
|
| + if (info()->saves_caller_doubles()) {
|
| + ASSERT(info()->IsStub());
|
| + RestoreCallerDoubles();
|
| + }
|
| __ mov(lr, Operand(pc), LeaveCC, al);
|
| __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
|
| }
|
| @@ -828,7 +856,10 @@ void LCodeGen::DeoptimizeIf(Condition condition,
|
| }
|
|
|
| ASSERT(info()->IsStub() || frame_is_built_);
|
| - if (condition == al && frame_is_built_) {
|
| + // Go through jump table if we need to handle condition, build frame, or
|
| + // restore caller doubles.
|
| + if (condition == al && frame_is_built_ &&
|
| + !info()->saves_caller_doubles()) {
|
| __ Call(entry, RelocInfo::RUNTIME_ENTRY);
|
| } else {
|
| // We often have several deopts to the same entry, reuse the last
|
| @@ -2959,16 +2990,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
|
| __ CallRuntime(Runtime::kTraceExit, 1);
|
| }
|
| if (info()->saves_caller_doubles()) {
|
| - ASSERT(NeedsEagerFrame());
|
| - BitVector* doubles = chunk()->allocated_double_registers();
|
| - BitVector::Iterator save_iterator(doubles);
|
| - int count = 0;
|
| - while (!save_iterator.Done()) {
|
| - __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
|
| - MemOperand(sp, count * kDoubleSize));
|
| - save_iterator.Advance();
|
| - count++;
|
| - }
|
| + RestoreCallerDoubles();
|
| }
|
| int no_frame_start = -1;
|
| if (NeedsEagerFrame()) {
|
|
|