Index: runtime/vm/exceptions.cc |
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc |
index 7c9d71dccbb5327f3db5be3086ee36e0ccd85f13..f5f66aee6c59fff91e118b2307996e7cda5ca393 100644 |
--- a/runtime/vm/exceptions.cc |
+++ b/runtime/vm/exceptions.cc |
@@ -21,6 +21,7 @@ |
namespace dart { |
+DECLARE_FLAG(bool, trace_deoptimization); |
DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
"Prints a stack trace everytime a throw occurs."); |
@@ -128,6 +129,7 @@ static void BuildStackTrace(StacktraceBuilder* builder) { |
while (frame != NULL) { |
if (frame->IsDartFrame()) { |
code = frame->LookupDartCode(); |
+ ASSERT(code.ContainsInstructionAt(frame->pc())); |
offset = Smi::New(frame->pc() - code.PayloadStart()); |
builder->AddFrame(code, offset); |
} |
@@ -214,6 +216,35 @@ static void JumpToExceptionHandler(Thread* thread, |
RawObject* raw_exception = exception_object.raw(); |
RawObject* raw_stacktrace = stacktrace_object.raw(); |
+#if !defined(TARGET_ARCH_DBC) |
+ MallocGrowableArray<PendingLazyDeopt>* pending_deopts = |
+ thread->isolate()->pending_deopts(); |
+ for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) { |
+ if ((*pending_deopts)[i].fp() == frame_pointer) { |
+ // Frame is scheduled for lazy deopt. |
+ |
+ // Deopt should now resume in the catch handler instead of after the call. |
+ (*pending_deopts)[i].set_pc(program_counter); |
+ |
+ // Jump to the deopt stub instead of the catch handler. |
+ program_counter = |
+ StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); |
+ if (FLAG_trace_deoptimization) { |
+ THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", |
+ frame_pointer); |
+ } |
+ break; |
+ } |
+ } |
+ for (intptr_t i = pending_deopts->length() - 1; i >= 0; i--) { |
+ // Leave the mapping at fp itself for use in DeoptimizeCopyFrame. |
+ if ((*pending_deopts)[i].fp() < frame_pointer) { |
+ pending_deopts->RemoveAt(i); |
+ } |
+ } |
+#endif // !DBC |
+ |
+ |
#if defined(USING_SIMULATOR) |
// Unwinding of the C++ frames and destroying of their stack resources is done |
// by the simulator, because the target stack_pointer is a simulated stack |