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 |