Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 6e8b44e135c975d36281dce13a7313ae93b04a05..7ce8d8351b6aa0fb28afdba4bd2b2d88ad52aa5f 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -1008,18 +1008,6 @@ 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(); |
@@ -1041,7 +1029,6 @@ Object* Isolate::FindHandler() { |
// For JSEntryStub frames we always have a handler. |
if (frame->is_entry() || frame->is_entry_construct()) { |
StackHandler* handler = frame->top_handler(); |
- DCHECK_EQ(0, handler->index()); |
// Restore the next handler. |
thread_local_top()->handler_ = handler->next()->address(); |
@@ -1053,39 +1040,44 @@ Object* Isolate::FindHandler() { |
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(); |
+ // For optimized frames we perform a lookup in the handler table. |
+ if (frame->is_optimized() && catchable_by_js) { |
+ OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); |
+ int stack_slots = 0; // Will contain stack slot count of frame. |
+ offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); |
+ if (offset < 0) continue; |
- // Restore the next handler. |
- thread_local_top()->handler_ = handler->next()->address(); |
+ // 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 - |
+ stack_slots * kPointerSize; |
- // Gather information from the handler. |
+ // Gather information from the frame. |
code = frame->LookupCode(); |
- context = handler->context(); |
- offset = Smi::cast(code->handler_table()->get(handler->index()))->value(); |
- handler_sp = handler->address() + StackHandlerConstants::kSize; |
+ handler_sp = return_sp; |
handler_fp = frame->fp(); |
break; |
} |
- // 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; |
+ // For JavaScript frames we perform a range lookup in the handler table. |
+ if (frame->is_java_script() && catchable_by_js) { |
+ JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
+ int stack_slots = 0; // Will contain operand stack depth of handler. |
+ offset = js_frame->LookupExceptionHandlerInTable(&stack_slots); |
+ if (offset < 0) continue; |
// Compute the stack pointer from the frame pointer. This ensures that |
- // argument slots on the stack are dropped as returning would. |
+ // operand stack slots are dropped for nested statements. Also restore |
+ // correct context for the handler which is pushed within the try-block. |
Address return_sp = frame->fp() - |
StandardFrameConstants::kFixedFrameSizeFromFp - |
- frame_code->stack_slots() * kPointerSize; |
+ stack_slots * kPointerSize; |
+ STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
+ context = Context::cast(Memory::Object_at(return_sp - kPointerSize)); |
// Gather information from the frame. |
- code = frame_code; |
- offset = handler_offset; |
+ code = frame->LookupCode(); |
handler_sp = return_sp; |
handler_fp = frame->fp(); |
break; |
@@ -1112,25 +1104,11 @@ Object* Isolate::FindHandler() { |
bool Isolate::PredictWhetherExceptionIsCaught(Object* exception) { |
if (IsExternalHandlerOnTop(exception)) return true; |
- // Search for a JavaScript handler 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 JavaScript frames which have a handler, we use the handler. |
- if (frame->is_java_script() && frame->HasHandler()) { |
- return true; |
- } |
- |
- // For optimized frames we perform a lookup in the handler table. |
- if (frame->is_optimized()) { |
- 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; |
- return true; |
- } |
+ // Search for a JavaScript handler by performing a full walk over the stack. |
+ for (JavaScriptFrameIterator iter(this); !iter.done(); iter.Advance()) { |
+ JavaScriptFrame* frame = iter.frame(); |
+ int stack_slots = 0; // The computed stack slot count is not used. |
+ if (frame->LookupExceptionHandlerInTable(&stack_slots) > 0) return true; |
} |
// Handler not found. |