Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Side by Side Diff: runtime/vm/simulator_dbc.cc

Issue 2636443004: Make rewind work on DBC (Closed)
Patch Set: Code Review Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/simulator_dbc.h ('k') | runtime/vm/stub_code_dbc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 HANDLE_EXCEPTION; \ 1097 HANDLE_EXCEPTION; \
1098 } 1098 }
1099 1099
1100 #define INVOKE_NATIVE_WRAPPER(Func, Args) \ 1100 #define INVOKE_NATIVE_WRAPPER(Func, Args) \
1101 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \ 1101 if (!InvokeNativeWrapper(thread, this, Func, &Args)) { \
1102 HANDLE_EXCEPTION; \ 1102 HANDLE_EXCEPTION; \
1103 } 1103 }
1104 1104
1105 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_) 1105 #define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_)
1106 1106
1107
1108 // Returns true if deoptimization succeeds.
1109 DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread,
1110 RawObjectPool** pp,
1111 uint32_t** pc,
1112 RawObject*** FP,
1113 RawObject*** SP,
1114 bool is_lazy) {
1115 // Note: frame translation will take care of preserving result at the
1116 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
1117
1118 // Make sure we preserve SP[0] when entering synthetic frame below.
1119 (*SP)++;
1120
1121 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
1122 // The code in this frame may not cause GC.
1123 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
1124 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0));
1125 const intptr_t frame_size_in_bytes =
1126 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(*FP), is_lazy ? 1 : 0);
1127 LeaveSyntheticFrame(FP, SP);
1128
1129 *SP = *FP + (frame_size_in_bytes / kWordSize);
1130 EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0));
1131 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(*FP));
1132
1133 // We are now inside a valid frame.
1134 {
1135 *++(*SP) = 0; // Space for the result: number of materialization args.
1136 Exit(thread, *FP, *SP + 1, /*pc=*/0);
1137 NativeArguments native_args(thread, 0, *SP, *SP);
1138 if (!InvokeRuntime(thread, this, DRT_DeoptimizeMaterialize, native_args)) {
1139 return false;
1140 }
1141 }
1142 const intptr_t materialization_arg_count =
1143 Smi::Value(RAW_CAST(Smi, *(*SP)--)) / kWordSize;
1144
1145 // Restore caller PC.
1146 *pc = SavedCallerPC(*FP);
1147 pc_ = reinterpret_cast<uword>(*pc); // For the profiler.
1148
1149 // Check if it is a fake PC marking the entry frame.
1150 ASSERT((reinterpret_cast<uword>(*pc) & 2) == 0);
1151
1152 // Restore SP, FP and PP.
1153 // Unoptimized frame SP is one below FrameArguments(...) because
1154 // FrameArguments(...) returns a pointer to the first argument.
1155 *SP = FrameArguments(*FP, materialization_arg_count) - 1;
1156 *FP = SavedCallerFP(*FP);
1157
1158 // Restore pp.
1159 *pp = SimulatorHelpers::FrameCode(*FP)->ptr()->object_pool_->ptr();
1160
1161 return true;
1162 }
1163
1164
1107 RawObject* Simulator::Call(const Code& code, 1165 RawObject* Simulator::Call(const Code& code,
1108 const Array& arguments_descriptor, 1166 const Array& arguments_descriptor,
1109 const Array& arguments, 1167 const Array& arguments,
1110 Thread* thread) { 1168 Thread* thread) {
1111 // Dispatch used to interpret bytecode. Contains addresses of 1169 // Dispatch used to interpret bytecode. Contains addresses of
1112 // labels of bytecode handlers. Handlers themselves are defined below. 1170 // labels of bytecode handlers. Handlers themselves are defined below.
1113 static const void* dispatch[] = { 1171 static const void* dispatch[] = {
1114 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name, 1172 #define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name,
1115 BYTECODES_LIST(TARGET) 1173 BYTECODES_LIST(TARGET)
1116 #undef TARGET 1174 #undef TARGET
(...skipping 2449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3566 BYTECODE(LoadIndexedTwoByteString, A_B_C); 3624 BYTECODE(LoadIndexedTwoByteString, A_B_C);
3567 RawTwoByteString* array = RAW_CAST(TwoByteString, FP[rB]); 3625 RawTwoByteString* array = RAW_CAST(TwoByteString, FP[rB]);
3568 RawSmi* index = RAW_CAST(Smi, FP[rC]); 3626 RawSmi* index = RAW_CAST(Smi, FP[rC]);
3569 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 3627 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
3570 FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]); 3628 FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]);
3571 DISPATCH(); 3629 DISPATCH();
3572 } 3630 }
3573 3631
3574 { 3632 {
3575 BYTECODE(Deopt, A_D); 3633 BYTECODE(Deopt, A_D);
3576
3577 // Note: frame translation will take care of preserving result at the
3578 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
3579 const bool is_lazy = rD == 0; 3634 const bool is_lazy = rD == 0;
3580 3635 if (!Deoptimize(thread, &pp, &pc, &FP, &SP, is_lazy)) {
3581 // Make sure we preserve SP[0] when entering synthetic frame below. 3636 HANDLE_EXCEPTION;
3582 SP++;
3583
3584 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
3585 // The code in this frame may not cause GC.
3586 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
3587 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
3588 const intptr_t frame_size_in_bytes =
3589 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0);
3590 LeaveSyntheticFrame(&FP, &SP);
3591
3592 SP = FP + (frame_size_in_bytes / kWordSize);
3593 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
3594 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
3595
3596 // We are now inside a valid frame.
3597 {
3598 *++SP = 0; // Space for the result: number of materialization args.
3599 Exit(thread, FP, SP + 1, /*pc=*/0);
3600 NativeArguments native_args(thread, 0, SP, SP);
3601 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
3602 } 3637 }
3603 const intptr_t materialization_arg_count =
3604 Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize;
3605
3606 // Restore caller PC.
3607 pc = SavedCallerPC(FP);
3608 pc_ = reinterpret_cast<uword>(pc); // For the profiler.
3609
3610 // Check if it is a fake PC marking the entry frame.
3611 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
3612
3613 // Restore SP, FP and PP.
3614 // Unoptimized frame SP is one below FrameArguments(...) because
3615 // FrameArguments(...) returns a pointer to the first argument.
3616 SP = FrameArguments(FP, materialization_arg_count) - 1;
3617 FP = SavedCallerFP(FP);
3618 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
3619
3620 DISPATCH(); 3638 DISPATCH();
3621 } 3639 }
3622 3640
3641 {
3642 BYTECODE(DeoptRewind, 0);
3643 pc = reinterpret_cast<uint32_t*>(thread->resume_pc());
3644 if (!Deoptimize(thread, &pp, &pc, &FP, &SP, false /* eager */)) {
3645 HANDLE_EXCEPTION;
3646 }
3647 {
3648 Exit(thread, FP, SP + 1, pc);
3649 NativeArguments args(thread, 0, NULL, NULL);
3650 INVOKE_RUNTIME(DRT_RewindPostDeopt, args);
3651 }
3652 UNREACHABLE(); // DRT_RewindPostDeopt does not exit normally.
3653 DISPATCH();
3654 }
3655
3623 { 3656 {
3624 BYTECODE(Nop, 0); 3657 BYTECODE(Nop, 0);
3625 DISPATCH(); 3658 DISPATCH();
3626 } 3659 }
3627 3660
3628 { 3661 {
3629 BYTECODE(Trap, 0); 3662 BYTECODE(Trap, 0);
3630 UNIMPLEMENTED(); 3663 UNIMPLEMENTED();
3631 DISPATCH(); 3664 DISPATCH();
3632 } 3665 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3692 DISPATCH(); 3725 DISPATCH();
3693 } 3726 }
3694 3727
3695 UNREACHABLE(); 3728 UNREACHABLE();
3696 return 0; 3729 return 0;
3697 } 3730 }
3698 3731
3699 3732
3700 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { 3733 void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
3701 // Walk over all setjmp buffers (simulated --> C++ transitions) 3734 // Walk over all setjmp buffers (simulated --> C++ transitions)
3702 // and try to find the setjmp associated with the simulated stack pointer. 3735 // and try to find the setjmp associated with the simulated frame pointer.
3703 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); 3736 SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
3704 while ((buf->link() != NULL) && (buf->link()->fp() > fp)) { 3737 while ((buf->link() != NULL) && (buf->link()->fp() > fp)) {
3705 buf = buf->link(); 3738 buf = buf->link();
3706 } 3739 }
3707 ASSERT(buf != NULL); 3740 ASSERT(buf != NULL);
3708 ASSERT(last_setjmp_buffer() == buf); 3741 ASSERT(last_setjmp_buffer() == buf);
3709 3742
3710 // The C++ caller has not cleaned up the stack memory of C++ frames. 3743 // The C++ caller has not cleaned up the stack memory of C++ frames.
3711 // Prepare for unwinding frames by destroying all the stack resources 3744 // Prepare for unwinding frames by destroying all the stack resources
3712 // in the previous C++ frames. 3745 // in the previous C++ frames.
3713 StackResource::Unwind(thread); 3746 StackResource::Unwind(thread);
3714 3747
3715 // Set the tag. 3748 // Set the tag.
3716 thread->set_vm_tag(VMTag::kDartTagId); 3749 thread->set_vm_tag(VMTag::kDartTagId);
3717 // Clear top exit frame. 3750 // Clear top exit frame.
3718 thread->set_top_exit_frame_info(0); 3751 thread->set_top_exit_frame_info(0);
3719 3752
3720 fp_ = reinterpret_cast<RawObject**>(fp); 3753 fp_ = reinterpret_cast<RawObject**>(fp);
3721 3754
3722 if (pc == StubCode::RunExceptionHandler_entry()->EntryPoint()) { 3755 if (pc == StubCode::RunExceptionHandler_entry()->EntryPoint()) {
3723 // The RunExceptionHandler stub is a placeholder. We implement 3756 // The RunExceptionHandler stub is a placeholder. We implement
3724 // its behavior here. 3757 // its behavior here.
3725 RawObject* raw_exception = thread->active_exception(); 3758 RawObject* raw_exception = thread->active_exception();
3726 RawObject* raw_stacktrace = thread->active_stacktrace(); 3759 RawObject* raw_stacktrace = thread->active_stacktrace();
3727 ASSERT(raw_exception != Object::null()); 3760 ASSERT(raw_exception != Object::null());
3728 special_[kExceptionSpecialIndex] = raw_exception; 3761 special_[kExceptionSpecialIndex] = raw_exception;
3729 special_[kStackTraceSpecialIndex] = raw_stacktrace; 3762 special_[kStackTraceSpecialIndex] = raw_stacktrace;
3730 pc_ = thread->resume_pc(); 3763 pc_ = thread->resume_pc();
3731 } else if (pc == StubCode::DeoptForRewind_entry()->EntryPoint()) {
3732 // The DeoptForRewind stub is a placeholder. We will eventually
3733 // implement its behavior here.
3734 //
3735 // TODO(turnidge): Refactor the Deopt bytecode so that we can use
3736 // the implementation here too. The deopt pc is stored in
3737 // Thread::resume_pc(). After invoking deoptimization, we usually
3738 // call into Debugger::RewindPostDeopt(), but I need to figure out
3739 // if that makes any sense (it would JumpToFrame during a
3740 // JumpToFrame, which seems wrong).
3741 UNIMPLEMENTED();
3742 } else { 3764 } else {
3743 pc_ = pc; 3765 pc_ = pc;
3744 } 3766 }
3745 3767
3746 buf->Longjmp(); 3768 buf->Longjmp();
3747 UNREACHABLE(); 3769 UNREACHABLE();
3748 } 3770 }
3749 3771
3750 } // namespace dart 3772 } // namespace dart
3751 3773
3752 #endif // defined TARGET_ARCH_DBC 3774 #endif // defined TARGET_ARCH_DBC
OLDNEW
« no previous file with comments | « runtime/vm/simulator_dbc.h ('k') | runtime/vm/stub_code_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698