| Index: src/ia32/code-stubs-ia32.cc
|
| ===================================================================
|
| --- src/ia32/code-stubs-ia32.cc (revision 6291)
|
| +++ src/ia32/code-stubs-ia32.cc (working copy)
|
| @@ -1773,12 +1773,40 @@
|
|
|
|
|
| void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
|
| + Label call_runtime;
|
| ASSERT(operands_type_ == TRBinaryOpIC::STRING);
|
| ASSERT(op_ == Token::ADD);
|
| + // If one of the arguments is a string, call the string add stub.
|
| + // Otherwise, transition to the generic TRBinaryOpIC type.
|
|
|
| - // Try to add arguments as strings, otherwise, transition to the generic
|
| - // TRBinaryOpIC type.
|
| - GenerateAddStrings(masm);
|
| + // Registers containing left and right operands respectively.
|
| + Register left = edx;
|
| + Register right = eax;
|
| +
|
| + // Test if left operand is a string.
|
| + NearLabel left_not_string;
|
| + __ test(left, Immediate(kSmiTagMask));
|
| + __ j(zero, &left_not_string);
|
| + __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
|
| + __ j(above_equal, &left_not_string);
|
| +
|
| + StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
|
| + GenerateRegisterArgsPush(masm);
|
| + __ TailCallStub(&string_add_left_stub);
|
| +
|
| + // Left operand is not a string, test right.
|
| + __ bind(&left_not_string);
|
| + __ test(right, Immediate(kSmiTagMask));
|
| + __ j(zero, &call_runtime);
|
| + __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
|
| + __ j(above_equal, &call_runtime);
|
| +
|
| + StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
|
| + GenerateRegisterArgsPush(masm);
|
| + __ TailCallStub(&string_add_right_stub);
|
| +
|
| + // Neither argument is a string.
|
| + __ bind(&call_runtime);
|
| GenerateTypeTransition(masm);
|
| }
|
|
|
| @@ -1939,7 +1967,49 @@
|
| // If an allocation fails, or SHR or MOD hit a hard case,
|
| // use the runtime system to get the correct result.
|
| __ bind(&call_runtime);
|
| - GenerateCallRuntime(masm);
|
| +
|
| + switch (op_) {
|
| + case Token::ADD:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SUB:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
|
| + break;
|
| + case Token::MUL:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
|
| + break;
|
| + case Token::DIV:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
|
| + break;
|
| + case Token::MOD:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_OR:
|
| + __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_AND:
|
| + __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_XOR:
|
| + __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SAR:
|
| + __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SHL:
|
| + __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SHR:
|
| + __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| @@ -2079,7 +2149,49 @@
|
| // If an allocation fails, or SHR or MOD hit a hard case,
|
| // use the runtime system to get the correct result.
|
| __ bind(&call_runtime);
|
| - GenerateCallRuntime(masm);
|
| +
|
| + switch (op_) {
|
| + case Token::ADD:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SUB:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
|
| + break;
|
| + case Token::MUL:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
|
| + break;
|
| + case Token::DIV:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
|
| + break;
|
| + case Token::MOD:
|
| + GenerateRegisterArgsPush(masm);
|
| + __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_OR:
|
| + __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_AND:
|
| + __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
|
| + break;
|
| + case Token::BIT_XOR:
|
| + __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SAR:
|
| + __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SHL:
|
| + __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
|
| + break;
|
| + case Token::SHR:
|
| + __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| @@ -2093,8 +2205,8 @@
|
| case Token::SUB:
|
| case Token::MUL:
|
| case Token::DIV:
|
| + break;
|
| case Token::MOD:
|
| - break;
|
| case Token::BIT_OR:
|
| case Token::BIT_AND:
|
| case Token::BIT_XOR:
|
| @@ -2160,7 +2272,7 @@
|
| }
|
| case Token::BIT_OR:
|
| case Token::BIT_AND:
|
| - case Token::BIT_XOR:
|
| + case Token::BIT_XOR:
|
| case Token::SAR:
|
| case Token::SHL:
|
| case Token::SHR: {
|
| @@ -2233,56 +2345,41 @@
|
| // If all else fails, use the runtime system to get the correct
|
| // result.
|
| __ bind(&call_runtime);
|
| + switch (op_) {
|
| + case Token::ADD: {
|
| + GenerateRegisterArgsPush(masm);
|
| + // Test for string arguments before calling runtime.
|
| + // Registers containing left and right operands respectively.
|
| + Register lhs, rhs;
|
| + lhs = edx;
|
| + rhs = eax;
|
|
|
| - // Try to add strings before calling runtime.
|
| - if (op_ == Token::ADD) {
|
| - GenerateAddStrings(masm);
|
| - }
|
| + // Test if left operand is a string.
|
| + NearLabel lhs_not_string;
|
| + __ test(lhs, Immediate(kSmiTagMask));
|
| + __ j(zero, &lhs_not_string);
|
| + __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx);
|
| + __ j(above_equal, &lhs_not_string);
|
|
|
| - // Generate the runtime call.
|
| - GenerateCallRuntime(masm);
|
| -}
|
| + StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
|
| + __ TailCallStub(&string_add_left_stub);
|
|
|
| + NearLabel call_add_runtime;
|
| + // Left operand is not a string, test right.
|
| + __ bind(&lhs_not_string);
|
| + __ test(rhs, Immediate(kSmiTagMask));
|
| + __ j(zero, &call_add_runtime);
|
| + __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx);
|
| + __ j(above_equal, &call_add_runtime);
|
|
|
| -void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
|
| - // If one of the arguments is a string, call the string add stub.
|
| - // Registers containing left and right operands respectively.
|
| - NearLabel left_not_string, neither_string;
|
| - Register left = edx;
|
| - Register right = eax;
|
| + StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
|
| + __ TailCallStub(&string_add_right_stub);
|
|
|
| - // Test if left operand is a string.
|
| - __ test(left, Immediate(kSmiTagMask));
|
| - __ j(zero, &left_not_string);
|
| - __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
|
| - __ j(above_equal, &left_not_string);
|
| -
|
| - StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
|
| - GenerateRegisterArgsPush(masm);
|
| - __ TailCallStub(&string_add_left_stub);
|
| -
|
| - // Left operand is not a string, test right.
|
| - __ bind(&left_not_string);
|
| - __ test(right, Immediate(kSmiTagMask));
|
| - __ j(zero, &neither_string);
|
| - __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
|
| - __ j(above_equal, &neither_string);
|
| -
|
| - StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
|
| - GenerateRegisterArgsPush(masm);
|
| - __ TailCallStub(&string_add_right_stub);
|
| -
|
| - // Neither argument is a string.
|
| - __ bind(&neither_string);
|
| -}
|
| -
|
| -
|
| -void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
|
| - switch (op_) {
|
| - case Token::ADD:
|
| - GenerateRegisterArgsPush(masm);
|
| + // Neither argument is a string.
|
| + __ bind(&call_add_runtime);
|
| __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
|
| break;
|
| + }
|
| case Token::SUB:
|
| GenerateRegisterArgsPush(masm);
|
| __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
|
| @@ -2296,7 +2393,6 @@
|
| __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
|
| break;
|
| case Token::MOD:
|
| - GenerateRegisterArgsPush(masm);
|
| __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
|
| break;
|
| case Token::BIT_OR:
|
|
|