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