Commit 03620298 authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Switch full-codegen from StackHandlers to handler table.

Port 38a719f9

Original commit message:
This switches full-codegen to no longer push and pop StackHandler
markers onto the operand stack, but relies on a range-based handler
table instead. We only use StackHandlers in JSEntryStubs to mark the
transition from C to JS code.

Note that this makes deoptimization and OSR from within any try-block
work out of the box, makes the non-exception paths faster and should
overall be neutral on the memory footprint (pros).

On the other hand it makes the exception paths slower and actually
throwing and exception more expensive (cons).

TEST=cctest/test-run-jsexceptions/DeoptTry
BUG=

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

Cr-Commit-Position: refs/heads/master@{#27443}
parent fc7ff65c
...@@ -1178,9 +1178,8 @@ void CEntryStub::Generate(MacroAssembler* masm) { ...@@ -1178,9 +1178,8 @@ void CEntryStub::Generate(MacroAssembler* masm) {
__ li(fp, Operand(pending_handler_fp_address)); __ li(fp, Operand(pending_handler_fp_address));
__ lw(fp, MemOperand(fp)); __ lw(fp, MemOperand(fp));
// If the handler is a JS frame, restore the context to the frame. // If the handler is a JS frame, restore the context to the frame. Note that
// (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp // the context will be set to (cp == 0) for non-JS frames.
// or cp.
Label zero; Label zero;
__ Branch(&zero, eq, cp, Operand(zero_reg)); __ Branch(&zero, eq, cp, Operand(zero_reg));
__ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
...@@ -1280,7 +1279,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1280,7 +1279,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
handler_offset_ = handler_entry.pos(); handler_offset_ = handler_entry.pos();
// Caught exception: Store result (exception) in the pending exception // Caught exception: Store result (exception) in the pending exception
// field in the JSEnv and return a failure sentinel. Coming in here the // field in the JSEnv and return a failure sentinel. Coming in here the
// fp will be invalid because the PushTryHandler below sets it to 0 to // fp will be invalid because the PushStackHandler below sets it to 0 to
// signal the existence of the JSEntry frame. // signal the existence of the JSEntry frame.
__ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
...@@ -1289,10 +1288,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1289,10 +1288,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ b(&exit); // b exposes branch delay slot. __ b(&exit); // b exposes branch delay slot.
__ nop(); // Branch delay slot nop. __ nop(); // Branch delay slot nop.
// Invoke: Link this frame into the handler chain. There's only one // Invoke: Link this frame into the handler chain.
// handler block in this code object, so its index is 0.
__ bind(&invoke); __ bind(&invoke);
__ PushTryHandler(StackHandler::JS_ENTRY, 0); __ PushStackHandler();
// 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
...@@ -1337,7 +1335,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1337,7 +1335,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Call(t9); __ Call(t9);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopTryHandler(); __ PopStackHandler();
__ bind(&exit); // v0 holds result __ bind(&exit); // v0 holds result
// Check if the current stack frame is marked as the outermost JS frame. // Check if the current stack frame is marked as the outermost JS frame.
......
...@@ -115,7 +115,8 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -115,7 +115,8 @@ class JumpPatchSite BASE_EMBEDDED {
void FullCodeGenerator::Generate() { void FullCodeGenerator::Generate() {
CompilationInfo* info = info_; CompilationInfo* info = info_;
handler_table_ = handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
HandlerTable::LengthForRange(function()->handler_count()), TENURED));
profiling_counter_ = isolate()->factory()->NewCell( profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
...@@ -2185,7 +2186,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2185,7 +2186,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
__ bind(&l_catch); __ bind(&l_catch);
__ mov(a0, v0); __ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
__ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ Push(load_name, a3, a0); // "throw", iter, except __ Push(load_name, a3, a0); // "throw", iter, except
...@@ -2196,17 +2196,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2196,17 +2196,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// re-boxing. // re-boxing.
__ bind(&l_try); __ bind(&l_try);
__ pop(a0); // result __ pop(a0); // result
__ PushTryHandler(StackHandler::CATCH, expr->index()); EnterTryBlock(expr->index(), &l_catch);
const int handler_size = StackHandlerConstants::kSize; const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(a0); // result __ push(a0); // result
__ jmp(&l_suspend); __ jmp(&l_suspend);
__ bind(&l_continuation); __ bind(&l_continuation);
__ mov(a0, v0); __ mov(a0, v0);
__ jmp(&l_resume); __ jmp(&l_resume);
__ bind(&l_suspend); __ bind(&l_suspend);
const int generator_object_depth = kPointerSize + handler_size; const int generator_object_depth = kPointerSize + try_block_size;
__ lw(a0, MemOperand(sp, generator_object_depth)); __ lw(a0, MemOperand(sp, generator_object_depth));
__ push(a0); // g __ push(a0); // g
__ Push(Smi::FromInt(expr->index())); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
__ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
...@@ -2214,13 +2215,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2214,13 +2215,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mov(a1, cp); __ mov(a1, cp);
__ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
kRAHasBeenSaved, kDontSaveFPRegs); kRAHasBeenSaved, kDontSaveFPRegs);
__ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 2);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ pop(v0); // result __ pop(v0); // result
EmitReturnSequence(); EmitReturnSequence();
__ mov(a0, v0); __ mov(a0, v0);
__ bind(&l_resume); // received in a0 __ bind(&l_resume); // received in a0
__ PopTryHandler(); ExitTryBlock(expr->index());
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ bind(&l_next); __ bind(&l_next);
...@@ -5359,34 +5360,6 @@ void FullCodeGenerator::ExitFinallyBlock() { ...@@ -5359,34 +5360,6 @@ void FullCodeGenerator::ExitFinallyBlock() {
} }
#undef __
#define __ ACCESS_MASM(masm())
FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
int* stack_depth,
int* context_length) {
// The macros used here must preserve the result register.
// Because the handler block contains the context of the finally
// code, we can restore it directly from there for the finally code
// rather than iteratively unwinding contexts via their previous
// links.
__ Drop(*stack_depth); // Down to the handler block.
if (*context_length > 0) {
// Restore the context to its dedicated register and the stack.
__ lw(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
__ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ PopTryHandler();
__ Call(finally_entry_);
*stack_depth = 0;
*context_length = 0;
return previous_;
}
#undef __ #undef __
......
...@@ -3235,40 +3235,22 @@ void MacroAssembler::DebugBreak() { ...@@ -3235,40 +3235,22 @@ void MacroAssembler::DebugBreak() {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Exception handling. // Exception handling.
void MacroAssembler::PushTryHandler(StackHandler::Kind kind, void MacroAssembler::PushStackHandler() {
int handler_index) {
// Adjust this code if not the case. // Adjust this code if not the case.
STATIC_ASSERT(StackHandlerConstants::kSize == 3 * kPointerSize); STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
// 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
// pushing on the stack.
// Set up the the index (t2) for pushing.
li(t2, Operand(handler_index));
// Push the context and index.
if (kind == StackHandler::JS_ENTRY) {
DCHECK(Smi::FromInt(0) == 0);
// The zero_reg indicates no context.
// The operands are reversed to match the order of MultiPush/Pop.
Push(zero_reg, t2);
} else {
MultiPush(t2.bit() | cp.bit());
}
// Link the current handler as the next handler. // Link the current handler as the next handler.
li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); li(t2, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
lw(t1, MemOperand(t2)); lw(t1, MemOperand(t2));
push(t1); push(t1);
// Set this new handler as the current one. // Set this new handler as the current one.
sw(sp, MemOperand(t2)); sw(sp, MemOperand(t2));
} }
void MacroAssembler::PopTryHandler() { void MacroAssembler::PopStackHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
pop(a1); pop(a1);
Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
......
...@@ -969,12 +969,12 @@ class MacroAssembler: public Assembler { ...@@ -969,12 +969,12 @@ class MacroAssembler: public Assembler {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Exception handling. // Exception handling.
// Push a new try handler and link into try handler chain. // Push a new stack handler and link into stack handler chain.
void PushTryHandler(StackHandler::Kind kind, int handler_index); void PushStackHandler();
// 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 stack handler chain.
// Must preserve the result register. // Must preserve the result register.
void PopTryHandler(); void PopStackHandler();
// Copies a fixed number of fields of heap objects from src to dst. // Copies a fixed number of fields of heap objects from src to dst.
void CopyFields(Register dst, Register src, RegList temps, int field_count); void CopyFields(Register dst, Register src, RegList temps, int field_count);
......
...@@ -1173,9 +1173,8 @@ void CEntryStub::Generate(MacroAssembler* masm) { ...@@ -1173,9 +1173,8 @@ void CEntryStub::Generate(MacroAssembler* masm) {
__ li(fp, Operand(pending_handler_fp_address)); __ li(fp, Operand(pending_handler_fp_address));
__ ld(fp, MemOperand(fp)); __ ld(fp, MemOperand(fp));
// If the handler is a JS frame, restore the context to the frame. // If the handler is a JS frame, restore the context to the frame. Note that
// (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp // the context will be set to (cp == 0) for non-JS frames.
// or cp.
Label zero; Label zero;
__ Branch(&zero, eq, cp, Operand(zero_reg)); __ Branch(&zero, eq, cp, Operand(zero_reg));
__ sd(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ sd(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
...@@ -1281,7 +1280,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1281,7 +1280,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
handler_offset_ = handler_entry.pos(); handler_offset_ = handler_entry.pos();
// Caught exception: Store result (exception) in the pending exception // Caught exception: Store result (exception) in the pending exception
// field in the JSEnv and return a failure sentinel. Coming in here the // field in the JSEnv and return a failure sentinel. Coming in here the
// fp will be invalid because the PushTryHandler below sets it to 0 to // fp will be invalid because the PushStackHandler below sets it to 0 to
// signal the existence of the JSEntry frame. // signal the existence of the JSEntry frame.
__ li(a4, Operand(ExternalReference(Isolate::kPendingExceptionAddress, __ li(a4, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
...@@ -1290,10 +1289,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1290,10 +1289,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ b(&exit); // b exposes branch delay slot. __ b(&exit); // b exposes branch delay slot.
__ nop(); // Branch delay slot nop. __ nop(); // Branch delay slot nop.
// Invoke: Link this frame into the handler chain. There's only one // Invoke: Link this frame into the handler chain.
// handler block in this code object, so its index is 0.
__ bind(&invoke); __ bind(&invoke);
__ PushTryHandler(StackHandler::JS_ENTRY, 0); __ PushStackHandler();
// 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
...@@ -1337,7 +1335,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) { ...@@ -1337,7 +1335,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Call(t9); __ Call(t9);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopTryHandler(); __ PopStackHandler();
__ bind(&exit); // v0 holds result __ bind(&exit); // v0 holds result
// Check if the current stack frame is marked as the outermost JS frame. // Check if the current stack frame is marked as the outermost JS frame.
......
...@@ -115,7 +115,8 @@ class JumpPatchSite BASE_EMBEDDED { ...@@ -115,7 +115,8 @@ class JumpPatchSite BASE_EMBEDDED {
void FullCodeGenerator::Generate() { void FullCodeGenerator::Generate() {
CompilationInfo* info = info_; CompilationInfo* info = info_;
handler_table_ = handler_table_ =
isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
HandlerTable::LengthForRange(function()->handler_count()), TENURED));
profiling_counter_ = isolate()->factory()->NewCell( profiling_counter_ = isolate()->factory()->NewCell(
Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
...@@ -2182,7 +2183,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2182,7 +2183,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
__ bind(&l_catch); __ bind(&l_catch);
__ mov(a0, v0); __ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
__ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
__ ld(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ ld(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ Push(a2, a3, a0); // "throw", iter, except __ Push(a2, a3, a0); // "throw", iter, except
...@@ -2193,17 +2193,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2193,17 +2193,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// re-boxing. // re-boxing.
__ bind(&l_try); __ bind(&l_try);
__ pop(a0); // result __ pop(a0); // result
__ PushTryHandler(StackHandler::CATCH, expr->index()); EnterTryBlock(expr->index(), &l_catch);
const int handler_size = StackHandlerConstants::kSize; const int try_block_size = TryCatch::kElementCount * kPointerSize;
__ push(a0); // result __ push(a0); // result
__ jmp(&l_suspend); __ jmp(&l_suspend);
__ bind(&l_continuation); __ bind(&l_continuation);
__ mov(a0, v0); __ mov(a0, v0);
__ jmp(&l_resume); __ jmp(&l_resume);
__ bind(&l_suspend); __ bind(&l_suspend);
const int generator_object_depth = kPointerSize + handler_size; const int generator_object_depth = kPointerSize + try_block_size;
__ ld(a0, MemOperand(sp, generator_object_depth)); __ ld(a0, MemOperand(sp, generator_object_depth));
__ push(a0); // g __ push(a0); // g
__ Push(Smi::FromInt(expr->index())); // handler-index
DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
__ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
__ sd(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); __ sd(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
...@@ -2211,13 +2212,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2211,13 +2212,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mov(a1, cp); __ mov(a1, cp);
__ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
kRAHasBeenSaved, kDontSaveFPRegs); kRAHasBeenSaved, kDontSaveFPRegs);
__ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 2);
__ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ pop(v0); // result __ pop(v0); // result
EmitReturnSequence(); EmitReturnSequence();
__ mov(a0, v0); __ mov(a0, v0);
__ bind(&l_resume); // received in a0 __ bind(&l_resume); // received in a0
__ PopTryHandler(); ExitTryBlock(expr->index());
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ bind(&l_next); __ bind(&l_next);
...@@ -5361,34 +5362,6 @@ void FullCodeGenerator::ExitFinallyBlock() { ...@@ -5361,34 +5362,6 @@ void FullCodeGenerator::ExitFinallyBlock() {
} }
#undef __
#define __ ACCESS_MASM(masm())
FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
int* stack_depth,
int* context_length) {
// The macros used here must preserve the result register.
// Because the handler block contains the context of the finally
// code, we can restore it directly from there for the finally code
// rather than iteratively unwinding contexts via their previous
// links.
__ Drop(*stack_depth); // Down to the handler block.
if (*context_length > 0) {
// Restore the context to its dedicated register and the stack.
__ ld(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
__ sd(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
}
__ PopTryHandler();
__ Call(finally_entry_);
*stack_depth = 0;
*context_length = 0;
return previous_;
}
#undef __ #undef __
......
...@@ -3222,40 +3222,22 @@ void MacroAssembler::DebugBreak() { ...@@ -3222,40 +3222,22 @@ void MacroAssembler::DebugBreak() {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Exception handling. // Exception handling.
void MacroAssembler::PushTryHandler(StackHandler::Kind kind, void MacroAssembler::PushStackHandler() {
int handler_index) {
// Adjust this code if not the case. // Adjust this code if not the case.
STATIC_ASSERT(StackHandlerConstants::kSize == 3 * kPointerSize); STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize);
STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
// For the JSEntry handler, we must preserve a0-a3 and s0.
// a5-a7 are available. We will build up the handler from the bottom by
// pushing on the stack.
// Set up the the index (a6) for pushing.
li(a6, Operand(handler_index));
// Push the context and index.
if (kind == StackHandler::JS_ENTRY) {
DCHECK(Smi::FromInt(0) == 0);
// The zero_reg indicates no context.
// The operands are reversed to match the order of MultiPush/Pop.
Push(zero_reg, a6);
} else {
MultiPush(a6.bit() | cp.bit());
}
// Link the current handler as the next handler. // Link the current handler as the next handler.
li(a6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); li(a6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
ld(a5, MemOperand(a6)); ld(a5, MemOperand(a6));
push(a5); push(a5);
// Set this new handler as the current one. // Set this new handler as the current one.
sd(sp, MemOperand(a6)); sd(sp, MemOperand(a6));
} }
void MacroAssembler::PopTryHandler() { void MacroAssembler::PopStackHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
pop(a1); pop(a1);
Daddu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); Daddu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
......
...@@ -999,12 +999,12 @@ class MacroAssembler: public Assembler { ...@@ -999,12 +999,12 @@ class MacroAssembler: public Assembler {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Exception handling. // Exception handling.
// Push a new try handler and link into try handler chain. // Push a new stack handler and link into stack handler chain.
void PushTryHandler(StackHandler::Kind kind, int handler_index); void PushStackHandler();
// 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 stack handler chain.
// Must preserve the result register. // Must preserve the result register.
void PopTryHandler(); void PopStackHandler();
// Copies a fixed number of fields of heap objects from src to dst. // Copies a fixed number of fields of heap objects from src to dst.
void CopyFields(Register dst, Register src, RegList temps, int field_count); void CopyFields(Register dst, Register src, RegList temps, int field_count);
......
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