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

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

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