Commit 96f79568 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

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

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

Cr-Commit-Position: refs/heads/master@{#27210}
parent 788d9d1b
......@@ -1406,13 +1406,10 @@ 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 state (r6) for pushing.
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
mov(r6, Operand(state));
// Set up the the index (r6) for pushing.
mov(r6, Operand(handler_index));
// Push the context and state.
// Push the context and index.
if (kind == StackHandler::JS_ENTRY) {
mov(cp, Operand(Smi::FromInt(0))); // Indicates no context.
stm(db_w, sp, r6.bit() | cp.bit());
......
......@@ -3050,12 +3050,8 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
// For the JSEntry handler, we must preserve the live registers x0-x4.
// (See JSEntryStub::GenerateBody().)
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
// Set up the state for pushing.
Mov(x11, state);
// Set up the index for pushing.
Mov(x11, handler_index);
// 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, bool uncaught) {
void Debug::OnThrow(Handle<Object> exception) {
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, bool uncaught) {
scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
isolate_->clear_scheduled_exception();
}
OnException(exception, uncaught, isolate_->GetPromiseOnStackOnThrow());
OnException(exception, 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, false, promise);
OnException(value, promise);
}
}
......@@ -2494,8 +2494,8 @@ MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
}
void Debug::OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise) {
void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
bool uncaught = !isolate_->PredictWhetherExceptionIsCaught(*exception);
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, bool uncaught);
void OnThrow(Handle<Object> exception);
void OnPromiseReject(Handle<JSObject> promise, Handle<Object> value);
void OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script);
......@@ -595,8 +595,7 @@ class Debug {
return break_disabled_ || in_debug_event_listener_;
}
void OnException(Handle<Object> exception, bool uncaught,
Handle<Object> promise);
void OnException(Handle<Object> exception, Handle<Object> promise);
// Constructors for debug event objects.
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
......
......@@ -61,36 +61,15 @@ 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 StackHandler::Kind StackHandler::kind() const {
const int offset = StackHandlerConstants::kStateIntOffset;
return KindField::decode(Memory::unsigned_at(address() + offset));
}
inline unsigned StackHandler::index() const {
inline int StackHandler::index() const {
const int offset = StackHandlerConstants::kStateIntOffset;
return IndexField::decode(Memory::unsigned_at(address() + offset));
return Memory::int_at(address() + offset);
}
......
......@@ -1338,7 +1338,6 @@ 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,15 +88,8 @@ 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;
......@@ -114,13 +107,7 @@ class StackHandler BASE_EMBEDDED {
// Accessors.
inline Context* context() 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;
inline int index() const;
// Generator support to preserve stack handlers.
void Unwind(Isolate* isolate, FixedArray* array, int offset,
......
......@@ -1038,11 +1038,9 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
} else {
push(esi);
}
// Push the state.
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
push(Immediate(state));
// Push the index.
push(Immediate(handler_index));
// Link the current handler as the next handler.
ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
......
This diff is collapsed.
......@@ -629,7 +629,8 @@ class Isolate {
thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
}
bool IsFinallyOnTop();
bool IsJavaScriptHandlerOnTop(Object* exception);
bool IsExternalHandlerOnTop(Object* exception);
bool is_catchable_by_javascript(Object* exception) {
return exception != heap()->termination_exception();
......@@ -743,6 +744,7 @@ 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,
......@@ -751,15 +753,20 @@ 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.
......@@ -769,14 +776,9 @@ 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.
......@@ -803,7 +805,6 @@ class Isolate {
char* Iterate(ObjectVisitor* v, char* t);
void IterateThread(ThreadVisitor* v, char* t);
// Returns the current native context.
Handle<Context> native_context();
......
......@@ -2995,11 +2995,8 @@ void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
Push(rsi);
}
// Push the state.
unsigned state =
StackHandler::IndexField::encode(handler_index) |
StackHandler::KindField::encode(kind);
Push(Immediate(state));
// Push the index.
Push(Immediate(handler_index));
// 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