| 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 |