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

Unified Diff: src/isolate.cc

Issue 969533004: [turbofan] Implement throwing exceptions into TurboFan code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix code lookup. Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 90a3aa1152b4287accf2e8294efa8a6433ff20d9..7cd8b002c4b096e15c83a085eba72eaaf4b8739c 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1031,29 +1031,94 @@ Object* Isolate::ReThrow(Object* exception) {
}
+// TODO(turbofan): Make sure table is sorted and use binary search.
+static int LookupInHandlerTable(Code* code, int pc_offset) {
+ FixedArray* handler_table = code->handler_table();
+ for (int i = 0; i < handler_table->length(); i += 2) {
+ int return_offset = Smi::cast(handler_table->get(i))->value();
+ int handler_offset = Smi::cast(handler_table->get(i + 1))->value();
+ if (pc_offset == return_offset) return handler_offset;
+ }
+ return -1;
+}
+
+
Object* Isolate::FindHandler() {
Object* exception = pending_exception();
- // Determine target stack handler. Special handling of termination exceptions
- // which are uncatchable by JavaScript code, we unwind the handlers until the
- // top ENTRY handler is found.
- StackHandler* handler =
- StackHandler::FromAddress(Isolate::handler(thread_local_top()));
- if (!is_catchable_by_javascript(exception)) {
- while (!handler->is_js_entry()) handler = handler->next();
- }
+ Code* code = nullptr;
+ Context* context = nullptr;
+ intptr_t offset = 0;
+ Address handler_sp = nullptr;
+ Address handler_fp = nullptr;
+
+ // Special handling of termination exceptions, uncatchable by JavaScript code,
+ // we unwind the handlers until the top ENTRY handler is found.
+ bool catchable_by_js = is_catchable_by_javascript(exception);
+
+ // Compute handler and stack unwinding information by performing a full walk
+ // over the stack and dispatching according to the frame type.
+ for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
+ StackFrame* frame = iter.frame();
+
+ // For JSEntryStub frames we always have a handler.
+ if (frame->is_entry() || frame->is_entry_construct()) {
+ StackHandler* handler = frame->top_handler();
+ DCHECK_EQ(StackHandler::JS_ENTRY, handler->kind());
+ DCHECK_EQ(0, handler->index());
+
+ // Restore the next handler.
+ thread_local_top()->handler_ = handler->next()->address();
+
+ // Gather information from the handler.
+ code = handler->code();
+ handler_sp = handler->address() + StackHandlerConstants::kSize;
+ offset = Smi::cast(code->handler_table()->get(0))->value();
+ break;
+ }
+
+ // For JavaScript frames which have a handler, we use the handler.
+ if (frame->is_java_script() && catchable_by_js && frame->HasHandler()) {
+ StackHandler* handler = frame->top_handler();
+ DCHECK_NE(StackHandler::JS_ENTRY, handler->kind());
+
+ // Restore the next handler.
+ thread_local_top()->handler_ = handler->next()->address();
+
+ // Gather information from the handler.
+ code = handler->code();
+ context = handler->context();
+ offset = Smi::cast(code->handler_table()->get(handler->index()))->value();
+ handler_sp = handler->address() + StackHandlerConstants::kSize;
+ handler_fp = handler->frame_pointer();
+ break;
+ }
- // Restore the next handler.
- thread_local_top()->handler_ = handler->next()->address();
+ // For optimized frames we perform a lookup in the handler table.
+ if (frame->is_optimized() && catchable_by_js) {
+ Code* frame_code = frame->LookupCode();
+ DCHECK(frame_code->is_optimized_code());
+ int pc_offset = static_cast<int>(frame->pc() - frame_code->entry());
+ int handler_offset = LookupInHandlerTable(frame_code, pc_offset);
+ if (handler_offset < 0) continue;
+
+ // Compute the stack pointer from the frame pointer. This ensures that
+ // argument slots on the stack are dropped as returning would.
+ Address return_sp = frame->fp() -
+ StandardFrameConstants::kFixedFrameSizeFromFp -
+ frame_code->stack_slots() * kPointerSize;
+
+ // Gather information from the frame.
+ code = frame_code;
+ offset = handler_offset;
+ handler_sp = return_sp;
+ handler_fp = frame->fp();
+ break;
+ }
+ }
- // Compute handler and stack unwinding information.
- // TODO(mstarzinger): Extend this to perform actual stack-walk and take into
- // account that TurboFan code can contain handlers as well.
- Code* code = handler->code();
- Context* context = handler->is_js_entry() ? nullptr : handler->context();
- int offset = Smi::cast(code->handler_table()->get(handler->index()))->value();
- Address handler_sp = handler->address() + StackHandlerConstants::kSize;
- Address handler_fp = handler->frame_pointer();
+ // Handler must exist.
+ CHECK(code != nullptr);
// Store information to be consumed by the CEntryStub.
thread_local_top()->pending_handler_context_ = context;
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698