OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/exceptions.h" | 5 #include "vm/exceptions.h" |
6 | 6 |
7 #include "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
8 | 8 |
9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 } | 182 } |
183 // No catch-all encountered, needs stacktrace. | 183 // No catch-all encountered, needs stacktrace. |
184 *needs_stacktrace = true; | 184 *needs_stacktrace = true; |
185 return handler_pc_set; | 185 return handler_pc_set; |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 static void FindErrorHandler(uword* handler_pc, | 189 static void FindErrorHandler(uword* handler_pc, |
190 uword* handler_sp, | 190 uword* handler_sp, |
191 uword* handler_fp) { | 191 uword* handler_fp) { |
192 // TODO(turnidge): Is there a faster way to get the next entry frame? | |
193 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 192 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
194 StackFrame* frame = frames.NextFrame(); | 193 StackFrame* frame = frames.NextFrame(); |
195 ASSERT(frame != NULL); | 194 ASSERT(frame != NULL); |
196 while (!frame->IsEntryFrame()) { | 195 while (!frame->IsEntryFrame()) { |
197 frame = frames.NextFrame(); | 196 frame = frames.NextFrame(); |
198 ASSERT(frame != NULL); | 197 ASSERT(frame != NULL); |
199 } | 198 } |
200 ASSERT(frame->IsEntryFrame()); | 199 ASSERT(frame->IsEntryFrame()); |
201 *handler_pc = frame->pc(); | 200 *handler_pc = frame->pc(); |
202 *handler_sp = frame->sp(); | 201 *handler_sp = frame->sp(); |
(...skipping 18 matching lines...) Expand all Loading... |
221 // Jump to the deopt stub instead of the catch handler. | 220 // Jump to the deopt stub instead of the catch handler. |
222 program_counter = | 221 program_counter = |
223 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); | 222 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); |
224 if (FLAG_trace_deoptimization) { | 223 if (FLAG_trace_deoptimization) { |
225 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", | 224 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", |
226 frame_pointer); | 225 frame_pointer); |
227 } | 226 } |
228 break; | 227 break; |
229 } | 228 } |
230 } | 229 } |
| 230 } |
| 231 #endif // !DBC |
| 232 return program_counter; |
| 233 } |
231 | 234 |
| 235 |
| 236 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { |
| 237 #if !defined(TARGET_ARCH_DBC) |
| 238 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = |
| 239 thread->isolate()->pending_deopts(); |
| 240 if (pending_deopts->length() > 0) { |
232 // We may be jumping over frames scheduled for lazy deopt. Remove these | 241 // We may be jumping over frames scheduled for lazy deopt. Remove these |
233 // frames from the pending deopt table, but only after unmarking them so | 242 // frames from the pending deopt table, but only after unmarking them so |
234 // any stack walk that happens before the stack is unwound will still work. | 243 // any stack walk that happens before the stack is unwound will still work. |
235 { | 244 { |
236 DartFrameIterator frames(thread); | 245 DartFrameIterator frames(thread); |
237 StackFrame* frame = frames.NextFrame(); | 246 StackFrame* frame = frames.NextFrame(); |
238 while ((frame != NULL) && (frame->fp() < frame_pointer)) { | 247 while ((frame != NULL) && (frame->fp() < frame_pointer)) { |
239 if (frame->IsMarkedForLazyDeopt()) { | 248 if (frame->IsMarkedForLazyDeopt()) { |
240 frame->UnmarkForLazyDeopt(); | 249 frame->UnmarkForLazyDeopt(); |
241 } | 250 } |
(...skipping 15 matching lines...) Expand all Loading... |
257 } | 266 } |
258 pending_deopts->RemoveAt(i); | 267 pending_deopts->RemoveAt(i); |
259 } | 268 } |
260 } | 269 } |
261 | 270 |
262 #if defined(DEBUG) | 271 #if defined(DEBUG) |
263 ValidateFrames(); | 272 ValidateFrames(); |
264 #endif | 273 #endif |
265 } | 274 } |
266 #endif // !DBC | 275 #endif // !DBC |
267 return program_counter; | |
268 } | 276 } |
269 | 277 |
270 | 278 |
271 static void JumpToExceptionHandler(Thread* thread, | 279 static void JumpToExceptionHandler(Thread* thread, |
272 uword program_counter, | 280 uword program_counter, |
273 uword stack_pointer, | 281 uword stack_pointer, |
274 uword frame_pointer, | 282 uword frame_pointer, |
275 const Object& exception_object, | 283 const Object& exception_object, |
276 const Object& stacktrace_object) { | 284 const Object& stacktrace_object) { |
277 uword remapped_pc = | 285 uword remapped_pc = |
278 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); | 286 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); |
279 thread->set_active_exception(exception_object); | 287 thread->set_active_exception(exception_object); |
280 thread->set_active_stacktrace(stacktrace_object); | 288 thread->set_active_stacktrace(stacktrace_object); |
281 thread->set_resume_pc(remapped_pc); | 289 thread->set_resume_pc(remapped_pc); |
282 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); | 290 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); |
283 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, | 291 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, |
284 frame_pointer); | 292 frame_pointer, false /* do not clear deopt */); |
285 } | 293 } |
286 | 294 |
287 | 295 |
288 void Exceptions::JumpToFrame(Thread* thread, | 296 void Exceptions::JumpToFrame(Thread* thread, |
289 uword program_counter, | 297 uword program_counter, |
290 uword stack_pointer, | 298 uword stack_pointer, |
291 uword frame_pointer) { | 299 uword frame_pointer, |
| 300 bool clear_deopt_at_target) { |
| 301 uword fp_for_clearing = |
| 302 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); |
| 303 ClearLazyDeopts(thread, fp_for_clearing); |
292 #if defined(USING_SIMULATOR) | 304 #if defined(USING_SIMULATOR) |
293 // Unwinding of the C++ frames and destroying of their stack resources is done | 305 // Unwinding of the C++ frames and destroying of their stack resources is done |
294 // by the simulator, because the target stack_pointer is a simulated stack | 306 // by the simulator, because the target stack_pointer is a simulated stack |
295 // pointer and not the C++ stack pointer. | 307 // pointer and not the C++ stack pointer. |
296 | 308 |
297 // Continue simulating at the given pc in the given frame after setting up the | 309 // Continue simulating at the given pc in the given frame after setting up the |
298 // exception object in the kExceptionObjectReg register and the stacktrace | 310 // exception object in the kExceptionObjectReg register and the stacktrace |
299 // object (may be raw null) in the kStackTraceObjectReg register. | 311 // object (may be raw null) in the kStackTraceObjectReg register. |
300 | 312 |
301 Simulator::Current()->JumpToFrame(program_counter, stack_pointer, | 313 Simulator::Current()->JumpToFrame(program_counter, stack_pointer, |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 class_name = &Symbols::_CompileTimeError(); | 810 class_name = &Symbols::_CompileTimeError(); |
799 break; | 811 break; |
800 } | 812 } |
801 | 813 |
802 return DartLibraryCalls::InstanceCreate(library, *class_name, | 814 return DartLibraryCalls::InstanceCreate(library, *class_name, |
803 *constructor_name, arguments); | 815 *constructor_name, arguments); |
804 } | 816 } |
805 | 817 |
806 | 818 |
807 } // namespace dart | 819 } // namespace dart |
OLD | NEW |