| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 2538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2550 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 2550 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 2551 __ pop(pc); | 2551 __ pop(pc); |
| 2552 } | 2552 } |
| 2553 | 2553 |
| 2554 | 2554 |
| 2555 void CEntryStub::GenerateCore(MacroAssembler* masm, | 2555 void CEntryStub::GenerateCore(MacroAssembler* masm, |
| 2556 Label* throw_normal_exception, | 2556 Label* throw_normal_exception, |
| 2557 Label* throw_termination_exception, | 2557 Label* throw_termination_exception, |
| 2558 Label* throw_out_of_memory_exception, | 2558 Label* throw_out_of_memory_exception, |
| 2559 bool do_gc, | 2559 bool do_gc, |
| 2560 bool always_allocate, | 2560 bool always_allocate) { |
| 2561 int frame_alignment_skew) { | |
| 2562 // r0: result parameter for PerformGC, if any | 2561 // r0: result parameter for PerformGC, if any |
| 2563 // r4: number of arguments including receiver (C callee-saved) | 2562 // r4: number of arguments including receiver (C callee-saved) |
| 2564 // r5: pointer to builtin function (C callee-saved) | 2563 // r5: pointer to builtin function (C callee-saved) |
| 2565 // r6: pointer to the first argument (C callee-saved) | 2564 // r6: pointer to the first argument (C callee-saved) |
| 2566 | 2565 |
| 2567 if (do_gc) { | 2566 if (do_gc) { |
| 2568 // Passing r0. | 2567 // Passing r0. |
| 2569 __ PrepareCallCFunction(1, r1); | 2568 __ PrepareCallCFunction(1, r1); |
| 2570 __ CallCFunction(ExternalReference::perform_gc_function(), 1); | 2569 __ CallCFunction(ExternalReference::perform_gc_function(), 1); |
| 2571 } | 2570 } |
| 2572 | 2571 |
| 2573 ExternalReference scope_depth = | 2572 ExternalReference scope_depth = |
| 2574 ExternalReference::heap_always_allocate_scope_depth(); | 2573 ExternalReference::heap_always_allocate_scope_depth(); |
| 2575 if (always_allocate) { | 2574 if (always_allocate) { |
| 2576 __ mov(r0, Operand(scope_depth)); | 2575 __ mov(r0, Operand(scope_depth)); |
| 2577 __ ldr(r1, MemOperand(r0)); | 2576 __ ldr(r1, MemOperand(r0)); |
| 2578 __ add(r1, r1, Operand(1)); | 2577 __ add(r1, r1, Operand(1)); |
| 2579 __ str(r1, MemOperand(r0)); | 2578 __ str(r1, MemOperand(r0)); |
| 2580 } | 2579 } |
| 2581 | 2580 |
| 2582 // Call C built-in. | 2581 // Call C built-in. |
| 2583 // r0 = argc, r1 = argv | 2582 // r0 = argc, r1 = argv |
| 2584 __ mov(r0, Operand(r4)); | 2583 __ mov(r0, Operand(r4)); |
| 2585 __ mov(r1, Operand(r6)); | 2584 __ mov(r1, Operand(r6)); |
| 2586 | 2585 |
| 2586 #if defined(V8_HOST_ARCH_ARM) |
| 2587 int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 2587 int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
| 2588 int frame_alignment_mask = frame_alignment - 1; | 2588 int frame_alignment_mask = frame_alignment - 1; |
| 2589 #if defined(V8_HOST_ARCH_ARM) | |
| 2590 if (FLAG_debug_code) { | 2589 if (FLAG_debug_code) { |
| 2591 if (frame_alignment > kPointerSize) { | 2590 if (frame_alignment > kPointerSize) { |
| 2592 Label alignment_as_expected; | 2591 Label alignment_as_expected; |
| 2593 ASSERT(IsPowerOf2(frame_alignment)); | 2592 ASSERT(IsPowerOf2(frame_alignment)); |
| 2594 __ sub(r2, sp, Operand(frame_alignment_skew)); | |
| 2595 __ tst(r2, Operand(frame_alignment_mask)); | 2593 __ tst(r2, Operand(frame_alignment_mask)); |
| 2596 __ b(eq, &alignment_as_expected); | 2594 __ b(eq, &alignment_as_expected); |
| 2597 // Don't use Check here, as it will call Runtime_Abort re-entering here. | 2595 // Don't use Check here, as it will call Runtime_Abort re-entering here. |
| 2598 __ stop("Unexpected alignment"); | 2596 __ stop("Unexpected alignment"); |
| 2599 __ bind(&alignment_as_expected); | 2597 __ bind(&alignment_as_expected); |
| 2600 } | 2598 } |
| 2601 } | 2599 } |
| 2602 #endif | 2600 #endif |
| 2603 | 2601 |
| 2604 // Just before the call (jump) below lr is pushed, so the actual alignment is | |
| 2605 // adding one to the current skew. | |
| 2606 int alignment_before_call = | |
| 2607 (frame_alignment_skew + kPointerSize) & frame_alignment_mask; | |
| 2608 if (alignment_before_call > 0) { | |
| 2609 // Push until the alignment before the call is met. | |
| 2610 __ mov(r2, Operand(0, RelocInfo::NONE)); | |
| 2611 for (int i = alignment_before_call; | |
| 2612 (i & frame_alignment_mask) != 0; | |
| 2613 i += kPointerSize) { | |
| 2614 __ push(r2); | |
| 2615 } | |
| 2616 } | |
| 2617 | |
| 2618 // TODO(1242173): To let the GC traverse the return address of the exit | 2602 // TODO(1242173): To let the GC traverse the return address of the exit |
| 2619 // frames, we need to know where the return address is. Right now, | 2603 // frames, we need to know where the return address is. Right now, |
| 2620 // we push it on the stack to be able to find it again, but we never | 2604 // we store it on the stack to be able to find it again, but we never |
| 2621 // restore from it in case of changes, which makes it impossible to | 2605 // restore from it in case of changes, which makes it impossible to |
| 2622 // support moving the C entry code stub. This should be fixed, but currently | 2606 // support moving the C entry code stub. This should be fixed, but currently |
| 2623 // this is OK because the CEntryStub gets generated so early in the V8 boot | 2607 // this is OK because the CEntryStub gets generated so early in the V8 boot |
| 2624 // sequence that it is not moving ever. | 2608 // sequence that it is not moving ever. |
| 2625 masm->add(lr, pc, Operand(4)); // Compute return address: (pc + 8) + 4 | 2609 |
| 2626 masm->push(lr); | 2610 // Compute the return address in lr to return to after the jump below. Pc is |
| 2611 // already at '+ 8' from the current instruction but return is after three |
| 2612 // instructions so add another 4 to pc to get the return address. |
| 2613 masm->add(lr, pc, Operand(4)); |
| 2614 __ str(lr, MemOperand(sp, 0)); |
| 2627 masm->Jump(r5); | 2615 masm->Jump(r5); |
| 2628 | 2616 |
| 2629 // Restore sp back to before aligning the stack. | |
| 2630 if (alignment_before_call > 0) { | |
| 2631 __ add(sp, sp, Operand(alignment_before_call)); | |
| 2632 } | |
| 2633 | |
| 2634 if (always_allocate) { | 2617 if (always_allocate) { |
| 2635 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 | 2618 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 |
| 2636 // though (contain the result). | 2619 // though (contain the result). |
| 2637 __ mov(r2, Operand(scope_depth)); | 2620 __ mov(r2, Operand(scope_depth)); |
| 2638 __ ldr(r3, MemOperand(r2)); | 2621 __ ldr(r3, MemOperand(r2)); |
| 2639 __ sub(r3, r3, Operand(1)); | 2622 __ sub(r3, r3, Operand(1)); |
| 2640 __ str(r3, MemOperand(r2)); | 2623 __ str(r3, MemOperand(r2)); |
| 2641 } | 2624 } |
| 2642 | 2625 |
| 2643 // check for failure result | 2626 // check for failure result |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2710 Label throw_normal_exception; | 2693 Label throw_normal_exception; |
| 2711 Label throw_termination_exception; | 2694 Label throw_termination_exception; |
| 2712 Label throw_out_of_memory_exception; | 2695 Label throw_out_of_memory_exception; |
| 2713 | 2696 |
| 2714 // Call into the runtime system. | 2697 // Call into the runtime system. |
| 2715 GenerateCore(masm, | 2698 GenerateCore(masm, |
| 2716 &throw_normal_exception, | 2699 &throw_normal_exception, |
| 2717 &throw_termination_exception, | 2700 &throw_termination_exception, |
| 2718 &throw_out_of_memory_exception, | 2701 &throw_out_of_memory_exception, |
| 2719 false, | 2702 false, |
| 2720 false, | 2703 false); |
| 2721 -kPointerSize); | |
| 2722 | 2704 |
| 2723 // Do space-specific GC and retry runtime call. | 2705 // Do space-specific GC and retry runtime call. |
| 2724 GenerateCore(masm, | 2706 GenerateCore(masm, |
| 2725 &throw_normal_exception, | 2707 &throw_normal_exception, |
| 2726 &throw_termination_exception, | 2708 &throw_termination_exception, |
| 2727 &throw_out_of_memory_exception, | 2709 &throw_out_of_memory_exception, |
| 2728 true, | 2710 true, |
| 2729 false, | 2711 false); |
| 2730 0); | |
| 2731 | 2712 |
| 2732 // Do full GC and retry runtime call one final time. | 2713 // Do full GC and retry runtime call one final time. |
| 2733 Failure* failure = Failure::InternalError(); | 2714 Failure* failure = Failure::InternalError(); |
| 2734 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); | 2715 __ mov(r0, Operand(reinterpret_cast<int32_t>(failure))); |
| 2735 GenerateCore(masm, | 2716 GenerateCore(masm, |
| 2736 &throw_normal_exception, | 2717 &throw_normal_exception, |
| 2737 &throw_termination_exception, | 2718 &throw_termination_exception, |
| 2738 &throw_out_of_memory_exception, | 2719 &throw_out_of_memory_exception, |
| 2739 true, | 2720 true, |
| 2740 true, | 2721 true); |
| 2741 kPointerSize); | |
| 2742 | 2722 |
| 2743 __ bind(&throw_out_of_memory_exception); | 2723 __ bind(&throw_out_of_memory_exception); |
| 2744 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); | 2724 GenerateThrowUncatchable(masm, OUT_OF_MEMORY); |
| 2745 | 2725 |
| 2746 __ bind(&throw_termination_exception); | 2726 __ bind(&throw_termination_exception); |
| 2747 GenerateThrowUncatchable(masm, TERMINATION); | 2727 GenerateThrowUncatchable(masm, TERMINATION); |
| 2748 | 2728 |
| 2749 __ bind(&throw_normal_exception); | 2729 __ bind(&throw_normal_exception); |
| 2750 GenerateThrowTOS(masm); | 2730 GenerateThrowTOS(masm); |
| 2751 } | 2731 } |
| (...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5106 __ pop(r1); | 5086 __ pop(r1); |
| 5107 __ Jump(r2); | 5087 __ Jump(r2); |
| 5108 } | 5088 } |
| 5109 | 5089 |
| 5110 | 5090 |
| 5111 #undef __ | 5091 #undef __ |
| 5112 | 5092 |
| 5113 } } // namespace v8::internal | 5093 } } // namespace v8::internal |
| 5114 | 5094 |
| 5115 #endif // V8_TARGET_ARCH_ARM | 5095 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |