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