Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index e6f46966517f37a78818bb0c4d4116b85fba628a..0fb827bb08fbbd49bf4e6067222407c7b6128a9f 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); |