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

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,
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 = 0;
Florian Schneider 2016/09/27 22:21:08 ObjectPool& saved_pp = ObjectPool::Handle();
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 = saved_pp;
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 = frame->saved_caller_pp();
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 = saved_pp;
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) {
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);
194 while (!frame->IsEntryFrame()) { 202 while (!frame->IsEntryFrame()) {
195 frame = frames.NextFrame(); 203 frame = frames.NextFrame();
196 ASSERT(frame != NULL); 204 ASSERT(frame != NULL);
197 } 205 }
198 ASSERT(frame->IsEntryFrame()); 206 ASSERT(frame->IsEntryFrame());
199 *handler_pc = frame->pc(); 207 *handler_pc = frame->pc();
200 *handler_sp = frame->sp(); 208 *handler_sp = frame->sp();
201 *handler_fp = frame->fp(); 209 *handler_fp = frame->fp();
210 *handler_pp = 0;
202 } 211 }
203 212
204 213
205 static void JumpToExceptionHandler(Thread* thread, 214 static void JumpToExceptionHandler(Thread* thread,
206 uword program_counter, 215 uword program_counter,
207 uword stack_pointer, 216 uword stack_pointer,
208 uword frame_pointer, 217 uword frame_pointer,
218 uword pool_pointer,
Florian Schneider 2016/09/27 22:21:08 Pass const ObjectPool& pool_pointer like we pass t
209 const Object& exception_object, 219 const Object& exception_object,
210 const Object& stacktrace_object) { 220 const Object& stacktrace_object) {
211 // The no_gc StackResource is unwound through the tear down of 221 // The no_gc StackResource is unwound through the tear down of
212 // stack resources below. 222 // stack resources below.
213 NoSafepointScope no_safepoint; 223 NoSafepointScope no_safepoint;
214 RawObject* raw_exception = exception_object.raw(); 224 RawObject* raw_exception = exception_object.raw();
215 RawObject* raw_stacktrace = stacktrace_object.raw(); 225 RawObject* raw_stacktrace = stacktrace_object.raw();
216 226
217 #if defined(USING_SIMULATOR) 227 #if defined(USING_SIMULATOR)
218 // Unwinding of the C++ frames and destroying of their stack resources is done 228 // 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 229 // by the simulator, because the target stack_pointer is a simulated stack
220 // pointer and not the C++ stack pointer. 230 // pointer and not the C++ stack pointer.
221 231
222 // Continue simulating at the given pc in the given frame after setting up the 232 // Continue simulating at the given pc in the given frame after setting up the
223 // exception object in the kExceptionObjectReg register and the stacktrace 233 // exception object in the kExceptionObjectReg register and the stacktrace
224 // object (may be raw null) in the kStackTraceObjectReg register. 234 // object (may be raw null) in the kStackTraceObjectReg register.
225 235
226 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer, 236 Simulator::Current()->Longjmp(program_counter, stack_pointer, frame_pointer,
227 raw_exception, raw_stacktrace, thread); 237 pool_pointer, raw_exception, raw_stacktrace,
238 thread);
228 #else 239 #else
229 // Prepare for unwinding frames by destroying all the stack resources 240 // Prepare for unwinding frames by destroying all the stack resources
230 // in the previous frames. 241 // in the previous frames.
231 StackResource::Unwind(thread); 242 StackResource::Unwind(thread);
232 243
233 // Call a stub to set up the exception object in kExceptionObjectReg, 244 // Call a stub to set up the exception object in kExceptionObjectReg,
234 // to set up the stacktrace object in kStackTraceObjectReg, and to 245 // to set up the stacktrace object in kStackTraceObjectReg, and to
235 // continue execution at the given pc in the given frame. 246 // continue execution at the given pc in the given frame.
236 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*, 247 typedef void (*ExcpHandler)(uword, uword, uword, RawObject*, RawObject*,
237 Thread*); 248 Thread*, uword);
Florian Schneider 2016/09/27 22:21:08 Can you make the pool pointer argument RawObject*?
238 ExcpHandler func = reinterpret_cast<ExcpHandler>( 249 ExcpHandler func = reinterpret_cast<ExcpHandler>(
239 StubCode::JumpToExceptionHandler_entry()->EntryPoint()); 250 StubCode::JumpToExceptionHandler_entry()->EntryPoint());
240 251
241 // Unpoison the stack before we tear it down in the generated stub code. 252 // Unpoison the stack before we tear it down in the generated stub code.
242 uword current_sp = Thread::GetCurrentStackPointer() - 1024; 253 uword current_sp = Thread::GetCurrentStackPointer() - 1024;
243 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp), 254 ASAN_UNPOISON(reinterpret_cast<void*>(current_sp),
244 stack_pointer - current_sp); 255 stack_pointer - current_sp);
245 256
246 func(program_counter, stack_pointer, frame_pointer, 257 func(program_counter, stack_pointer, frame_pointer,
247 raw_exception, raw_stacktrace, thread); 258 raw_exception, raw_stacktrace, thread, pool_pointer);
248 #endif 259 #endif
249 UNREACHABLE(); 260 UNREACHABLE();
250 } 261 }
251 262
252 263
253 static RawField* LookupStacktraceField(const Instance& instance) { 264 static RawField* LookupStacktraceField(const Instance& instance) {
254 if (instance.GetClassId() < kNumPredefinedCids) { 265 if (instance.GetClassId() < kNumPredefinedCids) {
255 // 'class Error' is not a predefined class. 266 // 'class Error' is not a predefined class.
256 return Field::null(); 267 return Field::null();
257 } 268 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 if (exception.IsNull()) { 321 if (exception.IsNull()) {
311 exception ^= Exceptions::Create(Exceptions::kNullThrown, 322 exception ^= Exceptions::Create(Exceptions::kNullThrown,
312 Object::empty_array()); 323 Object::empty_array());
313 } else if (exception.raw() == isolate->object_store()->out_of_memory() || 324 } else if (exception.raw() == isolate->object_store()->out_of_memory() ||
314 exception.raw() == isolate->object_store()->stack_overflow()) { 325 exception.raw() == isolate->object_store()->stack_overflow()) {
315 use_preallocated_stacktrace = true; 326 use_preallocated_stacktrace = true;
316 } 327 }
317 uword handler_pc = 0; 328 uword handler_pc = 0;
318 uword handler_sp = 0; 329 uword handler_sp = 0;
319 uword handler_fp = 0; 330 uword handler_fp = 0;
331 uword handler_pp = 0;
320 Instance& stacktrace = Instance::Handle(zone); 332 Instance& stacktrace = Instance::Handle(zone);
321 bool handler_exists = false; 333 bool handler_exists = false;
322 bool handler_needs_stacktrace = false; 334 bool handler_needs_stacktrace = false;
323 if (use_preallocated_stacktrace) { 335 if (use_preallocated_stacktrace) {
324 stacktrace ^= isolate->object_store()->preallocated_stack_trace(); 336 stacktrace ^= isolate->object_store()->preallocated_stack_trace();
325 PreallocatedStacktraceBuilder frame_builder(stacktrace); 337 PreallocatedStacktraceBuilder frame_builder(stacktrace);
326 handler_exists = FindExceptionHandler(thread, 338 handler_exists = FindExceptionHandler(thread,
327 &handler_pc, 339 &handler_pc,
328 &handler_sp, 340 &handler_sp,
329 &handler_fp, 341 &handler_fp,
342 &handler_pp,
330 &handler_needs_stacktrace); 343 &handler_needs_stacktrace);
331 if (handler_pc == 0) { 344 if (handler_pc == 0) {
332 // No Dart frame. 345 // No Dart frame.
333 ASSERT(incoming_exception.raw() == 346 ASSERT(incoming_exception.raw() ==
334 isolate->object_store()->out_of_memory()); 347 isolate->object_store()->out_of_memory());
335 const UnhandledException& error = UnhandledException::Handle( 348 const UnhandledException& error = UnhandledException::Handle(
336 zone, isolate->object_store()->preallocated_unhandled_exception()); 349 zone, isolate->object_store()->preallocated_unhandled_exception());
337 thread->long_jump_base()->Jump(1, error); 350 thread->long_jump_base()->Jump(1, error);
338 UNREACHABLE(); 351 UNREACHABLE();
339 } 352 }
340 if (handler_needs_stacktrace) { 353 if (handler_needs_stacktrace) {
341 BuildStackTrace(&frame_builder); 354 BuildStackTrace(&frame_builder);
342 } 355 }
343 } else { 356 } else {
344 // Get stacktrace field of class Error. This is needed to determine whether 357 // 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. 358 // we have a subclass of Error which carries around its stack trace.
346 const Field& stacktrace_field = 359 const Field& stacktrace_field =
347 Field::Handle(zone, LookupStacktraceField(exception)); 360 Field::Handle(zone, LookupStacktraceField(exception));
348 361
349 // Find the exception handler and determine if the handler needs a 362 // Find the exception handler and determine if the handler needs a
350 // stacktrace. 363 // stacktrace.
351 handler_exists = FindExceptionHandler(thread, 364 handler_exists = FindExceptionHandler(thread,
352 &handler_pc, 365 &handler_pc,
353 &handler_sp, 366 &handler_sp,
354 &handler_fp, 367 &handler_fp,
368 &handler_pp,
355 &handler_needs_stacktrace); 369 &handler_needs_stacktrace);
356 if (!existing_stacktrace.IsNull()) { 370 if (!existing_stacktrace.IsNull()) {
357 // If we have an existing stack trace then this better be a rethrow. The 371 // 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 372 // reverse is not necessarily true (e.g. Dart_PropagateError can cause
359 // a rethrow being called without an existing stacktrace.) 373 // a rethrow being called without an existing stacktrace.)
360 ASSERT(is_rethrow); 374 ASSERT(is_rethrow);
361 ASSERT(stacktrace_field.IsNull() || 375 ASSERT(stacktrace_field.IsNull() ||
362 (exception.GetField(stacktrace_field) != Object::null())); 376 (exception.GetField(stacktrace_field) != Object::null()));
363 stacktrace = existing_stacktrace.raw(); 377 stacktrace = existing_stacktrace.raw();
364 } else if (!stacktrace_field.IsNull() || handler_needs_stacktrace) { 378 } else if (!stacktrace_field.IsNull() || handler_needs_stacktrace) {
(...skipping 17 matching lines...) Expand all
382 if (FLAG_print_stacktrace_at_throw) { 396 if (FLAG_print_stacktrace_at_throw) {
383 THR_Print("Exception '%s' thrown:\n", exception.ToCString()); 397 THR_Print("Exception '%s' thrown:\n", exception.ToCString());
384 THR_Print("%s\n", stacktrace.ToCString()); 398 THR_Print("%s\n", stacktrace.ToCString());
385 } 399 }
386 if (handler_exists) { 400 if (handler_exists) {
387 // Found a dart handler for the exception, jump to it. 401 // Found a dart handler for the exception, jump to it.
388 JumpToExceptionHandler(thread, 402 JumpToExceptionHandler(thread,
389 handler_pc, 403 handler_pc,
390 handler_sp, 404 handler_sp,
391 handler_fp, 405 handler_fp,
406 handler_pp,
392 exception, 407 exception,
393 stacktrace); 408 stacktrace);
394 } else { 409 } else {
395 // No dart exception handler found in this invocation sequence, 410 // No dart exception handler found in this invocation sequence,
396 // so we create an unhandled exception object and return to the 411 // so we create an unhandled exception object and return to the
397 // invocation stub so that it returns this unhandled exception 412 // invocation stub so that it returns this unhandled exception
398 // object. The C++ code which invoked this dart sequence can check 413 // object. The C++ code which invoked this dart sequence can check
399 // and do the appropriate thing (rethrow the exception to the 414 // and do the appropriate thing (rethrow the exception to the
400 // dart invocation sequence above it, print diagnostics and terminate 415 // dart invocation sequence above it, print diagnostics and terminate
401 // the isolate etc.). 416 // the isolate etc.).
402 const UnhandledException& unhandled_exception = UnhandledException::Handle( 417 const UnhandledException& unhandled_exception = UnhandledException::Handle(
403 zone, UnhandledException::New(exception, stacktrace)); 418 zone, UnhandledException::New(exception, stacktrace));
404 stacktrace = Stacktrace::null(); 419 stacktrace = Stacktrace::null();
405 JumpToExceptionHandler(thread, 420 JumpToExceptionHandler(thread,
406 handler_pc, 421 handler_pc,
407 handler_sp, 422 handler_sp,
408 handler_fp, 423 handler_fp,
424 handler_pp,
409 unhandled_exception, 425 unhandled_exception,
410 stacktrace); 426 stacktrace);
411 } 427 }
412 UNREACHABLE(); 428 UNREACHABLE();
413 } 429 }
414 430
415 431
416 // Static helpers for allocating, initializing, and throwing an error instance. 432 // Static helpers for allocating, initializing, and throwing an error instance.
417 433
418 // Return the script of the Dart function that called the native entry or the 434 // 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()); 598 const Instance& exc = Instance::Handle(zone, uhe.exception());
583 const Instance& stk = Instance::Handle(zone, uhe.stacktrace()); 599 const Instance& stk = Instance::Handle(zone, uhe.stacktrace());
584 Exceptions::ReThrow(thread, exc, stk); 600 Exceptions::ReThrow(thread, exc, stk);
585 } else { 601 } else {
586 // Return to the invocation stub and return this error object. The 602 // Return to the invocation stub and return this error object. The
587 // C++ code which invoked this dart sequence can check and do the 603 // C++ code which invoked this dart sequence can check and do the
588 // appropriate thing. 604 // appropriate thing.
589 uword handler_pc = 0; 605 uword handler_pc = 0;
590 uword handler_sp = 0; 606 uword handler_sp = 0;
591 uword handler_fp = 0; 607 uword handler_fp = 0;
592 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); 608 uword handler_pp = 0;
593 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error, 609 const Stacktrace& stacktrace = Stacktrace::Handle(zone); // null
594 Stacktrace::Handle(zone)); // Null stacktrace. 610 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp, &handler_pp);
611 JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
612 handler_pp, error, stacktrace);
595 } 613 }
596 UNREACHABLE(); 614 UNREACHABLE();
597 } 615 }
598 616
599 617
600 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) { 618 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
601 Thread* thread = Thread::Current(); 619 Thread* thread = Thread::Current();
602 const Object& result = 620 const Object& result =
603 Object::Handle(thread->zone(), Create(type, arguments)); 621 Object::Handle(thread->zone(), Create(type, arguments));
604 if (result.IsError()) { 622 if (result.IsError()) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 } 756 }
739 757
740 return DartLibraryCalls::InstanceCreate(library, 758 return DartLibraryCalls::InstanceCreate(library,
741 *class_name, 759 *class_name,
742 *constructor_name, 760 *constructor_name,
743 arguments); 761 arguments);
744 } 762 }
745 763
746 764
747 } // namespace dart 765 } // 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