Skip to content

Commit 00df60d

Browse files
rmcilroyCommit bot
authored andcommitted
[interpreter]: Changes to interpreter builtins for accumulator and register file registers.
Makes the following modifications to the interpreter builtins and InterpreterAssembler: - Adds an accumulator register and initializes it to undefined() - Adds a register file pointer register and use it instead of FramePointer to access registers - Modifies builtin to support functions with 0 regiters in the register file - Modifies builtin to Call rather than TailCall to first bytecode handler. BUG=v8:4280 LOG=N Review URL: https://codereview.chromium.org/1289863003 Cr-Commit-Position: refs/heads/master@{#30219}
1 parent 8aef442 commit 00df60d

24 files changed

Lines changed: 340 additions & 205 deletions

src/arm/builtins-arm.cc

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "src/debug/debug.h"
99
#include "src/deoptimizer.h"
1010
#include "src/full-codegen/full-codegen.h"
11-
#include "src/interpreter/bytecodes.h"
1211
#include "src/runtime/runtime.h"
1312

1413
namespace v8 {
@@ -925,16 +924,17 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
925924
__ bind(&ok);
926925

927926
// If ok, push undefined as the initial value for all register file entries.
928-
// Note: there should always be at least one stack slot for the return
929-
// register in the register file.
930927
Label loop_header;
928+
Label loop_check;
931929
__ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
930+
__ b(&loop_check, al);
932931
__ bind(&loop_header);
933932
// TODO(rmcilroy): Consider doing more than one push per loop iteration.
934933
__ push(r9);
935934
// Continue loop if not done.
935+
__ bind(&loop_check);
936936
__ sub(r4, r4, Operand(kPointerSize), SetCC);
937-
__ b(&loop_header, ne);
937+
__ b(&loop_header, ge);
938938
}
939939

940940
// TODO(rmcilroy): List of things not currently dealt with here but done in
@@ -968,7 +968,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
968968
__ bind(&ok);
969969
}
970970

971-
// Load bytecode offset and dispatch table into registers.
971+
// Load accumulator, register file, bytecode offset, dispatch table into
972+
// registers.
973+
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
974+
__ sub(kInterpreterRegisterFileRegister, fp,
975+
Operand(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp));
972976
__ mov(kInterpreterBytecodeOffsetRegister,
973977
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
974978
__ LoadRoot(kInterpreterDispatchTableRegister,
@@ -977,14 +981,14 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
977981
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
978982

979983
// Dispatch to the first bytecode handler for the function.
980-
__ ldrb(r0, MemOperand(kInterpreterBytecodeArrayRegister,
984+
__ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
981985
kInterpreterBytecodeOffsetRegister));
982-
__ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r0, LSL,
986+
__ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
983987
kPointerSizeLog2));
984988
// TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
985989
// and header removal.
986990
__ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
987-
__ Jump(ip);
991+
__ Call(ip);
988992
}
989993

990994

@@ -995,9 +999,8 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
995999
// - Support profiler (specifically decrementing profiling_counter
9961000
// appropriately and calling out to HandleInterrupts if necessary).
9971001

998-
// Load return value into r0.
999-
__ ldr(r0, MemOperand(fp, -kPointerSize -
1000-
StandardFrameConstants::kFixedFrameSizeFromFp));
1002+
// The return value is in accumulator, which is already in r0.
1003+
10011004
// Leave the frame (also dropping the register file).
10021005
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
10031006
// Drop receiver + arguments.

src/arm/macro-assembler-arm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const Register kReturnRegister0 = {kRegister_r0_Code};
1818
const Register kReturnRegister1 = {kRegister_r1_Code};
1919
const Register kJSFunctionRegister = {kRegister_r1_Code};
2020
const Register kContextRegister = {kRegister_r7_Code};
21+
const Register kInterpreterAccumulatorRegister = {kRegister_r0_Code};
22+
const Register kInterpreterRegisterFileRegister = {kRegister_r4_Code};
2123
const Register kInterpreterBytecodeOffsetRegister = {kRegister_r5_Code};
2224
const Register kInterpreterBytecodeArrayRegister = {kRegister_r6_Code};
2325
const Register kInterpreterDispatchTableRegister = {kRegister_r8_Code};

