| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 7e8ca78a9fc4d2ac9b62061217d9f481f5ba9b26..af09c369b0182504a099cdb6661e557a2acbc326 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -372,6 +372,9 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
|
| case TRBinaryOpIC::ODDBALL:
|
| GenerateOddballStub(masm);
|
| break;
|
| + case TRBinaryOpIC::BOTH_STRING:
|
| + GenerateBothStringStub(masm);
|
| + break;
|
| case TRBinaryOpIC::STRING:
|
| GenerateStringStub(masm);
|
| break;
|
| @@ -771,6 +774,36 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
|
| }
|
|
|
|
|
| +void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
|
| + Label call_runtime;
|
| + ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING);
|
| + ASSERT(op_ == Token::ADD);
|
| + // If both arguments are strings, call the string add stub.
|
| + // Otherwise, do a transition.
|
| +
|
| + // Registers containing left and right operands respectively.
|
| + Register left = rdx;
|
| + Register right = rax;
|
| +
|
| + // Test if left operand is a string.
|
| + __ JumpIfSmi(left, &call_runtime);
|
| + __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx);
|
| + __ j(above_equal, &call_runtime);
|
| +
|
| + // Test if right operand is a string.
|
| + __ JumpIfSmi(right, &call_runtime);
|
| + __ CmpObjectType(right, FIRST_NONSTRING_TYPE, rcx);
|
| + __ j(above_equal, &call_runtime);
|
| +
|
| + StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
|
| + GenerateRegisterArgsPush(masm);
|
| + __ TailCallStub(&string_add_stub);
|
| +
|
| + __ bind(&call_runtime);
|
| + GenerateTypeTransition(masm);
|
| +}
|
| +
|
| +
|
| void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
|
| Label call_runtime;
|
|
|
|
|