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

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

Issue 1393373003: Remove isolate argument from handle allocation: Part I (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanups Created 5 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 | « runtime/vm/debugger.cc ('k') | no next file » | 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 19 matching lines...) Expand all
30 public: 30 public:
31 StacktraceBuilder() { } 31 StacktraceBuilder() { }
32 virtual ~StacktraceBuilder() { } 32 virtual ~StacktraceBuilder() { }
33 33
34 virtual void AddFrame(const Code& code, const Smi& offset) = 0; 34 virtual void AddFrame(const Code& code, const Smi& offset) = 0;
35 }; 35 };
36 36
37 37
38 class RegularStacktraceBuilder : public StacktraceBuilder { 38 class RegularStacktraceBuilder : public StacktraceBuilder {
39 public: 39 public:
40 explicit RegularStacktraceBuilder(Isolate* isolate) 40 explicit RegularStacktraceBuilder(Zone* zone)
41 : code_list_( 41 : code_list_(
42 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New())), 42 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())),
43 pc_offset_list_( 43 pc_offset_list_(
44 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New())) { } 44 GrowableObjectArray::Handle(zone, GrowableObjectArray::New())) { }
45 ~RegularStacktraceBuilder() { } 45 ~RegularStacktraceBuilder() { }
46 46
47 const GrowableObjectArray& code_list() const { return code_list_; } 47 const GrowableObjectArray& code_list() const { return code_list_; }
48 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; } 48 const GrowableObjectArray& pc_offset_list() const { return pc_offset_list_; }
49 49
50 virtual void AddFrame(const Code& code, const Smi& offset) { 50 virtual void AddFrame(const Code& code, const Smi& offset) {
51 code_list_.Add(code); 51 code_list_.Add(code);
52 pc_offset_list_.Add(offset); 52 pc_offset_list_.Add(offset);
53 } 53 }
54 54
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset); 104 stacktrace_.SetPcOffsetAtFrame(prev, frame_offset);
105 } 105 }
106 cur_index_ = (Stacktrace::kPreallocatedStackdepth - 1); 106 cur_index_ = (Stacktrace::kPreallocatedStackdepth - 1);
107 } 107 }
108 stacktrace_.SetCodeAtFrame(cur_index_, code); 108 stacktrace_.SetCodeAtFrame(cur_index_, code);
109 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset); 109 stacktrace_.SetPcOffsetAtFrame(cur_index_, offset);
110 cur_index_ += 1; 110 cur_index_ += 1;
111 } 111 }
112 112
113 113
114 static void BuildStackTrace(Isolate* isolate, StacktraceBuilder* builder) { 114 static void BuildStackTrace(StacktraceBuilder* builder) {
115 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); 115 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
116 StackFrame* frame = frames.NextFrame(); 116 StackFrame* frame = frames.NextFrame();
117 ASSERT(frame != NULL); // We expect to find a dart invocation frame. 117 ASSERT(frame != NULL); // We expect to find a dart invocation frame.
118 Code& code = Code::Handle(); 118 Code& code = Code::Handle();
119 Smi& offset = Smi::Handle(); 119 Smi& offset = Smi::Handle();
120 while (frame != NULL) { 120 while (frame != NULL) {
121 if (frame->IsDartFrame()) { 121 if (frame->IsDartFrame()) {
122 code = frame->LookupDartCode(); 122 code = frame->LookupDartCode();
123 offset = Smi::New(frame->pc() - code.EntryPoint()); 123 offset = Smi::New(frame->pc() - code.EntryPoint());
124 builder->AddFrame(code, offset); 124 builder->AddFrame(code, offset);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 }
250 Isolate* isolate = Isolate::Current(); 250 Thread* thread = Thread::Current();
251 Class& error_class = Class::Handle(isolate, 251 Zone* zone = thread->zone();
252 Isolate* isolate = thread->isolate();
253 Class& error_class = Class::Handle(zone,
252 isolate->object_store()->error_class()); 254 isolate->object_store()->error_class());
253 if (error_class.IsNull()) { 255 if (error_class.IsNull()) {
254 const Library& core_lib = Library::Handle(isolate, Library::CoreLibrary()); 256 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
255 error_class = core_lib.LookupClass(Symbols::Error()); 257 error_class = core_lib.LookupClass(Symbols::Error());
256 ASSERT(!error_class.IsNull()); 258 ASSERT(!error_class.IsNull());
257 isolate->object_store()->set_error_class(error_class); 259 isolate->object_store()->set_error_class(error_class);
258 } 260 }
259 // If instance class extends 'class Error' return '_stackTrace' field. 261 // If instance class extends 'class Error' return '_stackTrace' field.
260 Class& test_class = Class::Handle(isolate, instance.clazz()); 262 Class& test_class = Class::Handle(zone, instance.clazz());
261 AbstractType& type = AbstractType::Handle(isolate, AbstractType::null()); 263 AbstractType& type = AbstractType::Handle(zone, AbstractType::null());
262 while (true) { 264 while (true) {
263 if (test_class.raw() == error_class.raw()) { 265 if (test_class.raw() == error_class.raw()) {
264 return error_class.LookupInstanceField(Symbols::_stackTrace()); 266 return error_class.LookupInstanceField(Symbols::_stackTrace());
265 } 267 }
266 type = test_class.super_type(); 268 type = test_class.super_type();
267 if (type.IsNull()) return Field::null(); 269 if (type.IsNull()) return Field::null();
268 test_class = type.type_class(); 270 test_class = type.type_class();
269 } 271 }
270 UNREACHABLE(); 272 UNREACHABLE();
271 return Field::null(); 273 return Field::null();
272 } 274 }
273 275
274 276
275 RawStacktrace* Exceptions::CurrentStacktrace() { 277 RawStacktrace* Exceptions::CurrentStacktrace() {
276 Isolate* isolate = Isolate::Current(); 278 Zone* zone = Thread::Current()->zone();
277 RegularStacktraceBuilder frame_builder(isolate); 279 RegularStacktraceBuilder frame_builder(zone);
278 BuildStackTrace(isolate, &frame_builder); 280 BuildStackTrace(&frame_builder);
279 281
280 // Create arrays for code and pc_offset tuples of each frame. 282 // Create arrays for code and pc_offset tuples of each frame.
281 const Array& full_code_array = Array::Handle(isolate, 283 const Array& full_code_array = Array::Handle(zone,
282 Array::MakeArray(frame_builder.code_list())); 284 Array::MakeArray(frame_builder.code_list()));
283 const Array& full_pc_offset_array = Array::Handle(isolate, 285 const Array& full_pc_offset_array = Array::Handle(zone,
284 Array::MakeArray(frame_builder.pc_offset_list())); 286 Array::MakeArray(frame_builder.pc_offset_list()));
285 const Stacktrace& full_stacktrace = Stacktrace::Handle( 287 const Stacktrace& full_stacktrace = Stacktrace::Handle(
286 Stacktrace::New(full_code_array, full_pc_offset_array)); 288 Stacktrace::New(full_code_array, full_pc_offset_array));
287 return full_stacktrace.raw(); 289 return full_stacktrace.raw();
288 } 290 }
289 291
290 292
291 static void ThrowExceptionHelper(Thread* thread, 293 static void ThrowExceptionHelper(Thread* thread,
292 const Instance& incoming_exception, 294 const Instance& incoming_exception,
293 const Instance& existing_stacktrace, 295 const Instance& existing_stacktrace,
294 const bool is_rethrow) { 296 const bool is_rethrow) {
297 Zone* zone = thread->zone();
295 Isolate* isolate = thread->isolate(); 298 Isolate* isolate = thread->isolate();
296 bool use_preallocated_stacktrace = false; 299 bool use_preallocated_stacktrace = false;
297 Instance& exception = Instance::Handle(isolate, incoming_exception.raw()); 300 Instance& exception = Instance::Handle(zone, incoming_exception.raw());
298 if (exception.IsNull()) { 301 if (exception.IsNull()) {
299 exception ^= Exceptions::Create(Exceptions::kNullThrown, 302 exception ^= Exceptions::Create(Exceptions::kNullThrown,
300 Object::empty_array()); 303 Object::empty_array());
301 } else if (exception.raw() == isolate->object_store()->out_of_memory() || 304 } else if (exception.raw() == isolate->object_store()->out_of_memory() ||
302 exception.raw() == isolate->object_store()->stack_overflow()) { 305 exception.raw() == isolate->object_store()->stack_overflow()) {
303 use_preallocated_stacktrace = true; 306 use_preallocated_stacktrace = true;
304 } 307 }
305 uword handler_pc = 0; 308 uword handler_pc = 0;
306 uword handler_sp = 0; 309 uword handler_sp = 0;
307 uword handler_fp = 0; 310 uword handler_fp = 0;
308 Instance& stacktrace = Instance::Handle(isolate); 311 Instance& stacktrace = Instance::Handle(zone);
309 bool handler_exists = false; 312 bool handler_exists = false;
310 bool handler_needs_stacktrace = false; 313 bool handler_needs_stacktrace = false;
311 if (use_preallocated_stacktrace) { 314 if (use_preallocated_stacktrace) {
312 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); 315 stacktrace ^= isolate->object_store()->preallocated_stack_trace();
313 PreallocatedStacktraceBuilder frame_builder(stacktrace); 316 PreallocatedStacktraceBuilder frame_builder(stacktrace);
314 handler_exists = FindExceptionHandler(thread, 317 handler_exists = FindExceptionHandler(thread,
315 &handler_pc, 318 &handler_pc,
316 &handler_sp, 319 &handler_sp,
317 &handler_fp, 320 &handler_fp,
318 &handler_needs_stacktrace); 321 &handler_needs_stacktrace);
319 if (handler_needs_stacktrace) { 322 if (handler_needs_stacktrace) {
320 BuildStackTrace(isolate, &frame_builder); 323 BuildStackTrace(&frame_builder);
321 } 324 }
322 } else { 325 } else {
323 // Get stacktrace field of class Error. This is needed to determine whether 326 // Get stacktrace field of class Error. This is needed to determine whether
324 // we have a subclass of Error which carries around its stack trace. 327 // we have a subclass of Error which carries around its stack trace.
325 const Field& stacktrace_field = 328 const Field& stacktrace_field =
326 Field::Handle(isolate, LookupStacktraceField(exception)); 329 Field::Handle(zone, LookupStacktraceField(exception));
327 330
328 // Find the exception handler and determine if the handler needs a 331 // Find the exception handler and determine if the handler needs a
329 // stacktrace. 332 // stacktrace.
330 handler_exists = FindExceptionHandler(thread, 333 handler_exists = FindExceptionHandler(thread,
331 &handler_pc, 334 &handler_pc,
332 &handler_sp, 335 &handler_sp,
333 &handler_fp, 336 &handler_fp,
334 &handler_needs_stacktrace); 337 &handler_needs_stacktrace);
335 if (!existing_stacktrace.IsNull()) { 338 if (!existing_stacktrace.IsNull()) {
336 // If we have an existing stack trace then this better be a rethrow. The 339 // If we have an existing stack trace then this better be a rethrow. The
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 stacktrace); 375 stacktrace);
373 } else { 376 } else {
374 // No dart exception handler found in this invocation sequence, 377 // No dart exception handler found in this invocation sequence,
375 // so we create an unhandled exception object and return to the 378 // so we create an unhandled exception object and return to the
376 // invocation stub so that it returns this unhandled exception 379 // invocation stub so that it returns this unhandled exception
377 // object. The C++ code which invoked this dart sequence can check 380 // object. The C++ code which invoked this dart sequence can check
378 // and do the appropriate thing (rethrow the exception to the 381 // and do the appropriate thing (rethrow the exception to the
379 // dart invocation sequence above it, print diagnostics and terminate 382 // dart invocation sequence above it, print diagnostics and terminate
380 // the isolate etc.). 383 // the isolate etc.).
381 const UnhandledException& unhandled_exception = UnhandledException::Handle( 384 const UnhandledException& unhandled_exception = UnhandledException::Handle(
382 isolate, UnhandledException::New(exception, stacktrace)); 385 zone, UnhandledException::New(exception, stacktrace));
383 stacktrace = Stacktrace::null(); 386 stacktrace = Stacktrace::null();
384 JumpToExceptionHandler(thread, 387 JumpToExceptionHandler(thread,
385 handler_pc, 388 handler_pc,
386 handler_sp, 389 handler_sp,
387 handler_fp, 390 handler_fp,
388 unhandled_exception, 391 unhandled_exception,
389 stacktrace); 392 stacktrace);
390 } 393 }
391 UNREACHABLE(); 394 UNREACHABLE();
392 } 395 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 void Exceptions::Throw(Thread* thread, const Instance& exception) { 481 void Exceptions::Throw(Thread* thread, const Instance& exception) {
479 // Do not notify debugger on stack overflow and out of memory exceptions. 482 // Do not notify debugger on stack overflow and out of memory exceptions.
480 // The VM would crash when the debugger calls back into the VM to 483 // The VM would crash when the debugger calls back into the VM to
481 // get values of variables. 484 // get values of variables.
482 Isolate* isolate = thread->isolate(); 485 Isolate* isolate = thread->isolate();
483 if (exception.raw() != isolate->object_store()->out_of_memory() && 486 if (exception.raw() != isolate->object_store()->out_of_memory() &&
484 exception.raw() != isolate->object_store()->stack_overflow()) { 487 exception.raw() != isolate->object_store()->stack_overflow()) {
485 isolate->debugger()->SignalExceptionThrown(exception); 488 isolate->debugger()->SignalExceptionThrown(exception);
486 } 489 }
487 // Null object is a valid exception object. 490 // Null object is a valid exception object.
488 ThrowExceptionHelper(thread, exception, Stacktrace::Handle(isolate), false); 491 ThrowExceptionHelper(thread, exception,
492 Stacktrace::Handle(thread->zone()), false);
489 } 493 }
490 494
491 void Exceptions::ReThrow(Thread* thread, 495 void Exceptions::ReThrow(Thread* thread,
492 const Instance& exception, 496 const Instance& exception,
493 const Instance& stacktrace) { 497 const Instance& stacktrace) {
494 // Null object is a valid exception object. 498 // Null object is a valid exception object.
495 ThrowExceptionHelper(thread, exception, stacktrace, true); 499 ThrowExceptionHelper(thread, exception, stacktrace, true);
496 } 500 }
497 501
498 502
499 void Exceptions::PropagateError(const Error& error) { 503 void Exceptions::PropagateError(const Error& error) {
500 Thread* thread = Thread::Current(); 504 Thread* thread = Thread::Current();
501 Isolate* isolate = thread->isolate(); 505 Isolate* isolate = thread->isolate();
506 Zone* zone = thread->zone();
502 ASSERT(isolate->top_exit_frame_info() != 0); 507 ASSERT(isolate->top_exit_frame_info() != 0);
503 if (error.IsUnhandledException()) { 508 if (error.IsUnhandledException()) {
504 // If the error object represents an unhandled exception, then 509 // If the error object represents an unhandled exception, then
505 // rethrow the exception in the normal fashion. 510 // rethrow the exception in the normal fashion.
506 const UnhandledException& uhe = UnhandledException::Cast(error); 511 const UnhandledException& uhe = UnhandledException::Cast(error);
507 const Instance& exc = Instance::Handle(isolate, uhe.exception()); 512 const Instance& exc = Instance::Handle(zone, uhe.exception());
508 const Instance& stk = Instance::Handle(isolate, uhe.stacktrace()); 513 const Instance& stk = Instance::Handle(zone, uhe.stacktrace());
509 Exceptions::ReThrow(thread, exc, stk); 514 Exceptions::ReThrow(thread, exc, stk);
510 } else { 515 } else {
511 // Return to the invocation stub and return this error object. The 516 // Return to the invocation stub and return this error object. The
512 // C++ code which invoked this dart sequence can check and do the 517 // C++ code which invoked this dart sequence can check and do the
513 // appropriate thing. 518 // appropriate thing.
514 uword handler_pc = 0; 519 uword handler_pc = 0;
515 uword handler_sp = 0; 520 uword handler_sp = 0;
516 uword handler_fp = 0; 521 uword handler_fp = 0;
517 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); 522 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
518 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error, 523 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
519 Stacktrace::Handle(isolate)); // Null stacktrace. 524 Stacktrace::Handle(zone)); // Null stacktrace.
520 } 525 }
521 UNREACHABLE(); 526 UNREACHABLE();
522 } 527 }
523 528
524 529
525 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { 530 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
526 Thread* thread = Thread::Current(); 531 Thread* thread = Thread::Current();
527 Isolate* isolate = thread->isolate(); 532 const Object& result =
528 const Object& result = Object::Handle(isolate, Create(type, arguments)); 533 Object::Handle(thread->zone(), Create(type, arguments));
529 if (result.IsError()) { 534 if (result.IsError()) {
530 // We got an error while constructing the exception object. 535 // We got an error while constructing the exception object.
531 // Propagate the error instead of throwing the exception. 536 // Propagate the error instead of throwing the exception.
532 PropagateError(Error::Cast(result)); 537 PropagateError(Error::Cast(result));
533 } else { 538 } else {
534 ASSERT(result.IsInstance()); 539 ASSERT(result.IsInstance());
535 Throw(thread, Instance::Cast(result)); 540 Throw(thread, Instance::Cast(result));
536 } 541 }
537 } 542 }
538 543
539 544
540 void Exceptions::ThrowOOM() { 545 void Exceptions::ThrowOOM() {
541 Thread* thread = Thread::Current(); 546 Thread* thread = Thread::Current();
542 Isolate* isolate = thread->isolate(); 547 Isolate* isolate = thread->isolate();
543 const Instance& oom = Instance::Handle( 548 const Instance& oom = Instance::Handle(
544 isolate, isolate->object_store()->out_of_memory()); 549 thread->zone(), isolate->object_store()->out_of_memory());
545 Throw(thread, oom); 550 Throw(thread, oom);
546 } 551 }
547 552
548 553
549 void Exceptions::ThrowStackOverflow() { 554 void Exceptions::ThrowStackOverflow() {
550 Thread* thread = Thread::Current(); 555 Thread* thread = Thread::Current();
551 Isolate* isolate = thread->isolate(); 556 Isolate* isolate = thread->isolate();
552 const Instance& stack_overflow = Instance::Handle( 557 const Instance& stack_overflow = Instance::Handle(
553 isolate, isolate->object_store()->stack_overflow()); 558 thread->zone(), isolate->object_store()->stack_overflow());
554 Throw(thread, stack_overflow); 559 Throw(thread, stack_overflow);
555 } 560 }
556 561
557 562
558 void Exceptions::ThrowArgumentError(const Instance& arg) { 563 void Exceptions::ThrowArgumentError(const Instance& arg) {
559 const Array& args = Array::Handle(Array::New(1)); 564 const Array& args = Array::Handle(Array::New(1));
560 args.SetAt(0, arg); 565 args.SetAt(0, arg);
561 Exceptions::ThrowByType(Exceptions::kArgument, args); 566 Exceptions::ThrowByType(Exceptions::kArgument, args);
562 } 567 }
563 568
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 676
672 // Throw JavascriptCompatibilityError exception. 677 // Throw JavascriptCompatibilityError exception.
673 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) { 678 void Exceptions::ThrowJavascriptCompatibilityError(const char* msg) {
674 const Array& exc_args = Array::Handle(Array::New(1)); 679 const Array& exc_args = Array::Handle(Array::New(1));
675 const String& msg_str = String::Handle(String::New(msg)); 680 const String& msg_str = String::Handle(String::New(msg));
676 exc_args.SetAt(0, msg_str); 681 exc_args.SetAt(0, msg_str);
677 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args); 682 Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args);
678 } 683 }
679 684
680 } // namespace dart 685 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698