src/arm64/builtins-arm64.cc

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
990990
__ Bind(&ok);
991991
}
992992

993-
// Load bytecode offset and dispatch table into registers.
993+
// Load accumulator, register file, bytecode offset, dispatch table into
994+
// registers.
995+
__ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
996+
__ Sub(kInterpreterRegisterFileRegister, fp,
997+
Operand(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp));
994998
__ Mov(kInterpreterBytecodeOffsetRegister,
995999
Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
9961000
__ LoadRoot(kInterpreterDispatchTableRegister,
@@ -999,14 +1003,14 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
9991003
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
10001004

10011005
// Dispatch to the first bytecode handler for the function.
1002-
__ Ldrb(x0, MemOperand(kInterpreterBytecodeArrayRegister,
1006+
__ Ldrb(x1, MemOperand(kInterpreterBytecodeArrayRegister,
10031007
kInterpreterBytecodeOffsetRegister));
1004-
__ Mov(x0, Operand(x0, LSL, kPointerSizeLog2));
1005-
__ Ldr(ip0, MemOperand(kInterpreterDispatchTableRegister, x0));
1008+
__ Mov(x1, Operand(x1, LSL, kPointerSizeLog2));
1009+
__ Ldr(ip0, MemOperand(kInterpreterDispatchTableRegister, x1));
10061010
// TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
10071011
// and header removal.
10081012
__ Add(ip0, ip0, Operand(Code::kHeaderSize - kHeapObjectTag));
1009-
__ Jump(ip0);
1013+
__ Call(ip0);
10101014
}
10111015

10121016

@@ -1017,9 +1021,8 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
10171021
// - Support profiler (specifically decrementing profiling_counter
10181022
// appropriately and calling out to HandleInterrupts if necessary).
10191023

1020-
// Load return value into x0.
1021-
__ ldr(x0, MemOperand(fp, -kPointerSize -
1022-
StandardFrameConstants::kFixedFrameSizeFromFp));
1024+
// The return value is in accumulator, which is already in x0.
1025+
10231026
// Leave the frame (also dropping the register file).
10241027
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
10251028
// Drop receiver + arguments.

src/arm64/macro-assembler-arm64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ namespace internal {
3939
#define kReturnRegister1 x1
4040
#define kJSFunctionRegister x1
4141
#define kContextRegister cp
42+
#define kInterpreterAccumulatorRegister x0
43+
#define kInterpreterRegisterFileRegister x18
4244
#define kInterpreterBytecodeOffsetRegister x19
4345
#define kInterpreterBytecodeArrayRegister x20
4446
#define kInterpreterDispatchTableRegister x21

src/compiler/interpreter-assembler.cc

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
3131
Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr,
3232
InstructionSelector::SupportedMachineOperatorFlags())),
3333
end_node_(nullptr),
34+
accumulator_(
35+
raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)),
3436
code_generated_(false) {}
3537

3638

@@ -60,70 +62,72 @@ Handle<Code> InterpreterAssembler::GenerateCode() {
6062
}
6163

6264

63-
Node* InterpreterAssembler::BytecodeArrayPointer() {
64-
return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter);
65+
Node* InterpreterAssembler::GetAccumulator() {
66+
return accumulator_;
6567
}
6668

6769

68-
Node* InterpreterAssembler::BytecodeOffset() {
69-
return raw_assembler_->Parameter(
70-
Linkage::kInterpreterBytecodeOffsetParameter);
70+
void InterpreterAssembler::SetAccumulator(Node* value) {
71+
accumulator_ = value;
7172
}
7273

7374

74-
Node* InterpreterAssembler::DispatchTablePointer() {
75-
return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter);
75+
Node* InterpreterAssembler::RegisterFileRawPointer() {
76+
return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter);
7677
}
7778

7879

79-
Node* InterpreterAssembler::FramePointer() {
80-
return raw_assembler_->LoadFramePointer();
80+
Node* InterpreterAssembler::BytecodeArrayTaggedPointer() {
81+
return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter);
8182
}
8283

8384

84-
Node* InterpreterAssembler::RegisterFrameOffset(int index) {
85-
DCHECK_LE(index, kMaxRegisterIndex);
86-
return Int32Constant(kFirstRegisterOffsetFromFp -
87-
(index << kPointerSizeLog2));
85+
Node* InterpreterAssembler::BytecodeOffset() {
86+
return raw_assembler_->Parameter(
87+
Linkage::kInterpreterBytecodeOffsetParameter);
8888
}
8989

9090

91-
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
92-
return raw_assembler_->IntPtrSub(
93-
Int32Constant(kFirstRegisterOffsetFromFp),
94-
raw_assembler_->WordShl(index, Int32Constant(kPointerSizeLog2)));
91+
Node* InterpreterAssembler::DispatchTableRawPointer() {
92+
return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter);
9593
}
9694

9795

98-
Node* InterpreterAssembler::BytecodeOperand(int delta) {
99-
DCHECK_LT(delta, interpreter::Bytecodes::NumberOfOperands(bytecode_));
100-
return raw_assembler_->Load(
101-
kMachUint8, BytecodeArrayPointer(),
102-
raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(1 + delta)));
96+
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
97+
return raw_assembler_->WordShl(index, Int32Constant(kPointerSizeLog2));
10398
}
10499

