Add binary-op stub variant to handle oddball objects more efficiently.
Review URL: http://codereview.chromium.org/6744006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7396 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
91fcaa9a0c
commit
fb457a8b87
@ -2884,6 +2884,9 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
|
||||
case TRBinaryOpIC::HEAP_NUMBER:
|
||||
GenerateHeapNumberStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::ODDBALL:
|
||||
GenerateOddballStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::STRING:
|
||||
GenerateStringStub(masm);
|
||||
break;
|
||||
@ -3606,10 +3609,41 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
|
||||
Label call_runtime;
|
||||
|
||||
if (op_ == Token::ADD) {
|
||||
// Handle string addition here, because it is the only operation
|
||||
// that does not do a ToNumber conversion on the operands.
|
||||
GenerateAddStrings(masm);
|
||||
}
|
||||
|
||||
// Convert oddball arguments to numbers.
|
||||
Label check, done;
|
||||
__ CompareRoot(r1, Heap::kUndefinedValueRootIndex);
|
||||
__ b(ne, &check);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ mov(r1, Operand(Smi::FromInt(0)));
|
||||
} else {
|
||||
__ LoadRoot(r1, Heap::kNanValueRootIndex);
|
||||
}
|
||||
__ jmp(&done);
|
||||
__ bind(&check);
|
||||
__ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
|
||||
__ b(ne, &done);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ mov(r0, Operand(Smi::FromInt(0)));
|
||||
} else {
|
||||
__ LoadRoot(r0, Heap::kNanValueRootIndex);
|
||||
}
|
||||
__ bind(&done);
|
||||
|
||||
GenerateHeapNumberStub(masm);
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
|
||||
Label call_runtime;
|
||||
ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER);
|
||||
|
||||
GenerateFPOperation(masm, false, &call_runtime, &call_runtime);
|
||||
|
||||
__ bind(&call_runtime);
|
||||
|
@ -311,6 +311,7 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
||||
void GenerateSmiStub(MacroAssembler* masm);
|
||||
void GenerateInt32Stub(MacroAssembler* masm);
|
||||
void GenerateHeapNumberStub(MacroAssembler* masm);
|
||||
void GenerateOddballStub(MacroAssembler* masm);
|
||||
void GenerateStringStub(MacroAssembler* masm);
|
||||
void GenerateGenericStub(MacroAssembler* masm);
|
||||
void GenerateAddStrings(MacroAssembler* masm);
|
||||
|
@ -1359,6 +1359,9 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
|
||||
case TRBinaryOpIC::HEAP_NUMBER:
|
||||
GenerateHeapNumberStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::ODDBALL:
|
||||
GenerateOddballStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::STRING:
|
||||
GenerateStringStub(masm);
|
||||
break;
|
||||
@ -2024,9 +2027,41 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
|
||||
Label call_runtime;
|
||||
|
||||
if (op_ == Token::ADD) {
|
||||
// Handle string addition here, because it is the only operation
|
||||
// that does not do a ToNumber conversion on the operands.
|
||||
GenerateAddStrings(masm);
|
||||
}
|
||||
|
||||
// Convert odd ball arguments to numbers.
|
||||
NearLabel check, done;
|
||||
__ cmp(edx, FACTORY->undefined_value());
|
||||
__ j(not_equal, &check);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ xor_(edx, Operand(edx));
|
||||
} else {
|
||||
__ mov(edx, Immediate(FACTORY->nan_value()));
|
||||
}
|
||||
__ jmp(&done);
|
||||
__ bind(&check);
|
||||
__ cmp(eax, FACTORY->undefined_value());
|
||||
__ j(not_equal, &done);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ xor_(eax, Operand(eax));
|
||||
} else {
|
||||
__ mov(eax, Immediate(FACTORY->nan_value()));
|
||||
}
|
||||
__ bind(&done);
|
||||
|
||||
GenerateHeapNumberStub(masm);
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
|
||||
Label call_runtime;
|
||||
ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER);
|
||||
|
||||
// Floating point case.
|
||||
switch (op_) {
|
||||
|
@ -306,6 +306,7 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
||||
void GenerateSmiStub(MacroAssembler* masm);
|
||||
void GenerateInt32Stub(MacroAssembler* masm);
|
||||
void GenerateHeapNumberStub(MacroAssembler* masm);
|
||||
void GenerateOddballStub(MacroAssembler* masm);
|
||||
void GenerateStringStub(MacroAssembler* masm);
|
||||
void GenerateGenericStub(MacroAssembler* masm);
|
||||
void GenerateAddStrings(MacroAssembler* masm);
|
||||
|
@ -2131,6 +2131,7 @@ const char* TRBinaryOpIC::GetName(TypeInfo type_info) {
|
||||
case SMI: return "SMI";
|
||||
case INT32: return "Int32s";
|
||||
case HEAP_NUMBER: return "HeapNumbers";
|
||||
case ODDBALL: return "Oddball";
|
||||
case STRING: return "Strings";
|
||||
case GENERIC: return "Generic";
|
||||
default: return "Invalid";
|
||||
@ -2145,6 +2146,7 @@ TRBinaryOpIC::State TRBinaryOpIC::ToState(TypeInfo type_info) {
|
||||
case SMI:
|
||||
case INT32:
|
||||
case HEAP_NUMBER:
|
||||
case ODDBALL:
|
||||
case STRING:
|
||||
return MONOMORPHIC;
|
||||
case GENERIC:
|
||||
@ -2192,6 +2194,10 @@ TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left,
|
||||
return STRING;
|
||||
}
|
||||
|
||||
// Check for oddball objects.
|
||||
if (left->IsUndefined() && right->IsNumber()) return ODDBALL;
|
||||
if (left->IsNumber() && right->IsUndefined()) return ODDBALL;
|
||||
|
||||
return GENERIC;
|
||||
}
|
||||
|
||||
|
1
src/ic.h
1
src/ic.h
@ -610,6 +610,7 @@ class TRBinaryOpIC: public IC {
|
||||
SMI,
|
||||
INT32,
|
||||
HEAP_NUMBER,
|
||||
ODDBALL,
|
||||
STRING, // Only used for addition operation. At least one string operand.
|
||||
GENERIC
|
||||
};
|
||||
|
@ -1062,6 +1062,9 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
|
||||
case TRBinaryOpIC::HEAP_NUMBER:
|
||||
GenerateHeapNumberStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::ODDBALL:
|
||||
GenerateOddballStub(masm);
|
||||
break;
|
||||
case TRBinaryOpIC::STRING:
|
||||
GenerateStringStub(masm);
|
||||
break;
|
||||
@ -1438,6 +1441,39 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
|
||||
Label call_runtime;
|
||||
|
||||
if (op_ == Token::ADD) {
|
||||
// Handle string addition here, because it is the only operation
|
||||
// that does not do a ToNumber conversion on the operands.
|
||||
GenerateStringAddCode(masm);
|
||||
}
|
||||
|
||||
// Convert oddball arguments to numbers.
|
||||
NearLabel check, done;
|
||||
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
|
||||
__ j(not_equal, &check);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ xor_(rdx, rdx);
|
||||
} else {
|
||||
__ LoadRoot(rdx, Heap::kNanValueRootIndex);
|
||||
}
|
||||
__ jmp(&done);
|
||||
__ bind(&check);
|
||||
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
|
||||
__ j(not_equal, &done);
|
||||
if (Token::IsBitOp(op_)) {
|
||||
__ xor_(rax, rax);
|
||||
} else {
|
||||
__ LoadRoot(rax, Heap::kNanValueRootIndex);
|
||||
}
|
||||
__ bind(&done);
|
||||
|
||||
GenerateHeapNumberStub(masm);
|
||||
}
|
||||
|
||||
|
||||
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
|
||||
Label gc_required, not_number;
|
||||
GenerateFloatingPointCode(masm, &gc_required, ¬_number);
|
||||
|
@ -289,6 +289,7 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
||||
void GenerateSmiStub(MacroAssembler* masm);
|
||||
void GenerateInt32Stub(MacroAssembler* masm);
|
||||
void GenerateHeapNumberStub(MacroAssembler* masm);
|
||||
void GenerateOddballStub(MacroAssembler* masm);
|
||||
void GenerateStringStub(MacroAssembler* masm);
|
||||
void GenerateGenericStub(MacroAssembler* masm);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user