Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: runtime/vm/exceptions.cc

Issue 2374173002: Revert "Pass new pool pointer to the JumpToException stub instead of reloading in through the frame… (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/simulator_arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 137
138 138
139 // Iterate through the stack frames and try to find a frame with an 139 // Iterate through the stack frames and try to find a frame with an
140 // exception handler. Once found, set the pc, sp and fp so that execution 140 // exception handler. Once found, set the pc, sp and fp so that execution
141 // can continue in that frame. Sets 'needs_stacktrace' if there is no 141 // can continue in that frame. Sets 'needs_stacktrace' if there is no
142 // cath-all handler or if a stack-trace is specified in the catch. 142 // cath-all handler or if a stack-trace is specified in the catch.
143 static bool FindExceptionHandler(Thread* thread, 143 static bool FindExceptionHandler(Thread* thread,
144 uword* handler_pc, 144 uword* handler_pc,
145 uword* handler_sp, 145 uword* handler_sp,
146 uword* handler_fp, 146 uword* handler_fp,
147 uword** handler_pp_slot,
148 bool* needs_stacktrace) { 147 bool* needs_stacktrace) {
149 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); 148 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
150 StackFrame* frame = frames.NextFrame(); 149 StackFrame* frame = frames.NextFrame();
151 if (frame == NULL) return false; // No Dart frame. 150 if (frame == NULL) return false; // No Dart frame.
152 bool handler_pc_set = false; 151 bool handler_pc_set = false;
153 *needs_stacktrace = false; 152 *needs_stacktrace = false;
154 bool is_catch_all = false; 153 bool is_catch_all = false;
155 uword temp_handler_pc = kUwordMax; 154 uword temp_handler_pc = kUwordMax;
156 uword* saved_pp_slot = 0;
157 while (!frame->IsEntryFrame()) { 155 while (!frame->IsEntryFrame()) {
158 if (frame->IsDartFrame()) { 156 if (frame->IsDartFrame()) {
159 if (frame->FindExceptionHandler(thread, 157 if (frame->FindExceptionHandler(thread,
160 &temp_handler_pc, 158 &temp_handler_pc,
161 needs_stacktrace, 159 needs_stacktrace,
162 &is_catch_all)) { 160 &is_catch_all)) {
163 if (!handler_pc_set) { 161 if (!handler_pc_set) {
164 handler_pc_set = true; 162 handler_pc_set = true;
165 *handler_pc = temp_handler_pc; 163 *handler_pc = temp_handler_pc;
166 *handler_sp = frame->sp(); 164 *handler_sp = frame->sp();
167 *handler_fp = frame->fp(); 165 *handler_fp = frame->fp();
168 *handler_pp_slot = saved_pp_slot;
169 } 166 }
170 if (*needs_stacktrace || is_catch_all) { 167 if (*needs_stacktrace || is_catch_all) {
171 return true; 168 return true;
172 } 169 }
173 } 170 }
174 } // if frame->IsDartFrame 171 } // if frame->IsDartFrame
175 #if !defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_DBC)
176 saved_pp_slot = frame->saved_caller_pp_slot();
177 #endif
178 frame = frames.NextFrame(); 172 frame = frames.NextFrame();
179 ASSERT(frame != NULL); 173 ASSERT(frame != NULL);
180 } // while !frame->IsEntryFrame 174 } // while !frame->IsEntryFrame
181 ASSERT(frame->IsEntryFrame()); 175 ASSERT(frame->IsEntryFrame());
182 if (!handler_pc_set) { 176 if (!handler_pc_set) {
183 *handler_pc = frame->pc(); 177 *handler_pc = frame->pc();
184 *handler_sp = frame->sp(); 178 *handler_sp = frame->sp();
185 *handler_fp = frame->fp(); 179 *handler_fp = frame->fp();
186 *handler_pp_slot = saved_pp_slot;
187 } 180 }
188 // No catch-all encountered, needs stacktrace. 181 // No catch-all encountered, needs stacktrace.
189 *needs_stacktrace = true; 182 *needs_stacktrace = true;
190 return handler_pc_set; 183 return handler_pc_set;
191 } 184 }
192 185
193 186
194 static void FindErrorHandler(uword* handler_pc, 187 static void FindErrorHandler(uword* handler_pc,
195 uword* handler_sp, 188 uword* handler_sp,
196 uword* handler_fp, 189 uword* handler_fp) {
197 uword** handler_pp_slot) {
198 // TODO(turnidge): Is there a faster way to get the next entry frame? 190 // TODO(turnidge): Is there a faster way to get the next entry frame?
199 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); 191 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
200 StackFrame* frame = frames.NextFrame(); 192 StackFrame* frame = frames.NextFrame();
201 ASSERT(frame != NULL); 193 ASSERT(frame != NULL);
202 uword* saved_pp_slot = NULL;
203 while (!frame->IsEntryFrame()) { 194 while (!frame->IsEntryFrame()) {
204 #if !defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_DBC)
205 saved_pp_slot = frame->saved_caller_pp_slot();
206 #endif
207 frame = frames.NextFrame(); 195 frame = frames.NextFrame();
208 ASSERT(frame != NULL); 196 ASSERT(frame != NULL);
209 } 197 }
210 ASSERT(frame->IsEntryFrame()); 198 ASSERT(frame->IsEntryFrame());
211 *handler_pc = frame->pc(); 199 *handler_pc = frame->pc();
212 *handler_sp = frame->sp(); 200 *handler_sp = frame->sp();
213 *handler_fp = frame->fp(); 201 *handler_fp = frame->fp();
214 *handler_pp_slot = saved_pp_slot;
215 } 202 }
216 203
217 204
218 static void JumpToExceptionHandler(Thread* thread, 205 static void JumpToExceptionHandler(Thread* thread,
219 uword program_counter, 206 uword program_counter,
220 uword stack_pointer, 207 uword stack_pointer,
221 uword frame_pointer, 208 uword frame_pointer,
222 uword* pool_pointer_slot,
223 const Object& exception_object, 209 const Object& exception_object,
224 const Object& stacktrace_object) { 210 const Object& stacktrace_object) {
225 // The no_gc StackResource is unwound through the tear down of 211 // The no_gc StackResource is unwound through the tear down of
226 // stack resources below. 212 // stack resources below.
227 NoSafepointScope no_safepoint; 213 NoSafepointScope no_safepoint;
228 RawObject* raw_exception = exception_object.raw(); 214 RawObject* raw_exception = exception_object.raw();
229 RawObject* raw_stacktrace = stacktrace_object.raw(); 215 RawObject* raw_stacktrace = stacktrace_object.raw();
230 216
231 #if !defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_DBC)
232 ASSERT(pool_pointer_slot != NULL);
233 uword pool_pointer = *pool_pointer_slot;
234 // TODO(rmacnak): Lazy deopt without patching alters pc and pp here.
235 #else
236 uword pool_pointer = 0;
237 #endif
238
239 #if defined(USING_SIMULATOR) 217 #if defined(USING_SIMULATOR)
240 // Unwinding of the C++ frames and destroying of their stack resources is done 218 // Unwinding of the C++ frames and destroying of their stack resources is done
241 // by the simulator, because the target stack_pointer is a simulated stack 219 // by the simulator, because the target stack_pointer is a simulated stack
242 // pointer and not the C++ stack pointer. 220 // pointer and not the C++ stack pointer.
243 221
244 // Continue simulating at the given pc in the given frame after setting up the 222 // Continue simulating at the given pc in the given frame after setting up the
245 // exception object in the kExceptionObjectReg register and the stacktrace 223 // exception object in the kExceptionObjectReg register and the stacktrace
246 // object (may be raw null) in the kStackTraceObjectReg register. 224 // object (may be raw null) in the kStackTraceObjectReg register.
247 225
248 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer, 226 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer,
249 pool_pointer, raw_exception, raw_stacktrace, 227 raw_exception, raw_stacktrace, thread);
250 thread);
251 #else 228 #else
252 // Prepare for unwinding frames by destroying all the stack resources 229 // Prepare for unwinding frames by destroying all the stack resources
253 // in the previous frames. 230 // in the previous frames.
254 StackResource::Unwind(thread); 231 StackResource::Unwind(thread);
255 232
256 // Call a stub to set up the exception object in kExceptionObjectReg, 233 // Call a stub to set up the exception object in kExceptionObjectReg,
257 // to set up the stacktrace object in kStackTraceObjectReg, and to 234 // to set up the stacktrace object in kStackTraceObjectReg, and to
258 // continue execution at the given pc in the given frame. 235 // continue execution at the given pc in the given frame.
259 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*, 236 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*,
260 Thread*, uword); 237 Thread*);
261 ExcpHandler func = reinterpret_cast<ExcpHandler>( 238 ExcpHandler func = reinterpret_cast<ExcpHandler>(
262 StubCode::JumpToExceptionHandler_entry()->EntryPoint()); 239 StubCode::JumpToExceptionHandler_entry()->EntryPoint());
263 240
264 // Unpoison the stack before we tear it down in the generated stub code. 241 // Unpoison the stack before we tear it down in the generated stub code.
265 uword current_sp = Thread::GetCurrentStackPointer() - 1024; 242 uword current_sp = Thread::GetCurrentStackPointer() - 1024;
266 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), 243 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp),
267 stack_pointer - current_sp); 244 stack_pointer - current_sp);
268 245
269 func(program_counter, stack_pointer, frame_pointer, 246 func(program_counter, stack_pointer, frame_pointer,
270 raw_exception, raw_stacktrace, thread, pool_pointer); 247 raw_exception, raw_stacktrace, thread);
271 #endif 248 #endif
272 UNREACHABLE(); 249 UNREACHABLE();
273 } 250 }
274 251
275 252
276 static RawField* LookupStacktraceField(const Instance& instance) { 253 static RawField* LookupStacktraceField(const Instance& instance) {
277 if (instance.GetClassId() < kNumPredefinedCids) { 254 if (instance.GetClassId() < kNumPredefinedCids) {
278 // 'class Error' is not a predefined class. 255 // 'class Error' is not a predefined class.
279 return Field::null(); 256 return Field::null();
280 } 257 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 if (exception.IsNull()) { 310 if (exception.IsNull()) {
334 exception ^= Exceptions::Create(Exceptions::kNullThrown, 311 exception ^= Exceptions::Create(Exceptions::kNullThrown,
335 Object::empty_array()); 312 Object::empty_array());
336 } else if (exception.raw() == isolate->object_store()->out_of_memory() || 313 } else if (exception.raw() == isolate->object_store()->out_of_memory() ||
337 exception.raw() == isolate->object_store()->stack_overflow()) { 314 exception.raw() == isolate->object_store()->stack_overflow()) {
338 use_preallocated_stacktrace = true; 315 use_preallocated_stacktrace = true;
339 } 316 }
340 uword handler_pc = 0; 317 uword handler_pc = 0;
341 uword handler_sp = 0; 318 uword handler_sp = 0;
342 uword handler_fp = 0; 319 uword handler_fp = 0;
343 uword* handler_pp_slot = 0;
344 Instance& stacktrace = Instance::Handle(zone); 320 Instance& stacktrace = Instance::Handle(zone);
345 bool handler_exists = false; 321 bool handler_exists = false;
346 bool handler_needs_stacktrace = false; 322 bool handler_needs_stacktrace = false;
347 if (use_preallocated_stacktrace) { 323 if (use_preallocated_stacktrace) {
348 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); 324 stacktrace ^= isolate->object_store()->preallocated_stack_trace();
349 PreallocatedStacktraceBuilder frame_builder(stacktrace); 325 PreallocatedStacktraceBuilder frame_builder(stacktrace);
350 handler_exists = FindExceptionHandler(thread, 326 handler_exists = FindExceptionHandler(thread,
351 &handler_pc, 327 &handler_pc,
352 &handler_sp, 328 &handler_sp,
353 &handler_fp, 329 &handler_fp,
354 &handler_pp_slot,
355 &handler_needs_stacktrace); 330 &handler_needs_stacktrace);
356 if (handler_pc == 0) { 331 if (handler_pc == 0) {
357 // No Dart frame. 332 // No Dart frame.
358 ASSERT(incoming_exception.raw() == 333 ASSERT(incoming_exception.raw() ==
359 isolate->object_store()->out_of_memory()); 334 isolate->object_store()->out_of_memory());
360 const UnhandledException& error = UnhandledException::Handle( 335 const UnhandledException& error = UnhandledException::Handle(
361 zone, isolate->object_store()->preallocated_unhandled_exception()); 336 zone, isolate->object_store()->preallocated_unhandled_exception());
362 thread->long_jump_base()->Jump(1, error); 337 thread->long_jump_base()->Jump(1, error);
363 UNREACHABLE(); 338 UNREACHABLE();
364 } 339 }
365 if (handler_needs_stacktrace) { 340 if (handler_needs_stacktrace) {
366 BuildStackTrace(&frame_builder); 341 BuildStackTrace(&frame_builder);
367 } 342 }
368 } else { 343 } else {
369 // Get stacktrace field of class Error. This is needed to determine whether 344 // Get stacktrace field of class Error. This is needed to determine whether
370 // we have a subclass of Error which carries around its stack trace. 345 // we have a subclass of Error which carries around its stack trace.
371 const Field& stacktrace_field = 346 const Field& stacktrace_field =
372 Field::Handle(zone, LookupStacktraceField(exception)); 347 Field::Handle(zone, LookupStacktraceField(exception));
373 348
374 // Find the exception handler and determine if the handler needs a 349 // Find the exception handler and determine if the handler needs a
375 // stacktrace. 350 // stacktrace.
376 handler_exists = FindExceptionHandler(thread, 351 handler_exists = FindExceptionHandler(thread,
377 &handler_pc, 352 &handler_pc,
378 &handler_sp, 353 &handler_sp,
379 &handler_fp, 354 &handler_fp,
380 &handler_pp_slot,
381 &handler_needs_stacktrace); 355 &handler_needs_stacktrace);
382 if (!existing_stacktrace.IsNull()) { 356 if (!existing_stacktrace.IsNull()) {
383 // If we have an existing stack trace then this better be a rethrow. The 357 // If we have an existing stack trace then this better be a rethrow. The
384 // reverse is not necessarily true (e.g. Dart_PropagateError can cause 358 // reverse is not necessarily true (e.g. Dart_PropagateError can cause
385 // a rethrow being called without an existing stacktrace.) 359 // a rethrow being called without an existing stacktrace.)
386 ASSERT(is_rethrow); 360 ASSERT(is_rethrow);
387 ASSERT(stacktrace_field.IsNull() || 361 ASSERT(stacktrace_field.IsNull() ||
388 (exception.GetField(stacktrace_field) != Object::null())); 362 (exception.GetField(stacktrace_field) != Object::null()));
389 stacktrace = existing_stacktrace.raw(); 363 stacktrace = existing_stacktrace.raw();
390 } else if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { 364 } else if (!stacktrace_field.IsNull() || handler_needs_stacktrace) {
(...skipping 17 matching lines...) Expand all
408 if (FLAG_print_stacktrace_at_throw) { 382 if (FLAG_print_stacktrace_at_throw) {
409 THR_Print("Exception '%s' thrown:\n", exception.ToCString()); 383 THR_Print("Exception '%s' thrown:\n", exception.ToCString());
410 THR_Print("%s\n", stacktrace.ToCString()); 384 THR_Print("%s\n", stacktrace.ToCString());
411 } 385 }
412 if (handler_exists) { 386 if (handler_exists) {
413 // Found a dart handler for the exception, jump to it. 387 // Found a dart handler for the exception, jump to it.
414 JumpToExceptionHandler(thread, 388 JumpToExceptionHandler(thread,
415 handler_pc, 389 handler_pc,
416 handler_sp, 390 handler_sp,
417 handler_fp, 391 handler_fp,
418 handler_pp_slot,
419 exception, 392 exception,
420 stacktrace); 393 stacktrace);
421 } else { 394 } else {
422 // No dart exception handler found in this invocation sequence, 395 // No dart exception handler found in this invocation sequence,
423 // so we create an unhandled exception object and return to the 396 // so we create an unhandled exception object and return to the
424 // invocation stub so that it returns this unhandled exception 397 // invocation stub so that it returns this unhandled exception
425 // object. The C++ code which invoked this dart sequence can check 398 // object. The C++ code which invoked this dart sequence can check
426 // and do the appropriate thing (rethrow the exception to the 399 // and do the appropriate thing (rethrow the exception to the
427 // dart invocation sequence above it, print diagnostics and terminate 400 // dart invocation sequence above it, print diagnostics and terminate
428 // the isolate etc.). 401 // the isolate etc.).
429 const UnhandledException& unhandled_exception = UnhandledException::Handle( 402 const UnhandledException& unhandled_exception = UnhandledException::Handle(
430 zone, UnhandledException::New(exception, stacktrace)); 403 zone, UnhandledException::New(exception, stacktrace));
431 stacktrace = Stacktrace::null(); 404 stacktrace = Stacktrace::null();
432 JumpToExceptionHandler(thread, 405 JumpToExceptionHandler(thread,
433 handler_pc, 406 handler_pc,
434 handler_sp, 407 handler_sp,
435 handler_fp, 408 handler_fp,
436 handler_pp_slot,
437 unhandled_exception, 409 unhandled_exception,
438 stacktrace); 410 stacktrace);
439 } 411 }
440 UNREACHABLE(); 412 UNREACHABLE();
441 } 413 }
442 414
443 415
444 // Static helpers for allocating, initializing, and throwing an error instance. 416 // Static helpers for allocating, initializing, and throwing an error instance.
445 417
446 // Return the script of the Dart function that called the native entry or the 418 // Return the script of the Dart function that called the native entry or the
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 const Instance& exc = Instance::Handle(zone, uhe.exception()); 582 const Instance& exc = Instance::Handle(zone, uhe.exception());
611 const Instance& stk = Instance::Handle(zone, uhe.stacktrace()); 583 const Instance& stk = Instance::Handle(zone, uhe.stacktrace());
612 Exceptions::ReThrow(thread, exc, stk); 584 Exceptions::ReThrow(thread, exc, stk);
613 } else { 585 } else {
614 // Return to the invocation stub and return this error object. The 586 // Return to the invocation stub and return this error object. The
615 // C++ code which invoked this dart sequence can check and do the 587 // C++ code which invoked this dart sequence can check and do the
616 // appropriate thing. 588 // appropriate thing.
617 uword handler_pc = 0; 589 uword handler_pc = 0;
618 uword handler_sp = 0; 590 uword handler_sp = 0;
619 uword handler_fp = 0; 591 uword handler_fp = 0;
620 uword* handler_pp_slot = NULL; 592 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
621 const Stacktrace& stacktrace = Stacktrace::Handle(zone); // null 593 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
622 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp, &handler_pp_slot); 594 Stacktrace::Handle(zone)); // Null stacktrace.
623 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
624 handler_pp_slot, error, stacktrace);
625 } 595 }
626 UNREACHABLE(); 596 UNREACHABLE();
627 } 597 }
628 598
629 599
630 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { 600 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
631 Thread* thread = Thread::Current(); 601 Thread* thread = Thread::Current();
632 const Object& result = 602 const Object& result =
633 Object::Handle(thread->zone(), Create(type, arguments)); 603 Object::Handle(thread->zone(), Create(type, arguments));
634 if (result.IsError()) { 604 if (result.IsError()) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 } 738 }
769 739
770 return DartLibraryCalls::InstanceCreate(library, 740 return DartLibraryCalls::InstanceCreate(library,
771 *class_name, 741 *class_name,
772 *constructor_name, 742 *constructor_name,
773 arguments); 743 arguments);
774 } 744 }
775 745
776 746
777 } // namespace dart 747 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/simulator_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698