| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 BinaryOpStub_GenerateSmiCode( | 2155 BinaryOpStub_GenerateSmiCode( |
| 2156 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, | 2156 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, |
| 2157 mode_); | 2157 mode_); |
| 2158 } | 2158 } |
| 2159 | 2159 |
| 2160 // Code falls through if the result is not returned as either a smi or heap | 2160 // Code falls through if the result is not returned as either a smi or heap |
| 2161 // number. | 2161 // number. |
| 2162 GenerateTypeTransition(masm); | 2162 GenerateTypeTransition(masm); |
| 2163 | 2163 |
| 2164 __ bind(&call_runtime); | 2164 __ bind(&call_runtime); |
| 2165 GenerateRegisterArgsPush(masm); | 2165 { |
| 2166 GenerateCallRuntime(masm); | 2166 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2167 GenerateRegisterArgsPush(masm); |
| 2168 GenerateCallRuntime(masm); |
| 2169 } |
| 2170 __ Ret(); |
| 2167 } | 2171 } |
| 2168 | 2172 |
| 2169 | 2173 |
| 2170 void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { | 2174 void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { |
| 2171 Label call_runtime; | 2175 Label call_runtime; |
| 2172 ASSERT(left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING); | 2176 ASSERT(left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING); |
| 2173 ASSERT(op_ == Token::ADD); | 2177 ASSERT(op_ == Token::ADD); |
| 2174 // If both arguments are strings, call the string add stub. | 2178 // If both arguments are strings, call the string add stub. |
| 2175 // Otherwise, do a transition. | 2179 // Otherwise, do a transition. |
| 2176 | 2180 |
| 2177 // Registers containing left and right operands respectively. | 2181 // Registers containing left and right operands respectively. |
| 2178 Register left = r1; | 2182 Register left = r1; |
| 2179 Register right = r0; | 2183 Register right = r0; |
| 2180 | 2184 |
| 2181 // Test if left operand is a string. | 2185 // Test if left operand is a string. |
| 2182 __ JumpIfSmi(left, &call_runtime); | 2186 __ JumpIfSmi(left, &call_runtime); |
| 2183 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE); | 2187 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE); |
| 2184 __ b(ge, &call_runtime); | 2188 __ b(ge, &call_runtime); |
| 2185 | 2189 |
| 2186 // Test if right operand is a string. | 2190 // Test if right operand is a string. |
| 2187 __ JumpIfSmi(right, &call_runtime); | 2191 __ JumpIfSmi(right, &call_runtime); |
| 2188 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE); | 2192 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE); |
| 2189 __ b(ge, &call_runtime); | 2193 __ b(ge, &call_runtime); |
| 2190 | 2194 |
| 2191 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); | 2195 StringAddStub string_add_stub((StringAddFlags) |
| 2196 (ERECT_FRAME | NO_STRING_CHECK_IN_STUB)); |
| 2192 GenerateRegisterArgsPush(masm); | 2197 GenerateRegisterArgsPush(masm); |
| 2193 __ TailCallStub(&string_add_stub); | 2198 __ TailCallStub(&string_add_stub); |
| 2194 | 2199 |
| 2195 __ bind(&call_runtime); | 2200 __ bind(&call_runtime); |
| 2196 GenerateTypeTransition(masm); | 2201 GenerateTypeTransition(masm); |
| 2197 } | 2202 } |
| 2198 | 2203 |
| 2199 | 2204 |
| 2200 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 2205 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| 2201 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32); | 2206 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2452 // We never expect DIV to yield an integer result, so we always generate | 2457 // We never expect DIV to yield an integer result, so we always generate |
| 2453 // type transition code for DIV operations expecting an integer result: the | 2458 // type transition code for DIV operations expecting an integer result: the |
| 2454 // code will fall through to this type transition. | 2459 // code will fall through to this type transition. |
| 2455 if (transition.is_linked() || | 2460 if (transition.is_linked() || |
| 2456 ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) { | 2461 ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) { |
| 2457 __ bind(&transition); | 2462 __ bind(&transition); |
| 2458 GenerateTypeTransition(masm); | 2463 GenerateTypeTransition(masm); |
| 2459 } | 2464 } |
| 2460 | 2465 |
| 2461 __ bind(&call_runtime); | 2466 __ bind(&call_runtime); |
| 2462 GenerateRegisterArgsPush(masm); | 2467 { |
| 2463 GenerateCallRuntime(masm); | 2468 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2469 GenerateRegisterArgsPush(masm); |
| 2470 GenerateCallRuntime(masm); |
| 2471 } |
| 2472 __ Ret(); |
| 2464 } | 2473 } |
| 2465 | 2474 |
| 2466 | 2475 |
| 2467 void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { | 2476 void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { |
| 2468 Label call_runtime; | 2477 Label call_runtime; |
| 2469 | 2478 |
| 2470 if (op_ == Token::ADD) { | 2479 if (op_ == Token::ADD) { |
| 2471 // Handle string addition here, because it is the only operation | 2480 // Handle string addition here, because it is the only operation |
| 2472 // that does not do a ToNumber conversion on the operands. | 2481 // that does not do a ToNumber conversion on the operands. |
| 2473 GenerateAddStrings(masm); | 2482 GenerateAddStrings(masm); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2500 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { | 2509 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { |
| 2501 Label call_runtime, transition; | 2510 Label call_runtime, transition; |
| 2502 BinaryOpStub_GenerateFPOperation( | 2511 BinaryOpStub_GenerateFPOperation( |
| 2503 masm, left_type_, right_type_, false, | 2512 masm, left_type_, right_type_, false, |
| 2504 &transition, &call_runtime, &transition, op_, mode_); | 2513 &transition, &call_runtime, &transition, op_, mode_); |
| 2505 | 2514 |
| 2506 __ bind(&transition); | 2515 __ bind(&transition); |
| 2507 GenerateTypeTransition(masm); | 2516 GenerateTypeTransition(masm); |
| 2508 | 2517 |
| 2509 __ bind(&call_runtime); | 2518 __ bind(&call_runtime); |
| 2510 GenerateRegisterArgsPush(masm); | 2519 { |
| 2511 GenerateCallRuntime(masm); | 2520 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2521 GenerateRegisterArgsPush(masm); |
| 2522 GenerateCallRuntime(masm); |
| 2523 } |
| 2524 __ Ret(); |
| 2512 } | 2525 } |
| 2513 | 2526 |
| 2514 | 2527 |
| 2515 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 2528 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
| 2516 Label call_runtime, call_string_add_or_runtime, transition; | 2529 Label call_runtime, call_string_add_or_runtime, transition; |
| 2517 | 2530 |
| 2518 BinaryOpStub_GenerateSmiCode( | 2531 BinaryOpStub_GenerateSmiCode( |
| 2519 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_); | 2532 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_); |
| 2520 | 2533 |
| 2521 BinaryOpStub_GenerateFPOperation( | 2534 BinaryOpStub_GenerateFPOperation( |
| 2522 masm, left_type_, right_type_, false, | 2535 masm, left_type_, right_type_, false, |
| 2523 &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_); | 2536 &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_); |
| 2524 | 2537 |
| 2525 __ bind(&transition); | 2538 __ bind(&transition); |
| 2526 GenerateTypeTransition(masm); | 2539 GenerateTypeTransition(masm); |
| 2527 | 2540 |
| 2528 __ bind(&call_string_add_or_runtime); | 2541 __ bind(&call_string_add_or_runtime); |
| 2529 if (op_ == Token::ADD) { | 2542 if (op_ == Token::ADD) { |
| 2530 GenerateAddStrings(masm); | 2543 GenerateAddStrings(masm); |
| 2531 } | 2544 } |
| 2532 | 2545 |
| 2533 __ bind(&call_runtime); | 2546 __ bind(&call_runtime); |
| 2534 GenerateRegisterArgsPush(masm); | 2547 { |
| 2535 GenerateCallRuntime(masm); | 2548 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2549 GenerateRegisterArgsPush(masm); |
| 2550 GenerateCallRuntime(masm); |
| 2551 } |
| 2552 __ Ret(); |
| 2536 } | 2553 } |
| 2537 | 2554 |
| 2538 | 2555 |
| 2539 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { | 2556 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { |
| 2540 ASSERT(op_ == Token::ADD); | 2557 ASSERT(op_ == Token::ADD); |
| 2541 Label left_not_string, call_runtime; | 2558 Label left_not_string, call_runtime; |
| 2542 | 2559 |
| 2543 Register left = r1; | 2560 Register left = r1; |
| 2544 Register right = r0; | 2561 Register right = r0; |
| 2545 | 2562 |
| 2546 // Check if left argument is a string. | 2563 // Check if left argument is a string. |
| 2547 __ JumpIfSmi(left, &left_not_string); | 2564 __ JumpIfSmi(left, &left_not_string); |
| 2548 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE); | 2565 __ CompareObjectType(left, r2, r2, FIRST_NONSTRING_TYPE); |
| 2549 __ b(ge, &left_not_string); | 2566 __ b(ge, &left_not_string); |
| 2550 | 2567 |
| 2551 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | 2568 StringAddStub string_add_left_stub((StringAddFlags) |
| 2569 (ERECT_FRAME | NO_STRING_CHECK_LEFT_IN_STUB)); |
| 2552 GenerateRegisterArgsPush(masm); | 2570 GenerateRegisterArgsPush(masm); |
| 2553 __ TailCallStub(&string_add_left_stub); | 2571 __ TailCallStub(&string_add_left_stub); |
| 2554 | 2572 |
| 2555 // Left operand is not a string, test right. | 2573 // Left operand is not a string, test right. |
| 2556 __ bind(&left_not_string); | 2574 __ bind(&left_not_string); |
| 2557 __ JumpIfSmi(right, &call_runtime); | 2575 __ JumpIfSmi(right, &call_runtime); |
| 2558 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE); | 2576 __ CompareObjectType(right, r2, r2, FIRST_NONSTRING_TYPE); |
| 2559 __ b(ge, &call_runtime); | 2577 __ b(ge, &call_runtime); |
| 2560 | 2578 |
| 2561 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | 2579 StringAddStub string_add_right_stub((StringAddFlags) |
| 2580 (ERECT_FRAME | NO_STRING_CHECK_RIGHT_IN_STUB)); |
| 2562 GenerateRegisterArgsPush(masm); | 2581 GenerateRegisterArgsPush(masm); |
| 2563 __ TailCallStub(&string_add_right_stub); | 2582 __ TailCallStub(&string_add_right_stub); |
| 2564 | 2583 |
| 2565 // At least one argument is not a string. | 2584 // At least one argument is not a string. |
| 2566 __ bind(&call_runtime); | 2585 __ bind(&call_runtime); |
| 2567 } | 2586 } |
| 2568 | 2587 |
| 2569 | 2588 |
| 2570 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, | 2589 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, |
| 2571 Register result, | 2590 Register result, |
| (...skipping 3243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5815 | 5834 |
| 5816 // Stack on entry: | 5835 // Stack on entry: |
| 5817 // sp[0]: second argument (right). | 5836 // sp[0]: second argument (right). |
| 5818 // sp[4]: first argument (left). | 5837 // sp[4]: first argument (left). |
| 5819 | 5838 |
| 5820 // Load the two arguments. | 5839 // Load the two arguments. |
| 5821 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument. | 5840 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // First argument. |
| 5822 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument. | 5841 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // Second argument. |
| 5823 | 5842 |
| 5824 // Make sure that both arguments are strings if not known in advance. | 5843 // Make sure that both arguments are strings if not known in advance. |
| 5825 if (flags_ == NO_STRING_ADD_FLAGS) { | 5844 if ((flags_ & NO_STRING_ADD_FLAGS) != 0) { |
| 5826 __ JumpIfEitherSmi(r0, r1, &call_runtime); | 5845 __ JumpIfEitherSmi(r0, r1, &call_runtime); |
| 5827 // Load instance types. | 5846 // Load instance types. |
| 5828 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); | 5847 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 5829 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); | 5848 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| 5830 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); | 5849 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
| 5831 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); | 5850 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); |
| 5832 STATIC_ASSERT(kStringTag == 0); | 5851 STATIC_ASSERT(kStringTag == 0); |
| 5833 // If either is not a string, go to runtime. | 5852 // If either is not a string, go to runtime. |
| 5834 __ tst(r4, Operand(kIsNotStringMask)); | 5853 __ tst(r4, Operand(kIsNotStringMask)); |
| 5835 __ tst(r5, Operand(kIsNotStringMask), eq); | 5854 __ tst(r5, Operand(kIsNotStringMask), eq); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6107 // r6: first character of result. | 6126 // r6: first character of result. |
| 6108 StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, false); | 6127 StringHelper::GenerateCopyCharacters(masm, r6, r7, r2, r4, false); |
| 6109 // r6: next character of result. | 6128 // r6: next character of result. |
| 6110 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false); | 6129 StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false); |
| 6111 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); | 6130 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); |
| 6112 __ add(sp, sp, Operand(2 * kPointerSize)); | 6131 __ add(sp, sp, Operand(2 * kPointerSize)); |
| 6113 __ Ret(); | 6132 __ Ret(); |
| 6114 | 6133 |
| 6115 // Just jump to runtime to add the two strings. | 6134 // Just jump to runtime to add the two strings. |
| 6116 __ bind(&call_runtime); | 6135 __ bind(&call_runtime); |
| 6117 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 6136 if ((flags_ & ERECT_FRAME) != 0) { |
| 6137 GenerateRegisterArgsPop(masm); |
| 6138 // Build a frame |
| 6139 { |
| 6140 FrameScope scope(masm, StackFrame::INTERNAL); |
| 6141 GenerateRegisterArgsPush(masm); |
| 6142 __ CallRuntime(Runtime::kStringAdd, 2); |
| 6143 } |
| 6144 __ Ret(); |
| 6145 } else { |
| 6146 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 6147 } |
| 6118 | 6148 |
| 6119 if (call_builtin.is_linked()) { | 6149 if (call_builtin.is_linked()) { |
| 6120 __ bind(&call_builtin); | 6150 __ bind(&call_builtin); |
| 6121 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); | 6151 if ((flags_ & ERECT_FRAME) != 0) { |
| 6152 GenerateRegisterArgsPop(masm); |
| 6153 // Build a frame |
| 6154 { |
| 6155 FrameScope scope(masm, StackFrame::INTERNAL); |
| 6156 GenerateRegisterArgsPush(masm); |
| 6157 __ InvokeBuiltin(builtin_id, CALL_FUNCTION); |
| 6158 } |
| 6159 __ Ret(); |
| 6160 } else { |
| 6161 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); |
| 6162 } |
| 6122 } | 6163 } |
| 6123 } | 6164 } |
| 6124 | 6165 |
| 6125 | 6166 |
| 6167 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 6168 __ push(r0); |
| 6169 __ push(r1); |
| 6170 } |
| 6171 |
| 6172 |
| 6173 void StringAddStub::GenerateRegisterArgsPop(MacroAssembler* masm) { |
| 6174 __ pop(r1); |
| 6175 __ pop(r0); |
| 6176 } |
| 6177 |
| 6178 |
| 6126 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, | 6179 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, |
| 6127 int stack_offset, | 6180 int stack_offset, |
| 6128 Register arg, | 6181 Register arg, |
| 6129 Register scratch1, | 6182 Register scratch1, |
| 6130 Register scratch2, | 6183 Register scratch2, |
| 6131 Register scratch3, | 6184 Register scratch3, |
| 6132 Register scratch4, | 6185 Register scratch4, |
| 6133 Label* slow) { | 6186 Label* slow) { |
| 6134 // First check if the argument is already a string. | 6187 // First check if the argument is already a string. |
| 6135 Label not_string, done; | 6188 Label not_string, done; |
| (...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7405 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 7458 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 7406 } | 7459 } |
| 7407 } | 7460 } |
| 7408 | 7461 |
| 7409 | 7462 |
| 7410 #undef __ | 7463 #undef __ |
| 7411 | 7464 |
| 7412 } } // namespace v8::internal | 7465 } } // namespace v8::internal |
| 7413 | 7466 |
| 7414 #endif // V8_TARGET_ARCH_ARM | 7467 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |