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