105100

106-
Node* InterpreterAssembler::LoadRegister(int index) {
107-
return raw_assembler_->Load(kMachPtr, FramePointer(),
108-
RegisterFrameOffset(index));
101+
Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
102+
return raw_assembler_->Load(kMachPtr, RegisterFileRawPointer(),
103+
RegisterFrameOffset(reg_index));
109104
}
110105

111106

112-
Node* InterpreterAssembler::LoadRegister(Node* index) {
113-
return raw_assembler_->Load(kMachPtr, FramePointer(),
114-
RegisterFrameOffset(index));
107+
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
108+
return raw_assembler_->Store(kMachPtr, RegisterFileRawPointer(),
109+
RegisterFrameOffset(reg_index), value);
115110
}
116111

117112

118-
Node* InterpreterAssembler::StoreRegister(Node* value, int index) {
119-
return raw_assembler_->Store(kMachPtr, FramePointer(),
120-
RegisterFrameOffset(index), value);
113+
Node* InterpreterAssembler::BytecodeOperand(int delta) {
114+
DCHECK_LT(delta, interpreter::Bytecodes::NumberOfOperands(bytecode_));
115+
return raw_assembler_->Load(
116+
kMachUint8, BytecodeArrayTaggedPointer(),
117+
raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(1 + delta)));
121118
}
122119

123120

124-
Node* InterpreterAssembler::StoreRegister(Node* value, Node* index) {
125-
return raw_assembler_->Store(kMachPtr, FramePointer(),
126-
RegisterFrameOffset(index), value);
121+
Node* InterpreterAssembler::BytecodeOperandSignExtended(int delta) {
122+
DCHECK_LT(delta, interpreter::Bytecodes::NumberOfOperands(bytecode_));
123+
Node* load = raw_assembler_->Load(
124+
kMachInt8, BytecodeArrayTaggedPointer(),
125+
raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(1 + delta)));
126+
// Ensure that we sign extend to full pointer size
127+
if (kPointerSize == 8) {
128+
load = raw_assembler_->ChangeInt32ToInt64(load);
129+
}
130+
return load;
127131
}
128132

129133

