Revision: 3681
Author: [email protected]
Date: Fri Jan 22 06:07:25 2010
Log: Inline smi code in count operations in the full code generator.
We now test for a smi before calling ToNumber and inline
the smi increment/decrement for ++ and --. There only a small
increase in code size but loops in top-level code are
becoming much faster as a result.
Review URL: http://codereview.chromium.org/553056
http://code.google.com/p/v8/source/detail?r=3681
Modified:
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jan 20 08:28:21
2010
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Jan 22 06:07:25
2010
@@ -1376,7 +1376,7 @@
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
Location saved_location = location_;
- location_ = kStack;
+ location_ = kAccumulator;
EmitVariableLoad(expr->expression()->AsVariableProxy()->var(),
Expression::kValue);
location_ = saved_location;
@@ -1393,11 +1393,15 @@
VisitForValue(prop->key(), kStack);
EmitKeyedPropertyLoad(prop);
}
- __ push(r0);
}
- // Convert to number.
+ // Call ToNumber only if operand is not a smi.
+ Label no_conversion;
+ __ tst(r0, Operand(kSmiTagMask));
+ __ b(eq, &no_conversion);
+ __ push(r0);
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
+ __ bind(&no_conversion);
// Save result for postfix expressions.
if (expr->is_postfix()) {
@@ -1429,12 +1433,28 @@
}
}
- // Call stub for +1/-1.
+
+ // Inline smi case if we are in a loop.
+ Label stub_call, done;
+ if (loop_depth() > 0) {
+ __ add(r0, r0, Operand(expr->op() == Token::INC
+ ? Smi::FromInt(1)
+ : Smi::FromInt(-1)));
+ __ b(vs, &stub_call);
+ // We could eliminate this smi check if we split the code at
+ // the first smi check before calling ToNumber.
+ __ tst(r0, Operand(kSmiTagMask));
+ __ b(eq, &done);
+ __ bind(&stub_call);
+ // Call stub. Undo operation first.
+ __ sub(r0, r0, Operand(r1));
+ }
__ mov(r1, Operand(expr->op() == Token::INC
? Smi::FromInt(1)
: Smi::FromInt(-1)));
GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE);
__ CallStub(&stub);
+ __ bind(&done);
// Store the value returned in r0.
switch (assign_type) {
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Wed Jan 20
08:28:21 2010
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Jan 22
06:07:25 2010
@@ -1482,7 +1482,7 @@
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
Location saved_location = location_;
- location_ = kStack;
+ location_ = kAccumulator;
EmitVariableLoad(expr->expression()->AsVariableProxy()->var(),
Expression::kValue);
location_ = saved_location;
@@ -1498,11 +1498,15 @@
VisitForValue(prop->key(), kStack);
EmitKeyedPropertyLoad(prop);
}
- __ push(eax);
}
- // Convert to number.
+ // Call ToNumber only if operand is not a smi.
+ Label no_conversion;
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &no_conversion);
+ __ push(eax);
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+ __ bind(&no_conversion);
// Save result for postfix expressions.
if (expr->is_postfix()) {
@@ -1534,6 +1538,27 @@
}
}
+ // Inline smi case if we are in a loop.
+ Label stub_call, done;
+ if (loop_depth() > 0) {
+ if (expr->op() == Token::INC) {
+ __ add(Operand(eax), Immediate(Smi::FromInt(1)));
+ } else {
+ __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
+ }
+ __ j(overflow, &stub_call);
+ // We could eliminate this smi check if we split the code at
+ // the first smi check before calling ToNumber.
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &done);
+ __ bind(&stub_call);
+ // Call stub. Undo operation first.
+ if (expr->op() == Token::INC) {
+ __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
+ } else {
+ __ add(Operand(eax), Immediate(Smi::FromInt(1)));
+ }
+ }
// Call stub for +1/-1.
__ push(eax);
__ push(Immediate(Smi::FromInt(1)));
@@ -1541,6 +1566,7 @@
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub);
+ __ bind(&done);
// Store the value returned in eax.
switch (assign_type) {
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Jan 20 08:28:21
2010
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Jan 22 06:07:25
2010
@@ -1489,7 +1489,7 @@
if (assign_type == VARIABLE) {
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
Location saved_location = location_;
- location_ = kStack;
+ location_ = kAccumulator;
EmitVariableLoad(expr->expression()->AsVariableProxy()->var(),
Expression::kValue);
location_ = saved_location;
@@ -1505,11 +1505,16 @@
VisitForValue(prop->key(), kStack);
EmitKeyedPropertyLoad(prop);
}
- __ push(rax);
}
- // Convert to number.
+ // Call ToNumber only if operand is not a smi.
+ Label no_conversion;
+ Condition is_smi;
+ is_smi = masm_->CheckSmi(rax);
+ __ j(is_smi, &no_conversion);
+ __ push(rax);
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+ __ bind(&no_conversion);
// Save result for postfix expressions.
if (expr->is_postfix()) {
@@ -1541,6 +1546,27 @@
}
}
+ // Inline smi case if we are in a loop.
+ Label stub_call, done;
+ if (loop_depth() > 0) {
+ if (expr->op() == Token::INC) {
+ __ SmiAddConstant(rax, rax, Smi::FromInt(1));
+ } else {
+ __ SmiSubConstant(rax, rax, Smi::FromInt(1));
+ }
+ __ j(overflow, &stub_call);
+ // We could eliminate this smi check if we split the code at
+ // the first smi check before calling ToNumber.
+ is_smi = masm_->CheckSmi(rax);
+ __ j(is_smi, &done);
+ __ bind(&stub_call);
+ // Call stub. Undo operation first.
+ if (expr->op() == Token::INC) {
+ __ SmiSubConstant(rax, rax, Smi::FromInt(1));
+ } else {
+ __ SmiAddConstant(rax, rax, Smi::FromInt(1));
+ }
+ }
// Call stub for +1/-1.
__ push(rax);
__ Push(Smi::FromInt(1));
@@ -1548,6 +1574,7 @@
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS);
__ CallStub(&stub);
+ __ bind(&done);
// Store the value returned in rax.
switch (assign_type) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev