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 "lib/stacktrace.h" | 9 #include "lib/stacktrace.h" |
10 | 10 |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 ASSERT(frame->IsEntryFrame()); | 202 ASSERT(frame->IsEntryFrame()); |
203 *handler_pc = frame->pc(); | 203 *handler_pc = frame->pc(); |
204 *handler_sp = frame->sp(); | 204 *handler_sp = frame->sp(); |
205 *handler_fp = frame->fp(); | 205 *handler_fp = frame->fp(); |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 static uword RemapExceptionPCForDeopt(Thread* thread, | 209 static uword RemapExceptionPCForDeopt(Thread* thread, |
210 uword program_counter, | 210 uword program_counter, |
211 uword frame_pointer) { | 211 uword frame_pointer) { |
212 #if !defined(TARGET_ARCH_DBC) | |
213 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = | 212 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = |
214 thread->isolate()->pending_deopts(); | 213 thread->isolate()->pending_deopts(); |
215 if (pending_deopts->length() > 0) { | 214 if (pending_deopts->length() > 0) { |
216 // Check if the target frame is scheduled for lazy deopt. | 215 // Check if the target frame is scheduled for lazy deopt. |
217 for (intptr_t i = 0; i < pending_deopts->length(); i++) { | 216 for (intptr_t i = 0; i < pending_deopts->length(); i++) { |
218 if ((*pending_deopts)[i].fp() == frame_pointer) { | 217 if ((*pending_deopts)[i].fp() == frame_pointer) { |
219 // Deopt should now resume in the catch handler instead of after the | 218 // Deopt should now resume in the catch handler instead of after the |
220 // call. | 219 // call. |
221 (*pending_deopts)[i].set_pc(program_counter); | 220 (*pending_deopts)[i].set_pc(program_counter); |
222 | 221 |
223 // Jump to the deopt stub instead of the catch handler. | 222 // Jump to the deopt stub instead of the catch handler. |
224 program_counter = | 223 program_counter = |
225 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); | 224 StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint(); |
226 if (FLAG_trace_deoptimization) { | 225 if (FLAG_trace_deoptimization) { |
227 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", | 226 THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n", |
228 frame_pointer); | 227 frame_pointer); |
229 } | 228 } |
230 break; | 229 break; |
231 } | 230 } |
232 } | 231 } |
233 } | 232 } |
234 #endif // !DBC | |
235 return program_counter; | 233 return program_counter; |
236 } | 234 } |
237 | 235 |
238 | 236 |
239 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { | 237 static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { |
240 #if !defined(TARGET_ARCH_DBC) | |
241 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = | 238 MallocGrowableArray<PendingLazyDeopt>* pending_deopts = |
242 thread->isolate()->pending_deopts(); | 239 thread->isolate()->pending_deopts(); |
243 if (pending_deopts->length() > 0) { | 240 if (pending_deopts->length() > 0) { |
244 // 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 |
245 // 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 |
246 // 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. |
247 { | 244 { |
248 DartFrameIterator frames(thread); | 245 DartFrameIterator frames(thread); |
249 StackFrame* frame = frames.NextFrame(); | 246 StackFrame* frame = frames.NextFrame(); |
250 while ((frame != NULL) && (frame->fp() < frame_pointer)) { | 247 while ((frame != NULL) && IsCalleeFrameOf(frame_pointer, frame->fp())) { |
251 if (frame->IsMarkedForLazyDeopt()) { | 248 if (frame->IsMarkedForLazyDeopt()) { |
252 frame->UnmarkForLazyDeopt(); | 249 frame->UnmarkForLazyDeopt(); |
253 } | 250 } |
254 frame = frames.NextFrame(); | 251 frame = frames.NextFrame(); |
255 } | 252 } |
256 } | 253 } |
257 | 254 |
258 #if defined(DEBUG) | 255 #if defined(DEBUG) |
259 ValidateFrames(); | 256 ValidateFrames(); |
260 #endif | 257 #endif |
261 | 258 |
262 for (intptr_t i = 0; i < pending_deopts->length(); i++) { | 259 for (intptr_t i = 0; i < pending_deopts->length(); i++) { |
263 if ((*pending_deopts)[i].fp() < frame_pointer) { | 260 if (IsCalleeFrameOf(frame_pointer, (*pending_deopts)[i].fp())) { |
264 if (FLAG_trace_deoptimization) { | 261 if (FLAG_trace_deoptimization) { |
265 THR_Print( | 262 THR_Print( |
266 "Lazy deopt skipped due to throw for " | 263 "Lazy deopt skipped due to throw for " |
267 "fp=%" Pp ", pc=%" Pp "\n", | 264 "fp=%" Pp ", pc=%" Pp "\n", |
268 (*pending_deopts)[i].fp(), (*pending_deopts)[i].pc()); | 265 (*pending_deopts)[i].fp(), (*pending_deopts)[i].pc()); |
269 } | 266 } |
270 pending_deopts->RemoveAt(i); | 267 pending_deopts->RemoveAt(i); |
271 } | 268 } |
272 } | 269 } |
273 | 270 |
274 #if defined(DEBUG) | 271 #if defined(DEBUG) |
275 ValidateFrames(); | 272 ValidateFrames(); |
276 #endif | 273 #endif |
277 } | 274 } |
278 #endif // !DBC | |
279 } | 275 } |
280 | 276 |
281 | 277 |
282 static void JumpToExceptionHandler(Thread* thread, | 278 static void JumpToExceptionHandler(Thread* thread, |
283 uword program_counter, | 279 uword program_counter, |
284 uword stack_pointer, | 280 uword stack_pointer, |
285 uword frame_pointer, | 281 uword frame_pointer, |
286 const Object& exception_object, | 282 const Object& exception_object, |
287 const Object& stacktrace_object) { | 283 const Object& stacktrace_object) { |
288 uword remapped_pc = | 284 uword remapped_pc = |
289 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); | 285 RemapExceptionPCForDeopt(thread, program_counter, frame_pointer); |
290 thread->set_active_exception(exception_object); | 286 thread->set_active_exception(exception_object); |
291 thread->set_active_stacktrace(stacktrace_object); | 287 thread->set_active_stacktrace(stacktrace_object); |
292 thread->set_resume_pc(remapped_pc); | 288 thread->set_resume_pc(remapped_pc); |
293 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); | 289 uword run_exception_pc = StubCode::RunExceptionHandler_entry()->EntryPoint(); |
294 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, | 290 Exceptions::JumpToFrame(thread, run_exception_pc, stack_pointer, |
295 frame_pointer, false /* do not clear deopt */); | 291 frame_pointer, false /* do not clear deopt */); |
296 } | 292 } |
297 | 293 |
298 | 294 |
299 void Exceptions::JumpToFrame(Thread* thread, | 295 void Exceptions::JumpToFrame(Thread* thread, |
300 uword program_counter, | 296 uword program_counter, |
301 uword stack_pointer, | 297 uword stack_pointer, |
302 uword frame_pointer, | 298 uword frame_pointer, |
303 bool clear_deopt_at_target) { | 299 bool clear_deopt_at_target) { |
304 uword fp_for_clearing = | 300 uword fp_for_clearing = (clear_deopt_at_target |
305 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); | 301 #if defined(TARGET_ARCH_DBC) |
| 302 ? frame_pointer - 1 |
| 303 #else |
| 304 ? frame_pointer + 1 |
| 305 #endif |
| 306 : frame_pointer); |
306 ClearLazyDeopts(thread, fp_for_clearing); | 307 ClearLazyDeopts(thread, fp_for_clearing); |
307 #if defined(USING_SIMULATOR) | 308 #if defined(USING_SIMULATOR) |
308 // Unwinding of the C++ frames and destroying of their stack resources is done | 309 // Unwinding of the C++ frames and destroying of their stack resources is done |
309 // by the simulator, because the target stack_pointer is a simulated stack | 310 // by the simulator, because the target stack_pointer is a simulated stack |
310 // pointer and not the C++ stack pointer. | 311 // pointer and not the C++ stack pointer. |
311 | 312 |
312 // Continue simulating at the given pc in the given frame after setting up the | 313 // Continue simulating at the given pc in the given frame after setting up the |
313 // exception object in the kExceptionObjectReg register and the stacktrace | 314 // exception object in the kExceptionObjectReg register and the stacktrace |
314 // object (may be raw null) in the kStackTraceObjectReg register. | 315 // object (may be raw null) in the kStackTraceObjectReg register. |
315 | 316 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 class_name = &Symbols::_CompileTimeError(); | 818 class_name = &Symbols::_CompileTimeError(); |
818 break; | 819 break; |
819 } | 820 } |
820 | 821 |
821 return DartLibraryCalls::InstanceCreate(library, *class_name, | 822 return DartLibraryCalls::InstanceCreate(library, *class_name, |
822 *constructor_name, arguments); | 823 *constructor_name, arguments); |
823 } | 824 } |
824 | 825 |
825 | 826 |
826 } // namespace dart | 827 } // namespace dart |
OLD | NEW |