@@ -132,14 +136,15 @@ void InterpreterAssembler::Return() {
132136
HeapConstant(Unique<HeapObject>::CreateImmovable(
133137
isolate()->builtins()->InterpreterExitTrampoline()));
134138
// If the order of the parameters you need to change the call signature below.
135-
STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeOffsetParameter);
136-
STATIC_ASSERT(1 == Linkage::kInterpreterBytecodeArrayParameter);
137-
STATIC_ASSERT(2 == Linkage::kInterpreterDispatchTableParameter);
138-
Node* tail_call = graph()->NewNode(
139-
common()->TailCall(call_descriptor()), exit_trampoline_code_object,
140-
BytecodeOffset(), BytecodeArrayPointer(), DispatchTablePointer(),
141-
graph()->start(), graph()->start());
142-
schedule()->AddTailCall(raw_assembler_->CurrentBlock(), tail_call);
139+
STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
140+
STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
141+
STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
142+
STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
143+
STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
144+
Node* tail_call = raw_assembler_->TailCallInterpreterDispatch(
145+
call_descriptor(), exit_trampoline_code_object, GetAccumulator(),
146+
RegisterFileRawPointer(), BytecodeOffset(), BytecodeArrayTaggedPointer(),
147+
DispatchTableRawPointer());
143148
// This should always be the end node.
144149
SetEndInput(tail_call);
145150
}
@@ -153,24 +158,25 @@ Node* InterpreterAssembler::Advance(int delta) {
153158
void InterpreterAssembler::Dispatch() {
154159
Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_));
155160
Node* target_bytecode = raw_assembler_->Load(
156-
kMachUint8, BytecodeArrayPointer(), new_bytecode_offset);
161+
kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset);
157162

158163
// TODO(rmcilroy): Create a code target dispatch table to avoid conversion
159164
// from code object on every dispatch.
160165
Node* target_code_object = raw_assembler_->Load(
161-
kMachPtr, DispatchTablePointer(),
166+
kMachPtr, DispatchTableRawPointer(),
162167
raw_assembler_->Word32Shl(target_bytecode,
163168
Int32Constant(kPointerSizeLog2)));
164169

165170
// If the order of the parameters you need to change the call signature below.
166-
STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeOffsetParameter);
167-
STATIC_ASSERT(1 == Linkage::kInterpreterBytecodeArrayParameter);
168-
STATIC_ASSERT(2 == Linkage::kInterpreterDispatchTableParameter);
169-
Node* tail_call = graph()->NewNode(
170-
common()->TailCall(call_descriptor()), target_code_object,
171-
new_bytecode_offset, BytecodeArrayPointer(), DispatchTablePointer(),
172-
graph()->start(), graph()->start());
173-
schedule()->AddTailCall(raw_assembler_->CurrentBlock(), tail_call);
171+
STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
172+
STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
173+
STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
174+
STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
175+
STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
176+
Node* tail_call = raw_assembler_->TailCallInterpreterDispatch(
177+
call_descriptor(), target_code_object, GetAccumulator(),
178+
RegisterFileRawPointer(), new_bytecode_offset,
179+
BytecodeArrayTaggedPointer(), DispatchTableRawPointer());
174180
// This should always be the end node.
175181
SetEndInput(tail_call);
176182
}
@@ -185,7 +191,7 @@ void InterpreterAssembler::SetEndInput(Node* input) {
185191
void InterpreterAssembler::End() {
186192
DCHECK(end_node_);
187193
// TODO(rmcilroy): Support more than 1 end input.
188-
Node* end = graph()->NewNode(common()->End(1), end_node_);
194+
Node* end = graph()->NewNode(raw_assembler_->common()->End(1), end_node_);
189195
graph()->SetEnd(end);
190196
}
191197

@@ -207,16 +213,6 @@ Schedule* InterpreterAssembler::schedule() {
207213
}
208214

209215

210-
MachineOperatorBuilder* InterpreterAssembler::machine() {
211-
return raw_assembler_->machine();
212-
}
213-
214-
215-
CommonOperatorBuilder* InterpreterAssembler::common() {
216-
return raw_assembler_->common();
217-
}
218-
219-
220216
Node* InterpreterAssembler::Int32Constant(int value) {
221217
return raw_assembler_->Int32Constant(value);
222218
}
@@ -231,7 +227,6 @@ Node* InterpreterAssembler::HeapConstant(Unique<HeapObject> object) {
231227
return raw_assembler_->HeapConstant(object);
232228
}
233229

234-
235230
} // namespace interpreter
236231
} // namespace internal
237232
} // namespace v8

0 commit comments

Comments
 (0)