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,
// 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.
// Set up the the index (r6) for pushing.
mov(r6, Operand(handler_index));
// Set up the the state (r6) for pushing.
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) {
mov(cp, Operand(Smi::FromInt(0))); // Indicates no context.
stm(db_w, sp, r6.bit() | cp.bit());
......
......@@ -3050,8 +3050,12 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
// For the JSEntry handler, we must preserve the live registers x0-x4.
// (See JSEntryStub::GenerateBody().)
// Set up the index for pushing.
Mov(x11, handler_index);
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
// Set up the state for pushing.
Mov(x11, state);
// Push the context and state.
if (kind == StackHandler::JS_ENTRY) {
......
......@@ -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;
// Temporarily clear any scheduled_exception to allow evaluating
// JavaScript from the debug event handler.
......@@ -2466,7 +2466,7 @@ void Debug::OnThrow(Handle<Object> exception) {
scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
isolate_->clear_scheduled_exception();
}
OnException(exception, isolate_->GetPromiseOnStackOnThrow());
OnException(exception, uncaught, isolate_->GetPromiseOnStackOnThrow());
if (!scheduled_exception.is_null()) {
isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
}
......@@ -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.
Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
if (JSObject::GetDataProperty(promise, key)->IsUndefined()) {
OnException(value, promise);
OnException(value, false, promise);
}
}
......@@ -2494,8 +2494,8 @@ MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
}
void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
bool uncaught = !isolate_->PredictWhetherExceptionIsCaught(*exception);
void Debug::OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise) {
if (!uncaught && promise->IsJSObject()) {
Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
// Mark the promise as already having triggered a message.
......
......@@ -425,7 +425,7 @@ class Debug {
// Debug event triggers.
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 OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script);
......@@ -595,7 +595,8 @@ class Debug {
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.
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
......
......@@ -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 {
const int offset = StackHandlerConstants::kContextOffset;
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;
return Memory::int_at(address() + offset);
return IndexField::decode(Memory::unsigned_at(address() + offset));
}
......
......@@ -1338,6 +1338,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const {
StackHandlerIterator it(this, top_handler());
DCHECK(!it.done());
StackHandler* handler = it.handler();
DCHECK(handler->is_js_entry());
handler->Iterate(v, LookupCode());
#ifdef DEBUG
// Make sure that the entry frame does not contain more than one
......
......@@ -88,8 +88,15 @@ class StackHandler BASE_EMBEDDED {
JS_ENTRY,
CATCH,
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.
inline Address address() const;
......@@ -107,7 +114,13 @@ class StackHandler BASE_EMBEDDED {
// Accessors.
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.
void Unwind(Isolate* isolate, FixedArray* array, int offset,
......
......@@ -1038,9 +1038,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
} else {
push(esi);
}
// Push the index.
push(Immediate(handler_index));
// Push the state.
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
push(Immediate(state));
// Link the current handler as the next handler.
ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
......
This diff is collapsed.
......@@ -629,8 +629,7 @@ class Isolate {
thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
}
bool IsJavaScriptHandlerOnTop(Object* exception);
bool IsExternalHandlerOnTop(Object* exception);
bool IsFinallyOnTop();
bool is_catchable_by_javascript(Object* exception) {
return exception != heap()->termination_exception();
......@@ -744,7 +743,6 @@ class Isolate {
// Exception throwing support. The caller should use the result
// of Throw() as its return value.
Object* Throw(Object* exception, MessageLocation* location = NULL);
Object* ThrowIllegalOperation();
template <typename T>
MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception,
......@@ -753,20 +751,15 @@ class Isolate {
return MaybeHandle<T>();
}
// Re-throw an exception. This involves no error reporting since error
// reporting was handled when the exception was thrown originally.
// Re-throw an exception. This involves no error reporting since
// error reporting was handled when the exception was thrown
// originally.
Object* ReThrow(Object* exception);
// Find the correct handler for the current pending exception. This also
// clears and returns the current pending exception.
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);
// Re-set pending message, script and positions reported to the TryCatch
// back to the TLS for re-use when rethrowing.
......@@ -776,9 +769,14 @@ class Isolate {
void ReportPendingMessages();
// Return pending location if any or unfilled structure.
MessageLocation GetMessageLocation();
Object* ThrowIllegalOperation();
// Promote a scheduled exception to pending. Asserts has_scheduled_exception.
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
// result in the target out parameter.
......@@ -805,6 +803,7 @@ class Isolate {
char* Iterate(ObjectVisitor* v, char* t);
void IterateThread(ThreadVisitor* v, char* t);
// Returns the current native context.
Handle<Context> native_context();
......
......@@ -2995,8 +2995,11 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
Push(rsi);
}
// Push the index.
Push(Immediate(handler_index));
// Push the state.
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
Push(Immediate(state));
// Link the current handler as the next handler.
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