Commit 27204d6e authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Push BytecodeArray onto interpreted stack frames.

Replaces the push of the dispatch table on the interpreted stack frame with a
push of the bytecode array. This enables the debugger to replace the bytecode
array with a patched version containing breakpoints.

BUG=v8:4690
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#34032}
parent 4fdc19ae
......@@ -989,12 +989,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ PushFixedFrame(r1);
__ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Push new.target, dispatch table pointer and zero for bytecode array offset.
__ mov(r0, Operand(0));
__ mov(r2, Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Push(r3, r2, r0);
// Get the bytecode array from the function object and load the pointer to the
// first entry into kInterpreterBytecodeRegister.
__ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
......@@ -1010,6 +1004,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ mov(r0, Operand(0));
__ Push(r3, kInterpreterBytecodeArrayRegister, r0);
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -1052,8 +1050,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ ldr(kInterpreterDispatchTableRegister,
MemOperand(fp, InterpreterFrameConstants::kDispatchTableFromFp));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1165,12 +1164,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ ldr(r1,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(kInterpreterBytecodeArrayRegister,
FieldMemOperand(r1, SharedFunctionInfo::kFunctionDataOffset));
__ ldr(
kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -997,12 +997,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Push(lr, fp, cp, x1);
__ Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
// Push dispatch table pointer.
__ Mov(x0, Operand(0));
__ Mov(x2, Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Push(x3, x2, x0);
// Get the bytecode array from the function object and load the pointer to the
// first entry into kInterpreterBytecodeRegister.
__ Ldr(x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
......@@ -1018,6 +1012,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ Mov(x0, Operand(0));
__ Push(x3, kInterpreterBytecodeArrayRegister, x0);
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -1058,8 +1056,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ Mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ Ldr(kInterpreterDispatchTableRegister,
MemOperand(fp, InterpreterFrameConstants::kDispatchTableFromFp));
__ Mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Ldrb(x1, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1110,12 +1109,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ Ldr(x1,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ Ldr(x1, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(kInterpreterBytecodeArrayRegister,
FieldMemOperand(x1, SharedFunctionInfo::kFunctionDataOffset));
__ Ldr(
kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -1254,12 +1254,12 @@ void Deoptimizer::DoComputeInterpretedFrame(int frame_index,
Object* new_target = isolate_->heap()->undefined_value();
WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target ");
// Set the dispatch table pointer.
// Set the bytecode array pointer.
output_offset -= kPointerSize;
input_offset -= kPointerSize;
Address dispatch_table = isolate()->interpreter()->dispatch_table_address();
WriteValueToOutput(reinterpret_cast<Object*>(dispatch_table), 0, frame_index,
output_offset, "dispatch_table ");
Object* bytecode_array = shared->bytecode_array();
WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
"bytecode array ");
// The bytecode offset was mentioned explicitly in the BEGIN_FRAME.
output_offset -= kPointerSize;
......
......@@ -1152,22 +1152,25 @@ void InterpretedFrame::PatchBytecodeOffset(int new_offset) {
SetExpression(index, Smi::FromInt(raw_offset));
}
Object* InterpretedFrame::GetInterpreterRegister(int register_index) const {
const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
DCHECK_EQ(InterpreterFrameConstants::kRegisterFilePointerFromFp,
Object* InterpretedFrame::GetBytecodeArray() const {
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
DCHECK_EQ(InterpreterFrameConstants::kBytecodeArrayFromFp,
StandardFrameConstants::kExpressionsOffset - index * kPointerSize);
return GetExpression(index + register_index);
return GetExpression(index);
}
Address InterpretedFrame::GetDispatchTable() const {
return Memory::Address_at(
fp() + InterpreterFrameConstants::kDispatchTableFromFp);
void InterpretedFrame::PatchBytecodeArray(Object* bytecode_array) {
const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
DCHECK_EQ(InterpreterFrameConstants::kBytecodeArrayFromFp,
StandardFrameConstants::kExpressionsOffset - index * kPointerSize);
SetExpression(index, bytecode_array);
}
void InterpretedFrame::PatchDispatchTable(Address dispatch_table) {
Address* dispatch_table_address = reinterpret_cast<Address*>(
fp() + InterpreterFrameConstants::kDispatchTableFromFp);
*dispatch_table_address = dispatch_table;
Object* InterpretedFrame::GetInterpreterRegister(int register_index) const {
const int index = InterpreterFrameConstants::kRegisterFileExpressionIndex;
DCHECK_EQ(InterpreterFrameConstants::kRegisterFilePointerFromFp,
StandardFrameConstants::kExpressionsOffset - index * kPointerSize);
return GetExpression(index + register_index);
}
void InterpretedFrame::Summarize(List<FrameSummary>* functions) {
......@@ -1421,23 +1424,6 @@ void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
}
void InterpretedFrame::Iterate(ObjectVisitor* v) const {
// Visit tagged pointers in the fixed frame.
Object** fixed_frame_base =
&Memory::Object_at(fp() + InterpreterFrameConstants::kNewTargetFromFp);
Object** fixed_frame_limit =
&Memory::Object_at(fp() + StandardFrameConstants::kLastObjectOffset) + 1;
v->VisitPointers(fixed_frame_base, fixed_frame_limit);
// Visit the expressions.
Object** expression_base = &Memory::Object_at(sp());
Object** expression_limit = &Memory::Object_at(
fp() + InterpreterFrameConstants::kBytecodeOffsetFromFp) + 1;
v->VisitPointers(expression_base, expression_limit);
IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
}
void InternalFrame::Iterate(ObjectVisitor* v) const {
// Internal frames only have object pointers on the expression stack
// as they never have any arguments.
......
......@@ -185,7 +185,7 @@ class InterpreterFrameConstants : public AllStatic {
// FP-relative.
static const int kNewTargetFromFp =
-StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
static const int kDispatchTableFromFp =
static const int kBytecodeArrayFromFp =
-StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
static const int kBytecodeOffsetFromFp =
-StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
......@@ -193,6 +193,7 @@ class InterpreterFrameConstants : public AllStatic {
-StandardFrameConstants::kFixedFrameSizeFromFp - 4 * kPointerSize;
// Expression index for {StandardFrame::GetExpressionAddress}.
static const int kBytecodeArrayExpressionIndex = 1;
static const int kBytecodeOffsetExpressionIndex = 2;
static const int kRegisterFileExpressionIndex = 3;
......@@ -201,7 +202,7 @@ class InterpreterFrameConstants : public AllStatic {
StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
static const int kBytecodeOffsetFromRegisterPointer = 1 * kPointerSize;
static const int kDispatchTableFromRegisterPointer = 2 * kPointerSize;
static const int kBytecodeArrayFromRegisterPointer = 2 * kPointerSize;
static const int kNewTargetFromRegisterPointer = 3 * kPointerSize;
static const int kFunctionFromRegisterPointer = 4 * kPointerSize;
static const int kContextFromRegisterPointer = 5 * kPointerSize;
......@@ -728,9 +729,6 @@ class InterpretedFrame : public JavaScriptFrame {
public:
Type type() const override { return INTERPRETED; }
// GC support.
void Iterate(ObjectVisitor* v) const override;
// Lookup exception handler for current {pc}, returns -1 if none found.
int LookupExceptionHandlerInTable(
int* data, HandlerTable::CatchPrediction* prediction) override;
......@@ -742,12 +740,12 @@ class InterpretedFrame : public JavaScriptFrame {
// unwinding to continue execution at a different bytecode offset.
void PatchBytecodeOffset(int new_offset);
// Returns the current dispatch table pointer.
Address GetDispatchTable() const;
// Returns the frame's current bytecode array.
Object* GetBytecodeArray() const;
// Updates the current dispatch table pointer with |dispatch_table|. Used by
// the debugger to swap execution onto the debugger dispatch table.
void PatchDispatchTable(Address dispatch_table);
// Updates the frame's BytecodeArray with |bytecode_array|. Used by the
// debugger to swap execution onto a BytecodeArray patched with breakpoints.
void PatchBytecodeArray(Object* bytecode_array);
// Access to the interpreter register file for this frame.
Object* GetInterpreterRegister(int register_index) const;
......
......@@ -546,13 +546,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ push(edi); // Callee's JS function.
__ push(edx); // Callee's new target.
// Push dispatch table pointer.
__ mov(eax, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ push(eax);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Get the bytecode array from the function object and load the pointer to the
// first entry into edi (InterpreterBytecodeRegister).
__ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
......@@ -567,6 +560,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push bytecode array.
__ push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -612,7 +610,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Operand(ebp, InterpreterFrameConstants::kDispatchTableFromFp));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Push dispatch table as a stack located parameter to the bytecode handler.
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
......@@ -752,11 +751,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
// Get the bytecode array pointer from the frame.
__ mov(ebx, Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ mov(kInterpreterBytecodeArrayRegister,
FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -28,14 +28,14 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
bytecode_(bytecode),
accumulator_(this, MachineRepresentation::kTagged),
context_(this, MachineRepresentation::kTagged),
dispatch_table_(this, MachineType::PointerRepresentation()),
bytecode_array_(this, MachineRepresentation::kTagged),
disable_stack_check_across_call_(false),
stack_pointer_before_call_(nullptr) {
accumulator_.Bind(
Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter));
context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter));
dispatch_table_.Bind(
Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter));
bytecode_array_.Bind(
Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter));
if (FLAG_trace_ignition) {
TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry);
}
......@@ -65,11 +65,11 @@ Node* InterpreterAssembler::RegisterFileRawPointer() {
}
Node* InterpreterAssembler::BytecodeArrayTaggedPointer() {
return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter);
return bytecode_array_.value();
}
Node* InterpreterAssembler::DispatchTableRawPointer() {
return dispatch_table_.value();
return Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter);
}
Node* InterpreterAssembler::RegisterLocation(Node* reg_index) {
......@@ -310,8 +310,8 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
void InterpreterAssembler::CallPrologue() {
StoreRegister(SmiTag(BytecodeOffset()),
InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer);
StoreRegister(DispatchTableRawPointer(),
InterpreterFrameConstants::kDispatchTableFromRegisterPointer);
StoreRegister(BytecodeArrayTaggedPointer(),
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer);
if (FLAG_debug_code && !disable_stack_check_across_call_) {
DCHECK(stack_pointer_before_call_ == nullptr);
......@@ -328,10 +328,10 @@ void InterpreterAssembler::CallEpilogue() {
kUnexpectedStackPointer);
}
// Restore dispatch table from stack frame in case the debugger has swapped us
// to the debugger dispatch table.
dispatch_table_.Bind(LoadRegister(
InterpreterFrameConstants::kDispatchTableFromRegisterPointer));
// Restore bytecode array from stack frame in case the debugger has swapped us
// to the patched debugger bytecode array.
bytecode_array_.Bind(LoadRegister(
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
}
Node* InterpreterAssembler::CallJS(Node* function, Node* context,
......
......@@ -178,7 +178,7 @@ class InterpreterAssembler : public compiler::CodeStubAssembler {
Bytecode bytecode_;
CodeStubAssembler::Variable accumulator_;
CodeStubAssembler::Variable context_;
CodeStubAssembler::Variable dispatch_table_;
CodeStubAssembler::Variable bytecode_array_;
bool disable_stack_check_across_call_;
compiler::Node* stack_pointer_before_call_;
......
......@@ -975,11 +975,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Push(ra, fp, cp, a1);
__ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Push new.target, dispatch table pointer and zero for bytecode array offset.
__ li(a0, Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Push(a3, a0, zero_reg);
// Get the bytecode array from the function object and load the pointer to the
// first entry into kInterpreterBytecodeRegister.
__ lw(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
......@@ -996,6 +991,9 @@ 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);
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -1036,8 +1034,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ lw(kInterpreterDispatchTableRegister,
MemOperand(fp, InterpreterFrameConstants::kDispatchTableFromFp));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Addu(a0, kInterpreterBytecodeArrayRegister,
......@@ -1150,12 +1149,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ lw(a1,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ lw(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(kInterpreterBytecodeArrayRegister,
FieldMemOperand(a1, SharedFunctionInfo::kFunctionDataOffset));
__ lw(
kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -967,11 +967,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Push(ra, fp, cp, a1);
__ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Push new.target, dispatch table pointer and zero for bytecode array offset.
__ li(a0, Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Push(a3, a0, zero_reg);
// Get the bytecode array from the function object and load the pointer to the
// first entry into kInterpreterBytecodeRegister.
__ ld(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
......@@ -988,6 +983,9 @@ 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);
// Allocate the local and temporary register file on the stack.
{
// Load frame size (word) from the BytecodeArray object.
......@@ -1028,8 +1026,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ li(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ lw(kInterpreterDispatchTableRegister,
MemOperand(fp, InterpreterFrameConstants::kDispatchTableFromFp));
__ li(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ Daddu(a0, kInterpreterBytecodeArrayRegister,
......@@ -1142,12 +1141,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ ld(a1,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ ld(kInterpreterBytecodeArrayRegister,
FieldMemOperand(a1, SharedFunctionInfo::kFunctionDataOffset));
__ ld(
kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -978,12 +978,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ PushFixedFrame(r4);
__ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Push new.target, dispatch table pointer and zero for bytecode array offset.
__ li(r3, Operand::Zero());
__ mov(r5, Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ Push(r6, r5, r3);
// Get the bytecode array from the function object and load the pointer to the
// first entry into kInterpreterBytecodeRegister.
__ LoadP(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
......@@ -999,6 +993,10 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push new.target, bytecode array and zero for bytecode array offset.
__ li(r3, Operand::Zero());
__ Push(r6, kInterpreterBytecodeArrayRegister, r3);
// Allocate the local and temporary register file on the stack.
{
// Load frame size (word) from the BytecodeArray object.
......@@ -1040,8 +1038,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Operand(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ LoadP(kInterpreterDispatchTableRegister,
MemOperand(fp, InterpreterFrameConstants::kDispatchTableFromFp));
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Dispatch to the first bytecode handler for the function.
__ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister,
......@@ -1150,12 +1149,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ LoadP(r4,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ LoadP(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(kInterpreterBytecodeArrayRegister,
FieldMemOperand(r4, SharedFunctionInfo::kFunctionDataOffset));
__ LoadP(
kInterpreterBytecodeArrayRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -620,13 +620,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Push(rdi); // Callee's JS function.
__ Push(rdx); // Callee's new target.
// Push dispatch table pointer.
__ Move(rax, ExternalReference::interpreter_dispatch_table_address(
masm->isolate()));
__ Push(rax);
// Push zero for bytecode array offset.
__ Push(Immediate(0));
// Get the bytecode array from the function object and load the pointer to the
// first entry into edi (InterpreterBytecodeRegister).
__ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
......@@ -641,6 +634,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push bytecode array.
__ Push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ Push(Immediate(0));
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -684,8 +682,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ movp(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ movp(kInterpreterDispatchTableRegister,
Operand(rbp, InterpreterFrameConstants::kDispatchTableFromFp));
__ Move(
kInterpreterDispatchTableRegister,
ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
// Dispatch to the first bytecode handler for the function.
__ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister,
......@@ -819,12 +818,10 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
InterpreterFrameConstants::kContextFromRegisterPointer));
// Get the bytecode array pointer from the frame.
__ movp(rbx,
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ movp(kInterpreterBytecodeArrayRegister,
FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
__ movp(
kInterpreterBytecodeArrayRegister,
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -548,13 +548,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ push(edi); // Callee's JS function.
__ push(edx); // Callee's new target.
// Push dispatch table pointer.
__ mov(eax, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
__ push(eax);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Get the bytecode array from the function object and load the pointer to the
// first entry into edi (InterpreterBytecodeRegister).
__ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
......@@ -569,6 +562,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
// Push bytecode array.
__ push(kInterpreterBytecodeArrayRegister);
// Push zero for bytecode array offset.
__ push(Immediate(0));
// Allocate the local and temporary register file on the stack.
{
// Load frame size from the BytecodeArray object.
......@@ -614,7 +612,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
__ mov(kInterpreterBytecodeOffsetRegister,
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
__ mov(ebx, Operand(ebp, InterpreterFrameConstants::kDispatchTableFromFp));
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
masm->isolate())));
// Push dispatch table as a stack located parameter to the bytecode handler.
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
......@@ -754,11 +753,9 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
// Get the bytecode array pointer from the frame.
__ mov(ebx, Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kFunctionFromRegisterPointer));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ mov(kInterpreterBytecodeArrayRegister,
FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer));
if (FLAG_debug_code) {
// Check function data field is actually a BytecodeArray object.
......
......@@ -836,6 +836,10 @@
# TODO(rmcilroy,4680): Check failed: osr_normal_entry.
'regress/regress-123919': [FAIL],
# TODO(rmcilroy,4680): Fails due to debugger loading bytecodearray as an
# expression local.
'harmony/default-parameters-debug': [FAIL],
# TODO(rmcilroy,4680): Pass on debug, fail on release.
'compiler/regress-stacktrace-methods': [PASS, FAIL],
......
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