Commit 5977ed02 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

Revert of Remove kind field from StackHandler. (patchset #4 id:60001 of...

Revert of Remove kind field from StackHandler. (patchset #4 id:60001 of https://codereview.chromium.org/1002203002/)

Reason for revert:
Layout test failure in inspector/sources/debugger/debugger-pause-on-promise-rejection.html

Original issue's description:
> Remove kind field from StackHandler.
>
> This makes the Isolate::Throw logic not depend on a prediction of
> whether an exception is caught or uncaught. Such a prediction is
> inherently undecidable because a finally block can decide between
> consuming or re-throwing an exception depending on arbitray control
> flow.
>
> There still is a conservative prediction mechanism in place that
> components like the debugger or tracing can use for reporting.
>
> With this change we can get rid of the StackHandler::kind field, a
> pre-requisite to do table-based lookups of exception handlers.
>
> R=yangguo@chromium.org
>
> Committed: https://crrev.com/96f79568a926966ebcf0685bf9adc947f4e1fbff
> Cr-Commit-Position: refs/heads/master@{#27210}

TBR=yangguo@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.chromium.org/1009903002

Cr-Commit-Position: refs/heads/master@{#27215}
parent 3e924dd0
...@@ -1406,10 +1406,13 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, ...@@ -1406,10 +1406,13 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
// For the JSEntry handler, we must preserve r0-r4, r5-r6 are available. // For the JSEntry handler, we must preserve r0-r4, r5-r6 are available.
// We will build up the handler from the bottom by pushing on the stack. // We will build up the handler from the bottom by pushing on the stack.
// Set up the the index (r6) for pushing. // Set up the the state (r6) for pushing.
mov(r6, Operand(handler_index)); unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
mov(r6, Operand(state));
// Push the context and index. // Push the context and state.
if (kind == StackHandler::JS_ENTRY) { if (kind == StackHandler::JS_ENTRY) {
mov(cp, Operand(Smi::FromInt(0))); // Indicates no context. mov(cp, Operand(Smi::FromInt(0))); // Indicates no context.
stm(db_w, sp, r6.bit() | cp.bit()); stm(db_w, sp, r6.bit() | cp.bit());
......
...@@ -3050,8 +3050,12 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, ...@@ -3050,8 +3050,12 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
// For the JSEntry handler, we must preserve the live registers x0-x4. // For the JSEntry handler, we must preserve the live registers x0-x4.
// (See JSEntryStub::GenerateBody().) // (See JSEntryStub::GenerateBody().)
// Set up the index for pushing. unsigned state =
Mov(x11, handler_index); StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
// Set up the state for pushing.
Mov(x11, state);
// Push the context and state. // Push the context and state.
if (kind == StackHandler::JS_ENTRY) { if (kind == StackHandler::JS_ENTRY) {
......
...@@ -2456,7 +2456,7 @@ MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) { ...@@ -2456,7 +2456,7 @@ MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
} }
void Debug::OnThrow(Handle<Object> exception) { void Debug::OnThrow(Handle<Object> exception, bool uncaught) {
if (in_debug_scope() || ignore_events()) return; if (in_debug_scope() || ignore_events()) return;
// Temporarily clear any scheduled_exception to allow evaluating // Temporarily clear any scheduled_exception to allow evaluating
// JavaScript from the debug event handler. // JavaScript from the debug event handler.
...@@ -2466,7 +2466,7 @@ void Debug::OnThrow(Handle<Object> exception) { ...@@ -2466,7 +2466,7 @@ void Debug::OnThrow(Handle<Object> exception) {
scheduled_exception = handle(isolate_->scheduled_exception(), isolate_); scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
isolate_->clear_scheduled_exception(); isolate_->clear_scheduled_exception();
} }
OnException(exception, isolate_->GetPromiseOnStackOnThrow()); OnException(exception, uncaught, isolate_->GetPromiseOnStackOnThrow());
if (!scheduled_exception.is_null()) { if (!scheduled_exception.is_null()) {
isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception; isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
} }
...@@ -2479,7 +2479,7 @@ void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) { ...@@ -2479,7 +2479,7 @@ void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
// Check whether the promise has been marked as having triggered a message. // Check whether the promise has been marked as having triggered a message.
Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
if (JSObject::GetDataProperty(promise, key)->IsUndefined()) { if (JSObject::GetDataProperty(promise, key)->IsUndefined()) {
OnException(value, promise); OnException(value, false, promise);
} }
} }
...@@ -2494,8 +2494,8 @@ MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler( ...@@ -2494,8 +2494,8 @@ MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
} }
void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { void Debug::OnException(Handle<Object> exception, bool uncaught,
bool uncaught = !isolate_->PredictWhetherExceptionIsCaught(*exception); Handle<Object> promise) {
if (!uncaught && promise->IsJSObject()) { if (!uncaught && promise->IsJSObject()) {
Handle<JSObject> jspromise = Handle<JSObject>::cast(promise); Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
// Mark the promise as already having triggered a message. // Mark the promise as already having triggered a message.
......
...@@ -425,7 +425,7 @@ class Debug { ...@@ -425,7 +425,7 @@ class Debug {
// Debug event triggers. // Debug event triggers.
void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
void OnThrow(Handle<Object> exception); void OnThrow(Handle<Object> exception, bool uncaught);
void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value); void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value);
void OnCompileError(Handle<Script> script); void OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script); void OnBeforeCompile(Handle<Script> script);
...@@ -595,7 +595,8 @@ class Debug { ...@@ -595,7 +595,8 @@ class Debug {
return break_disabled_ || in_debug_event_listener_; return break_disabled_ || in_debug_event_listener_;
} }
void OnException(Handle<Object> exception, Handle<Object> promise); void OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise);
// Constructors for debug event objects. // Constructors for debug event objects.
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
......
...@@ -61,15 +61,36 @@ inline StackHandler* StackHandler::FromAddress(Address address) { ...@@ -61,15 +61,36 @@ inline StackHandler* StackHandler::FromAddress(Address address) {
} }
inline bool StackHandler::is_js_entry() const {
return kind() == JS_ENTRY;
}
inline bool StackHandler::is_catch() const {
return kind() == CATCH;
}
inline bool StackHandler::is_finally() const {
return kind() == FINALLY;
}
inline Context* StackHandler::context() const { inline Context* StackHandler::context() const {
const int offset = StackHandlerConstants::kContextOffset; const int offset = StackHandlerConstants::kContextOffset;
return Context::cast(Memory::Object_at(address() + offset)); return Context::cast(Memory::Object_at(address() + offset));
} }
inline int StackHandler::index() const { inline StackHandler::Kind StackHandler::kind() const {
const int offset = StackHandlerConstants::kStateIntOffset;
return KindField::decode(Memory::unsigned_at(address() + offset));
}
inline unsigned StackHandler::index() const {
const int offset = StackHandlerConstants::kStateIntOffset; const int offset = StackHandlerConstants::kStateIntOffset;
return Memory::int_at(address() + offset); return IndexField::decode(Memory::unsigned_at(address() + offset));
} }
......
...@@ -1338,6 +1338,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const { ...@@ -1338,6 +1338,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const {
StackHandlerIterator it(this, top_handler()); StackHandlerIterator it(this, top_handler());
DCHECK(!it.done()); DCHECK(!it.done());
StackHandler* handler = it.handler(); StackHandler* handler = it.handler();
DCHECK(handler->is_js_entry());
handler->Iterate(v, LookupCode()); handler->Iterate(v, LookupCode());
#ifdef DEBUG #ifdef DEBUG
// Make sure that the entry frame does not contain more than one // Make sure that the entry frame does not contain more than one
......
...@@ -88,8 +88,15 @@ class StackHandler BASE_EMBEDDED { ...@@ -88,8 +88,15 @@ class StackHandler BASE_EMBEDDED {
JS_ENTRY, JS_ENTRY,
CATCH, CATCH,
FINALLY, FINALLY,
LAST_KIND = FINALLY
}; };
static const int kKindWidth = 2;
STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
static const int kIndexWidth = 32 - kKindWidth;
class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
// Get the address of this stack handler. // Get the address of this stack handler.
inline Address address() const; inline Address address() const;
...@@ -107,7 +114,13 @@ class StackHandler BASE_EMBEDDED { ...@@ -107,7 +114,13 @@ class StackHandler BASE_EMBEDDED {
// Accessors. // Accessors.
inline Context* context() const; inline Context* context() const;
inline int index() const; inline Kind kind() const;
inline unsigned index() const;
// Testers.
inline bool is_js_entry() const;
inline bool is_catch() const;
inline bool is_finally() const;
// Generator support to preserve stack handlers. // Generator support to preserve stack handlers.
void Unwind(Isolate* isolate, FixedArray* array, int offset, void Unwind(Isolate* isolate, FixedArray* array, int offset,
......
...@@ -1038,9 +1038,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, ...@@ -1038,9 +1038,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
} else { } else {
push(esi); push(esi);
} }
// Push the state.
// Push the index. unsigned state =
push(Immediate(handler_index)); StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
push(Immediate(state));
// Link the current handler as the next handler. // Link the current handler as the next handler.
ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
......
This diff is collapsed.
...@@ -629,8 +629,7 @@ class Isolate { ...@@ -629,8 +629,7 @@ class Isolate {
thread_local_top_.scheduled_exception_ = heap_.the_hole_value(); thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
} }
bool IsJavaScriptHandlerOnTop(Object* exception); bool IsFinallyOnTop();
bool IsExternalHandlerOnTop(Object* exception);
bool is_catchable_by_javascript(Object* exception) { bool is_catchable_by_javascript(Object* exception) {
return exception != heap()->termination_exception(); return exception != heap()->termination_exception();
...@@ -744,7 +743,6 @@ class Isolate { ...@@ -744,7 +743,6 @@ class Isolate {
// Exception throwing support. The caller should use the result // Exception throwing support. The caller should use the result
// of Throw() as its return value. // of Throw() as its return value.
Object* Throw(Object* exception, MessageLocation* location = NULL); Object* Throw(Object* exception, MessageLocation* location = NULL);
Object* ThrowIllegalOperation();
template <typename T> template <typename T>
MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception, MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception,
...@@ -753,20 +751,15 @@ class Isolate { ...@@ -753,20 +751,15 @@ class Isolate {
return MaybeHandle<T>(); return MaybeHandle<T>();
} }
// Re-throw an exception. This involves no error reporting since error // Re-throw an exception. This involves no error reporting since
// reporting was handled when the exception was thrown originally. // error reporting was handled when the exception was thrown
// originally.
Object* ReThrow(Object* exception); Object* ReThrow(Object* exception);
// Find the correct handler for the current pending exception. This also // Find the correct handler for the current pending exception. This also
// clears and returns the current pending exception. // clears and returns the current pending exception.
Object* FindHandler(); Object* FindHandler();
// Tries to predict whether the exception will be caught. Note that this can
// only produce an estimate, because it is undecidable whether a finally
// clause will consume or re-throw an exception. We conservatively assume any
// finally clause will behave as if the exception were consumed.
bool PredictWhetherExceptionIsCaught(Object* exception);
void ScheduleThrow(Object* exception); void ScheduleThrow(Object* exception);
// Re-set pending message, script and positions reported to the TryCatch // Re-set pending message, script and positions reported to the TryCatch
// back to the TLS for re-use when rethrowing. // back to the TLS for re-use when rethrowing.
...@@ -776,9 +769,14 @@ class Isolate { ...@@ -776,9 +769,14 @@ class Isolate {
void ReportPendingMessages(); void ReportPendingMessages();
// Return pending location if any or unfilled structure. // Return pending location if any or unfilled structure.
MessageLocation GetMessageLocation(); MessageLocation GetMessageLocation();
Object* ThrowIllegalOperation();
// Promote a scheduled exception to pending. Asserts has_scheduled_exception. // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
Object* PromoteScheduledException(); Object* PromoteScheduledException();
// Checks if exception should be reported and finds out if it's
// caught externally.
bool ShouldReportException(bool* can_be_caught_externally,
bool catchable_by_javascript);
// Attempts to compute the current source location, storing the // Attempts to compute the current source location, storing the
// result in the target out parameter. // result in the target out parameter.
...@@ -805,6 +803,7 @@ class Isolate { ...@@ -805,6 +803,7 @@ class Isolate {
char* Iterate(ObjectVisitor* v, char* t); char* Iterate(ObjectVisitor* v, char* t);
void IterateThread(ThreadVisitor* v, char* t); void IterateThread(ThreadVisitor* v, char* t);
// Returns the current native context. // Returns the current native context.
Handle<Context> native_context(); Handle<Context> native_context();
......
...@@ -2995,8 +2995,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind, ...@@ -2995,8 +2995,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
Push(rsi); Push(rsi);
} }
// Push the index. // Push the state.
Push(Immediate(handler_index)); unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
Push(Immediate(state));
// Link the current handler as the next handler. // Link the current handler as the next handler.
ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment