OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <setjmp.h> // NOLINT | 5 #include <setjmp.h> // NOLINT |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 | 7 |
8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
9 #if defined(TARGET_ARCH_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
10 | 10 |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 fp_ = reinterpret_cast<RawObject**>(fp_[0]); \ | 1079 fp_ = reinterpret_cast<RawObject**>(fp_[0]); \ |
1080 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); \ | 1080 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); \ |
1081 thread->set_top_resource(top_resource); \ | 1081 thread->set_top_resource(top_resource); \ |
1082 thread->set_vm_tag(vm_tag); \ | 1082 thread->set_vm_tag(vm_tag); \ |
1083 return special_[kExceptionSpecialIndex]; \ | 1083 return special_[kExceptionSpecialIndex]; \ |
1084 } \ | 1084 } \ |
1085 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ | 1085 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ |
1086 goto DispatchAfterException; \ | 1086 goto DispatchAfterException; \ |
1087 } while (0) | 1087 } while (0) |
1088 | 1088 |
1089 // Runtime call helpers: handle invocation and potential exception after return. | 1089 // Runtime call helpers: handle invocation and potential exception |
| 1090 // after return. The caller may have changed the return address on |
| 1091 // the stack. Handle this by updating the pc. |
1090 #define INVOKE_RUNTIME(Func, Args) \ | 1092 #define INVOKE_RUNTIME(Func, Args) \ |
1091 if (!InvokeRuntime(thread, this, Func, Args)) { \ | 1093 if (!InvokeRuntime(thread, this, Func, Args)) { \ |
1092 HANDLE_EXCEPTION; \ | 1094 HANDLE_EXCEPTION; \ |
| 1095 } else { \ |
| 1096 pc = reinterpret_cast<uint32_t*>(fp_[kSavedCallerPcSlotFromFp]); \ |
1093 } | 1097 } |
1094 | 1098 |
1095 #define INVOKE_NATIVE(Func, Args) \ | 1099 #define INVOKE_NATIVE(Func, Args) \ |
1096 if (!InvokeNative(thread, this, Func, &Args)) { \ | 1100 if (!InvokeNative(thread, this, Func, &Args)) { \ |
1097 HANDLE_EXCEPTION; \ | 1101 HANDLE_EXCEPTION; \ |
| 1102 } else { \ |
| 1103 pc = reinterpret_cast<uint32_t*>(fp_[kSavedCallerPcSlotFromFp]); \ |
1098 } | 1104 } |
1099 | 1105 |
1100 #define INVOKE_NATIVE_WRAPPER(Func, Args) \ | 1106 #define INVOKE_NATIVE_WRAPPER(Func, Args) \ |
1101 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \ | 1107 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \ |
1102 HANDLE_EXCEPTION; \ | 1108 HANDLE_EXCEPTION; \ |
| 1109 } else { \ |
| 1110 pc = reinterpret_cast<uint32_t*>(fp_[kSavedCallerPcSlotFromFp]); \ |
1103 } | 1111 } |
1104 | 1112 |
1105 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) | 1113 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) |
1106 | 1114 |
1107 | 1115 |
1108 // Returns true if deoptimization succeeds. | 1116 // Returns true if deoptimization succeeds. |
1109 DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread, | 1117 DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread, |
1110 RawObjectPool** pp, | 1118 RawObjectPool** pp, |
1111 uint32_t** pc, | 1119 uint32_t** pc, |
1112 RawObject*** FP, | 1120 RawObject*** FP, |
1113 RawObject*** SP, | 1121 RawObject*** SP, |
1114 bool is_lazy) { | 1122 bool is_lazy) { |
1115 // Note: frame translation will take care of preserving result at the | 1123 // Note: frame translation will take care of preserving result at the |
1116 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo. | 1124 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo. |
1117 | 1125 |
1118 // Make sure we preserve SP[0] when entering synthetic frame below. | 1126 // Make sure we preserve SP[0] when entering synthetic frame below. |
1119 (*SP)++; | 1127 (*SP)++; |
1120 | 1128 |
1121 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. | 1129 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. |
1122 // The code in this frame may not cause GC. | 1130 // The code in this frame may not cause GC. |
1123 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. | 1131 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. |
1124 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0)); | 1132 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0)); |
1125 const intptr_t frame_size_in_bytes = | 1133 const intptr_t frame_size_in_bytes = |
1126 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(*FP), is_lazy ? 1 : 0); | 1134 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(*FP), is_lazy ? 1 : 0); |
| 1135 // Copy frame updates the caller pc (which is our pc). |
| 1136 *pc = reinterpret_cast<uint32_t*>((*FP)[kSavedCallerPcSlotFromFp]); |
1127 LeaveSyntheticFrame(FP, SP); | 1137 LeaveSyntheticFrame(FP, SP); |
1128 | 1138 |
1129 *SP = *FP + (frame_size_in_bytes / kWordSize); | 1139 *SP = *FP + (frame_size_in_bytes / kWordSize); |
1130 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0)); | 1140 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0)); |
1131 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(*FP)); | 1141 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(*FP)); |
1132 | 1142 |
1133 // We are now inside a valid frame. | 1143 // We are now inside a valid frame. |
1134 { | 1144 { |
1135 *++(*SP) = 0; // Space for the result: number of materialization args. | 1145 *++(*SP) = 0; // Space for the result: number of materialization args. |
1136 Exit(thread, *FP, *SP + 1, /*pc=*/0); | 1146 Exit(thread, *FP, *SP + 1, /*pc=*/0); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 #if !defined(PRODUCT) | 1555 #if !defined(PRODUCT) |
1546 { | 1556 { |
1547 const uint32_t original_bc = | 1557 const uint32_t original_bc = |
1548 static_cast<uint32_t>(reinterpret_cast<uintptr_t>( | 1558 static_cast<uint32_t>(reinterpret_cast<uintptr_t>( |
1549 thread->isolate()->debugger()->GetPatchedStubAddress( | 1559 thread->isolate()->debugger()->GetPatchedStubAddress( |
1550 reinterpret_cast<uword>(pc)))); | 1560 reinterpret_cast<uword>(pc)))); |
1551 | 1561 |
1552 SP[1] = null_value; | 1562 SP[1] = null_value; |
1553 Exit(thread, FP, SP + 2, pc); | 1563 Exit(thread, FP, SP + 2, pc); |
1554 NativeArguments args(thread, 0, NULL, SP + 1); | 1564 NativeArguments args(thread, 0, NULL, SP + 1); |
1555 INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args) | 1565 INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args); |
1556 DISPATCH_OP(original_bc); | 1566 DISPATCH_OP(original_bc); |
1557 } | 1567 } |
1558 #else | 1568 #else |
1559 // There should be no debug breaks in product mode. | 1569 // There should be no debug breaks in product mode. |
1560 UNREACHABLE(); | 1570 UNREACHABLE(); |
1561 #endif | 1571 #endif |
1562 DISPATCH(); | 1572 DISPATCH(); |
1563 } | 1573 } |
1564 | 1574 |
1565 { | 1575 { |
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2649 // Check if it is a fake PC marking the entry frame. | 2659 // Check if it is a fake PC marking the entry frame. |
2650 if ((reinterpret_cast<uword>(pc) & 2) != 0) { | 2660 if ((reinterpret_cast<uword>(pc) & 2) != 0) { |
2651 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; | 2661 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; |
2652 fp_ = reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); | 2662 fp_ = reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); |
2653 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); | 2663 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); |
2654 thread->set_top_resource(top_resource); | 2664 thread->set_top_resource(top_resource); |
2655 thread->set_vm_tag(vm_tag); | 2665 thread->set_vm_tag(vm_tag); |
2656 return result; | 2666 return result; |
2657 } | 2667 } |
2658 | 2668 |
| 2669 // If we have a pending lazy deopt then the caller's pc is stored |
| 2670 // in the isolate. |
| 2671 uint32_t* caller_pc = pc; |
| 2672 if ((reinterpret_cast<uword>(pc) == |
| 2673 StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint())) { |
| 2674 caller_pc = |
| 2675 reinterpret_cast<uint32_t*>(thread->isolate()->FindPendingDeopt( |
| 2676 reinterpret_cast<uword>(SavedCallerFP(FP)))); |
| 2677 } |
| 2678 |
2659 // Look at the caller to determine how many arguments to pop. | 2679 // Look at the caller to determine how many arguments to pop. |
2660 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); | 2680 const uint8_t argc = Bytecode::DecodeArgc(caller_pc[-1]); |
2661 | 2681 |
2662 // Restore SP, FP and PP. Push result and dispatch. | 2682 // Restore SP, FP and PP. Push result and dispatch. |
2663 SP = FrameArguments(FP, argc); | 2683 SP = FrameArguments(FP, argc); |
2664 FP = SavedCallerFP(FP); | 2684 FP = SavedCallerFP(FP); |
2665 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); | 2685 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
2666 *SP = result; | 2686 *SP = result; |
2667 DISPATCH(); | 2687 DISPATCH(); |
2668 } | 2688 } |
2669 | 2689 |
2670 { | 2690 { |
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3765 pc_ = pc; | 3785 pc_ = pc; |
3766 } | 3786 } |
3767 | 3787 |
3768 buf->Longjmp(); | 3788 buf->Longjmp(); |
3769 UNREACHABLE(); | 3789 UNREACHABLE(); |
3770 } | 3790 } |
3771 | 3791 |
3772 } // namespace dart | 3792 } // namespace dart |
3773 | 3793 |
3774 #endif // defined TARGET_ARCH_DBC | 3794 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |