[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:
parent
2da70f853d
commit
d9fd822aa2
@ -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())));
|
||||
|
@ -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())));
|
||||
|
@ -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,
|
||||
|
@ -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())));
|
||||
|
@ -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())));
|
||||
|
@ -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())));
|
||||
|
@ -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())));
|
||||
|
@ -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};
|
||||
|
@ -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()));
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 ]
|
||||
|
Loading…
Reference in New Issue
Block a user