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

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

Issue 1156143003: Refactor Isolate -> Thread in NativeArguments and exception handler jump. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix comment; remove unused accessor. Created 5 years, 6 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 | « runtime/vm/exceptions.h ('k') | runtime/vm/isolate.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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 frame = frames.NextFrame(); 187 frame = frames.NextFrame();
188 ASSERT(frame != NULL); 188 ASSERT(frame != NULL);
189 } 189 }
190 ASSERT(frame->IsEntryFrame()); 190 ASSERT(frame->IsEntryFrame());
191 *handler_pc = frame->pc(); 191 *handler_pc = frame->pc();
192 *handler_sp = frame->sp(); 192 *handler_sp = frame->sp();
193 *handler_fp = frame->fp(); 193 *handler_fp = frame->fp();
194 } 194 }
195 195
196 196
197 static void JumpToExceptionHandler(Isolate* isolate, 197 static void JumpToExceptionHandler(Thread* thread,
198 uword program_counter, 198 uword program_counter,
199 uword stack_pointer, 199 uword stack_pointer,
200 uword frame_pointer, 200 uword frame_pointer,
201 const Object& exception_object, 201 const Object& exception_object,
202 const Object& stacktrace_object) { 202 const Object& stacktrace_object) {
203 // The no_gc StackResource is unwound through the tear down of 203 // The no_gc StackResource is unwound through the tear down of
204 // stack resources below. 204 // stack resources below.
205 NoSafepointScope no_safepoint; 205 NoSafepointScope no_safepoint;
206 RawObject* raw_exception = exception_object.raw(); 206 RawObject* raw_exception = exception_object.raw();
207 RawObject* raw_stacktrace = stacktrace_object.raw(); 207 RawObject* raw_stacktrace = stacktrace_object.raw();
208 208
209 #if defined(USING_SIMULATOR) 209 #if defined(USING_SIMULATOR)
210 // Unwinding of the C++ frames and destroying of their stack resources is done 210 // Unwinding of the C++ frames and destroying of their stack resources is done
211 // by the simulator, because the target stack_pointer is a simulated stack 211 // by the simulator, because the target stack_pointer is a simulated stack
212 // pointer and not the C++ stack pointer. 212 // pointer and not the C++ stack pointer.
213 213
214 // Continue simulating at the given pc in the given frame after setting up the 214 // Continue simulating at the given pc in the given frame after setting up the
215 // exception object in the kExceptionObjectReg register and the stacktrace 215 // exception object in the kExceptionObjectReg register and the stacktrace
216 // object (may be raw null) in the kStackTraceObjectReg register. 216 // object (may be raw null) in the kStackTraceObjectReg register.
217 217
218 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer, 218 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer,
219 raw_exception, raw_stacktrace, isolate); 219 raw_exception, raw_stacktrace, thread);
220 #else 220 #else
221 // Prepare for unwinding frames by destroying all the stack resources 221 // Prepare for unwinding frames by destroying all the stack resources
222 // in the previous frames. 222 // in the previous frames.
223 StackResource::Unwind(isolate); 223 StackResource::Unwind(thread->isolate());
224 224
225 // Call a stub to set up the exception object in kExceptionObjectReg, 225 // Call a stub to set up the exception object in kExceptionObjectReg,
226 // to set up the stacktrace object in kStackTraceObjectReg, and to 226 // to set up the stacktrace object in kStackTraceObjectReg, and to
227 // continue execution at the given pc in the given frame. 227 // continue execution at the given pc in the given frame.
228 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*, 228 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*,
229 Isolate*); 229 Thread*);
230 ExcpHandler func = reinterpret_cast<ExcpHandler>( 230 ExcpHandler func = reinterpret_cast<ExcpHandler>(
231 StubCode::JumpToExceptionHandlerEntryPoint()); 231 StubCode::JumpToExceptionHandlerEntryPoint());
232 232
233 // Unpoison the stack before we tear it down in the generated stub code. 233 // Unpoison the stack before we tear it down in the generated stub code.
234 uword current_sp = Isolate::GetCurrentStackPointer() - 1024; 234 uword current_sp = Isolate::GetCurrentStackPointer() - 1024;
235 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), 235 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp),
236 stack_pointer - current_sp); 236 stack_pointer - current_sp);
237 237
238 func(program_counter, stack_pointer, frame_pointer, 238 func(program_counter, stack_pointer, frame_pointer,
239 raw_exception, raw_stacktrace, isolate); 239 raw_exception, raw_stacktrace, thread);
240 #endif 240 #endif
241 UNREACHABLE(); 241 UNREACHABLE();
242 } 242 }
243 243
244 244
245 static RawField* LookupStacktraceField(const Instance& instance) { 245 static RawField* LookupStacktraceField(const Instance& instance) {
246 if (instance.GetClassId() < kNumPredefinedCids) { 246 if (instance.GetClassId() < kNumPredefinedCids) {
247 // 'class Error' is not a predefined class. 247 // 'class Error' is not a predefined class.
248 return Field::null(); 248 return Field::null();
249 } 249 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 const Array& full_code_array = Array::Handle(isolate, 281 const Array& full_code_array = Array::Handle(isolate,
282 Array::MakeArray(frame_builder.code_list())); 282 Array::MakeArray(frame_builder.code_list()));
283 const Array& full_pc_offset_array = Array::Handle(isolate, 283 const Array& full_pc_offset_array = Array::Handle(isolate,
284 Array::MakeArray(frame_builder.pc_offset_list())); 284 Array::MakeArray(frame_builder.pc_offset_list()));
285 const Stacktrace& full_stacktrace = Stacktrace::Handle( 285 const Stacktrace& full_stacktrace = Stacktrace::Handle(
286 Stacktrace::New(full_code_array, full_pc_offset_array)); 286 Stacktrace::New(full_code_array, full_pc_offset_array));
287 return full_stacktrace.raw(); 287 return full_stacktrace.raw();
288 } 288 }
289 289
290 290
291 static void ThrowExceptionHelper(Isolate* isolate, 291 static void ThrowExceptionHelper(Thread* thread,
292 const Instance& incoming_exception, 292 const Instance& incoming_exception,
293 const Instance& existing_stacktrace, 293 const Instance& existing_stacktrace,
294 const bool is_rethrow) { 294 const bool is_rethrow) {
295 Isolate* isolate = thread->isolate();
295 bool use_preallocated_stacktrace = false; 296 bool use_preallocated_stacktrace = false;
296 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); 297 Instance& exception = Instance::Handle(isolate, incoming_exception.raw());
297 if (exception.IsNull()) { 298 if (exception.IsNull()) {
298 exception ^= Exceptions::Create(Exceptions::kNullThrown, 299 exception ^= Exceptions::Create(Exceptions::kNullThrown,
299 Object::empty_array()); 300 Object::empty_array());
300 } else if (exception.raw() == isolate->object_store()->out_of_memory() || 301 } else if (exception.raw() == isolate->object_store()->out_of_memory() ||
301 exception.raw() == isolate->object_store()->stack_overflow()) { 302 exception.raw() == isolate->object_store()->stack_overflow()) {
302 use_preallocated_stacktrace = true; 303 use_preallocated_stacktrace = true;
303 } 304 }
304 uword handler_pc = 0; 305 uword handler_pc = 0;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // stack as Exceptions::Throw should happen only after a dart 357 // stack as Exceptions::Throw should happen only after a dart
357 // invocation has been done. 358 // invocation has been done.
358 ASSERT(handler_pc != 0); 359 ASSERT(handler_pc != 0);
359 360
360 if (FLAG_print_stacktrace_at_throw) { 361 if (FLAG_print_stacktrace_at_throw) {
361 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); 362 OS::Print("Exception '%s' thrown:\n", exception.ToCString());
362 OS::Print("%s\n", stacktrace.ToCString()); 363 OS::Print("%s\n", stacktrace.ToCString());
363 } 364 }
364 if (handler_exists) { 365 if (handler_exists) {
365 // Found a dart handler for the exception, jump to it. 366 // Found a dart handler for the exception, jump to it.
366 JumpToExceptionHandler(isolate, 367 JumpToExceptionHandler(thread,
367 handler_pc, 368 handler_pc,
368 handler_sp, 369 handler_sp,
369 handler_fp, 370 handler_fp,
370 exception, 371 exception,
371 stacktrace); 372 stacktrace);
372 } else { 373 } else {
373 // No dart exception handler found in this invocation sequence, 374 // No dart exception handler found in this invocation sequence,
374 // so we create an unhandled exception object and return to the 375 // so we create an unhandled exception object and return to the
375 // invocation stub so that it returns this unhandled exception 376 // invocation stub so that it returns this unhandled exception
376 // object. The C++ code which invoked this dart sequence can check 377 // object. The C++ code which invoked this dart sequence can check
377 // and do the appropriate thing (rethrow the exception to the 378 // and do the appropriate thing (rethrow the exception to the
378 // dart invocation sequence above it, print diagnostics and terminate 379 // dart invocation sequence above it, print diagnostics and terminate
379 // the isolate etc.). 380 // the isolate etc.).
380 const UnhandledException& unhandled_exception = UnhandledException::Handle( 381 const UnhandledException& unhandled_exception = UnhandledException::Handle(
381 isolate, UnhandledException::New(exception, stacktrace)); 382 isolate, UnhandledException::New(exception, stacktrace));
382 stacktrace = Stacktrace::null(); 383 stacktrace = Stacktrace::null();
383 JumpToExceptionHandler(isolate, 384 JumpToExceptionHandler(thread,
384 handler_pc, 385 handler_pc,
385 handler_sp, 386 handler_sp,
386 handler_fp, 387 handler_fp,
387 unhandled_exception, 388 unhandled_exception,
388 stacktrace); 389 stacktrace);
389 } 390 }
390 UNREACHABLE(); 391 UNREACHABLE();
391 } 392 }
392 393
393 394
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } else { 468 } else {
468 OS::Print("type error.\n"); 469 OS::Print("type error.\n");
469 } 470 }
470 } 471 }
471 // Throw TypeError or CastError instance. 472 // Throw TypeError or CastError instance.
472 Exceptions::ThrowByType(exception_type, args); 473 Exceptions::ThrowByType(exception_type, args);
473 UNREACHABLE(); 474 UNREACHABLE();
474 } 475 }
475 476
476 477
477 void Exceptions::Throw(Isolate* isolate, const Instance& exception) { 478 void Exceptions::Throw(Thread* thread, const Instance& exception) {
478 // Do not notify debugger on stack overflow and out of memory exceptions. 479 // Do not notify debugger on stack overflow and out of memory exceptions.
479 // The VM would crash when the debugger calls back into the VM to 480 // The VM would crash when the debugger calls back into the VM to
480 // get values of variables. 481 // get values of variables.
482 Isolate* isolate = thread->isolate();
481 if (exception.raw() != isolate->object_store()->out_of_memory() && 483 if (exception.raw() != isolate->object_store()->out_of_memory() &&
482 exception.raw() != isolate->object_store()->stack_overflow()) { 484 exception.raw() != isolate->object_store()->stack_overflow()) {
483 isolate->debugger()->SignalExceptionThrown(exception); 485 isolate->debugger()->SignalExceptionThrown(exception);
484 } 486 }
485 // Null object is a valid exception object. 487 // Null object is a valid exception object.
486 ThrowExceptionHelper(isolate, exception, Stacktrace::Handle(isolate), false); 488 ThrowExceptionHelper(thread, exception, Stacktrace::Handle(isolate), false);
487 } 489 }
488 490
489 491 void Exceptions::ReThrow(Thread* thread,
490 void Exceptions::ReThrow(Isolate* isolate,
491 const Instance& exception, 492 const Instance& exception,
492 const Instance& stacktrace) { 493 const Instance& stacktrace) {
493 // Null object is a valid exception object. 494 // Null object is a valid exception object.
494 ThrowExceptionHelper(isolate, exception, stacktrace, true); 495 ThrowExceptionHelper(thread, exception, stacktrace, true);
495 } 496 }
496 497
497 498
498 void Exceptions::PropagateError(const Error& error) { 499 void Exceptions::PropagateError(const Error& error) {
499 Isolate* isolate = Isolate::Current(); 500 Thread* thread = Thread::Current();
501 Isolate* isolate = thread->isolate();
500 ASSERT(isolate->top_exit_frame_info() != 0); 502 ASSERT(isolate->top_exit_frame_info() != 0);
501 if (error.IsUnhandledException()) { 503 if (error.IsUnhandledException()) {
502 // If the error object represents an unhandled exception, then 504 // If the error object represents an unhandled exception, then
503 // rethrow the exception in the normal fashion. 505 // rethrow the exception in the normal fashion.
504 const UnhandledException& uhe = UnhandledException::Cast(error); 506 const UnhandledException& uhe = UnhandledException::Cast(error);
505 const Instance& exc = Instance::Handle(isolate, uhe.exception()); 507 const Instance& exc = Instance::Handle(isolate, uhe.exception());
506 const Instance& stk = Instance::Handle(isolate, uhe.stacktrace()); 508 const Instance& stk = Instance::Handle(isolate, uhe.stacktrace());
507 Exceptions::ReThrow(isolate, exc, stk); 509 Exceptions::ReThrow(thread, exc, stk);
508 } else { 510 } else {
509 // Return to the invocation stub and return this error object. The 511 // Return to the invocation stub and return this error object. The
510 // C++ code which invoked this dart sequence can check and do the 512 // C++ code which invoked this dart sequence can check and do the
511 // appropriate thing. 513 // appropriate thing.
512 uword handler_pc = 0; 514 uword handler_pc = 0;
513 uword handler_sp = 0; 515 uword handler_sp = 0;
514 uword handler_fp = 0; 516 uword handler_fp = 0;
515 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); 517 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
516 JumpToExceptionHandler(isolate, handler_pc, handler_sp, handler_fp, error, 518 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
517 Stacktrace::Handle(isolate)); // Null stacktrace. 519 Stacktrace::Handle(isolate)); // Null stacktrace.
518 } 520 }
519 UNREACHABLE(); 521 UNREACHABLE();
520 } 522 }
521 523
522 524
523 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { 525 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
524 Isolate* isolate = Isolate::Current(); 526 Thread* thread = Thread::Current();
527 Isolate* isolate = thread->isolate();
525 const Object& result = Object::Handle(isolate, Create(type, arguments)); 528 const Object& result = Object::Handle(isolate, Create(type, arguments));
526 if (result.IsError()) { 529 if (result.IsError()) {
527 // We got an error while constructing the exception object. 530 // We got an error while constructing the exception object.
528 // Propagate the error instead of throwing the exception. 531 // Propagate the error instead of throwing the exception.
529 PropagateError(Error::Cast(result)); 532 PropagateError(Error::Cast(result));
530 } else { 533 } else {
531 ASSERT(result.IsInstance()); 534 ASSERT(result.IsInstance());
532 Throw(isolate, Instance::Cast(result)); 535 Throw(thread, Instance::Cast(result));
533 } 536 }
534 } 537 }
535 538
536 539
537 void Exceptions::ThrowOOM() { 540 void Exceptions::ThrowOOM() {
538 Isolate* isolate = Isolate::Current(); 541 Thread* thread = Thread::Current();
542 Isolate* isolate = thread->isolate();
539 const Instance& oom = Instance::Handle( 543 const Instance& oom = Instance::Handle(
540 isolate, isolate->object_store()->out_of_memory()); 544 isolate, isolate->object_store()->out_of_memory());
541 Throw(isolate, oom); 545 Throw(thread, oom);
542 } 546 }
543 547
544 548
545 void Exceptions::ThrowStackOverflow() { 549 void Exceptions::ThrowStackOverflow() {
546 Isolate* isolate = Isolate::Current(); 550 Thread* thread = Thread::Current();
551 Isolate* isolate = thread->isolate();
547 const Instance& stack_overflow = Instance::Handle( 552 const Instance& stack_overflow = Instance::Handle(
548 isolate, isolate->object_store()->stack_overflow()); 553 isolate, isolate->object_store()->stack_overflow());
549 Throw(isolate, stack_overflow); 554 Throw(thread, stack_overflow);
550 } 555 }
551 556
552 557
553 void Exceptions::ThrowArgumentError(const Instance& arg) { 558 void Exceptions::ThrowArgumentError(const Instance& arg) {
554 const Array& args = Array::Handle(Array::New(1)); 559 const Array& args = Array::Handle(Array::New(1));
555 args.SetAt(0, arg); 560 args.SetAt(0, arg);
556 Exceptions::ThrowByType(Exceptions::kArgument, args); 561 Exceptions::ThrowByType(Exceptions::kArgument, args);
557 } 562 }
558 563
559 564
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 669
665 // Throw JavascriptCompatibilityError exception. 670 // Throw JavascriptCompatibilityError exception.
666 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { 671 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) {
667 const Array& exc_args = Array::Handle(Array::New(1)); 672 const Array& exc_args = Array::Handle(Array::New(1));
668 const String& msg_str = String::Handle(String::New(msg)); 673 const String& msg_str = String::Handle(String::New(msg));
669 exc_args.SetAt(0, msg_str); 674 exc_args.SetAt(0, msg_str);
670 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); 675 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args);
671 } 676 }
672 677
673 } // namespace dart 678 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/exceptions.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698