| 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.
|
|
|