Simplify handler pushing.
Instead of using two separate bits to encode three possible values, use three values to encode the three possible values. R=svenpanne@chromium.org BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9372016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10654 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
34f220001d
commit
831ada2f0d
@ -3964,7 +3964,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
|||||||
// handler block in this code object, so its index is 0.
|
// handler block in this code object, so its index is 0.
|
||||||
__ bind(&invoke);
|
__ bind(&invoke);
|
||||||
// Must preserve r0-r4, r5-r7 are available.
|
// Must preserve r0-r4, r5-r7 are available.
|
||||||
__ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER, 0);
|
__ PushTryHandler(StackHandler::JS_ENTRY, 0);
|
||||||
// If an exception not caught by another handler occurs, this handler
|
// If an exception not caught by another handler occurs, this handler
|
||||||
// returns control to the code after the bl(&invoke) above, which
|
// returns control to the code after the bl(&invoke) above, which
|
||||||
// restores all kCalleeSaved registers (including cp and fp) to their
|
// restores all kCalleeSaved registers (including cp and fp) to their
|
||||||
|
@ -1188,8 +1188,7 @@ void MacroAssembler::DebugBreak() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
|
||||||
HandlerType type,
|
|
||||||
int handler_index) {
|
int handler_index) {
|
||||||
// Adjust this code if not the case.
|
// Adjust this code if not the case.
|
||||||
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
||||||
@ -1201,28 +1200,20 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
|||||||
|
|
||||||
// For the JSEntry handler, we must preserve r0-r4, r5-r7 are available.
|
// For the JSEntry handler, we must preserve r0-r4, r5-r7 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.
|
||||||
// First compute the state.
|
|
||||||
unsigned state = StackHandler::OffsetField::encode(handler_index);
|
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
|
||||||
state |= (type == TRY_CATCH_HANDLER)
|
|
||||||
? StackHandler::KindField::encode(StackHandler::TRY_CATCH)
|
|
||||||
: StackHandler::KindField::encode(StackHandler::TRY_FINALLY);
|
|
||||||
} else {
|
|
||||||
ASSERT(try_location == IN_JS_ENTRY);
|
|
||||||
state |= StackHandler::KindField::encode(StackHandler::ENTRY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the code object (r5) and the state (r6) for pushing.
|
// Set up the code object (r5) and the state (r6) for pushing.
|
||||||
|
unsigned state =
|
||||||
|
StackHandler::IndexField::encode(handler_index) |
|
||||||
|
StackHandler::KindField::encode(kind);
|
||||||
mov(r5, Operand(CodeObject()));
|
mov(r5, Operand(CodeObject()));
|
||||||
mov(r6, Operand(state));
|
mov(r6, Operand(state));
|
||||||
|
|
||||||
// Push the frame pointer, context, state, and code object.
|
// Push the frame pointer, context, state, and code object.
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
if (kind == StackHandler::JS_ENTRY) {
|
||||||
stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit());
|
|
||||||
} else {
|
|
||||||
mov(r7, Operand(Smi::FromInt(0))); // Indicates no context.
|
mov(r7, Operand(Smi::FromInt(0))); // Indicates no context.
|
||||||
mov(ip, Operand(0, RelocInfo::NONE)); // NULL frame pointer.
|
mov(ip, Operand(0, RelocInfo::NONE)); // NULL frame pointer.
|
||||||
stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit());
|
stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit());
|
||||||
|
} else {
|
||||||
|
stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link the current handler as the next handler.
|
// Link the current handler as the next handler.
|
||||||
@ -1330,7 +1321,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
|||||||
ldr(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
ldr(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
||||||
|
|
||||||
bind(&check_kind);
|
bind(&check_kind);
|
||||||
STATIC_ASSERT(StackHandler::ENTRY == 0);
|
STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
|
||||||
ldr(r2, MemOperand(sp, StackHandlerConstants::kStateOffset));
|
ldr(r2, MemOperand(sp, StackHandlerConstants::kStateOffset));
|
||||||
tst(r2, Operand(StackHandler::KindField::kMask));
|
tst(r2, Operand(StackHandler::KindField::kMask));
|
||||||
b(ne, &fetch_next);
|
b(ne, &fetch_next);
|
||||||
|
@ -582,9 +582,7 @@ class MacroAssembler: public Assembler {
|
|||||||
// Exception handling
|
// Exception handling
|
||||||
|
|
||||||
// Push a new try handler and link into try handler chain.
|
// Push a new try handler and link into try handler chain.
|
||||||
void PushTryHandler(CodeLocation try_location,
|
void PushTryHandler(StackHandler::Kind kind, int handler_index);
|
||||||
HandlerType type,
|
|
||||||
int handler_index);
|
|
||||||
|
|
||||||
// Unlink the stack handler on top of the stack from the try handler chain.
|
// Unlink the stack handler on top of the stack from the try handler chain.
|
||||||
// Must preserve the result register.
|
// Must preserve the result register.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -77,18 +77,18 @@ inline StackHandler* StackHandler::FromAddress(Address address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool StackHandler::is_entry() const {
|
inline bool StackHandler::is_js_entry() const {
|
||||||
return kind() == ENTRY;
|
return kind() == JS_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool StackHandler::is_try_catch() const {
|
inline bool StackHandler::is_catch() const {
|
||||||
return kind() == TRY_CATCH;
|
return kind() == CATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool StackHandler::is_try_finally() const {
|
inline bool StackHandler::is_finally() const {
|
||||||
return kind() == TRY_FINALLY;
|
return kind() == FINALLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1174,7 +1174,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const {
|
|||||||
StackHandlerIterator it(this, top_handler());
|
StackHandlerIterator it(this, top_handler());
|
||||||
ASSERT(!it.done());
|
ASSERT(!it.done());
|
||||||
StackHandler* handler = it.handler();
|
StackHandler* handler = it.handler();
|
||||||
ASSERT(handler->is_entry());
|
ASSERT(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
|
||||||
|
20
src/frames.h
20
src/frames.h
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -85,15 +85,17 @@ class InnerPointerToCodeCache {
|
|||||||
class StackHandler BASE_EMBEDDED {
|
class StackHandler BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
enum Kind {
|
enum Kind {
|
||||||
ENTRY,
|
JS_ENTRY,
|
||||||
TRY_CATCH,
|
CATCH,
|
||||||
TRY_FINALLY
|
FINALLY,
|
||||||
|
LAST_KIND = FINALLY
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kKindWidth = 2;
|
static const int kKindWidth = 2;
|
||||||
static const int kOffsetWidth = 32 - kKindWidth;
|
STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
|
||||||
|
static const int kIndexWidth = 32 - kKindWidth;
|
||||||
class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
|
class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
|
||||||
class OffsetField: public BitField<unsigned, kKindWidth, kOffsetWidth> {};
|
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;
|
||||||
@ -111,9 +113,9 @@ class StackHandler BASE_EMBEDDED {
|
|||||||
static inline StackHandler* FromAddress(Address address);
|
static inline StackHandler* FromAddress(Address address);
|
||||||
|
|
||||||
// Testers
|
// Testers
|
||||||
inline bool is_entry() const;
|
inline bool is_js_entry() const;
|
||||||
inline bool is_try_catch() const;
|
inline bool is_catch() const;
|
||||||
inline bool is_try_finally() const;
|
inline bool is_finally() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Accessors.
|
// Accessors.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -1147,7 +1147,7 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
|||||||
|
|
||||||
// Try block code. Sets up the exception handler chain.
|
// Try block code. Sets up the exception handler chain.
|
||||||
__ bind(&try_entry);
|
__ bind(&try_entry);
|
||||||
__ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER, stmt->index());
|
__ PushTryHandler(StackHandler::CATCH, stmt->index());
|
||||||
{ TryCatch try_body(this);
|
{ TryCatch try_body(this);
|
||||||
Visit(stmt->try_block());
|
Visit(stmt->try_block());
|
||||||
}
|
}
|
||||||
@ -1204,7 +1204,7 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
|||||||
|
|
||||||
// Set up try handler.
|
// Set up try handler.
|
||||||
__ bind(&try_entry);
|
__ bind(&try_entry);
|
||||||
__ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER, stmt->index());
|
__ PushTryHandler(StackHandler::FINALLY, stmt->index());
|
||||||
{ TryFinally try_body(this, &finally_entry);
|
{ TryFinally try_body(this, &finally_entry);
|
||||||
Visit(stmt->try_block());
|
Visit(stmt->try_block());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -5022,7 +5022,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
|||||||
// Invoke: Link this frame into the handler chain. There's only one
|
// Invoke: Link this frame into the handler chain. There's only one
|
||||||
// handler block in this code object, so its index is 0.
|
// handler block in this code object, so its index is 0.
|
||||||
__ bind(&invoke);
|
__ bind(&invoke);
|
||||||
__ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER, 0);
|
__ PushTryHandler(StackHandler::JS_ENTRY, 0);
|
||||||
|
|
||||||
// Clear any pending exceptions.
|
// Clear any pending exceptions.
|
||||||
__ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
|
__ mov(edx, Immediate(masm->isolate()->factory()->the_hole_value()));
|
||||||
|
@ -764,8 +764,7 @@ void MacroAssembler::LeaveApiExitFrame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
|
||||||
HandlerType type,
|
|
||||||
int handler_index) {
|
int handler_index) {
|
||||||
// Adjust this code if not the case.
|
// Adjust this code if not the case.
|
||||||
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
||||||
@ -776,25 +775,21 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
|||||||
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
|
||||||
|
|
||||||
// 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.
|
||||||
// First compute the state and push the frame pointer and context.
|
// First push the frame pointer and context.
|
||||||
unsigned state = StackHandler::OffsetField::encode(handler_index);
|
if (kind == StackHandler::JS_ENTRY) {
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
|
||||||
push(ebp);
|
|
||||||
push(esi);
|
|
||||||
state |= (type == TRY_CATCH_HANDLER)
|
|
||||||
? StackHandler::KindField::encode(StackHandler::TRY_CATCH)
|
|
||||||
: StackHandler::KindField::encode(StackHandler::TRY_FINALLY);
|
|
||||||
} else {
|
|
||||||
ASSERT(try_location == IN_JS_ENTRY);
|
|
||||||
// The frame pointer does not point to a JS frame so we save NULL for
|
// The frame pointer does not point to a JS frame so we save NULL for
|
||||||
// ebp. We expect the code throwing an exception to check ebp before
|
// ebp. We expect the code throwing an exception to check ebp before
|
||||||
// dereferencing it to restore the context.
|
// dereferencing it to restore the context.
|
||||||
push(Immediate(0)); // NULL frame pointer.
|
push(Immediate(0)); // NULL frame pointer.
|
||||||
push(Immediate(Smi::FromInt(0))); // No context.
|
push(Immediate(Smi::FromInt(0))); // No context.
|
||||||
state |= StackHandler::KindField::encode(StackHandler::ENTRY);
|
} else {
|
||||||
|
push(ebp);
|
||||||
|
push(esi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the state and the code object.
|
// Push the state and the code object.
|
||||||
|
unsigned state =
|
||||||
|
StackHandler::IndexField::encode(handler_index) |
|
||||||
|
StackHandler::KindField::encode(kind);
|
||||||
push(Immediate(state));
|
push(Immediate(state));
|
||||||
Push(CodeObject());
|
Push(CodeObject());
|
||||||
|
|
||||||
@ -904,7 +899,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
|||||||
mov(esp, Operand(esp, StackHandlerConstants::kNextOffset));
|
mov(esp, Operand(esp, StackHandlerConstants::kNextOffset));
|
||||||
|
|
||||||
bind(&check_kind);
|
bind(&check_kind);
|
||||||
STATIC_ASSERT(StackHandler::ENTRY == 0);
|
STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
|
||||||
test(Operand(esp, StackHandlerConstants::kStateOffset),
|
test(Operand(esp, StackHandlerConstants::kStateOffset),
|
||||||
Immediate(StackHandler::KindField::kMask));
|
Immediate(StackHandler::KindField::kMask));
|
||||||
j(not_zero, &fetch_next);
|
j(not_zero, &fetch_next);
|
||||||
|
@ -491,9 +491,7 @@ class MacroAssembler: public Assembler {
|
|||||||
// Exception handling
|
// Exception handling
|
||||||
|
|
||||||
// Push a new try handler and link it into try handler chain.
|
// Push a new try handler and link it into try handler chain.
|
||||||
void PushTryHandler(CodeLocation try_location,
|
void PushTryHandler(StackHandler::Kind kind, int handler_index);
|
||||||
HandlerType type,
|
|
||||||
int handler_index);
|
|
||||||
|
|
||||||
// Unlink the stack handler on top of the stack from the try handler chain.
|
// Unlink the stack handler on top of the stack from the try handler chain.
|
||||||
void PopTryHandler();
|
void PopTryHandler();
|
||||||
|
@ -1023,7 +1023,7 @@ bool Isolate::ShouldReportException(bool* can_be_caught_externally,
|
|||||||
// Find the top-most try-catch handler.
|
// Find the top-most try-catch handler.
|
||||||
StackHandler* handler =
|
StackHandler* handler =
|
||||||
StackHandler::FromAddress(Isolate::handler(thread_local_top()));
|
StackHandler::FromAddress(Isolate::handler(thread_local_top()));
|
||||||
while (handler != NULL && !handler->is_try_catch()) {
|
while (handler != NULL && !handler->is_catch()) {
|
||||||
handler = handler->next();
|
handler = handler->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1193,8 +1193,8 @@ bool Isolate::IsExternallyCaught() {
|
|||||||
StackHandler* handler =
|
StackHandler* handler =
|
||||||
StackHandler::FromAddress(Isolate::handler(thread_local_top()));
|
StackHandler::FromAddress(Isolate::handler(thread_local_top()));
|
||||||
while (handler != NULL && handler->address() < external_handler_address) {
|
while (handler != NULL && handler->address() < external_handler_address) {
|
||||||
ASSERT(!handler->is_try_catch());
|
ASSERT(!handler->is_catch());
|
||||||
if (handler->is_try_finally()) return false;
|
if (handler->is_finally()) return false;
|
||||||
|
|
||||||
handler = handler->next();
|
handler = handler->next();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -36,20 +36,6 @@ enum InvokeFlag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum CodeLocation {
|
|
||||||
IN_JAVASCRIPT,
|
|
||||||
IN_JS_ENTRY,
|
|
||||||
IN_C_ENTRY
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum HandlerType {
|
|
||||||
TRY_CATCH_HANDLER,
|
|
||||||
TRY_FINALLY_HANDLER,
|
|
||||||
JS_ENTRY_HANDLER
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Types of uncatchable exceptions.
|
// Types of uncatchable exceptions.
|
||||||
enum UncatchableExceptionType {
|
enum UncatchableExceptionType {
|
||||||
OUT_OF_MEMORY,
|
OUT_OF_MEMORY,
|
||||||
|
@ -4140,7 +4140,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
|||||||
// Invoke: Link this frame into the handler chain. There's only one
|
// Invoke: Link this frame into the handler chain. There's only one
|
||||||
// handler block in this code object, so its index is 0.
|
// handler block in this code object, so its index is 0.
|
||||||
__ bind(&invoke);
|
__ bind(&invoke);
|
||||||
__ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER, 0);
|
__ PushTryHandler(StackHandler::JS_ENTRY, 0);
|
||||||
// If an exception not caught by another handler occurs, this handler
|
// If an exception not caught by another handler occurs, this handler
|
||||||
// returns control to the code after the bal(&invoke) above, which
|
// returns control to the code after the bal(&invoke) above, which
|
||||||
// restores all kCalleeSaved registers (including cp and fp) to their
|
// restores all kCalleeSaved registers (including cp and fp) to their
|
||||||
|
@ -2576,8 +2576,7 @@ void MacroAssembler::DebugBreak() {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Exception handling.
|
// Exception handling.
|
||||||
|
|
||||||
void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
|
||||||
HandlerType type,
|
|
||||||
int handler_index) {
|
int handler_index) {
|
||||||
// Adjust this code if not the case.
|
// Adjust this code if not the case.
|
||||||
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
||||||
@ -2589,30 +2588,23 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
|||||||
|
|
||||||
// For the JSEntry handler, we must preserve a0-a3 and s0.
|
// For the JSEntry handler, we must preserve a0-a3 and s0.
|
||||||
// t1-t3 are available. We will build up the handler from the bottom by
|
// t1-t3 are available. We will build up the handler from the bottom by
|
||||||
// pushing on the stack. First compute the state.
|
// pushing on the stack.
|
||||||
unsigned state = StackHandler::OffsetField::encode(handler_index);
|
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
|
||||||
state |= (type == TRY_CATCH_HANDLER)
|
|
||||||
? StackHandler::KindField::encode(StackHandler::TRY_CATCH)
|
|
||||||
: StackHandler::KindField::encode(StackHandler::TRY_FINALLY);
|
|
||||||
} else {
|
|
||||||
ASSERT(try_location == IN_JS_ENTRY);
|
|
||||||
state |= StackHandler::KindField::encode(StackHandler::ENTRY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the code object (t1) and the state (t2) for pushing.
|
// Set up the code object (t1) and the state (t2) for pushing.
|
||||||
|
unsigned state =
|
||||||
|
StackHandler::IndexField::encode(handler_index) |
|
||||||
|
StackHandler::KindField::encode(kind);
|
||||||
li(t1, Operand(CodeObject()));
|
li(t1, Operand(CodeObject()));
|
||||||
li(t2, Operand(state));
|
li(t2, Operand(state));
|
||||||
|
|
||||||
// Push the frame pointer, context, state, and code object.
|
// Push the frame pointer, context, state, and code object.
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
if (kind == StackHandler::JS_ENTRY) {
|
||||||
MultiPush(t1.bit() | t2.bit() | cp.bit() | fp.bit());
|
|
||||||
} else {
|
|
||||||
ASSERT_EQ(Smi::FromInt(0), 0);
|
ASSERT_EQ(Smi::FromInt(0), 0);
|
||||||
// The second zero_reg indicates no context.
|
// The second zero_reg indicates no context.
|
||||||
// The first zero_reg is the NULL frame pointer.
|
// The first zero_reg is the NULL frame pointer.
|
||||||
// The operands are reversed to match the order of MultiPush/Pop.
|
// The operands are reversed to match the order of MultiPush/Pop.
|
||||||
Push(zero_reg, zero_reg, t2, t1);
|
Push(zero_reg, zero_reg, t2, t1);
|
||||||
|
} else {
|
||||||
|
MultiPush(t1.bit() | t2.bit() | cp.bit() | fp.bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link the current handler as the next handler.
|
// Link the current handler as the next handler.
|
||||||
@ -2727,7 +2719,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
|||||||
lw(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
lw(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
||||||
|
|
||||||
bind(&check_kind);
|
bind(&check_kind);
|
||||||
STATIC_ASSERT(StackHandler::ENTRY == 0);
|
STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
|
||||||
lw(a2, MemOperand(sp, StackHandlerConstants::kStateOffset));
|
lw(a2, MemOperand(sp, StackHandlerConstants::kStateOffset));
|
||||||
And(a2, a2, Operand(StackHandler::KindField::kMask));
|
And(a2, a2, Operand(StackHandler::KindField::kMask));
|
||||||
Branch(&fetch_next, ne, a2, Operand(zero_reg));
|
Branch(&fetch_next, ne, a2, Operand(zero_reg));
|
||||||
|
@ -865,9 +865,7 @@ class MacroAssembler: public Assembler {
|
|||||||
// Exception handling.
|
// Exception handling.
|
||||||
|
|
||||||
// Push a new try handler and link into try handler chain.
|
// Push a new try handler and link into try handler chain.
|
||||||
void PushTryHandler(CodeLocation try_location,
|
void PushTryHandler(StackHandler::Kind kind, int handler_index);
|
||||||
HandlerType type,
|
|
||||||
int handler_index);
|
|
||||||
|
|
||||||
// Unlink the stack handler on top of the stack from the try handler chain.
|
// Unlink the stack handler on top of the stack from the try handler chain.
|
||||||
// Must preserve the result register.
|
// Must preserve the result register.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -4077,7 +4077,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
|
|||||||
// Invoke: Link this frame into the handler chain. There's only one
|
// Invoke: Link this frame into the handler chain. There's only one
|
||||||
// handler block in this code object, so its index is 0.
|
// handler block in this code object, so its index is 0.
|
||||||
__ bind(&invoke);
|
__ bind(&invoke);
|
||||||
__ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER, 0);
|
__ PushTryHandler(StackHandler::JS_ENTRY, 0);
|
||||||
|
|
||||||
// Clear any pending exceptions.
|
// Clear any pending exceptions.
|
||||||
__ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
|
__ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
|
||||||
|
@ -2453,8 +2453,7 @@ Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
|
||||||
HandlerType type,
|
|
||||||
int handler_index) {
|
int handler_index) {
|
||||||
// Adjust this code if not the case.
|
// Adjust this code if not the case.
|
||||||
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
||||||
@ -2465,25 +2464,22 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
|||||||
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
|
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
|
||||||
|
|
||||||
// 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.
|
||||||
// First compute the state and push the frame pointer and context.
|
// First push the frame pointer and context.
|
||||||
unsigned state = StackHandler::OffsetField::encode(handler_index);
|
if (kind == StackHandler::JS_ENTRY) {
|
||||||
if (try_location == IN_JAVASCRIPT) {
|
|
||||||
push(rbp);
|
|
||||||
push(rsi);
|
|
||||||
state |= (type == TRY_CATCH_HANDLER)
|
|
||||||
? StackHandler::KindField::encode(StackHandler::TRY_CATCH)
|
|
||||||
: StackHandler::KindField::encode(StackHandler::TRY_FINALLY);
|
|
||||||
} else {
|
|
||||||
ASSERT(try_location == IN_JS_ENTRY);
|
|
||||||
// The frame pointer does not point to a JS frame so we save NULL for
|
// The frame pointer does not point to a JS frame so we save NULL for
|
||||||
// rbp. We expect the code throwing an exception to check rbp before
|
// rbp. We expect the code throwing an exception to check rbp before
|
||||||
// dereferencing it to restore the context.
|
// dereferencing it to restore the context.
|
||||||
push(Immediate(0)); // NULL frame pointer.
|
push(Immediate(0)); // NULL frame pointer.
|
||||||
Push(Smi::FromInt(0)); // No context.
|
Push(Smi::FromInt(0)); // No context.
|
||||||
state |= StackHandler::KindField::encode(StackHandler::ENTRY);
|
} else {
|
||||||
|
push(rbp);
|
||||||
|
push(rsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the state and the code object.
|
// Push the state and the code object.
|
||||||
|
unsigned state =
|
||||||
|
StackHandler::IndexField::encode(handler_index) |
|
||||||
|
StackHandler::KindField::encode(kind);
|
||||||
push(Immediate(state));
|
push(Immediate(state));
|
||||||
Push(CodeObject());
|
Push(CodeObject());
|
||||||
|
|
||||||
@ -2594,7 +2590,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
|||||||
movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset));
|
movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset));
|
||||||
|
|
||||||
bind(&check_kind);
|
bind(&check_kind);
|
||||||
STATIC_ASSERT(StackHandler::ENTRY == 0);
|
STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
|
||||||
testl(Operand(rsp, StackHandlerConstants::kStateOffset),
|
testl(Operand(rsp, StackHandlerConstants::kStateOffset),
|
||||||
Immediate(StackHandler::KindField::kMask));
|
Immediate(StackHandler::KindField::kMask));
|
||||||
j(not_zero, &fetch_next);
|
j(not_zero, &fetch_next);
|
||||||
|
@ -961,9 +961,7 @@ class MacroAssembler: public Assembler {
|
|||||||
// Exception handling
|
// Exception handling
|
||||||
|
|
||||||
// Push a new try handler and link it into try handler chain.
|
// Push a new try handler and link it into try handler chain.
|
||||||
void PushTryHandler(CodeLocation try_location,
|
void PushTryHandler(StackHandler::Kind kind, int handler_index);
|
||||||
HandlerType type,
|
|
||||||
int handler_index);
|
|
||||||
|
|
||||||
// Unlink the stack handler on top of the stack from the try handler chain.
|
// Unlink the stack handler on top of the stack from the try handler chain.
|
||||||
void PopTryHandler();
|
void PopTryHandler();
|
||||||
|
Loading…
Reference in New Issue
Block a user