Revision: 3416 Author: [email protected] Date: Fri Dec 4 01:58:05 2009 Log: String check for binary add on x64 and ARM
The checking for strings when performing binary add was missing on x64 and ARM. This is a prerequisite for adding string add in generated code for these two platforms. Review URL: http://codereview.chromium.org/465028 http://code.google.com/p/v8/source/detail?r=3416 Modified: /branches/bleeding_edge/src/arm/codegen-arm.cc /branches/bleeding_edge/src/x64/codegen-x64.cc ======================================= --- /branches/bleeding_edge/src/arm/codegen-arm.cc Thu Dec 3 02:24:16 2009 +++ /branches/bleeding_edge/src/arm/codegen-arm.cc Fri Dec 4 01:58:05 2009 @@ -5215,8 +5215,53 @@ // We jump to here if something goes wrong (one param is not a number of any // sort or new-space allocation fails). __ bind(&slow); + + // Push arguments to the stack __ push(r1); __ push(r0); + + if (Token::ADD == operation) { + // Test for string arguments before calling runtime. + // r1 : first argument + // r0 : second argument + // sp[0] : second argument + // sp[1] : first argument + + Label not_strings, not_string1, string1; + __ tst(r1, Operand(kSmiTagMask)); + __ b(eq, ¬_string1); + __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); + __ b(ge, ¬_string1); + + // First argument is a a string, test second. + __ tst(r0, Operand(kSmiTagMask)); + __ b(eq, &string1); + __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE); + __ b(ge, &string1); + + // First and second argument are strings. + __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); + + // Only first argument is a string. + __ bind(&string1); + __ mov(r0, Operand(2)); // Set number of arguments. + __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_JS); + + // First argument was not a string, test second. + __ bind(¬_string1); + __ tst(r0, Operand(kSmiTagMask)); + __ b(eq, ¬_strings); + __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE); + __ b(ge, ¬_strings); + + // Only second argument is a string. + __ b(¬_strings); + __ mov(r0, Operand(2)); // Set number of arguments. + __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_JS); + + __ bind(¬_strings); + } + __ mov(r0, Operand(1)); // Set number of arguments. __ InvokeBuiltin(builtin, JUMP_JS); // Tail call. No return. ======================================= --- /branches/bleeding_edge/src/x64/codegen-x64.cc Thu Dec 3 02:24:16 2009 +++ /branches/bleeding_edge/src/x64/codegen-x64.cc Fri Dec 4 01:58:05 2009 @@ -7777,9 +7777,47 @@ __ push(rcx); } switch (op_) { - case Token::ADD: + case Token::ADD: { + // Test for string arguments before calling runtime. + Label not_strings, both_strings, not_string1, string1; + Condition is_smi; + Result answer; + __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // First argument. + __ movq(rax, Operand(rsp, 1 * kPointerSize)); // Second argument. + is_smi = masm->CheckSmi(rdx); + __ j(is_smi, ¬_string1); + __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rdx); + __ j(above_equal, ¬_string1); + + // First argument is a a string, test second. + is_smi = masm->CheckSmi(rax); + __ j(is_smi, &string1); + __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax); + __ j(above_equal, &string1); + + // First and second argument are strings. + Runtime::Function* f = Runtime::FunctionForId(Runtime::kStringAdd); + __ TailCallRuntime(ExternalReference(f), 2, f->result_size); + + // Only first argument is a string. + __ bind(&string1); + __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION); + + // First argument was not a string, test second. + __ bind(¬_string1); + is_smi = masm->CheckSmi(rax); + __ j(is_smi, ¬_strings); + __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rax); + __ j(above_equal, ¬_strings); + + // Only second argument is a string. + __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION); + + __ bind(¬_strings); + // Neither argument is a string. __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); break; + } case Token::SUB: __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); break; -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
