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

Side by Side Diff: vm/exceptions.cc

Issue 10664004: Fix issue 1968, replace usage of inline 'asm' constructs in 'stack alignment', 'jump to exception h… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « vm/cpu_x64.cc ('k') | vm/native_arguments.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 "vm/cpu.h"
8 #include "vm/dart_entry.h" 7 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 8 #include "vm/debugger.h"
10 #include "vm/flags.h" 9 #include "vm/flags.h"
11 #include "vm/object.h" 10 #include "vm/object.h"
12 #include "vm/stack_frame.h" 11 #include "vm/stack_frame.h"
12 #include "vm/stub_code.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, print_stack_trace_at_throw, false, 16 DEFINE_FLAG(bool, print_stack_trace_at_throw, false,
17 "Prints a stack trace everytime a throw occurs."); 17 "Prints a stack trace everytime a throw occurs.");
18 18
19 // Iterate through the stack frames and try to find a frame with an 19 // Iterate through the stack frames and try to find a frame with an
20 // exception handler. Once found, set the pc, sp and fp so that execution 20 // exception handler. Once found, set the pc, sp and fp so that execution
21 // can continue in that frame. 21 // can continue in that frame.
22 static bool FindExceptionHandler(uword* handler_pc, 22 static bool FindExceptionHandler(uword* handler_pc,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 frame = frames.NextFrame(); 57 frame = frames.NextFrame();
58 ASSERT(frame != NULL); 58 ASSERT(frame != NULL);
59 } 59 }
60 ASSERT(frame->IsEntryFrame()); 60 ASSERT(frame->IsEntryFrame());
61 *handler_pc = frame->pc(); 61 *handler_pc = frame->pc();
62 *handler_sp = frame->sp(); 62 *handler_sp = frame->sp();
63 *handler_fp = frame->fp(); 63 *handler_fp = frame->fp();
64 } 64 }
65 65
66 66
67 void JumpToExceptionHandler(uword program_counter,
68 uword stack_pointer,
69 uword frame_pointer,
70 const Instance& exception_object,
71 const Instance& stacktrace_object) {
72 // The no_gc StackResource is unwound through the tear down of
73 // stack resources below.
74 NoGCScope no_gc;
75 RawInstance* exception = exception_object.raw();
76 RawInstance* stacktrace = stacktrace_object.raw();
77
78 // Prepare for unwinding frames by destroying all the stack resources
79 // in the previous frames.
80 Isolate* isolate = Isolate::Current();
81 while (isolate->top_resource() != NULL &&
82 (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) {
83 isolate->top_resource()->~StackResource();
84 }
85
86 // Set up the appropriate register state and jump to the handler.
87 typedef void (*ExcpHandler)(uword, uword, uword, RawInstance*, RawInstance*);
88 ExcpHandler func = reinterpret_cast<ExcpHandler>(
89 StubCode::JumpToExceptionHandlerEntryPoint());
90 func(program_counter, stack_pointer, frame_pointer, exception, stacktrace);
91 UNREACHABLE();
92 }
93
94
95 void JumpToErrorHandler(uword program_counter,
96 uword stack_pointer,
97 uword frame_pointer,
98 const Error& error) {
99 // The no_gc StackResource is unwound through the tear down of
100 // stack resources below.
101 NoGCScope no_gc;
102 ASSERT(!error.IsNull());
103 RawError* raw_error = error.raw();
104
105 // Prepare for unwinding frames by destroying all the stack resources
106 // in the previous frames.
107 Isolate* isolate = Isolate::Current();
108 while (isolate->top_resource() != NULL &&
109 (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) {
110 isolate->top_resource()->~StackResource();
111 }
112
113 // Set up the error object as the return value in EAX and continue
114 // from the invocation stub.
115 typedef void (*ErrorHandler)(uword, uword, uword, RawError*);
116 ErrorHandler func = reinterpret_cast<ErrorHandler>(
117 StubCode::JumpToErrorHandlerEntryPoint());
118 func(program_counter, stack_pointer, frame_pointer, raw_error);
119 UNREACHABLE();
120 }
121
122
67 static void ThrowExceptionHelper(const Instance& incoming_exception, 123 static void ThrowExceptionHelper(const Instance& incoming_exception,
68 const Instance& existing_stacktrace) { 124 const Instance& existing_stacktrace) {
69 Instance& exception = Instance::Handle(incoming_exception.raw()); 125 Instance& exception = Instance::Handle(incoming_exception.raw());
70 if (exception.IsNull()) { 126 if (exception.IsNull()) {
71 GrowableArray<const Object*> arguments; 127 GrowableArray<const Object*> arguments;
72 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments); 128 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments);
73 } 129 }
74 uword handler_pc = 0; 130 uword handler_pc = 0;
75 uword handler_sp = 0; 131 uword handler_sp = 0;
76 uword handler_fp = 0; 132 uword handler_fp = 0;
(...skipping 15 matching lines...) Expand all
92 } 148 }
93 } else { 149 } else {
94 stacktrace ^= existing_stacktrace.raw(); 150 stacktrace ^= existing_stacktrace.raw();
95 } 151 }
96 if (FLAG_print_stack_trace_at_throw) { 152 if (FLAG_print_stack_trace_at_throw) {
97 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); 153 OS::Print("Exception '%s' thrown:\n", exception.ToCString());
98 OS::Print("%s\n", stacktrace.ToCString()); 154 OS::Print("%s\n", stacktrace.ToCString());
99 } 155 }
100 if (handler_exists) { 156 if (handler_exists) {
101 // Found a dart handler for the exception, jump to it. 157 // Found a dart handler for the exception, jump to it.
102 CPU::JumpToExceptionHandler(handler_pc, 158 JumpToExceptionHandler(handler_pc,
103 handler_sp, 159 handler_sp,
104 handler_fp, 160 handler_fp,
105 exception, 161 exception,
106 stacktrace); 162 stacktrace);
107 } else { 163 } else {
108 // No dart exception handler found in this invocation sequence, 164 // No dart exception handler found in this invocation sequence,
109 // so we create an unhandled exception object and return to the 165 // so we create an unhandled exception object and return to the
110 // invocation stub so that it returns this unhandled exception 166 // invocation stub so that it returns this unhandled exception
111 // object. The C++ code which invoked this dart sequence can check 167 // object. The C++ code which invoked this dart sequence can check
112 // and do the appropriate thing (rethrow the exception to the 168 // and do the appropriate thing (rethrow the exception to the
113 // dart invocation sequence above it, print diagnostics and terminate 169 // dart invocation sequence above it, print diagnostics and terminate
114 // the isolate etc.). 170 // the isolate etc.).
115 const UnhandledException& unhandled_exception = UnhandledException::Handle( 171 const UnhandledException& unhandled_exception = UnhandledException::Handle(
116 UnhandledException::New(exception, stacktrace)); 172 UnhandledException::New(exception, stacktrace));
117 CPU::JumpToErrorHandler(handler_pc, 173 JumpToErrorHandler(handler_pc, handler_sp, handler_fp, unhandled_exception);
118 handler_sp,
119 handler_fp,
120 unhandled_exception);
121 } 174 }
122 UNREACHABLE(); 175 UNREACHABLE();
123 } 176 }
124 177
125 178
126 // Static helpers for allocating, initializing, and throwing an error instance. 179 // Static helpers for allocating, initializing, and throwing an error instance.
127 180
128 // Return the script of the Dart function that called the native entry or the 181 // Return the script of the Dart function that called the native entry or the
129 // runtime entry. The frame iterator points to the callee. 182 // runtime entry. The frame iterator points to the callee.
130 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) { 183 RawScript* Exceptions::GetCallerScript(DartFrameIterator* iterator) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const Instance& stk = Instance::Handle(uhe.stacktrace()); 325 const Instance& stk = Instance::Handle(uhe.stacktrace());
273 Exceptions::ReThrow(exc, stk); 326 Exceptions::ReThrow(exc, stk);
274 } else { 327 } else {
275 // Return to the invocation stub and return this error object. The 328 // Return to the invocation stub and return this error object. The
276 // C++ code which invoked this dart sequence can check and do the 329 // C++ code which invoked this dart sequence can check and do the
277 // appropriate thing. 330 // appropriate thing.
278 uword handler_pc = 0; 331 uword handler_pc = 0;
279 uword handler_sp = 0; 332 uword handler_sp = 0;
280 uword handler_fp = 0; 333 uword handler_fp = 0;
281 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp); 334 FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
282 CPU::JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error); 335 JumpToErrorHandler(handler_pc, handler_sp, handler_fp, error);
283 } 336 }
284 UNREACHABLE(); 337 UNREACHABLE();
285 } 338 }
286 339
287 340
288 void Exceptions::ThrowByType( 341 void Exceptions::ThrowByType(
289 ExceptionType type, const GrowableArray<const Object*>& arguments) { 342 ExceptionType type, const GrowableArray<const Object*>& arguments) {
290 const Object& result = Object::Handle(Create(type, arguments)); 343 const Object& result = Object::Handle(Create(type, arguments));
291 if (result.IsError()) { 344 if (result.IsError()) {
292 // We got an error while constructing the exception object. 345 // We got an error while constructing the exception object.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 case kIsolateSpawn: 412 case kIsolateSpawn:
360 library = Library::IsolateLibrary(); 413 library = Library::IsolateLibrary();
361 class_name = String::NewSymbol("IsolateSpawnException"); 414 class_name = String::NewSymbol("IsolateSpawnException");
362 break; 415 break;
363 } 416 }
364 417
365 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments); 418 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments);
366 } 419 }
367 420
368 } // namespace dart 421 } // namespace dart
OLDNEW
« no previous file with comments | « vm/cpu_x64.cc ('k') | vm/native_arguments.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698