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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_dbc.cc
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 86ca930a41aaaa0c5d639f206872e2fb6d65326c..d16a5a375869ea3c06faeb2d7826d0b627feec63 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1104,6 +1104,64 @@ static DART_NOINLINE bool InvokeNativeWrapper(Thread* thread,
#define LOAD_CONSTANT(index) (pp->data()[(index)].raw_obj_)
+
+// Returns true if deoptimization succeeds.
+DART_FORCE_INLINE bool Simulator::Deoptimize(Thread* thread,
+ RawObjectPool** pp,
+ uint32_t** pc,
+ RawObject*** FP,
+ RawObject*** SP,
+ bool is_lazy) {
+ // Note: frame translation will take care of preserving result at the
+ // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
+
+ // Make sure we preserve SP[0] when entering synthetic frame below.
+ (*SP)++;
+
+ // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
+ // The code in this frame may not cause GC.
+ // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
+ EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0));
+ const intptr_t frame_size_in_bytes =
+ DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(*FP), is_lazy ? 1 : 0);
+ LeaveSyntheticFrame(FP, SP);
+
+ *SP = *FP + (frame_size_in_bytes / kWordSize);
+ EnterSyntheticFrame(FP, SP, *pc - (is_lazy ? 1 : 0));
+ DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(*FP));
+
+ // We are now inside a valid frame.
+ {
+ *++(*SP) = 0; // Space for the result: number of materialization args.
+ Exit(thread, *FP, *SP + 1, /*pc=*/0);
+ NativeArguments native_args(thread, 0, *SP, *SP);
+ if (!InvokeRuntime(thread, this, DRT_DeoptimizeMaterialize, native_args)) {
+ return false;
+ }
+ }
+ const intptr_t materialization_arg_count =
+ Smi::Value(RAW_CAST(Smi, *(*SP)--)) / kWordSize;
+
+ // Restore caller PC.
+ *pc = SavedCallerPC(*FP);
+ pc_ = reinterpret_cast<uword>(*pc); // For the profiler.
+
+ // Check if it is a fake PC marking the entry frame.
+ ASSERT((reinterpret_cast<uword>(*pc) & 2) == 0);
+
+ // Restore SP, FP and PP.
+ // Unoptimized frame SP is one below FrameArguments(...) because
+ // FrameArguments(...) returns a pointer to the first argument.
+ *SP = FrameArguments(*FP, materialization_arg_count) - 1;
+ *FP = SavedCallerFP(*FP);
+
+ // Restore pp.
+ *pp = SimulatorHelpers::FrameCode(*FP)->ptr()->object_pool_->ptr();
+
+ return true;
+}
+
+
RawObject* Simulator::Call(const Code& code,
const Array& arguments_descriptor,
const Array& arguments,
@@ -3573,50 +3631,25 @@ RawObject* Simulator::Call(const Code& code,
{
BYTECODE(Deopt, A_D);
-
- // Note: frame translation will take care of preserving result at the
- // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
const bool is_lazy = rD == 0;
+ if (!Deoptimize(thread, &pp, &pc, &FP, &SP, is_lazy)) {
+ HANDLE_EXCEPTION;
+ }
+ DISPATCH();
+ }
- // Make sure we preserve SP[0] when entering synthetic frame below.
- SP++;
-
- // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
- // The code in this frame may not cause GC.
- // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
- EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
- const intptr_t frame_size_in_bytes =
- DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0);
- LeaveSyntheticFrame(&FP, &SP);
-
- SP = FP + (frame_size_in_bytes / kWordSize);
- EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
- DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
-
- // We are now inside a valid frame.
+ {
+ BYTECODE(DeoptRewind, 0);
+ pc = reinterpret_cast<uint32_t*>(thread->resume_pc());
+ if (!Deoptimize(thread, &pp, &pc, &FP, &SP, false /* eager */)) {
+ HANDLE_EXCEPTION;
+ }
{
- *++SP = 0; // Space for the result: number of materialization args.
- Exit(thread, FP, SP + 1, /*pc=*/0);
- NativeArguments native_args(thread, 0, SP, SP);
- INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
+ Exit(thread, FP, SP + 1, pc);
+ NativeArguments args(thread, 0, NULL, NULL);
+ INVOKE_RUNTIME(DRT_RewindPostDeopt, args);
}
- const intptr_t materialization_arg_count =
- Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize;
-
- // Restore caller PC.
- pc = SavedCallerPC(FP);
- pc_ = reinterpret_cast<uword>(pc); // For the profiler.
-
- // Check if it is a fake PC marking the entry frame.
- ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
-
- // Restore SP, FP and PP.
- // Unoptimized frame SP is one below FrameArguments(...) because
- // FrameArguments(...) returns a pointer to the first argument.
- SP = FrameArguments(FP, materialization_arg_count) - 1;
- FP = SavedCallerFP(FP);
- pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
-
+ UNREACHABLE(); // DRT_RewindPostDeopt does not exit normally.
DISPATCH();
}
@@ -3699,7 +3732,7 @@ RawObject* Simulator::Call(const Code& code,
void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
// Walk over all setjmp buffers (simulated --> C++ transitions)
- // and try to find the setjmp associated with the simulated stack pointer.
+ // and try to find the setjmp associated with the simulated frame pointer.
SimulatorSetjmpBuffer* buf = last_setjmp_buffer();
while ((buf->link() != NULL) && (buf->link()->fp() > fp)) {
buf = buf->link();
@@ -3728,17 +3761,6 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
special_[kExceptionSpecialIndex] = raw_exception;
special_[kStackTraceSpecialIndex] = raw_stacktrace;
pc_ = thread->resume_pc();
- } else if (pc == StubCode::DeoptForRewind_entry()->EntryPoint()) {
- // The DeoptForRewind stub is a placeholder. We will eventually
- // implement its behavior here.
- //
- // TODO(turnidge): Refactor the Deopt bytecode so that we can use
- // the implementation here too. The deopt pc is stored in
- // Thread::resume_pc(). After invoking deoptimization, we usually
- // call into Debugger::RewindPostDeopt(), but I need to figure out
- // if that makes any sense (it would JumpToFrame during a
- // JumpToFrame, which seems wrong).
- UNIMPLEMENTED();
} else {
pc_ = pc;
}
« 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