From: fschneider@chromium.org Date: Mon, 28 Mar 2011 16:36:08 +0000 (+0000) Subject: Add binary-op stub variant to handle oddball objects more efficiently. X-Git-Tag: upstream/4.7.83~19787 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fb457a8b87ebb4197bca088409f4b029b2aeb4e2;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index c25d44522..6c1cccf74 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -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::GenerateHeapNumberStub(MacroAssembler* masm) { +void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { Label call_runtime; - ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); + 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; GenerateFPOperation(masm, false, &call_runtime, &call_runtime); __ bind(&call_runtime); diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h index 5615b7e68..1dde255cb 100644 --- a/src/arm/code-stubs-arm.h +++ b/src/arm/code-stubs-arm.h @@ -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); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 711616fc4..96faae991 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -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_) { diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h index 9e5f0a5de..31fa64512 100644 --- a/src/ia32/code-stubs-ia32.h +++ b/src/ia32/code-stubs-ia32.h @@ -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); diff --git a/src/ic.cc b/src/ic.cc index 01d4ca086..382b438a0 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -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 left, return STRING; } + // Check for oddball objects. + if (left->IsUndefined() && right->IsNumber()) return ODDBALL; + if (left->IsNumber() && right->IsUndefined()) return ODDBALL; + return GENERIC; } diff --git a/src/ic.h b/src/ic.h index f22666083..bb8a98138 100644 --- a/src/ic.h +++ b/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 }; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index e6f469665..0fb827bb0 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -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); diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h index 0d24af5f8..246650af4 100644 --- a/src/x64/code-stubs-x64.h +++ b/src/x64/code-stubs-x64.h @@ -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);