Commit 597da503 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[interpreter] Change interpreter to use an BytecodeArray pointer and and offset.

Changes the interpreter to use a BytecodeArray pointer and an offset to avoid
having an inner pointer to a BytecodeArray object in registers during dispatch.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#29910}
parent 39bcda21
...@@ -17,7 +17,8 @@ struct ArmLinkageHelperTraits { ...@@ -17,7 +17,8 @@ struct ArmLinkageHelperTraits {
static Register ReturnValue2Reg() { return r1; } static Register ReturnValue2Reg() { return r1; }
static Register JSCallFunctionReg() { return r1; } static Register JSCallFunctionReg() { return r1; }
static Register ContextReg() { return cp; } static Register ContextReg() { return cp; }
static Register InterpreterBytecodePointerReg() { return r6; } static Register InterpreterBytecodeOffsetReg() { return r5; }
static Register InterpreterBytecodeArrayReg() { return r6; }
static Register InterpreterDispatchTableReg() { return r8; } static Register InterpreterDispatchTableReg() { return r8; }
static Register RuntimeCallFunctionReg() { return r1; } static Register RuntimeCallFunctionReg() { return r1; }
static Register RuntimeCallArgCountReg() { return r0; } static Register RuntimeCallArgCountReg() { return r0; }
......
...@@ -17,8 +17,9 @@ struct Arm64LinkageHelperTraits { ...@@ -17,8 +17,9 @@ struct Arm64LinkageHelperTraits {
static Register ReturnValue2Reg() { return x1; } static Register ReturnValue2Reg() { return x1; }
static Register JSCallFunctionReg() { return x1; } static Register JSCallFunctionReg() { return x1; }
static Register ContextReg() { return cp; } static Register ContextReg() { return cp; }
static Register InterpreterBytecodePointerReg() { return x19; } static Register InterpreterBytecodeOffsetReg() { return x19; }
static Register InterpreterDispatchTableReg() { return x20; } static Register InterpreterBytecodeArrayReg() { return x20; }
static Register InterpreterDispatchTableReg() { return x21; }
static Register RuntimeCallFunctionReg() { return x1; } static Register RuntimeCallFunctionReg() { return x1; }
static Register RuntimeCallArgCountReg() { return x0; } static Register RuntimeCallArgCountReg() { return x0; }
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
......
...@@ -17,7 +17,8 @@ struct IA32LinkageHelperTraits { ...@@ -17,7 +17,8 @@ struct IA32LinkageHelperTraits {
static Register ReturnValue2Reg() { return edx; } static Register ReturnValue2Reg() { return edx; }
static Register JSCallFunctionReg() { return edi; } static Register JSCallFunctionReg() { return edi; }
static Register ContextReg() { return esi; } static Register ContextReg() { return esi; }
static Register InterpreterBytecodePointerReg() { return edi; } static Register InterpreterBytecodeOffsetReg() { return ecx; }
static Register InterpreterBytecodeArrayReg() { return edi; }
static Register InterpreterDispatchTableReg() { return ebx; } static Register InterpreterDispatchTableReg() { return ebx; }
static Register RuntimeCallFunctionReg() { return ebx; } static Register RuntimeCallFunctionReg() { return ebx; }
static Register RuntimeCallArgCountReg() { return eax; } static Register RuntimeCallArgCountReg() { return eax; }
......
...@@ -60,8 +60,14 @@ Handle<Code> InterpreterAssembler::GenerateCode() { ...@@ -60,8 +60,14 @@ Handle<Code> InterpreterAssembler::GenerateCode() {
} }
Node* InterpreterAssembler::BytecodePointer() { Node* InterpreterAssembler::BytecodeArrayPointer() {
return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeParameter); return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter);
}
Node* InterpreterAssembler::BytecodeOffset() {
return raw_assembler_->Parameter(
Linkage::kInterpreterBytecodeOffsetParameter);
} }
...@@ -91,8 +97,9 @@ Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { ...@@ -91,8 +97,9 @@ Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
Node* InterpreterAssembler::BytecodeArg(int delta) { Node* InterpreterAssembler::BytecodeArg(int delta) {
DCHECK_LT(delta, interpreter::Bytecodes::NumberOfArguments(bytecode_)); DCHECK_LT(delta, interpreter::Bytecodes::NumberOfArguments(bytecode_));
return raw_assembler_->Load(kMachUint8, BytecodePointer(), return raw_assembler_->Load(
Int32Constant(1 + delta)); kMachUint8, BytecodeArrayPointer(),
raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(1 + delta)));
} }
...@@ -121,14 +128,14 @@ Node* InterpreterAssembler::StoreRegister(Node* value, Node* index) { ...@@ -121,14 +128,14 @@ Node* InterpreterAssembler::StoreRegister(Node* value, Node* index) {
Node* InterpreterAssembler::Advance(int delta) { Node* InterpreterAssembler::Advance(int delta) {
return raw_assembler_->IntPtrAdd(BytecodePointer(), Int32Constant(delta)); return raw_assembler_->IntPtrAdd(BytecodeOffset(), Int32Constant(delta));
} }
void InterpreterAssembler::Dispatch() { void InterpreterAssembler::Dispatch() {
Node* new_bytecode_pointer = Advance(interpreter::Bytecodes::Size(bytecode_)); Node* new_bytecode_offset = Advance(interpreter::Bytecodes::Size(bytecode_));
Node* target_bytecode = Node* target_bytecode = raw_assembler_->Load(
raw_assembler_->Load(kMachUint8, new_bytecode_pointer); kMachUint8, BytecodeArrayPointer(), new_bytecode_offset);
// TODO(rmcilroy): Create a code target dispatch table to avoid conversion // TODO(rmcilroy): Create a code target dispatch table to avoid conversion
// from code object on every dispatch. // from code object on every dispatch.
...@@ -138,12 +145,13 @@ void InterpreterAssembler::Dispatch() { ...@@ -138,12 +145,13 @@ void InterpreterAssembler::Dispatch() {
Int32Constant(kPointerSizeLog2))); Int32Constant(kPointerSizeLog2)));
// If the order of the parameters you need to change the call signature below. // If the order of the parameters you need to change the call signature below.
STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeParameter); STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeOffsetParameter);
STATIC_ASSERT(1 == Linkage::kInterpreterDispatchTableParameter); STATIC_ASSERT(1 == Linkage::kInterpreterBytecodeArrayParameter);
Node* tail_call = graph()->NewNode(common()->TailCall(call_descriptor()), STATIC_ASSERT(2 == Linkage::kInterpreterDispatchTableParameter);
target_code_object, new_bytecode_pointer, Node* tail_call = graph()->NewNode(
DispatchTablePointer(), graph()->start(), common()->TailCall(call_descriptor()), target_code_object,
graph()->start()); new_bytecode_offset, BytecodeArrayPointer(), DispatchTablePointer(),
graph()->start(), graph()->start());
schedule()->AddTailCall(raw_assembler_->CurrentBlock(), tail_call); schedule()->AddTailCall(raw_assembler_->CurrentBlock(), tail_call);
// This should always be the end node. // This should always be the end node.
......
...@@ -68,9 +68,11 @@ class InterpreterAssembler { ...@@ -68,9 +68,11 @@ class InterpreterAssembler {
Graph* graph(); Graph* graph();
private: private:
// Returns the pointer to the current bytecode. // Returns a tagged pointer to the current function's BytecodeArray object.
Node* BytecodePointer(); Node* BytecodeArrayPointer();
// Returns the pointer to first entry in the interpreter dispatch table. // Returns the offset from the BytecodeArrayPointer of the current bytecode.
Node* BytecodeOffset();
// Returns a pointer to first entry in the interpreter dispatch table.
Node* DispatchTablePointer(); Node* DispatchTablePointer();
// Returns the frame pointer for the current function. // Returns the frame pointer for the current function.
Node* FramePointer(); Node* FramePointer();
...@@ -79,8 +81,8 @@ class InterpreterAssembler { ...@@ -79,8 +81,8 @@ class InterpreterAssembler {
Node* RegisterFrameOffset(int index); Node* RegisterFrameOffset(int index);
Node* RegisterFrameOffset(Node* index); Node* RegisterFrameOffset(Node* index);
// Returns BytecodePointer() advanced by delta bytecodes. Note: this does not // Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
// update BytecodePointer() itself. // update BytecodeOffset() itself.
Node* Advance(int delta); Node* Advance(int delta);
// Sets the end node of the graph. // Sets the end node of the graph.
......
...@@ -234,15 +234,19 @@ class LinkageHelper { ...@@ -234,15 +234,19 @@ class LinkageHelper {
} }
static CallDescriptor* GetInterpreterDispatchDescriptor(Zone* zone) { static CallDescriptor* GetInterpreterDispatchDescriptor(Zone* zone) {
MachineSignature::Builder types(zone, 0, 2); MachineSignature::Builder types(zone, 0, 3);
LocationSignature::Builder locations(zone, 0, 2); LocationSignature::Builder locations(zone, 0, 3);
// Add registers for fixed parameters passed via interpreter dispatch. // Add registers for fixed parameters passed via interpreter dispatch.
STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeParameter); STATIC_ASSERT(0 == Linkage::kInterpreterBytecodeOffsetParameter);
types.AddParam(kMachPtr); types.AddParam(kMachIntPtr);
locations.AddParam(regloc(LinkageTraits::InterpreterBytecodePointerReg())); locations.AddParam(regloc(LinkageTraits::InterpreterBytecodeOffsetReg()));
STATIC_ASSERT(1 == Linkage::kInterpreterBytecodeArrayParameter);
types.AddParam(kMachAnyTagged);
locations.AddParam(regloc(LinkageTraits::InterpreterBytecodeArrayReg()));
STATIC_ASSERT(1 == Linkage::kInterpreterDispatchTableParameter); STATIC_ASSERT(2 == Linkage::kInterpreterDispatchTableParameter);
types.AddParam(kMachPtr); types.AddParam(kMachPtr);
locations.AddParam(regloc(LinkageTraits::InterpreterDispatchTableReg())); locations.AddParam(regloc(LinkageTraits::InterpreterDispatchTableReg()));
......
...@@ -281,8 +281,9 @@ class Linkage : public ZoneObject { ...@@ -281,8 +281,9 @@ class Linkage : public ZoneObject {
// Special parameter indices used to pass fixed register data through // Special parameter indices used to pass fixed register data through
// interpreter dispatches. // interpreter dispatches.
static const int kInterpreterBytecodeParameter = 0; static const int kInterpreterBytecodeOffsetParameter = 0;
static const int kInterpreterDispatchTableParameter = 1; static const int kInterpreterBytecodeArrayParameter = 1;
static const int kInterpreterDispatchTableParameter = 2;
private: private:
CallDescriptor* const incoming_; CallDescriptor* const incoming_;
......
...@@ -17,8 +17,9 @@ struct MipsLinkageHelperTraits { ...@@ -17,8 +17,9 @@ struct MipsLinkageHelperTraits {
static Register ReturnValue2Reg() { return v1; } static Register ReturnValue2Reg() { return v1; }
static Register JSCallFunctionReg() { return a1; } static Register JSCallFunctionReg() { return a1; }
static Register ContextReg() { return cp; } static Register ContextReg() { return cp; }
static Register InterpreterBytecodePointerReg() { return s0; } static Register InterpreterBytecodeOffsetReg() { return t4; }
static Register InterpreterDispatchTableReg() { return s1; } static Register InterpreterBytecodeArrayReg() { return t5; }
static Register InterpreterDispatchTableReg() { return t6; }
static Register RuntimeCallFunctionReg() { return a1; } static Register RuntimeCallFunctionReg() { return a1; }
static Register RuntimeCallArgCountReg() { return a0; } static Register RuntimeCallArgCountReg() { return a0; }
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
......
...@@ -17,8 +17,9 @@ struct MipsLinkageHelperTraits { ...@@ -17,8 +17,9 @@ struct MipsLinkageHelperTraits {
static Register ReturnValue2Reg() { return v1; } static Register ReturnValue2Reg() { return v1; }
static Register JSCallFunctionReg() { return a1; } static Register JSCallFunctionReg() { return a1; }
static Register ContextReg() { return cp; } static Register ContextReg() { return cp; }
static Register InterpreterBytecodePointerReg() { return s0; } static Register InterpreterBytecodeOffsetReg() { return t1; }
static Register InterpreterDispatchTableReg() { return s1; } static Register InterpreterBytecodeArrayReg() { return t2; }
static Register InterpreterDispatchTableReg() { return t3; }
static Register RuntimeCallFunctionReg() { return a1; } static Register RuntimeCallFunctionReg() { return a1; }
static Register RuntimeCallArgCountReg() { return a0; } static Register RuntimeCallArgCountReg() { return a0; }
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
......
...@@ -17,8 +17,9 @@ struct PPCLinkageHelperTraits { ...@@ -17,8 +17,9 @@ struct PPCLinkageHelperTraits {
static Register ReturnValue2Reg() { return r4; } static Register ReturnValue2Reg() { return r4; }
static Register JSCallFunctionReg() { return r4; } static Register JSCallFunctionReg() { return r4; }
static Register ContextReg() { return cp; } static Register ContextReg() { return cp; }
static Register InterpreterBytecodePointerReg() { return r14; } static Register InterpreterBytecodeOffsetReg() { return r14; }
static Register InterpreterDispatchTableReg() { return r15; } static Register InterpreterBytecodeArrayReg() { return r15; }
static Register InterpreterDispatchTableReg() { return r16; }
static Register RuntimeCallFunctionReg() { return r4; } static Register RuntimeCallFunctionReg() { return r4; }
static Register RuntimeCallArgCountReg() { return r3; } static Register RuntimeCallArgCountReg() { return r3; }
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
......
...@@ -23,7 +23,8 @@ struct X64LinkageHelperTraits { ...@@ -23,7 +23,8 @@ struct X64LinkageHelperTraits {
static Register ReturnValue2Reg() { return rdx; } static Register ReturnValue2Reg() { return rdx; }
static Register JSCallFunctionReg() { return rdi; } static Register JSCallFunctionReg() { return rdi; }
static Register ContextReg() { return rsi; } static Register ContextReg() { return rsi; }
static Register InterpreterBytecodePointerReg() { return rbx; } static Register InterpreterBytecodeOffsetReg() { return r12; }
static Register InterpreterBytecodeArrayReg() { return rbx; }
static Register InterpreterDispatchTableReg() { return rdi; } static Register InterpreterDispatchTableReg() { return rdi; }
static Register RuntimeCallFunctionReg() { return rbx; } static Register RuntimeCallFunctionReg() { return rbx; }
static Register RuntimeCallArgCountReg() { return rax; } static Register RuntimeCallArgCountReg() { return rax; }
......
...@@ -28,6 +28,10 @@ void Interpreter::Initialize(bool create_heap_objects) { ...@@ -28,6 +28,10 @@ void Interpreter::Initialize(bool create_heap_objects) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
Handle<FixedArray> handler_table = isolate_->factory()->NewFixedArray( Handle<FixedArray> handler_table = isolate_->factory()->NewFixedArray(
static_cast<int>(Bytecode::kLast) + 1, TENURED); static_cast<int>(Bytecode::kLast) + 1, TENURED);
// We rely on the interpreter handler table being immovable, so check that
// it was allocated on the first page (which is always immovable).
DCHECK(isolate_->heap()->old_space()->FirstPage()->Contains(
handler_table->address()));
isolate_->heap()->public_set_interpreter_table(*handler_table); isolate_->heap()->public_set_interpreter_table(*handler_table);
#define GENERATE_CODE(Name, _) \ #define GENERATE_CODE(Name, _) \
......
...@@ -52,15 +52,6 @@ Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, ...@@ -52,15 +52,6 @@ Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
} }
Matcher<Node*> IsIntPtrConstant(intptr_t value) {
#ifdef V8_TARGET_ARCH_64_BIT
return IsInt64Constant(value);
#else
return IsInt32Constant(value);
#endif
}
TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -71,11 +62,12 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { ...@@ -71,11 +62,12 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
EXPECT_EQ(1, end->InputCount()); EXPECT_EQ(1, end->InputCount());
Node* tail_call_node = end->InputAt(0); Node* tail_call_node = end->InputAt(0);
Matcher<Node*> next_bytecode_matcher = Matcher<Node*> next_bytecode_offset_matcher =
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeParameter), IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); IsInt32Constant(interpreter::Bytecodes::Size(bytecode)));
Matcher<Node*> target_bytecode_matcher = Matcher<Node*> target_bytecode_matcher = m.IsLoad(
m.IsLoad(kMachUint8, next_bytecode_matcher, IsIntPtrConstant(0)); kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
next_bytecode_offset_matcher);
Matcher<Node*> code_target_matcher = m.IsLoad( Matcher<Node*> code_target_matcher = m.IsLoad(
kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter), kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter),
IsWord32Shl(target_bytecode_matcher, IsWord32Shl(target_bytecode_matcher,
...@@ -86,7 +78,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { ...@@ -86,7 +78,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
EXPECT_THAT( EXPECT_THAT(
tail_call_node, tail_call_node,
IsTailCall(m.call_descriptor(), code_target_matcher, IsTailCall(m.call_descriptor(), code_target_matcher,
next_bytecode_matcher, next_bytecode_offset_matcher,
IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
IsParameter(Linkage::kInterpreterDispatchTableParameter), IsParameter(Linkage::kInterpreterDispatchTableParameter),
graph->start(), graph->start())); graph->start(), graph->start()));
} }
...@@ -99,10 +92,14 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeArg) { ...@@ -99,10 +92,14 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeArg) {
int number_of_args = interpreter::Bytecodes::NumberOfArguments(bytecode); int number_of_args = interpreter::Bytecodes::NumberOfArguments(bytecode);
for (int i = 0; i < number_of_args; i++) { for (int i = 0; i < number_of_args; i++) {
Node* load_arg_node = m.BytecodeArg(i); Node* load_arg_node = m.BytecodeArg(i);
EXPECT_THAT(load_arg_node, EXPECT_THAT(
m.IsLoad(kMachUint8, load_arg_node,
IsParameter(Linkage::kInterpreterBytecodeParameter), m.IsLoad(
IsInt32Constant(1 + i))); kMachUint8,
IsParameter(Linkage::kInterpreterBytecodeArrayParameter),
IsIntPtrAdd(
IsParameter(Linkage::kInterpreterBytecodeOffsetParameter),
IsInt32Constant(1 + i))));
} }
} }
} }
......
...@@ -1714,6 +1714,22 @@ Matcher<Node*> IsTailCall( ...@@ -1714,6 +1714,22 @@ Matcher<Node*> IsTailCall(
} }
Matcher<Node*> IsTailCall(
const Matcher<CallDescriptor const*>& descriptor_matcher,
const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
std::vector<Matcher<Node*>> value_matchers;
value_matchers.push_back(value0_matcher);
value_matchers.push_back(value1_matcher);
value_matchers.push_back(value2_matcher);
value_matchers.push_back(value3_matcher);
return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
effect_matcher, control_matcher));
}
Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
......
...@@ -139,6 +139,12 @@ Matcher<Node*> IsTailCall( ...@@ -139,6 +139,12 @@ Matcher<Node*> IsTailCall(
const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher); const Matcher<Node*>& control_matcher);
Matcher<Node*> IsTailCall(
const Matcher<CallDescriptor const*>& descriptor_matcher,
const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher); Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
......
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