[Interpreter] Fix bytecode offset for stack overflows.

Rather than pushing zero for the initial bytecode offset, we should push the
offset of the first bytecode handler, Smi tagged. This fixes the line number
for the top stack frame on overflow errors.

BUG=v8:4981
LOG=N

Review-Url: https://codereview.chromium.org/1950913004
Cr-Commit-Position: refs/heads/master@{#36137}
This commit is contained in:
rmcilroy 2016-05-10 05:29:12 -07:00 committed by Commit bot
parent 2da70f853d
commit d9fd822aa2
12 changed files with 73 additions and 66 deletions

View File

@ -1011,8 +1011,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ mov(r0, Operand(0));
// Load the initial bytecode offset.
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(r0, kInterpreterBytecodeOffsetRegister);
__ Push(r3, kInterpreterBytecodeArrayRegister, r0);
// Allocate the local and temporary register file on the stack.
@ -1044,12 +1048,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ b(&loop_header, ge);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ add(r4, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -1015,8 +1015,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ Mov(x0, Operand(0));
// Load the initial bytecode offset.
__ Mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(x0, kInterpreterBytecodeOffsetRegister);
__ Push(x3, kInterpreterBytecodeArrayRegister, x0);
// Allocate the local and temporary register file on the stack.
@ -1046,12 +1050,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Bind(&loop_header);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ Add(x18, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ Mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ Mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -572,8 +572,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
// Push bytecode array.
__ push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Push Smi tagged initial bytecode array offset.
__ push(Immediate(Smi::FromInt(BytecodeArray::kHeaderSize - kHeapObjectTag)));
// Allocate the local and temporary register file on the stack.
{
@ -606,11 +606,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ j(greater_equal, &loop_header);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator, bytecode offset and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ mov(edx, ebp);
__ add(edx, Immediate(InterpreterFrameConstants::kRegisterFileFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,

View File

@ -1002,8 +1002,13 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(BYTECODE_ARRAY_TYPE));
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ Push(a3, kInterpreterBytecodeArrayRegister, zero_reg);
// Load initial bytecode offset.
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(t0, kInterpreterBytecodeOffsetRegister);
__ Push(a3, kInterpreterBytecodeArrayRegister, t0);
// Allocate the local and temporary register file on the stack.
{
@ -1033,11 +1038,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Branch(&loop_header, ge, t0, Operand(zero_reg));
}
// Load bytecode offset and dispatch table into registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ Addu(t3, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -991,8 +991,13 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(BYTECODE_ARRAY_TYPE));
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ Push(a3, kInterpreterBytecodeArrayRegister, zero_reg);
// Load initial bytecode offset.
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(a4, kInterpreterBytecodeOffsetRegister);
__ Push(a3, kInterpreterBytecodeArrayRegister, a4);
// Allocate the local and temporary register file on the stack.
{
@ -1022,11 +1027,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Branch(&loop_header, ge, a4, Operand(zero_reg));
}
// Load bytecode offset and dispatch table into registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ Daddu(a7, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -1025,8 +1025,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ li(r3, Operand::Zero());
// Load initial bytecode offset.
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(r3, kInterpreterBytecodeOffsetRegister);
__ Push(r6, kInterpreterBytecodeArrayRegister, r3);
// Allocate the local and temporary register file on the stack.
@ -1057,12 +1061,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ bind(&no_args);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ addi(r7, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -1013,9 +1013,13 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ LoadImmP(r2, Operand::Zero());
__ Push(r5, kInterpreterBytecodeArrayRegister, r2);
// Load the initial bytecode offset.
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push new.target, bytecode array and Smi tagged bytecode array offset.
__ SmiTag(r4, kInterpreterBytecodeOffsetRegister);
__ Push(r5, kInterpreterBytecodeArrayRegister, r4);
// Allocate the local and temporary register file on the stack.
{
@ -1047,12 +1051,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ bind(&no_args);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ AddP(r4, fp, Operand(InterpreterFrameConstants::kRegisterFileFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));

View File

@ -21,8 +21,8 @@ const Register kJSFunctionRegister = {Register::kCode_r3};
const Register kContextRegister = {Register::kCode_r13};
const Register kAllocateSizeRegister = {Register::kCode_r3};
const Register kInterpreterAccumulatorRegister = {Register::kCode_r2};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r5};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r6};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r6};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r7};
const Register kInterpreterDispatchTableRegister = {Register::kCode_r8};
const Register kJavaScriptCallArgCountRegister = {Register::kCode_r2};
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_r5};

View File

@ -649,10 +649,14 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push bytecode array.
// Load initial bytecode offset.
__ movp(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
// Push bytecode array and Smi tagged bytecode offset.
__ Push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ Push(Immediate(0));
__ Integer32ToSmi(rcx, kInterpreterBytecodeOffsetRegister);
__ Push(rcx);
// Allocate the local and temporary register file on the stack.
{
@ -683,13 +687,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ j(greater_equal, &loop_header, Label::kNear);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ movp(r11, rbp);
__ addp(r11, Immediate(InterpreterFrameConstants::kRegisterFileFromFp));
__ movp(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ Move(
kInterpreterDispatchTableRegister,
ExternalReference::interpreter_dispatch_table_address(masm->isolate()));

View File

@ -573,8 +573,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
// Push bytecode array.
__ push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Push Smi tagged initial bytecode array offset.
__ push(Immediate(Smi::FromInt(BytecodeArray::kHeaderSize - kHeapObjectTag)));
// Allocate the local and temporary register file on the stack.
{
@ -607,11 +607,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ j(greater_equal, &loop_header);
}
// Load accumulator, register file, bytecode offset, dispatch table into
// registers.
// Load accumulator, bytecode offset and dispatch table into registers.
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
__ mov(edx, ebp);
__ add(edx, Immediate(InterpreterFrameConstants::kRegisterFileFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(kInterpreterDispatchTableRegister,

View File

@ -27,10 +27,22 @@
// Flags: --stack-size=100
function overflow() {
var a, b, c, d, e; // Allocates some locals on the function's stack frame.
overflow();
}
function rec1(a) { rec1(a+1); }
function rec2(a) { rec3(a+1); }
function rec3(a) { rec2(a+1); }
// Test stack trace has correct function location at top of the stack.
try {
overflow();
} catch (e) {
var first_frame = e.stack.split("\n")[1]
assertTrue(first_frame.indexOf("stack-traces-overflow.js:30:18") > 0);
}
// Test stack trace getter and setter.
try {
rec1(0);

View File

@ -2,7 +2,6 @@
[ Linux ] inspector/sources/debugger/live-edit-no-reveal.html [ Failure ]
[ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.html [ Failure ]
[ Linux ] fast/xpath/xpath-other-nodeset-result-should-mark-its-nodeset.html [ Failure ]
[ Linux ] inspector/console/console-stack-overflow.html [ Failure ]
[ Linux ] netinfo/gc-unused-listeners.html [ Failure ]
[ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Failure ]
[ Linux ] inspector-protocol/debugger/setScriptSource.html [ Failure ]
@ -18,5 +17,4 @@
[ Linux ] inspector/sources/debugger-frameworks/frameworks-jquery.html [ Failure ]
[ Linux ] fast/dom/StyleSheet/gc-rule-children-wrappers.html [ Failure ]
[ Linux ] fast/dom/NodeIterator/NodeIterator-dont-overcollect.html [ Failure ]
[ Linux ] fast/dom/error-to-string-stack-overflow.html [ Failure ]
[ Linux ] editing/input/text-input-controller-leak-document.html [ Failure ]