Revision: 4831
Author: [email protected]
Date: Wed Jun 9 04:15:54 2010
Log: Use static type information on x64 in LikelySmiBinaryOperation.
Refactor check for smi operands, using type information, on ia32 and x64.
Review URL: http://codereview.chromium.org/2771001
http://code.google.com/p/v8/source/detail?r=4831
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/codegen-ia32.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/src/x64/codegen-x64.h
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Jun 7 06:16:05
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Jun 9 04:15:54
2010
@@ -1446,10 +1446,40 @@
}
-static void CheckTwoForSminess(MacroAssembler* masm,
- Register left, Register right, Register
scratch,
- TypeInfo left_info, TypeInfo right_info,
- DeferredInlineBinaryOperation* deferred);
+void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left,
+ Register right,
+ Register scratch,
+ TypeInfo left_info,
+ TypeInfo right_info,
+ DeferredCode* deferred) {
+ if (left.is(right)) {
+ if (!left_info.IsSmi()) {
+ __ test(left, Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ } else {
+ if (FLAG_debug_code) __ AbortIfNotSmi(left);
+ }
+ } else if (!left_info.IsSmi()) {
+ if (!right_info.IsSmi()) {
+ __ mov(scratch, left);
+ __ or_(scratch, Operand(right));
+ __ test(scratch, Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ } else {
+ __ test(left, Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ if (FLAG_debug_code) __ AbortIfNotSmi(right);
+ }
+ } else {
+ if (FLAG_debug_code) __ AbortIfNotSmi(left);
+ if (!right_info.IsSmi()) {
+ __ test(right, Immediate(kSmiTagMask));
+ deferred->Branch(not_zero);
+ } else {
+ if (FLAG_debug_code) __ AbortIfNotSmi(right);
+ }
+ }
+}
// Implements a binary operation using a deferred code object and some
@@ -1539,19 +1569,11 @@
left_type_info,
right_type_info,
overwrite_mode);
- if (left->reg().is(right->reg())) {
- __ test(left->reg(), Immediate(kSmiTagMask));
- } else {
- // Use the quotient register as a scratch for the tag check.
- if (!left_is_in_eax) __ mov(eax, left->reg());
- left_is_in_eax = false; // About to destroy the value in eax.
- __ or_(eax, Operand(right->reg()));
- ASSERT(kSmiTag == 0); // Adjust test if not the case.
- __ test(eax, Immediate(kSmiTagMask));
- }
- deferred->Branch(not_zero);
-
- if (!left_is_in_eax) __ mov(eax, left->reg());
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), edx,
+ left_type_info, right_type_info,
deferred);
+ if (!left_is_in_eax) {
+ __ mov(eax, left->reg());
+ }
// Sign extend eax into edx:eax.
__ cdq();
// Check for 0 divisor.
@@ -1674,8 +1696,8 @@
__ cmp(answer.reg(), 0xc0000000);
deferred->Branch(negative);
} else {
- CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
- left_type_info, right_type_info, deferred);
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(),
answer.reg(),
+ left_type_info, right_type_info,
deferred);
// Untag both operands.
__ mov(answer.reg(), left->reg());
@@ -1751,8 +1773,8 @@
left_type_info,
right_type_info,
overwrite_mode);
- CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
- left_type_info, right_type_info, deferred);
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), answer.reg(),
+ left_type_info, right_type_info, deferred);
__ mov(answer.reg(), left->reg());
switch (op) {
@@ -8974,40 +8996,6 @@
#undef __
#define __ ACCESS_MASM(masm)
-
-
-static void CheckTwoForSminess(MacroAssembler* masm,
- Register left, Register right, Register
scratch,
- TypeInfo left_info, TypeInfo right_info,
- DeferredInlineBinaryOperation* deferred) {
- if (left.is(right)) {
- if (!left_info.IsSmi()) {
- __ test(left, Immediate(kSmiTagMask));
- deferred->Branch(not_zero);
- } else {
- if (FLAG_debug_code) __ AbortIfNotSmi(left);
- }
- } else if (!left_info.IsSmi()) {
- if (!right_info.IsSmi()) {
- __ mov(scratch, left);
- __ or_(scratch, Operand(right));
- __ test(scratch, Immediate(kSmiTagMask));
- deferred->Branch(not_zero);
- } else {
- __ test(left, Immediate(kSmiTagMask));
- deferred->Branch(not_zero);
- if (FLAG_debug_code) __ AbortIfNotSmi(right);
- }
- } else {
- if (FLAG_debug_code) __ AbortIfNotSmi(left);
- if (!right_info.IsSmi()) {
- __ test(right, Immediate(kSmiTagMask));
- deferred->Branch(not_zero);
- } else {
- if (FLAG_debug_code) __ AbortIfNotSmi(right);
- }
- }
-}
Handle<String> Reference::GetName() {
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h Tue Jun 8 05:04:49 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h Wed Jun 9 04:15:54 2010
@@ -519,6 +519,16 @@
void GenericBinaryOperation(BinaryOperation* expr,
OverwriteMode overwrite_mode);
+ // Emits code sequence that jumps to deferred code if the inputs
+ // are not both smis. Cannot be in MacroAssembler because it takes
+ // advantage of TypeInfo to skip unneeded checks.
+ void JumpIfNotBothSmiUsingTypeInfo(Register left,
+ Register right,
+ Register scratch,
+ TypeInfo left_info,
+ TypeInfo right_info,
+ DeferredCode* deferred);
+
// If possible, combine two constant smi values using op to produce
// a smi result, and push it on the virtual frame, all at compile time.
// Returns true if it succeeds. Otherwise it has no effect.
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Mon Jun 7 00:12:00 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Wed Jun 9 04:15:54 2010
@@ -7131,6 +7131,25 @@
ASSERT(answer.is_valid());
return answer;
}
+
+
+void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left,
+ Register right,
+ TypeInfo left_info,
+ TypeInfo right_info,
+ DeferredCode* deferred) {
+ if (!left_info.IsSmi() && !right_info.IsSmi()) {
+ __ JumpIfNotBothSmi(left, right, deferred->entry_label());
+ } else if (!left_info.IsSmi()) {
+ __ JumpIfNotSmi(left, deferred->entry_label());
+ } else if (!right_info.IsSmi()) {
+ __ JumpIfNotSmi(right, deferred->entry_label());
+ }
+ if (FLAG_debug_code) {
+ __ AbortIfNotSmi(left);
+ __ AbortIfNotSmi(right);
+ }
+}
// Implements a binary operation using a deferred code object and some
@@ -7142,9 +7161,6 @@
// Copy the type info because left and right may be overwritten.
TypeInfo left_type_info = left->type_info();
TypeInfo right_type_info = right->type_info();
- USE(left_type_info);
- USE(right_type_info);
- // TODO(X64): Use type information in calculations.
Token::Value op = expr->op();
Result answer;
// Special handling of div and mod because they use fixed registers.
@@ -7221,7 +7237,8 @@
left->reg(),
right->reg(),
overwrite_mode);
- __ JumpIfNotBothSmi(left->reg(), right->reg(),
deferred->entry_label());
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(),
+ left_type_info, right_type_info,
deferred);
if (op == Token::DIV) {
__ SmiDiv(rax, left->reg(), right->reg(), deferred->entry_label());
@@ -7303,7 +7320,8 @@
}
}
} else {
- __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label());
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), rcx,
+ left_type_info, right_type_info,
deferred);
}
__ bind(&do_op);
@@ -7351,7 +7369,8 @@
left->reg(),
right->reg(),
overwrite_mode);
- __ JumpIfNotBothSmi(left->reg(), right->reg(), deferred->entry_label());
+ JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(),
+ left_type_info, right_type_info, deferred);
switch (op) {
case Token::ADD:
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h Tue Jun 8 05:04:49 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h Wed Jun 9 04:15:54 2010
@@ -477,6 +477,15 @@
void GenericBinaryOperation(BinaryOperation* expr,
OverwriteMode overwrite_mode);
+ // Emits code sequence that jumps to deferred code if the inputs
+ // are not both smis. Cannot be in MacroAssembler because it takes
+ // advantage of TypeInfo to skip unneeded checks.
+ void JumpIfNotBothSmiUsingTypeInfo(Register left,
+ Register right,
+ TypeInfo left_info,
+ TypeInfo right_info,
+ DeferredCode* deferred);
+
// If possible, combine two constant smi values using op to produce
// a smi result, and push it on the virtual frame, all at compile time.
// Returns true if it succeeds. Otherwise it has no effect.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev