Revision: 6032
Author: [email protected]
Date: Wed Dec 15 07:25:53 2010
Log: Fix deoptimization from %_MathPow. Do not prepare the stack for a C
call and then bailout without performing the call.
In order to not duplicate code, convert both heap number and smi to a
double in an xmm register if possible. Then setup the stack and call
the C function.
BUG=http://code.google.com/p/v8/issues/detail?id=986
Review URL: http://codereview.chromium.org/5900001
http://code.google.com/p/v8/source/detail?r=6032
Modified:
/branches/bleeding_edge/src/execution.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
=======================================
--- /branches/bleeding_edge/src/execution.cc Tue Dec 7 03:31:57 2010
+++ /branches/bleeding_edge/src/execution.cc Wed Dec 15 07:25:53 2010
@@ -720,7 +720,6 @@
return Top::TerminateExecution();
}
if (StackGuard::IsInterrupted()) {
- // interrupt
StackGuard::Continue(INTERRUPT);
return Top::StackOverflow();
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Dec 15
05:56:41 2010
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Dec 15
07:25:53 2010
@@ -2262,47 +2262,55 @@
void LCodeGen::DoPower(LPower* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
+ DoubleRegister result_reg = ToDoubleRegister(instr->result());
Representation exponent_type =
instr->hydrogen()->right()->representation();
if (exponent_type.IsDouble()) {
- // Pass two doubles as arguments on the stack.
- __ PrepareCallCFunction(4, eax);
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ __ PrepareCallCFunction(4, ebx);
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
__ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
__ CallCFunction(ExternalReference::power_double_double_function(), 4);
} else if (exponent_type.IsInteger32()) {
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ ASSERT(!ToRegister(right).is(ebx));
__ PrepareCallCFunction(4, ebx);
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
__ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
__ CallCFunction(ExternalReference::power_double_int_function(), 4);
} else {
ASSERT(exponent_type.IsTagged());
- __ PrepareCallCFunction(4, ebx);
- __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
+ CpuFeatures::Scope scope(SSE2);
Register right_reg = ToRegister(right);
- Label non_smi;
- Label done;
+
+ Label non_smi, call;
__ test(right_reg, Immediate(kSmiTagMask));
__ j(not_zero, &non_smi);
__ SmiUntag(right_reg);
- __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
- __ CallCFunction(ExternalReference::power_double_int_function(), 4);
- __ jmp(&done);
+ __ cvtsi2sd(result_reg, Operand(right_reg));
+ __ jmp(&call);
__ bind(&non_smi);
+ // It is safe to use ebx directly since the instruction is marked
+ // as a call.
+ ASSERT(!right_reg.is(ebx));
__ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , ebx);
DeoptimizeIf(not_equal, instr->environment());
- __ movdbl(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
- __ movdbl(Operand(esp, 1 * kDoubleSize), xmm1);
- __ CallCFunction(ExternalReference::power_double_double_function(), 4);
-
- __ bind(&done);
+ __ movdbl(result_reg, FieldOperand(right_reg,
HeapNumber::kValueOffset));
+
+ __ bind(&call);
+ __ PrepareCallCFunction(4, ebx);
+ __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
+ __ movdbl(Operand(esp, 1 * kDoubleSize), result_reg);
+ __ CallCFunction(ExternalReference::power_double_double_function(), 4);
}
// Return value is in st(0) on ia32.
// Store it into the (fixed) result register.
__ sub(Operand(esp), Immediate(kDoubleSize));
__ fstp_d(Operand(esp, 0));
- __ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0));
+ __ movdbl(result_reg, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Dec 15 04:32:19
2010
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Dec 15 07:25:53
2010
@@ -1603,7 +1603,7 @@
UseFixedDouble(instr->right(), xmm2) :
UseFixed(instr->right(), eax);
LPower* result = new LPower(left, right);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
+ return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
CAN_DEOPTIMIZE_EAGERLY);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev