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

Unified Diff: src/isolate.cc

Issue 1010883002: Switch full-codegen from StackHandlers to handler table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_cleanup-isolate-dead-code
Patch Set: Fix debugger-pause-on-promise-rejection. Created 5 years, 9 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/isolate.h ('k') | src/objects.h » ('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 ca38e9f221461b7f447e1bf35aa8939985a9b40c..bdf82926ceea02c8663061278c0c3e7846d2c845 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -978,7 +978,7 @@ Object* Isolate::Throw(Object* exception, MessageLocation* location) {
// present. This flag is intended for use by JavaScript developers, so
// print a user-friendly stack trace (not an internal one).
if (FLAG_abort_on_uncaught_exception &&
- !PredictWhetherExceptionIsCaught(*exception_handle)) {
+ PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) {
FLAG_abort_on_uncaught_exception = false; // Prevent endless recursion.
PrintF(stderr, "%s\n\nFROM\n",
MessageHandler::GetLocalizedMessage(this, message_obj).get());
@@ -1003,18 +1003,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();
@@ -1036,7 +1024,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();
@@ -1048,39 +1035,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;
@@ -1103,33 +1095,40 @@ Object* Isolate::FindHandler() {
}
-// TODO(mstarzinger): We shouldn't need the exception object here.
-bool Isolate::PredictWhetherExceptionIsCaught(Object* exception) {
- if (IsExternalHandlerOnTop(exception)) return true;
+Isolate::CatchType Isolate::PredictExceptionCatcher() {
+ Address external_handler = thread_local_top()->try_catch_handler_address();
+ Address entry_handler = Isolate::handler(thread_local_top());
+ if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL;
- // Search for a JavaScript handler by performing a full walk over the stack
- // and dispatching according to the frame type.
+ // Search for an exception handler by performing a full walk over the stack.
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 JSEntryStub frames we update the JS_ENTRY handler.
+ if (frame->is_entry() || frame->is_entry_construct()) {
+ entry_handler = frame->top_handler()->next()->address();
}
- // 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;
+ // For JavaScript frames we perform a lookup in the handler table.
+ if (frame->is_java_script()) {
+ JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
+ int stack_slots = 0; // The computed stack slot count is not used.
+ if (js_frame->LookupExceptionHandlerInTable(&stack_slots) > 0) {
+ return CAUGHT_BY_JAVASCRIPT;
+ }
+ }
+
+ // The exception has been externally caught if and only if there is an
+ // external handler which is on top of the top-most JS_ENTRY handler.
+ if (external_handler != nullptr && !try_catch_handler()->is_verbose_) {
+ if (entry_handler == nullptr || entry_handler > external_handler) {
+ return CAUGHT_BY_EXTERNAL;
+ }
}
}
// Handler not found.
- return false;
+ return NOT_CAUGHT;
}
@@ -1511,13 +1510,16 @@ bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
}
-void Isolate::PushPromise(Handle<JSObject> promise) {
+void Isolate::PushPromise(Handle<JSObject> promise,
+ Handle<JSFunction> function) {
ThreadLocalTop* tltop = thread_local_top();
PromiseOnStack* prev = tltop->promise_on_stack_;
- StackHandler* handler = StackHandler::FromAddress(Isolate::handler(tltop));
- Handle<JSObject> global_handle =
+ Handle<JSObject> global_promise =
Handle<JSObject>::cast(global_handles()->Create(*promise));
- tltop->promise_on_stack_ = new PromiseOnStack(handler, global_handle, prev);
+ Handle<JSFunction> global_function =
+ Handle<JSFunction>::cast(global_handles()->Create(*function));
+ tltop->promise_on_stack_ =
+ new PromiseOnStack(global_function, global_promise, prev);
}
@@ -1525,10 +1527,12 @@ void Isolate::PopPromise() {
ThreadLocalTop* tltop = thread_local_top();
if (tltop->promise_on_stack_ == NULL) return;
PromiseOnStack* prev = tltop->promise_on_stack_->prev();
- Handle<Object> global_handle = tltop->promise_on_stack_->promise();
+ Handle<Object> global_function = tltop->promise_on_stack_->function();
+ Handle<Object> global_promise = tltop->promise_on_stack_->promise();
delete tltop->promise_on_stack_;
tltop->promise_on_stack_ = prev;
- global_handles()->Destroy(global_handle.location());
+ global_handles()->Destroy(global_function.location());
+ global_handles()->Destroy(global_promise.location());
}
@@ -1536,12 +1540,21 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
Handle<Object> undefined = factory()->undefined_value();
ThreadLocalTop* tltop = thread_local_top();
if (tltop->promise_on_stack_ == NULL) return undefined;
- StackHandler* promise_try = tltop->promise_on_stack_->handler();
- // Find the top-most try-catch handler.
- StackHandler* handler = StackHandler::FromAddress(Isolate::handler(tltop));
- // Throwing inside a Promise only leads to a reject if not caught by an inner
- // try-catch or try-finally.
- if (handler == promise_try) return tltop->promise_on_stack_->promise();
+ Handle<JSFunction> promise_function = tltop->promise_on_stack_->function();
+ // Find the top-most try-catch or try-finally handler.
+ if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined;
+ for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
+ JavaScriptFrame* frame = it.frame();
+ int stack_slots = 0; // The computed stack slot count is not used.
+ if (frame->LookupExceptionHandlerInTable(&stack_slots) > 0) {
+ // Throwing inside a Promise only leads to a reject if not caught by an
+ // inner try-catch or try-finally.
+ if (frame->function() == *promise_function) {
+ return tltop->promise_on_stack_->promise();
+ }
+ return undefined;
+ }
+ }
return undefined;
}
« no previous file with comments | « src/isolate.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698