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