Commit d1c28849 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Make InterpreterAssembler a subclass of CodeStubAssembler.

Moves InterpreterAssembler out of the compiler directory and into the
interpreter directory. Makes InterpreterAssembler as subclass of
CodeStubAssembler.

As part of this change, the special bytecode dispatch linkage type
is removed and instead we use a InterfaceDispatchDescriptor and
a normal CodeStub linkage type.

Removes a bunch of duplicated logic in InterpreterAssembler and
instead uses the CodeStubAssembler logic. Refactors Interpreter
with these changes.

Modifies CodeStubAssembler to add the extra operations required
by the Interpreter (extra call types, raw memory access and some extra
binary ops). Also adds the ability for subclasses to add extra
prologue and epilogue operations around calls, which is required
for the Interpreter.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#33873}
parent e0d0c96a
...@@ -785,8 +785,6 @@ source_set("v8_base") { ...@@ -785,8 +785,6 @@ source_set("v8_base") {
"src/compiler/instruction.h", "src/compiler/instruction.h",
"src/compiler/int64-lowering.cc", "src/compiler/int64-lowering.cc",
"src/compiler/int64-lowering.h", "src/compiler/int64-lowering.h",
"src/compiler/interpreter-assembler.cc",
"src/compiler/interpreter-assembler.h",
"src/compiler/js-builtin-reducer.cc", "src/compiler/js-builtin-reducer.cc",
"src/compiler/js-builtin-reducer.h", "src/compiler/js-builtin-reducer.h",
"src/compiler/js-call-reducer.cc", "src/compiler/js-call-reducer.cc",
...@@ -1123,6 +1121,8 @@ source_set("v8_base") { ...@@ -1123,6 +1121,8 @@ source_set("v8_base") {
"src/interpreter/handler-table-builder.h", "src/interpreter/handler-table-builder.h",
"src/interpreter/interpreter.cc", "src/interpreter/interpreter.cc",
"src/interpreter/interpreter.h", "src/interpreter/interpreter.h",
"src/interpreter/interpreter-assembler.cc",
"src/interpreter/interpreter-assembler.h",
"src/interpreter/register-translator.cc", "src/interpreter/register-translator.cc",
"src/interpreter/register-translator.h", "src/interpreter/register-translator.h",
"src/interpreter/source-position-table.cc", "src/interpreter/source-position-table.cc",
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
}, },
'interpreter': { 'interpreter': {
'filepath': 'src/interpreter/' \ 'filepath': 'src/interpreter/' \
'|src/compiler/interpreter' \
'|src/compiler/bytecode' \ '|src/compiler/bytecode' \
'|test/cctest/interpreter/' \ '|test/cctest/interpreter/' \
'|test/unittests/interpreter/', '|test/unittests/interpreter/',
......
...@@ -431,6 +431,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -431,6 +431,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
&default_descriptor); &default_descriptor);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -442,7 +450,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -442,7 +450,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -454,7 +461,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -454,7 +461,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -465,6 +465,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -465,6 +465,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
&default_descriptor); &default_descriptor);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -476,7 +484,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -476,7 +484,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -488,7 +495,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -488,7 +495,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -26,11 +26,14 @@ namespace compiler { ...@@ -26,11 +26,14 @@ namespace compiler {
CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
const CallInterfaceDescriptor& descriptor, const CallInterfaceDescriptor& descriptor,
Code::Flags flags, const char* name) Code::Flags flags, const char* name,
size_t result_size)
: raw_assembler_(new RawMachineAssembler( : raw_assembler_(new RawMachineAssembler(
isolate, new (zone) Graph(zone), isolate, new (zone) Graph(zone),
Linkage::GetStubCallDescriptor(isolate, zone, descriptor, 0, Linkage::GetStubCallDescriptor(
CallDescriptor::kNoFlags))), isolate, zone, descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size))),
flags_(flags), flags_(flags),
name_(name), name_(name),
code_generated_(false), code_generated_(false),
...@@ -38,6 +41,9 @@ CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, ...@@ -38,6 +41,9 @@ CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
CodeStubAssembler::~CodeStubAssembler() {} CodeStubAssembler::~CodeStubAssembler() {}
void CodeStubAssembler::CallPrologue() {}
void CodeStubAssembler::CallEpilogue() {}
Handle<Code> CodeStubAssembler::GenerateCode() { Handle<Code> CodeStubAssembler::GenerateCode() {
DCHECK(!code_generated_); DCHECK(!code_generated_);
...@@ -97,6 +103,10 @@ Node* CodeStubAssembler::LoadFramePointer() { ...@@ -97,6 +103,10 @@ Node* CodeStubAssembler::LoadFramePointer() {
return raw_assembler_->LoadFramePointer(); return raw_assembler_->LoadFramePointer();
} }
Node* CodeStubAssembler::LoadStackPointer() {
return raw_assembler_->LoadStackPointer();
}
Node* CodeStubAssembler::SmiShiftBitsConstant() { Node* CodeStubAssembler::SmiShiftBitsConstant() {
return Int32Constant(kSmiShiftSize + kSmiTagSize); return Int32Constant(kSmiShiftSize + kSmiTagSize);
} }
...@@ -118,6 +128,10 @@ Node* CodeStubAssembler::SmiUntag(Node* value) { ...@@ -118,6 +128,10 @@ Node* CodeStubAssembler::SmiUntag(Node* value) {
CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_STUB_ASSEMBER_BINARY_OP) CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_STUB_ASSEMBER_BINARY_OP)
#undef DEFINE_CODE_STUB_ASSEMBER_BINARY_OP #undef DEFINE_CODE_STUB_ASSEMBER_BINARY_OP
Node* CodeStubAssembler::ChangeInt32ToInt64(Node* value) {
return raw_assembler_->ChangeInt32ToInt64(value);
}
Node* CodeStubAssembler::WordShl(Node* value, int shift) { Node* CodeStubAssembler::WordShl(Node* value, int shift) {
return raw_assembler_->WordShl(value, Int32Constant(shift)); return raw_assembler_->WordShl(value, Int32Constant(shift));
} }
...@@ -179,9 +193,45 @@ Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) { ...@@ -179,9 +193,45 @@ Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) {
return nullptr; return nullptr;
} }
Node* CodeStubAssembler::Load(MachineType rep, Node* base) {
return raw_assembler_->Load(rep, base);
}
Node* CodeStubAssembler::Load(MachineType rep, Node* base, Node* index) {
return raw_assembler_->Load(rep, base, index);
}
Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base,
Node* value) {
return raw_assembler_->Store(rep, base, value, kFullWriteBarrier);
}
Node* CodeStubAssembler::Store(MachineRepresentation rep, Node* base,
Node* index, Node* value) {
return raw_assembler_->Store(rep, base, index, value, kFullWriteBarrier);
}
Node* CodeStubAssembler::StoreNoWriteBarrier(MachineRepresentation rep,
Node* base, Node* value) {
return raw_assembler_->Store(rep, base, value, kNoWriteBarrier);
}
Node* CodeStubAssembler::StoreNoWriteBarrier(MachineRepresentation rep,
Node* base, Node* index,
Node* value) {
return raw_assembler_->Store(rep, base, index, value, kNoWriteBarrier);
}
Node* CodeStubAssembler::Projection(int index, Node* value) {
return raw_assembler_->Projection(index, value);
}
Node* CodeStubAssembler::CallN(CallDescriptor* descriptor, Node* code_target, Node* CodeStubAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
Node** args) { Node** args) {
return raw_assembler_->CallN(descriptor, code_target, args); CallPrologue();
Node* return_value = raw_assembler_->CallN(descriptor, code_target, args);
CallEpilogue();
return return_value;
} }
...@@ -190,16 +240,49 @@ Node* CodeStubAssembler::TailCallN(CallDescriptor* descriptor, ...@@ -190,16 +240,49 @@ Node* CodeStubAssembler::TailCallN(CallDescriptor* descriptor,
return raw_assembler_->TailCallN(descriptor, code_target, args); return raw_assembler_->TailCallN(descriptor, code_target, args);
} }
Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* context) {
CallPrologue();
Node* return_value = raw_assembler_->CallRuntime0(function_id, context);
CallEpilogue();
return return_value;
}
Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id, Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* context, Node* arg1) { Node* context, Node* arg1) {
return raw_assembler_->CallRuntime1(function_id, arg1, context); CallPrologue();
Node* return_value = raw_assembler_->CallRuntime1(function_id, arg1, context);
CallEpilogue();
return return_value;
} }
Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id, Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* context, Node* arg1, Node* arg2) { Node* context, Node* arg1, Node* arg2) {
return raw_assembler_->CallRuntime2(function_id, arg1, arg2, context); CallPrologue();
Node* return_value =
raw_assembler_->CallRuntime2(function_id, arg1, arg2, context);
CallEpilogue();
return return_value;
}
Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* context, Node* arg1, Node* arg2,
Node* arg3) {
CallPrologue();
Node* return_value =
raw_assembler_->CallRuntime3(function_id, arg1, arg2, arg3, context);
CallEpilogue();
return return_value;
}
Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* context, Node* arg1, Node* arg2,
Node* arg3, Node* arg4) {
CallPrologue();
Node* return_value = raw_assembler_->CallRuntime4(function_id, arg1, arg2,
arg3, arg4, context);
CallEpilogue();
return return_value;
} }
Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id, Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id,
...@@ -227,6 +310,93 @@ Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id, ...@@ -227,6 +310,93 @@ Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id,
context); context);
} }
Node* CodeStubAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(2);
args[0] = arg1;
args[1] = context;
return CallN(call_descriptor, target, args);
}
Node* CodeStubAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(3);
args[0] = arg1;
args[1] = arg2;
args[2] = context;
return CallN(call_descriptor, target, args);
}
Node* CodeStubAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, Node* arg3, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(4);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = context;
return CallN(call_descriptor, target, args);
}
Node* CodeStubAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4,
size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(5);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
args[4] = context;
return CallN(call_descriptor, target, args);
}
Node* CodeStubAssembler::CallStub(const CallInterfaceDescriptor& descriptor,
Node* target, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4,
Node* arg5, size_t result_size) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
Node** args = zone()->NewArray<Node*>(6);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
args[4] = arg5;
args[5] = context;
return CallN(call_descriptor, target, args);
}
Node* CodeStubAssembler::TailCallStub(CodeStub& stub, Node** args) { Node* CodeStubAssembler::TailCallStub(CodeStub& stub, Node** args) {
Node* code_target = HeapConstant(stub.GetCode()); Node* code_target = HeapConstant(stub.GetCode());
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
...@@ -237,11 +407,12 @@ Node* CodeStubAssembler::TailCallStub(CodeStub& stub, Node** args) { ...@@ -237,11 +407,12 @@ Node* CodeStubAssembler::TailCallStub(CodeStub& stub, Node** args) {
Node* CodeStubAssembler::TailCall( Node* CodeStubAssembler::TailCall(
const CallInterfaceDescriptor& interface_descriptor, Node* code_target, const CallInterfaceDescriptor& interface_descriptor, Node* code_target,
Node** args) { Node** args, size_t result_size) {
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), interface_descriptor, isolate(), zone(), interface_descriptor,
interface_descriptor.GetStackParameterCount(), interface_descriptor.GetStackParameterCount(),
CallDescriptor::kSupportsTailCalls); CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
return raw_assembler_->TailCallN(descriptor, code_target, args); return raw_assembler_->TailCallN(descriptor, code_target, args);
} }
...@@ -277,10 +448,8 @@ void CodeStubAssembler::Switch(Node* index, Label* default_label, ...@@ -277,10 +448,8 @@ void CodeStubAssembler::Switch(Node* index, Label* default_label,
// RawMachineAssembler delegate helpers: // RawMachineAssembler delegate helpers:
Isolate* CodeStubAssembler::isolate() { return raw_assembler_->isolate(); } Isolate* CodeStubAssembler::isolate() { return raw_assembler_->isolate(); }
Graph* CodeStubAssembler::graph() { return raw_assembler_->graph(); } Graph* CodeStubAssembler::graph() { return raw_assembler_->graph(); }
Zone* CodeStubAssembler::zone() { return raw_assembler_->zone(); } Zone* CodeStubAssembler::zone() { return raw_assembler_->zone(); }
// The core implementation of Variable is stored through an indirection so // The core implementation of Variable is stored through an indirection so
......
...@@ -53,6 +53,7 @@ class Schedule; ...@@ -53,6 +53,7 @@ class Schedule;
V(Word32Or) \ V(Word32Or) \
V(Word32And) \ V(Word32And) \
V(Word32Xor) \ V(Word32Xor) \
V(Word32Shl) \
V(Word32Shr) \ V(Word32Shr) \
V(Word32Sar) \ V(Word32Sar) \
V(Word32Ror) \ V(Word32Ror) \
...@@ -63,13 +64,17 @@ class Schedule; ...@@ -63,13 +64,17 @@ class Schedule;
V(Word64Xor) \ V(Word64Xor) \
V(Word64Shr) \ V(Word64Shr) \
V(Word64Sar) \ V(Word64Sar) \
V(Word64Ror) V(Word64Ror) \
V(UintPtrGreaterThanOrEqual)
class CodeStubAssembler { class CodeStubAssembler {
public: public:
// |result_size| specifies the number of results returned by the stub.
// TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
CodeStubAssembler(Isolate* isolate, Zone* zone, CodeStubAssembler(Isolate* isolate, Zone* zone,
const CallInterfaceDescriptor& descriptor, const CallInterfaceDescriptor& descriptor,
Code::Flags flags, const char* name); Code::Flags flags, const char* name,
size_t result_size = 1);
virtual ~CodeStubAssembler(); virtual ~CodeStubAssembler();
Handle<Code> GenerateCode(); Handle<Code> GenerateCode();
...@@ -115,6 +120,20 @@ class CodeStubAssembler { ...@@ -115,6 +120,20 @@ class CodeStubAssembler {
Node* LoadFramePointer(); Node* LoadFramePointer();
Node* LoadParentFramePointer(); Node* LoadParentFramePointer();
// Access to the stack pointer
Node* LoadStackPointer();
// Load raw memory location.
Node* Load(MachineType rep, Node* base);
Node* Load(MachineType rep, Node* base, Node* index);
// Store value to raw memory location.
Node* Store(MachineRepresentation rep, Node* base, Node* value);
Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
Node* value);
// Basic arithmetic operations. // Basic arithmetic operations.
#define DECLARE_CODE_STUB_ASSEMBER_BINARY_OP(name) Node* name(Node* a, Node* b); #define DECLARE_CODE_STUB_ASSEMBER_BINARY_OP(name) Node* name(Node* a, Node* b);
CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_STUB_ASSEMBER_BINARY_OP) CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_STUB_ASSEMBER_BINARY_OP)
...@@ -122,10 +141,23 @@ class CodeStubAssembler { ...@@ -122,10 +141,23 @@ class CodeStubAssembler {
Node* WordShl(Node* value, int shift); Node* WordShl(Node* value, int shift);
// Conversions
Node* ChangeInt32ToInt64(Node* value);
// Projections
Node* Projection(int index, Node* value);
// Calls // Calls
Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1); Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1, Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
Node* arg2); Node* arg2);
Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
Node* arg2, Node* arg3);
Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4);
Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
Node* arg2, Node* arg3, Node* arg4, Node* arg5);
Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
Node* arg1); Node* arg1);
...@@ -136,9 +168,23 @@ class CodeStubAssembler { ...@@ -136,9 +168,23 @@ class CodeStubAssembler {
Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
Node* arg1, Node* arg2, Node* arg3, Node* arg4); Node* arg1, Node* arg2, Node* arg3, Node* arg4);
Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, size_t result_size = 1);
Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3,
size_t result_size = 1);
Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
size_t result_size = 1);
Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
Node* arg5, size_t result_size = 1);
Node* TailCallStub(CodeStub& stub, Node** args); Node* TailCallStub(CodeStub& stub, Node** args);
Node* TailCall(const CallInterfaceDescriptor& descriptor, Node* target, Node* TailCall(const CallInterfaceDescriptor& descriptor, Node* target,
Node** args); Node** args, size_t result_size = 1);
// =========================================================================== // ===========================================================================
// Macros // Macros
...@@ -164,6 +210,16 @@ class CodeStubAssembler { ...@@ -164,6 +210,16 @@ class CodeStubAssembler {
int additional_offset = 0); int additional_offset = 0);
Node* LoadFixedArrayElementConstantIndex(Node* object, int index); Node* LoadFixedArrayElementConstantIndex(Node* object, int index);
protected:
// Protected helpers which delegate to RawMachineAssembler.
Graph* graph();
Isolate* isolate();
Zone* zone();
// Enables subclasses to perform operations before and after a call.
virtual void CallPrologue();
virtual void CallEpilogue();
private: private:
friend class CodeStubAssemblerTester; friend class CodeStubAssemblerTester;
...@@ -172,11 +228,6 @@ class CodeStubAssembler { ...@@ -172,11 +228,6 @@ class CodeStubAssembler {
Node* SmiShiftBitsConstant(); Node* SmiShiftBitsConstant();
// Private helpers which delegate to RawMachineAssembler.
Graph* graph();
Isolate* isolate();
Zone* zone();
base::SmartPointer<RawMachineAssembler> raw_assembler_; base::SmartPointer<RawMachineAssembler> raw_assembler_;
Code::Flags flags_; Code::Flags flags_;
const char* name_; const char* name_;
......
...@@ -366,60 +366,6 @@ CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr, ...@@ -366,60 +366,6 @@ CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
"js-call"); "js-call");
} }
CallDescriptor* Linkage::GetInterpreterDispatchDescriptor(Zone* zone) {
MachineSignature::Builder types(zone, 0, 6);
LocationSignature::Builder locations(zone, 0, 6);
// Add registers for fixed parameters passed via interpreter dispatch.
STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
types.AddParam(MachineType::AnyTagged());
locations.AddParam(regloc(kInterpreterAccumulatorRegister));
STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
types.AddParam(MachineType::Pointer());
locations.AddParam(regloc(kInterpreterRegisterFileRegister));
STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
types.AddParam(MachineType::IntPtr());
locations.AddParam(regloc(kInterpreterBytecodeOffsetRegister));
STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
types.AddParam(MachineType::AnyTagged());
locations.AddParam(regloc(kInterpreterBytecodeArrayRegister));
STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
types.AddParam(MachineType::Pointer());
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
// TODO(rmcilroy): Make the context param the one spilled to the stack once
// Turbofan supports modified stack arguments in tail calls.
locations.AddParam(
LinkageLocation::ForCallerFrameSlot(kInterpreterDispatchTableSpillSlot));
#else
locations.AddParam(regloc(kInterpreterDispatchTableRegister));
#endif
STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter);
types.AddParam(MachineType::AnyTagged());
locations.AddParam(regloc(kContextRegister));
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
return new (zone) CallDescriptor( // --
CallDescriptor::kCallCodeObject, // kind
MachineType::None(), // target MachineType
target_loc, // target location
types.Build(), // machine_sig
locations.Build(), // location_sig
0, // stack_parameter_count
Operator::kNoProperties, // properties
kNoCalleeSaved, // callee-saved registers
kNoCalleeSaved, // callee-saved fp regs
CallDescriptor::kSupportsTailCalls | // flags
CallDescriptor::kCanUseRoots, // flags
"interpreter-dispatch");
}
// TODO(all): Add support for return representations/locations to // TODO(all): Add support for return representations/locations to
// CallInterfaceDescriptor. // CallInterfaceDescriptor.
// TODO(turbofan): cache call descriptors for code stub calls. // TODO(turbofan): cache call descriptors for code stub calls.
......
...@@ -336,11 +336,6 @@ class Linkage : public ZoneObject { ...@@ -336,11 +336,6 @@ class Linkage : public ZoneObject {
Zone* zone, const MachineSignature* sig, Zone* zone, const MachineSignature* sig,
bool set_initialize_root_flag = false); bool set_initialize_root_flag = false);
// Creates a call descriptor for interpreter handler code stubs. These are not
// intended to be called directly but are instead dispatched to by the
// interpreter.
static CallDescriptor* GetInterpreterDispatchDescriptor(Zone* zone);
// Get the location of an (incoming) parameter to this function. // Get the location of an (incoming) parameter to this function.
LinkageLocation GetParameterLocation(int index) const { LinkageLocation GetParameterLocation(int index) const {
return incoming_->GetInputLocation(index + 1); // + 1 to skip target. return incoming_->GetInputLocation(index + 1); // + 1 to skip target.
...@@ -390,15 +385,6 @@ class Linkage : public ZoneObject { ...@@ -390,15 +385,6 @@ class Linkage : public ZoneObject {
// A special {OsrValue} index to indicate the context spill slot. // A special {OsrValue} index to indicate the context spill slot.
static const int kOsrContextSpillSlotIndex = -1; static const int kOsrContextSpillSlotIndex = -1;
// Special parameter indices used to pass fixed register data through
// interpreter dispatches.
static const int kInterpreterAccumulatorParameter = 0;
static const int kInterpreterRegisterFileParameter = 1;
static const int kInterpreterBytecodeOffsetParameter = 2;
static const int kInterpreterBytecodeArrayParameter = 3;
static const int kInterpreterDispatchTableParameter = 4;
static const int kInterpreterContextParameter = 5;
private: private:
CallDescriptor* const incoming_; CallDescriptor* const incoming_;
......
...@@ -412,6 +412,13 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -412,6 +412,13 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister };
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -423,7 +430,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -423,7 +430,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -435,7 +441,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -435,7 +441,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -545,6 +545,19 @@ FunctionType* ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType( ...@@ -545,6 +545,19 @@ FunctionType* ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
return function; return function;
} }
FunctionType*
InterpreterDispatchDescriptor::BuildCallInterfaceDescriptorFunctionType(
Isolate* isolate, int parameter_count) {
Zone* zone = isolate->interface_descriptor_zone();
FunctionType* function =
Type::Function(AnyTagged(zone), Type::Undefined(), 5, zone)->AsFunction();
function->InitParameter(kAccumulatorParameter, AnyTagged(zone));
function->InitParameter(kRegisterFileParameter, ExternalPointer(zone));
function->InitParameter(kBytecodeOffsetParameter, UntaggedIntegral32(zone));
function->InitParameter(kBytecodeArrayParameter, AnyTagged(zone));
function->InitParameter(kDispatchTableParameter, AnyTagged(zone));
return function;
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -76,6 +76,7 @@ class PlatformInterfaceDescriptor; ...@@ -76,6 +76,7 @@ class PlatformInterfaceDescriptor;
V(MathPowInteger) \ V(MathPowInteger) \
V(ContextOnly) \ V(ContextOnly) \
V(GrowArrayElements) \ V(GrowArrayElements) \
V(InterpreterDispatch) \
V(InterpreterPushArgsAndCall) \ V(InterpreterPushArgsAndCall) \
V(InterpreterPushArgsAndConstruct) \ V(InterpreterPushArgsAndConstruct) \
V(InterpreterCEntry) V(InterpreterCEntry)
...@@ -752,6 +753,18 @@ class GrowArrayElementsDescriptor : public CallInterfaceDescriptor { ...@@ -752,6 +753,18 @@ class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
static const Register KeyRegister(); static const Register KeyRegister();
}; };
class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor,
CallInterfaceDescriptor)
static const int kAccumulatorParameter = 0;
static const int kRegisterFileParameter = 1;
static const int kBytecodeOffsetParameter = 2;
static const int kBytecodeArrayParameter = 3;
static const int kDispatchTableParameter = 4;
static const int kContextParameter = 5;
};
class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor { class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor {
public: public:
...@@ -773,7 +786,6 @@ class InterpreterCEntryDescriptor : public CallInterfaceDescriptor { ...@@ -773,7 +786,6 @@ class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor) DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)
}; };
#undef DECLARE_DESCRIPTOR #undef DECLARE_DESCRIPTOR
......
include_rules = [
"+src/compiler/interpreter-assembler.h",
]
...@@ -2,17 +2,11 @@ ...@@ -2,17 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/interpreter-assembler.h" #include "src/interpreter/interpreter-assembler.h"
#include <ostream> #include <ostream>
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/compiler/graph.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/compiler/schedule.h"
#include "src/frames.h" #include "src/frames.h"
#include "src/interface-descriptors.h" #include "src/interface-descriptors.h"
#include "src/interpreter/bytecodes.h" #include "src/interpreter/bytecodes.h"
...@@ -22,21 +16,21 @@ ...@@ -22,21 +16,21 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace interpreter {
using compiler::Node;
InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
interpreter::Bytecode bytecode) Bytecode bytecode)
: bytecode_(bytecode), : compiler::CodeStubAssembler(
raw_assembler_(new RawMachineAssembler( isolate, zone, InterpreterDispatchDescriptor(isolate),
isolate, new (zone) Graph(zone), Code::ComputeFlags(Code::STUB), Bytecodes::ToString(bytecode), 0),
Linkage::GetInterpreterDispatchDescriptor(zone), bytecode_(bytecode),
MachineType::PointerRepresentation(),
InstructionSelector::SupportedMachineOperatorFlags())),
accumulator_( accumulator_(
raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)),
context_( context_(Parameter(InterpreterDispatchDescriptor::kContextParameter)),
raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), disable_stack_check_across_call_(false),
code_generated_(false) { stack_pointer_before_call_(nullptr) {
if (FLAG_trace_ignition) { if (FLAG_trace_ignition) {
TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry);
} }
...@@ -44,194 +38,137 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, ...@@ -44,194 +38,137 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
InterpreterAssembler::~InterpreterAssembler() {} InterpreterAssembler::~InterpreterAssembler() {}
Handle<Code> InterpreterAssembler::GenerateCode() {
DCHECK(!code_generated_);
// Disallow empty handlers that never return.
DCHECK_NE(0, graph()->end()->InputCount());
const char* bytecode_name = interpreter::Bytecodes::ToString(bytecode_);
Schedule* schedule = raw_assembler_->Export();
Code::Flags flags = Code::ComputeFlags(Code::STUB);
Handle<Code> code = Pipeline::GenerateCodeForCodeStub(
isolate(), raw_assembler_->call_descriptor(), graph(), schedule, flags,
bytecode_name);
#ifdef ENABLE_DISASSEMBLER
if (FLAG_trace_ignition_codegen) {
OFStream os(stdout);
code->Disassemble(bytecode_name, os);
os << std::flush;
}
#endif
code_generated_ = true;
return code;
}
Node* InterpreterAssembler::GetAccumulator() { return accumulator_; } Node* InterpreterAssembler::GetAccumulator() { return accumulator_; }
void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; } void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; }
Node* InterpreterAssembler::GetContext() { return context_; } Node* InterpreterAssembler::GetContext() { return context_; }
void InterpreterAssembler::SetContext(Node* value) { void InterpreterAssembler::SetContext(Node* value) {
StoreRegister(value, interpreter::Register::current_context()); StoreRegister(value, Register::current_context());
context_ = value; context_ = value;
} }
Node* InterpreterAssembler::BytecodeOffset() { Node* InterpreterAssembler::BytecodeOffset() {
return raw_assembler_->Parameter( return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter);
Linkage::kInterpreterBytecodeOffsetParameter);
} }
Node* InterpreterAssembler::RegisterFileRawPointer() { Node* InterpreterAssembler::RegisterFileRawPointer() {
return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); return Parameter(InterpreterDispatchDescriptor::kRegisterFileParameter);
} }
Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { Node* InterpreterAssembler::BytecodeArrayTaggedPointer() {
return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter); return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter);
} }
Node* InterpreterAssembler::DispatchTableRawPointer() { Node* InterpreterAssembler::DispatchTableRawPointer() {
return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); return Parameter(InterpreterDispatchDescriptor::kDispatchTableParameter);
} }
Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { Node* InterpreterAssembler::RegisterLocation(Node* reg_index) {
return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index));
} }
Node* InterpreterAssembler::LoadRegister(int offset) { Node* InterpreterAssembler::LoadRegister(int offset) {
return raw_assembler_->Load(MachineType::AnyTagged(), return Load(MachineType::AnyTagged(), RegisterFileRawPointer(),
RegisterFileRawPointer(), Int32Constant(offset)); Int32Constant(offset));
} }
Node* InterpreterAssembler::LoadRegister(Register reg) {
Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) {
return LoadRegister(reg.ToOperand() << kPointerSizeLog2); return LoadRegister(reg.ToOperand() << kPointerSizeLog2);
} }
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
return WordShl(index, kPointerSizeLog2); return WordShl(index, kPointerSizeLog2);
} }
Node* InterpreterAssembler::LoadRegister(Node* reg_index) { Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
return raw_assembler_->Load(MachineType::AnyTagged(), return Load(MachineType::AnyTagged(), RegisterFileRawPointer(),
RegisterFileRawPointer(), RegisterFrameOffset(reg_index));
RegisterFrameOffset(reg_index));
} }
Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { Node* InterpreterAssembler::StoreRegister(Node* value, int offset) {
return raw_assembler_->Store(MachineRepresentation::kTagged, return StoreNoWriteBarrier(MachineRepresentation::kTagged,
RegisterFileRawPointer(), Int32Constant(offset), RegisterFileRawPointer(), Int32Constant(offset),
value, kNoWriteBarrier); value);
} }
Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) {
Node* InterpreterAssembler::StoreRegister(Node* value,
interpreter::Register reg) {
return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2);
} }
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
return raw_assembler_->Store( return StoreNoWriteBarrier(MachineRepresentation::kTagged,
MachineRepresentation::kTagged, RegisterFileRawPointer(), RegisterFileRawPointer(),
RegisterFrameOffset(reg_index), value, kNoWriteBarrier); RegisterFrameOffset(reg_index), value);
} }
Node* InterpreterAssembler::NextRegister(Node* reg_index) { Node* InterpreterAssembler::NextRegister(Node* reg_index) {
// Register indexes are negative, so the next index is minus one. // Register indexes are negative, so the next index is minus one.
return IntPtrAdd(reg_index, Int32Constant(-1)); return IntPtrAdd(reg_index, Int32Constant(-1));
} }
Node* InterpreterAssembler::BytecodeOperand(int operand_index) { Node* InterpreterAssembler::BytecodeOperand(int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
DCHECK_EQ(interpreter::OperandSize::kByte, DCHECK_EQ(OperandSize::kByte,
interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); Bytecodes::GetOperandSize(bytecode_, operand_index));
return raw_assembler_->Load( return Load(
MachineType::Uint8(), BytecodeArrayTaggedPointer(), MachineType::Uint8(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index))));
bytecode_, operand_index))));
} }
Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) { Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
DCHECK_EQ(interpreter::OperandSize::kByte, DCHECK_EQ(OperandSize::kByte,
interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); Bytecodes::GetOperandSize(bytecode_, operand_index));
Node* load = raw_assembler_->Load( Node* load = Load(
MachineType::Int8(), BytecodeArrayTaggedPointer(), MachineType::Int8(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index))));
bytecode_, operand_index))));
// Ensure that we sign extend to full pointer size // Ensure that we sign extend to full pointer size
if (kPointerSize == 8) { if (kPointerSize == 8) {
load = raw_assembler_->ChangeInt32ToInt64(load); load = ChangeInt32ToInt64(load);
} }
return load; return load;
} }
Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
DCHECK_EQ(interpreter::OperandSize::kShort, DCHECK_EQ(OperandSize::kShort,
interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); Bytecodes::GetOperandSize(bytecode_, operand_index));
if (TargetSupportsUnalignedAccess()) { if (TargetSupportsUnalignedAccess()) {
return raw_assembler_->Load( return Load(
MachineType::Uint16(), BytecodeArrayTaggedPointer(), MachineType::Uint16(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index))));
bytecode_, operand_index))));
} else { } else {
int offset = int offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index); Node* first_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
Node* first_byte = raw_assembler_->Load( IntPtrAdd(BytecodeOffset(), Int32Constant(offset)));
MachineType::Uint8(), BytecodeArrayTaggedPointer(), Node* second_byte =
IntPtrAdd(BytecodeOffset(), Int32Constant(offset))); Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
Node* second_byte = raw_assembler_->Load( IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1)));
MachineType::Uint8(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1)));
#if V8_TARGET_LITTLE_ENDIAN #if V8_TARGET_LITTLE_ENDIAN
return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte), return WordOr(WordShl(second_byte, kBitsPerByte), first_byte);
first_byte);
#elif V8_TARGET_BIG_ENDIAN #elif V8_TARGET_BIG_ENDIAN
return raw_assembler_->WordOr(WordShl(first_byte, kBitsPerByte), return WordOr(WordShl(first_byte, kBitsPerByte), second_byte);
second_byte);
#else #else
#error "Unknown Architecture" #error "Unknown Architecture"
#endif #endif
} }
} }
Node* InterpreterAssembler::BytecodeOperandShortSignExtended( Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
int operand_index) { int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
DCHECK_EQ(interpreter::OperandSize::kShort, DCHECK_EQ(OperandSize::kShort,
interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); Bytecodes::GetOperandSize(bytecode_, operand_index));
int operand_offset = int operand_offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index);
Node* load; Node* load;
if (TargetSupportsUnalignedAccess()) { if (TargetSupportsUnalignedAccess()) {
load = raw_assembler_->Load( load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(),
MachineType::Int16(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(operand_offset)));
IntPtrAdd(BytecodeOffset(), Int32Constant(operand_offset)));
} else { } else {
#if V8_TARGET_LITTLE_ENDIAN #if V8_TARGET_LITTLE_ENDIAN
Node* hi_byte_offset = Int32Constant(operand_offset + 1); Node* hi_byte_offset = Int32Constant(operand_offset + 1);
...@@ -242,78 +179,67 @@ Node* InterpreterAssembler::BytecodeOperandShortSignExtended( ...@@ -242,78 +179,67 @@ Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
#else #else
#error "Unknown Architecture" #error "Unknown Architecture"
#endif #endif
Node* hi_byte = Node* hi_byte = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
raw_assembler_->Load(MachineType::Int8(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), hi_byte_offset));
IntPtrAdd(BytecodeOffset(), hi_byte_offset)); Node* lo_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
Node* lo_byte = IntPtrAdd(BytecodeOffset(), lo_byte_offset));
raw_assembler_->Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), hi_byte = Word32Shl(hi_byte, Int32Constant(kBitsPerByte));
IntPtrAdd(BytecodeOffset(), lo_byte_offset)); load = Word32Or(hi_byte, lo_byte);
hi_byte = raw_assembler_->Word32Shl(hi_byte, Int32Constant(kBitsPerByte));
load = raw_assembler_->Word32Or(hi_byte, lo_byte);
} }
// Ensure that we sign extend to full pointer size // Ensure that we sign extend to full pointer size
if (kPointerSize == 8) { if (kPointerSize == 8) {
load = raw_assembler_->ChangeInt32ToInt64(load); load = ChangeInt32ToInt64(load);
} }
return load; return load;
} }
Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) { Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) { switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
case interpreter::OperandSize::kByte: case OperandSize::kByte:
DCHECK_EQ( DCHECK_EQ(OperandType::kRegCount8,
interpreter::OperandType::kRegCount8, Bytecodes::GetOperandType(bytecode_, operand_index));
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index); return BytecodeOperand(operand_index);
case interpreter::OperandSize::kShort: case OperandSize::kShort:
DCHECK_EQ( DCHECK_EQ(OperandType::kRegCount16,
interpreter::OperandType::kRegCount16, Bytecodes::GetOperandType(bytecode_, operand_index));
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index); return BytecodeOperandShort(operand_index);
case interpreter::OperandSize::kNone: case OperandSize::kNone:
UNREACHABLE(); UNREACHABLE();
} }
return nullptr; return nullptr;
} }
Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kImm8, DCHECK_EQ(OperandType::kImm8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)); Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandSignExtended(operand_index); return BytecodeOperandSignExtended(operand_index);
} }
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) { switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
case interpreter::OperandSize::kByte: case OperandSize::kByte:
DCHECK_EQ( DCHECK_EQ(OperandType::kIdx8,
interpreter::OperandType::kIdx8, Bytecodes::GetOperandType(bytecode_, operand_index));
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index); return BytecodeOperand(operand_index);
case interpreter::OperandSize::kShort: case OperandSize::kShort:
DCHECK_EQ( DCHECK_EQ(OperandType::kIdx16,
interpreter::OperandType::kIdx16, Bytecodes::GetOperandType(bytecode_, operand_index));
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index); return BytecodeOperandShort(operand_index);
case interpreter::OperandSize::kNone: case OperandSize::kNone:
UNREACHABLE(); UNREACHABLE();
} }
return nullptr; return nullptr;
} }
Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) { Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
interpreter::OperandType operand_type = OperandType operand_type =
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index); Bytecodes::GetOperandType(bytecode_, operand_index);
if (interpreter::Bytecodes::IsRegisterOperandType(operand_type)) { if (Bytecodes::IsRegisterOperandType(operand_type)) {
interpreter::OperandSize operand_size = OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type);
interpreter::Bytecodes::SizeOfOperand(operand_type); if (operand_size == OperandSize::kByte) {
if (operand_size == interpreter::OperandSize::kByte) {
return BytecodeOperandSignExtended(operand_index); return BytecodeOperandSignExtended(operand_index);
} else if (operand_size == interpreter::OperandSize::kShort) { } else if (operand_size == OperandSize::kShort) {
return BytecodeOperandShortSignExtended(operand_index); return BytecodeOperandShortSignExtended(operand_index);
} }
} }
...@@ -321,118 +247,50 @@ Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) { ...@@ -321,118 +247,50 @@ Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
return nullptr; return nullptr;
} }
Node* InterpreterAssembler::Int32Constant(int value) {
return raw_assembler_->Int32Constant(value);
}
Node* InterpreterAssembler::IntPtrConstant(intptr_t value) {
return raw_assembler_->IntPtrConstant(value);
}
Node* InterpreterAssembler::NumberConstant(double value) {
return raw_assembler_->NumberConstant(value);
}
Node* InterpreterAssembler::HeapConstant(Handle<HeapObject> object) {
return raw_assembler_->HeapConstant(object);
}
Node* InterpreterAssembler::BooleanConstant(bool value) {
return raw_assembler_->BooleanConstant(value);
}
Node* InterpreterAssembler::SmiShiftBitsConstant() {
return Int32Constant(kSmiShiftSize + kSmiTagSize);
}
Node* InterpreterAssembler::SmiTag(Node* value) {
return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
}
Node* InterpreterAssembler::SmiUntag(Node* value) {
return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
}
Node* InterpreterAssembler::IntPtrAdd(Node* a, Node* b) {
return raw_assembler_->IntPtrAdd(a, b);
}
Node* InterpreterAssembler::IntPtrSub(Node* a, Node* b) {
return raw_assembler_->IntPtrSub(a, b);
}
Node* InterpreterAssembler::Int32Sub(Node* a, Node* b) {
return raw_assembler_->Int32Sub(a, b);
}
Node* InterpreterAssembler::WordShl(Node* value, int shift) {
return raw_assembler_->WordShl(value, Int32Constant(shift));
}
Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(),
BytecodeArray::kConstantPoolOffset); BytecodeArray::kConstantPoolOffset);
Node* entry_offset = Node* entry_offset =
IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
WordShl(index, kPointerSizeLog2)); WordShl(index, kPointerSizeLog2));
return raw_assembler_->Load(MachineType::AnyTagged(), constant_pool, return Load(MachineType::AnyTagged(), constant_pool, entry_offset);
entry_offset);
} }
Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array, Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array,
int index) { int index) {
Node* entry_offset = Node* entry_offset =
IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
WordShl(Int32Constant(index), kPointerSizeLog2)); WordShl(Int32Constant(index), kPointerSizeLog2));
return raw_assembler_->Load(MachineType::AnyTagged(), fixed_array, return Load(MachineType::AnyTagged(), fixed_array, entry_offset);
entry_offset);
} }
Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) { Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
return raw_assembler_->Load(MachineType::AnyTagged(), object, return Load(MachineType::AnyTagged(), object,
IntPtrConstant(offset - kHeapObjectTag)); IntPtrConstant(offset - kHeapObjectTag));
} }
Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) { Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
return raw_assembler_->Load(MachineType::AnyTagged(), context, return Load(MachineType::AnyTagged(), context,
IntPtrConstant(Context::SlotOffset(slot_index))); IntPtrConstant(Context::SlotOffset(slot_index)));
} }
Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) { Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) {
Node* offset = Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
Int32Constant(Context::kHeaderSize - kHeapObjectTag)); Int32Constant(Context::kHeaderSize - kHeapObjectTag));
return raw_assembler_->Load(MachineType::AnyTagged(), context, offset); return Load(MachineType::AnyTagged(), context, offset);
} }
Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
Node* value) { Node* value) {
Node* offset = Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
Int32Constant(Context::kHeaderSize - kHeapObjectTag)); Int32Constant(Context::kHeaderSize - kHeapObjectTag));
return raw_assembler_->Store(MachineRepresentation::kTagged, context, offset, return Store(MachineRepresentation::kTagged, context, offset, value);
value, kFullWriteBarrier);
} }
Node* InterpreterAssembler::LoadTypeFeedbackVector() { Node* InterpreterAssembler::LoadTypeFeedbackVector() {
Node* function = raw_assembler_->Load( Node* function = Load(
MachineType::AnyTagged(), RegisterFileRawPointer(), MachineType::AnyTagged(), RegisterFileRawPointer(),
IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer)); IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer));
Node* shared_info = Node* shared_info =
...@@ -442,315 +300,172 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() { ...@@ -442,315 +300,172 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
return vector; return vector;
} }
Node* InterpreterAssembler::Projection(int index, Node* node) {
return raw_assembler_->Projection(index, node);
}
Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor,
Node* first_arg, Node* arg_count) {
Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
Node* code_target = HeapConstant(callable.code());
Node** args = zone()->NewArray<Node*>(5);
args[0] = arg_count;
args[1] = new_target;
args[2] = constructor;
args[3] = first_arg;
args[4] = GetContext();
return CallN(descriptor, code_target, args);
}
void InterpreterAssembler::CallPrologue() { void InterpreterAssembler::CallPrologue() {
StoreRegister(SmiTag(BytecodeOffset()), StoreRegister(SmiTag(BytecodeOffset()),
InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer);
}
Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, if (FLAG_debug_code && !disable_stack_check_across_call_) {
Node** args) { DCHECK(stack_pointer_before_call_ == nullptr);
CallPrologue(); stack_pointer_before_call_ = LoadStackPointer();
Node* stack_pointer_before_call = nullptr;
if (FLAG_debug_code) {
stack_pointer_before_call = raw_assembler_->LoadStackPointer();
} }
Node* return_val = raw_assembler_->CallN(descriptor, code_target, args); }
if (FLAG_debug_code) {
Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer(); void InterpreterAssembler::CallEpilogue() {
if (FLAG_debug_code && !disable_stack_check_across_call_) {
Node* stack_pointer_after_call = LoadStackPointer();
Node* stack_pointer_before_call = stack_pointer_before_call_;
stack_pointer_before_call_ = nullptr;
AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call,
kUnexpectedStackPointer); kUnexpectedStackPointer);
} }
return return_val;
} }
Node* InterpreterAssembler::CallJS(Node* function, Node* context,
Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg, Node* first_arg, Node* arg_count) {
Node* arg_count) {
Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate()); Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate());
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
Node* code_target = HeapConstant(callable.code()); Node* code_target = HeapConstant(callable.code());
return CallStub(callable.descriptor(), code_target, context, arg_count,
Node** args = zone()->NewArray<Node*>(4); first_arg, function);
args[0] = arg_count;
args[1] = first_arg;
args[2] = function;
args[3] = GetContext();
return CallN(descriptor, code_target, args);
} }
Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor, Node* new_target, Node* first_arg,
Node* target, Node** args) { Node* arg_count) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
isolate(), zone(), descriptor, 0, CallDescriptor::kNoFlags); Node* code_target = HeapConstant(callable.code());
return CallN(call_descriptor, target, args); return CallStub(callable.descriptor(), code_target, context, arg_count,
} new_target, constructor, first_arg);
Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
Node* target, Node* arg1, Node* arg2,
Node* arg3) {
Node** args = zone()->NewArray<Node*>(4);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = GetContext();
return CallIC(descriptor, target, args);
}
Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
Node* target, Node* arg1, Node* arg2,
Node* arg3, Node* arg4) {
Node** args = zone()->NewArray<Node*>(5);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
args[4] = GetContext();
return CallIC(descriptor, target, args);
}
Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
Node* target, Node* arg1, Node* arg2,
Node* arg3, Node* arg4, Node* arg5) {
Node** args = zone()->NewArray<Node*>(6);
args[0] = arg1;
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
args[4] = arg5;
args[5] = GetContext();
return CallIC(descriptor, target, args);
} }
Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg, Node* first_arg, Node* arg_count,
Node* arg_count, int result_size) { int result_size) {
Callable callable = CodeFactory::InterpreterCEntry(isolate(), result_size); Callable callable = CodeFactory::InterpreterCEntry(isolate(), result_size);
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags,
Operator::kNoProperties, MachineType::AnyTagged(), result_size);
Node* code_target = HeapConstant(callable.code()); Node* code_target = HeapConstant(callable.code());
// Get the function entry from the function id. // Get the function entry from the function id.
Node* function_table = raw_assembler_->ExternalConstant( Node* function_table = ExternalConstant(
ExternalReference::runtime_function_table_address(isolate())); ExternalReference::runtime_function_table_address(isolate()));
Node* function_offset = raw_assembler_->Int32Mul( Node* function_offset =
function_id, Int32Constant(sizeof(Runtime::Function))); Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function)));
Node* function = IntPtrAdd(function_table, function_offset); Node* function = IntPtrAdd(function_table, function_offset);
Node* function_entry = Node* function_entry =
raw_assembler_->Load(MachineType::Pointer(), function, Load(MachineType::Pointer(), function,
Int32Constant(offsetof(Runtime::Function, entry))); Int32Constant(offsetof(Runtime::Function, entry)));
Node** args = zone()->NewArray<Node*>(4);
args[0] = arg_count;
args[1] = first_arg;
args[2] = function_entry;
args[3] = GetContext();
return CallN(descriptor, code_target, args);
}
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id) {
CallPrologue();
Node* return_val = raw_assembler_->CallRuntime0(function_id, GetContext());
return return_val;
}
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* arg1) {
CallPrologue();
Node* return_val =
raw_assembler_->CallRuntime1(function_id, arg1, GetContext());
return return_val;
}
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, return CallStub(callable.descriptor(), code_target, context, arg_count,
Node* arg1, Node* arg2) { first_arg, function_entry, result_size);
CallPrologue();
Node* return_val =
raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext());
return return_val;
} }
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* arg1, Node* arg2, Node* arg3) {
CallPrologue();
Node* return_val =
raw_assembler_->CallRuntime3(function_id, arg1, arg2, arg3, GetContext());
return return_val;
}
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* arg1, Node* arg2, Node* arg3,
Node* arg4) {
CallPrologue();
Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3,
arg4, GetContext());
return return_val;
}
void InterpreterAssembler::Return() {
if (FLAG_trace_ignition) {
TraceBytecode(Runtime::kInterpreterTraceBytecodeExit);
}
Node* exit_trampoline_code_object =
HeapConstant(isolate()->builtins()->InterpreterExitTrampoline());
// If the order of the parameters you need to change the call signature below.
STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter);
Node* args[] = { GetAccumulator(),
RegisterFileRawPointer(),
BytecodeOffset(),
BytecodeArrayTaggedPointer(),
DispatchTableRawPointer(),
GetContext() };
raw_assembler_->TailCallN(call_descriptor(), exit_trampoline_code_object,
args);
}
Node* InterpreterAssembler::Advance(int delta) { Node* InterpreterAssembler::Advance(int delta) {
return IntPtrAdd(BytecodeOffset(), Int32Constant(delta)); return IntPtrAdd(BytecodeOffset(), Int32Constant(delta));
} }
Node* InterpreterAssembler::Advance(Node* delta) { Node* InterpreterAssembler::Advance(Node* delta) {
return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta); return IntPtrAdd(BytecodeOffset(), delta);
} }
void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); } void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); }
void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) {
RawMachineLabel match, no_match; CodeStubAssembler::Label match(this);
raw_assembler_->Branch(condition, &match, &no_match); CodeStubAssembler::Label no_match(this);
raw_assembler_->Bind(&match);
Branch(condition, &match, &no_match);
Bind(&match);
DispatchTo(Advance(delta)); DispatchTo(Advance(delta));
raw_assembler_->Bind(&no_match); Bind(&no_match);
Dispatch(); Dispatch();
} }
void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
JumpConditional(raw_assembler_->WordEqual(lhs, rhs), delta); JumpConditional(WordEqual(lhs, rhs), delta);
} }
void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs,
Node* delta) { Node* delta) {
JumpConditional(raw_assembler_->WordNotEqual(lhs, rhs), delta); JumpConditional(WordNotEqual(lhs, rhs), delta);
} }
void InterpreterAssembler::Dispatch() { void InterpreterAssembler::Dispatch() {
DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_))); DispatchTo(Advance(Bytecodes::Size(bytecode_)));
} }
void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
if (FLAG_trace_ignition) { if (FLAG_trace_ignition) {
TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); TraceBytecode(Runtime::kInterpreterTraceBytecodeExit);
} }
Node* target_bytecode = raw_assembler_->Load( Node* target_bytecode = Load(
MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); MachineType::Uint8(), BytecodeArrayTaggedPointer(), 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.
Node* target_code_object = raw_assembler_->Load( Node* target_code_object =
MachineType::Pointer(), DispatchTableRawPointer(), Load(MachineType::Pointer(), DispatchTableRawPointer(),
raw_assembler_->Word32Shl(target_bytecode, Word32Shl(target_bytecode, Int32Constant(kPointerSizeLog2)));
Int32Constant(kPointerSizeLog2)));
InterpreterDispatchDescriptor descriptor(isolate());
// If the order of the parameters you need to change the call signature below. Node* args[] = {GetAccumulator(), RegisterFileRawPointer(),
STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); new_bytecode_offset, BytecodeArrayTaggedPointer(),
STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); DispatchTableRawPointer(), GetContext()};
STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); TailCall(descriptor, target_code_object, args, 0);
STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); }
STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); void InterpreterAssembler::InterpreterReturn() {
Node* args[] = { GetAccumulator(), if (FLAG_trace_ignition) {
RegisterFileRawPointer(), TraceBytecode(Runtime::kInterpreterTraceBytecodeExit);
new_bytecode_offset, }
BytecodeArrayTaggedPointer(), InterpreterDispatchDescriptor descriptor(isolate());
DispatchTableRawPointer(), Node* exit_trampoline_code_object =
GetContext() }; HeapConstant(isolate()->builtins()->InterpreterExitTrampoline());
raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); Node* args[] = {GetAccumulator(), RegisterFileRawPointer(),
BytecodeOffset(), BytecodeArrayTaggedPointer(),
DispatchTableRawPointer(), GetContext()};
TailCall(descriptor, exit_trampoline_code_object, args, 0);
} }
void InterpreterAssembler::StackCheck() { void InterpreterAssembler::StackCheck() {
RawMachineLabel end, ok, stack_guard; CodeStubAssembler::Label end(this);
Node* sp = raw_assembler_->LoadStackPointer(); CodeStubAssembler::Label ok(this);
Node* stack_limit = raw_assembler_->Load( CodeStubAssembler::Label stack_guard(this);
Node* sp = LoadStackPointer();
Node* stack_limit = Load(
MachineType::Pointer(), MachineType::Pointer(),
raw_assembler_->ExternalConstant( ExternalConstant(ExternalReference::address_of_stack_limit(isolate())));
ExternalReference::address_of_stack_limit(isolate()))); Node* condition = UintPtrGreaterThanOrEqual(sp, stack_limit);
Node* condition = raw_assembler_->UintPtrGreaterThanOrEqual(sp, stack_limit); Branch(condition, &ok, &stack_guard);
raw_assembler_->Branch(condition, &ok, &stack_guard); Bind(&stack_guard);
raw_assembler_->Bind(&stack_guard); CallRuntime(Runtime::kStackGuard, GetContext());
CallRuntime(Runtime::kStackGuard); Goto(&end);
raw_assembler_->Goto(&end); Bind(&ok);
raw_assembler_->Bind(&ok); Goto(&end);
raw_assembler_->Goto(&end); Bind(&end);
raw_assembler_->Bind(&end);
} }
void InterpreterAssembler::Abort(BailoutReason bailout_reason) { void InterpreterAssembler::Abort(BailoutReason bailout_reason) {
disable_stack_check_across_call_ = true;
Node* abort_id = SmiTag(Int32Constant(bailout_reason)); Node* abort_id = SmiTag(Int32Constant(bailout_reason));
Node* ret_value = CallRuntime(Runtime::kAbort, abort_id); Node* ret_value = CallRuntime(Runtime::kAbort, GetContext(), abort_id);
disable_stack_check_across_call_ = false;
// Unreached, but keeps turbofan happy. // Unreached, but keeps turbofan happy.
raw_assembler_->Return(ret_value); Return(ret_value);
} }
void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs,
BailoutReason bailout_reason) { BailoutReason bailout_reason) {
RawMachineLabel match, no_match; CodeStubAssembler::Label match(this);
Node* condition = raw_assembler_->WordEqual(lhs, rhs); CodeStubAssembler::Label no_match(this);
raw_assembler_->Branch(condition, &match, &no_match);
raw_assembler_->Bind(&no_match); Node* condition = WordEqual(lhs, rhs);
Branch(condition, &match, &no_match);
Bind(&no_match);
Abort(bailout_reason); Abort(bailout_reason);
raw_assembler_->Bind(&match); Bind(&match);
} }
void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) {
CallRuntime(function_id, BytecodeArrayTaggedPointer(), CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(),
SmiTag(BytecodeOffset()), GetAccumulator()); SmiTag(BytecodeOffset()), GetAccumulator());
} }
...@@ -767,22 +482,6 @@ bool InterpreterAssembler::TargetSupportsUnalignedAccess() { ...@@ -767,22 +482,6 @@ bool InterpreterAssembler::TargetSupportsUnalignedAccess() {
#endif #endif
} }
} // namespace interpreter
// RawMachineAssembler delegate helpers:
Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); }
Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); }
CallDescriptor* InterpreterAssembler::call_descriptor() const {
return raw_assembler_->call_descriptor();
}
Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); }
} // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -2,169 +2,131 @@ ...@@ -2,169 +2,131 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef V8_COMPILER_INTERPRETER_ASSEMBLER_H_ #ifndef V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_
#define V8_COMPILER_INTERPRETER_ASSEMBLER_H_ #define V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_
// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "src/allocation.h" #include "src/allocation.h"
#include "src/base/smart-pointers.h" #include "src/base/smart-pointers.h"
#include "src/builtins.h" #include "src/builtins.h"
#include "src/compiler/code-stub-assembler.h"
#include "src/frames.h" #include "src/frames.h"
#include "src/interpreter/bytecodes.h" #include "src/interpreter/bytecodes.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace interpreter {
class CallInterfaceDescriptor; class InterpreterAssembler : public compiler::CodeStubAssembler {
class Isolate;
class Zone;
namespace compiler {
class CallDescriptor;
class Graph;
class Node;
class Operator;
class RawMachineAssembler;
class Schedule;
class InterpreterAssembler {
public: public:
InterpreterAssembler(Isolate* isolate, Zone* zone, InterpreterAssembler(Isolate* isolate, Zone* zone, Bytecode bytecode);
interpreter::Bytecode bytecode);
virtual ~InterpreterAssembler(); virtual ~InterpreterAssembler();
Handle<Code> GenerateCode();
// Returns the count immediate for bytecode operand |operand_index| in the // Returns the count immediate for bytecode operand |operand_index| in the
// current bytecode. // current bytecode.
Node* BytecodeOperandCount(int operand_index); compiler::Node* BytecodeOperandCount(int operand_index);
// Returns the index immediate for bytecode operand |operand_index| in the // Returns the index immediate for bytecode operand |operand_index| in the
// current bytecode. // current bytecode.
Node* BytecodeOperandIdx(int operand_index); compiler::Node* BytecodeOperandIdx(int operand_index);
// Returns the Imm8 immediate for bytecode operand |operand_index| in the // Returns the Imm8 immediate for bytecode operand |operand_index| in the
// current bytecode. // current bytecode.
Node* BytecodeOperandImm(int operand_index); compiler::Node* BytecodeOperandImm(int operand_index);
// Returns the register index for bytecode operand |operand_index| in the // Returns the register index for bytecode operand |operand_index| in the
// current bytecode. // current bytecode.
Node* BytecodeOperandReg(int operand_index); compiler::Node* BytecodeOperandReg(int operand_index);
// Accumulator. // Accumulator.
Node* GetAccumulator(); compiler::Node* GetAccumulator();
void SetAccumulator(Node* value); void SetAccumulator(compiler::Node* value);
// Context. // Context.
Node* GetContext(); compiler::Node* GetContext();
void SetContext(Node* value); void SetContext(compiler::Node* value);
// Loads from and stores to the interpreter register file. // Loads from and stores to the interpreter register file.
Node* LoadRegister(int offset); compiler::Node* LoadRegister(int offset);
Node* LoadRegister(interpreter::Register reg); compiler::Node* LoadRegister(Register reg);
Node* LoadRegister(Node* reg_index); compiler::Node* LoadRegister(compiler::Node* reg_index);
Node* StoreRegister(Node* value, int offset); compiler::Node* StoreRegister(compiler::Node* value, int offset);
Node* StoreRegister(Node* value, interpreter::Register reg); compiler::Node* StoreRegister(compiler::Node* value, Register reg);
Node* StoreRegister(Node* value, Node* reg_index); compiler::Node* StoreRegister(compiler::Node* value,
compiler::Node* reg_index);
// Returns the next consecutive register. // Returns the next consecutive register.
Node* NextRegister(Node* reg_index); compiler::Node* NextRegister(compiler::Node* reg_index);
// Returns the location in memory of the register |reg_index| in the // Returns the location in memory of the register |reg_index| in the
// interpreter register file. // interpreter register file.
Node* RegisterLocation(Node* reg_index); compiler::Node* RegisterLocation(compiler::Node* reg_index);
// Constants.
Node* Int32Constant(int value);
Node* IntPtrConstant(intptr_t value);
Node* NumberConstant(double value);
Node* HeapConstant(Handle<HeapObject> object);
Node* BooleanConstant(bool value);
// Tag and untag Smi values.
Node* SmiTag(Node* value);
Node* SmiUntag(Node* value);
// Basic arithmetic operations.
Node* IntPtrAdd(Node* a, Node* b);
Node* IntPtrSub(Node* a, Node* b);
Node* Int32Sub(Node* a, Node* b);
Node* WordShl(Node* value, int shift);
// Load constant at |index| in the constant pool. // Load constant at |index| in the constant pool.
Node* LoadConstantPoolEntry(Node* index); compiler::Node* LoadConstantPoolEntry(compiler::Node* index);
// Load an element from a fixed array on the heap. // Load an element from a fixed array on the heap.
Node* LoadFixedArrayElement(Node* fixed_array, int index); compiler::Node* LoadFixedArrayElement(compiler::Node* fixed_array, int index);
// Load a field from an object on the heap. // Load a field from an object on the heap.
Node* LoadObjectField(Node* object, int offset); compiler::Node* LoadObjectField(compiler::Node* object, int offset);
// Load |slot_index| from |context|. // Load |slot_index| from |context|.
Node* LoadContextSlot(Node* context, int slot_index); compiler::Node* LoadContextSlot(compiler::Node* context, int slot_index);
Node* LoadContextSlot(Node* context, Node* slot_index); compiler::Node* LoadContextSlot(compiler::Node* context,
compiler::Node* slot_index);
// Stores |value| into |slot_index| of |context|. // Stores |value| into |slot_index| of |context|.
Node* StoreContextSlot(Node* context, Node* slot_index, Node* value); compiler::Node* StoreContextSlot(compiler::Node* context,
compiler::Node* slot_index,
compiler::Node* value);
// Load the TypeFeedbackVector for the current function. // Load the TypeFeedbackVector for the current function.
Node* LoadTypeFeedbackVector(); compiler::Node* LoadTypeFeedbackVector();
// Project the output value at index |index| // Call JSFunction or Callable |function| with |arg_count|
Node* Projection(int index, Node* node); // arguments (not including receiver) and the first argument
// located at |first_arg|.
compiler::Node* CallJS(compiler::Node* function, compiler::Node* context,
compiler::Node* first_arg, compiler::Node* arg_count);
// Call constructor |constructor| with |arg_count| arguments (not // Call constructor |constructor| with |arg_count| arguments (not
// including receiver) and the first argument located at // including receiver) and the first argument located at
// |first_arg|. The |new_target| is the same as the // |first_arg|. The |new_target| is the same as the
// |constructor| for the new keyword, but differs for the super // |constructor| for the new keyword, but differs for the super
// keyword. // keyword.
Node* CallConstruct(Node* new_target, Node* constructor, Node* first_arg, compiler::Node* CallConstruct(compiler::Node* constructor,
Node* arg_count); compiler::Node* context,
compiler::Node* new_target,
compiler::Node* first_arg,
compiler::Node* arg_count);
// Call JSFunction or Callable |function| with |arg_count| // Call runtime function with |arg_count| arguments and the first argument
// arguments (not including receiver) and the first argument
// located at |first_arg|. // located at |first_arg|.
Node* CallJS(Node* function, Node* first_arg, Node* arg_count); compiler::Node* CallRuntimeN(compiler::Node* function_id,
compiler::Node* context,
// Call an IC code stub. compiler::Node* first_arg,
Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1, compiler::Node* arg_count, int return_size = 1);
Node* arg2, Node* arg3);
Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
Node* arg2, Node* arg3, Node* arg4);
Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
Node* arg2, Node* arg3, Node* arg4, Node* arg5);
// Call runtime function.
Node* CallRuntime(Node* function_id, Node* first_arg, Node* arg_count,
int return_size = 1);
Node* CallRuntime(Runtime::FunctionId function_id);
Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1);
Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2);
Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2,
Node* arg3);
Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2,
Node* arg3, Node* arg4);
// Jump relative to the current bytecode by |jump_offset|. // Jump relative to the current bytecode by |jump_offset|.
void Jump(Node* jump_offset); void Jump(compiler::Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the // Jump relative to the current bytecode by |jump_offset| if the
// |condition| is true. Helper function for JumpIfWordEqual and // |condition| is true. Helper function for JumpIfWordEqual and
// JumpIfWordNotEqual. // JumpIfWordNotEqual.
void JumpConditional(Node* condition, Node* jump_offset); void JumpConditional(compiler::Node* condition, compiler::Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the // Jump relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are equal. // word values |lhs| and |rhs| are equal.
void JumpIfWordEqual(Node* lhs, Node* rhs, Node* jump_offset); void JumpIfWordEqual(compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* jump_offset);
// Jump relative to the current bytecode by |jump_offset| if the // Jump relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are not equal. // word values |lhs| and |rhs| are not equal.
void JumpIfWordNotEqual(Node* lhs, Node* rhs, Node* jump_offset); void JumpIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* jump_offset);
// Perform a stack guard check. // Perform a stack guard check.
void StackCheck(); void StackCheck();
// Returns from the function. // Returns from the function.
void Return(); void InterpreterReturn();
// Dispatch to the bytecode. // Dispatch to the bytecode.
void Dispatch(); void Dispatch();
...@@ -175,67 +137,56 @@ class InterpreterAssembler { ...@@ -175,67 +137,56 @@ class InterpreterAssembler {
protected: protected:
static bool TargetSupportsUnalignedAccess(); static bool TargetSupportsUnalignedAccess();
// Protected helpers (for testing) which delegate to RawMachineAssembler.
CallDescriptor* call_descriptor() const;
Graph* graph();
private: private:
// Returns a raw pointer to start of the register file on the stack. // Returns a raw pointer to start of the register file on the stack.
Node* RegisterFileRawPointer(); compiler::Node* RegisterFileRawPointer();
// Returns a tagged pointer to the current function's BytecodeArray object. // Returns a tagged pointer to the current function's BytecodeArray object.
Node* BytecodeArrayTaggedPointer(); compiler::Node* BytecodeArrayTaggedPointer();
// Returns the offset from the BytecodeArrayPointer of the current bytecode. // Returns the offset from the BytecodeArrayPointer of the current bytecode.
Node* BytecodeOffset(); compiler::Node* BytecodeOffset();
// Returns a raw pointer to first entry in the interpreter dispatch table. // Returns a raw pointer to first entry in the interpreter dispatch table.
Node* DispatchTableRawPointer(); compiler::Node* DispatchTableRawPointer();
// Saves and restores interpreter bytecode offset to the interpreter stack // Saves and restores interpreter bytecode offset to the interpreter stack
// frame when performing a call. // frame when performing a call.
void CallPrologue(); void CallPrologue() override;
void CallEpilogue() override;
// Traces the current bytecode by calling |function_id|. // Traces the current bytecode by calling |function_id|.
void TraceBytecode(Runtime::FunctionId function_id); void TraceBytecode(Runtime::FunctionId function_id);
// Returns the offset of register |index| relative to RegisterFilePointer(). // Returns the offset of register |index| relative to RegisterFilePointer().
Node* RegisterFrameOffset(Node* index); compiler::Node* RegisterFrameOffset(compiler::Node* index);
Node* SmiShiftBitsConstant();
Node* BytecodeOperand(int operand_index);
Node* BytecodeOperandSignExtended(int operand_index);
Node* BytecodeOperandShort(int operand_index);
Node* BytecodeOperandShortSignExtended(int operand_index);
Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args); compiler::Node* BytecodeOperand(int operand_index);
Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node** args); compiler::Node* BytecodeOperandSignExtended(int operand_index);
compiler::Node* BytecodeOperandShort(int operand_index);
compiler::Node* BytecodeOperandShortSignExtended(int operand_index);
// Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not // Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
// update BytecodeOffset() itself. // update BytecodeOffset() itself.
Node* Advance(int delta); compiler::Node* Advance(int delta);
Node* Advance(Node* delta); compiler::Node* Advance(compiler::Node* delta);
// Starts next instruction dispatch at |new_bytecode_offset|. // Starts next instruction dispatch at |new_bytecode_offset|.
void DispatchTo(Node* new_bytecode_offset); void DispatchTo(compiler::Node* new_bytecode_offset);
// Abort operations for debug code. // Abort operations for debug code.
void AbortIfWordNotEqual(Node* lhs, Node* rhs, BailoutReason bailout_reason); void AbortIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
BailoutReason bailout_reason);
// Private helpers which delegate to RawMachineAssembler.
Isolate* isolate();
Zone* zone();
interpreter::Bytecode bytecode_;
base::SmartPointer<RawMachineAssembler> raw_assembler_;
Node* accumulator_; Bytecode bytecode_;
Node* context_; compiler::Node* accumulator_;
compiler::Node* context_;
bool code_generated_; bool disable_stack_check_across_call_;
compiler::Node* stack_pointer_before_call_;
DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler); DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler);
}; };
} // namespace compiler } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_COMPILER_INTERPRETER_ASSEMBLER_H_ #endif // V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
#include "src/ast/prettyprinter.h" #include "src/ast/prettyprinter.h"
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/compiler.h" #include "src/compiler.h"
#include "src/compiler/interpreter-assembler.h"
#include "src/factory.h" #include "src/factory.h"
#include "src/interpreter/bytecode-generator.h" #include "src/interpreter/bytecode-generator.h"
#include "src/interpreter/bytecodes.h" #include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter-assembler.h"
#include "src/zone.h" #include "src/zone.h"
namespace v8 { namespace v8 {
...@@ -25,21 +25,20 @@ Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { ...@@ -25,21 +25,20 @@ Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) {
memset(&dispatch_table_, 0, sizeof(dispatch_table_)); memset(&dispatch_table_, 0, sizeof(dispatch_table_));
} }
void Interpreter::Initialize() { void Interpreter::Initialize() {
DCHECK(FLAG_ignition); DCHECK(FLAG_ignition);
if (IsDispatchTableInitialized()) return; if (IsDispatchTableInitialized()) return;
Zone zone; Zone zone;
HandleScope scope(isolate_); HandleScope scope(isolate_);
#define GENERATE_CODE(Name, ...) \ #define GENERATE_CODE(Name, ...) \
{ \ { \
compiler::InterpreterAssembler assembler(isolate_, &zone, \ InterpreterAssembler assembler(isolate_, &zone, Bytecode::k##Name); \
Bytecode::k##Name); \ Do##Name(&assembler); \
Do##Name(&assembler); \ Handle<Code> code = assembler.GenerateCode(); \
Handle<Code> code = assembler.GenerateCode(); \ TraceCodegen(code, #Name); \
int index = static_cast<int>(Bytecode::k##Name); \ int index = static_cast<int>(Bytecode::k##Name); \
dispatch_table_[index] = *code; \ dispatch_table_[index] = *code; \
} }
BYTECODE_LIST(GENERATE_CODE) BYTECODE_LIST(GENERATE_CODE)
#undef GENERATE_CODE #undef GENERATE_CODE
...@@ -50,7 +49,6 @@ void Interpreter::IterateDispatchTable(ObjectVisitor* v) { ...@@ -50,7 +49,6 @@ void Interpreter::IterateDispatchTable(ObjectVisitor* v) {
&dispatch_table_[0] + kDispatchTableSize); &dispatch_table_[0] + kDispatchTableSize);
} }
bool Interpreter::MakeBytecode(CompilationInfo* info) { bool Interpreter::MakeBytecode(CompilationInfo* info) {
if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) { if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) {
OFStream os(stdout); OFStream os(stdout);
...@@ -99,10 +97,20 @@ bool Interpreter::IsDispatchTableInitialized() { ...@@ -99,10 +97,20 @@ bool Interpreter::IsDispatchTableInitialized() {
return dispatch_table_[0] != nullptr; return dispatch_table_[0] != nullptr;
} }
void Interpreter::TraceCodegen(Handle<Code> code, const char* name) {
#ifdef ENABLE_DISASSEMBLER
if (FLAG_trace_ignition_codegen) {
OFStream os(stdout);
code->Disassemble(name, os);
os << std::flush;
}
#endif // ENABLE_DISASSEMBLER
}
// LdaZero // LdaZero
// //
// Load literal '0' into the accumulator. // Load literal '0' into the accumulator.
void Interpreter::DoLdaZero(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaZero(InterpreterAssembler* assembler) {
Node* zero_value = __ NumberConstant(0.0); Node* zero_value = __ NumberConstant(0.0);
__ SetAccumulator(zero_value); __ SetAccumulator(zero_value);
__ Dispatch(); __ Dispatch();
...@@ -112,15 +120,14 @@ void Interpreter::DoLdaZero(compiler::InterpreterAssembler* assembler) { ...@@ -112,15 +120,14 @@ void Interpreter::DoLdaZero(compiler::InterpreterAssembler* assembler) {
// LdaSmi8 <imm8> // LdaSmi8 <imm8>
// //
// Load an 8-bit integer literal into the accumulator as a Smi. // Load an 8-bit integer literal into the accumulator as a Smi.
void Interpreter::DoLdaSmi8(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaSmi8(InterpreterAssembler* assembler) {
Node* raw_int = __ BytecodeOperandImm(0); Node* raw_int = __ BytecodeOperandImm(0);
Node* smi_int = __ SmiTag(raw_int); Node* smi_int = __ SmiTag(raw_int);
__ SetAccumulator(smi_int); __ SetAccumulator(smi_int);
__ Dispatch(); __ Dispatch();
} }
void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) {
void Interpreter::DoLoadConstant(compiler::InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
__ SetAccumulator(constant); __ SetAccumulator(constant);
...@@ -131,7 +138,7 @@ void Interpreter::DoLoadConstant(compiler::InterpreterAssembler* assembler) { ...@@ -131,7 +138,7 @@ void Interpreter::DoLoadConstant(compiler::InterpreterAssembler* assembler) {
// LdaConstant <idx> // LdaConstant <idx>
// //
// Load constant literal at |idx| in the constant pool into the accumulator. // Load constant literal at |idx| in the constant pool into the accumulator.
void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
DoLoadConstant(assembler); DoLoadConstant(assembler);
} }
...@@ -139,7 +146,7 @@ void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) { ...@@ -139,7 +146,7 @@ void Interpreter::DoLdaConstant(compiler::InterpreterAssembler* assembler) {
// LdaConstantWide <idx> // LdaConstantWide <idx>
// //
// Load constant literal at |idx| in the constant pool into the accumulator. // Load constant literal at |idx| in the constant pool into the accumulator.
void Interpreter::DoLdaConstantWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaConstantWide(InterpreterAssembler* assembler) {
DoLoadConstant(assembler); DoLoadConstant(assembler);
} }
...@@ -147,7 +154,7 @@ void Interpreter::DoLdaConstantWide(compiler::InterpreterAssembler* assembler) { ...@@ -147,7 +154,7 @@ void Interpreter::DoLdaConstantWide(compiler::InterpreterAssembler* assembler) {
// LdaUndefined // LdaUndefined
// //
// Load Undefined into the accumulator. // Load Undefined into the accumulator.
void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
Node* undefined_value = Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value()); __ HeapConstant(isolate_->factory()->undefined_value());
__ SetAccumulator(undefined_value); __ SetAccumulator(undefined_value);
...@@ -158,7 +165,7 @@ void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) { ...@@ -158,7 +165,7 @@ void Interpreter::DoLdaUndefined(compiler::InterpreterAssembler* assembler) {
// LdaNull // LdaNull
// //
// Load Null into the accumulator. // Load Null into the accumulator.
void Interpreter::DoLdaNull(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaNull(InterpreterAssembler* assembler) {
Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
__ SetAccumulator(null_value); __ SetAccumulator(null_value);
__ Dispatch(); __ Dispatch();
...@@ -168,7 +175,7 @@ void Interpreter::DoLdaNull(compiler::InterpreterAssembler* assembler) { ...@@ -168,7 +175,7 @@ void Interpreter::DoLdaNull(compiler::InterpreterAssembler* assembler) {
// LdaTheHole // LdaTheHole
// //
// Load TheHole into the accumulator. // Load TheHole into the accumulator.
void Interpreter::DoLdaTheHole(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) {
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
__ SetAccumulator(the_hole_value); __ SetAccumulator(the_hole_value);
__ Dispatch(); __ Dispatch();
...@@ -178,7 +185,7 @@ void Interpreter::DoLdaTheHole(compiler::InterpreterAssembler* assembler) { ...@@ -178,7 +185,7 @@ void Interpreter::DoLdaTheHole(compiler::InterpreterAssembler* assembler) {
// LdaTrue // LdaTrue
// //
// Load True into the accumulator. // Load True into the accumulator.
void Interpreter::DoLdaTrue(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) {
Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); Node* true_value = __ HeapConstant(isolate_->factory()->true_value());
__ SetAccumulator(true_value); __ SetAccumulator(true_value);
__ Dispatch(); __ Dispatch();
...@@ -188,7 +195,7 @@ void Interpreter::DoLdaTrue(compiler::InterpreterAssembler* assembler) { ...@@ -188,7 +195,7 @@ void Interpreter::DoLdaTrue(compiler::InterpreterAssembler* assembler) {
// LdaFalse // LdaFalse
// //
// Load False into the accumulator. // Load False into the accumulator.
void Interpreter::DoLdaFalse(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) {
Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); Node* false_value = __ HeapConstant(isolate_->factory()->false_value());
__ SetAccumulator(false_value); __ SetAccumulator(false_value);
__ Dispatch(); __ Dispatch();
...@@ -198,7 +205,7 @@ void Interpreter::DoLdaFalse(compiler::InterpreterAssembler* assembler) { ...@@ -198,7 +205,7 @@ void Interpreter::DoLdaFalse(compiler::InterpreterAssembler* assembler) {
// Ldar <src> // Ldar <src>
// //
// Load accumulator with value from register <src>. // Load accumulator with value from register <src>.
void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdar(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* value = __ LoadRegister(reg_index); Node* value = __ LoadRegister(reg_index);
__ SetAccumulator(value); __ SetAccumulator(value);
...@@ -209,7 +216,7 @@ void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) { ...@@ -209,7 +216,7 @@ void Interpreter::DoLdar(compiler::InterpreterAssembler* assembler) {
// Star <dst> // Star <dst>
// //
// Store accumulator to register <dst>. // Store accumulator to register <dst>.
void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStar(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
__ StoreRegister(accumulator, reg_index); __ StoreRegister(accumulator, reg_index);
...@@ -220,7 +227,7 @@ void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { ...@@ -220,7 +227,7 @@ void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) {
// Mov <src> <dst> // Mov <src> <dst>
// //
// Stores the value of register <src> to register <dst>. // Stores the value of register <src> to register <dst>.
void Interpreter::DoMov(compiler::InterpreterAssembler* assembler) { void Interpreter::DoMov(InterpreterAssembler* assembler) {
Node* src_index = __ BytecodeOperandReg(0); Node* src_index = __ BytecodeOperandReg(0);
Node* src_value = __ LoadRegister(src_index); Node* src_value = __ LoadRegister(src_index);
Node* dst_index = __ BytecodeOperandReg(1); Node* dst_index = __ BytecodeOperandReg(1);
...@@ -232,13 +239,11 @@ void Interpreter::DoMov(compiler::InterpreterAssembler* assembler) { ...@@ -232,13 +239,11 @@ void Interpreter::DoMov(compiler::InterpreterAssembler* assembler) {
// MovWide <src> <dst> // MovWide <src> <dst>
// //
// Stores the value of register <src> to register <dst>. // Stores the value of register <src> to register <dst>.
void Interpreter::DoMovWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoMovWide(InterpreterAssembler* assembler) {
DoMov(assembler); DoMov(assembler);
} }
void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoLoadGlobal(Callable ic,
compiler::InterpreterAssembler* assembler) {
// Get the global object. // Get the global object.
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* native_context = Node* native_context =
...@@ -252,8 +257,8 @@ void Interpreter::DoLoadGlobal(Callable ic, ...@@ -252,8 +257,8 @@ void Interpreter::DoLoadGlobal(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(1); Node* raw_slot = __ BytecodeOperandIdx(1);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* result = __ CallIC(ic.descriptor(), code_target, global, name, smi_slot, Node* result = __ CallStub(ic.descriptor(), code_target, context, global,
type_feedback_vector); name, smi_slot, type_feedback_vector);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -263,7 +268,7 @@ void Interpreter::DoLoadGlobal(Callable ic, ...@@ -263,7 +268,7 @@ void Interpreter::DoLoadGlobal(Callable ic,
// //
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in sloppy mode. // accumulator using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoLdaGlobalSloppy(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaGlobalSloppy(InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -274,7 +279,7 @@ void Interpreter::DoLdaGlobalSloppy(compiler::InterpreterAssembler* assembler) { ...@@ -274,7 +279,7 @@ void Interpreter::DoLdaGlobalSloppy(compiler::InterpreterAssembler* assembler) {
// //
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in strict mode. // accumulator using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoLdaGlobalStrict(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaGlobalStrict(InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -286,7 +291,7 @@ void Interpreter::DoLdaGlobalStrict(compiler::InterpreterAssembler* assembler) { ...@@ -286,7 +291,7 @@ void Interpreter::DoLdaGlobalStrict(compiler::InterpreterAssembler* assembler) {
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in sloppy mode. // accumulator using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoLdaGlobalInsideTypeofSloppy( void Interpreter::DoLdaGlobalInsideTypeofSloppy(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -298,7 +303,7 @@ void Interpreter::DoLdaGlobalInsideTypeofSloppy( ...@@ -298,7 +303,7 @@ void Interpreter::DoLdaGlobalInsideTypeofSloppy(
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in strict mode. // accumulator using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoLdaGlobalInsideTypeofStrict( void Interpreter::DoLdaGlobalInsideTypeofStrict(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -309,8 +314,7 @@ void Interpreter::DoLdaGlobalInsideTypeofStrict( ...@@ -309,8 +314,7 @@ void Interpreter::DoLdaGlobalInsideTypeofStrict(
// //
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in sloppy mode. // accumulator using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoLdaGlobalSloppyWide( void Interpreter::DoLdaGlobalSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -321,8 +325,7 @@ void Interpreter::DoLdaGlobalSloppyWide( ...@@ -321,8 +325,7 @@ void Interpreter::DoLdaGlobalSloppyWide(
// //
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in strict mode. // accumulator using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoLdaGlobalStrictWide( void Interpreter::DoLdaGlobalStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -334,7 +337,7 @@ void Interpreter::DoLdaGlobalStrictWide( ...@@ -334,7 +337,7 @@ void Interpreter::DoLdaGlobalStrictWide(
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in sloppy mode. // accumulator using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoLdaGlobalInsideTypeofSloppyWide( void Interpreter::DoLdaGlobalInsideTypeofSloppyWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
...@@ -346,15 +349,13 @@ void Interpreter::DoLdaGlobalInsideTypeofSloppyWide( ...@@ -346,15 +349,13 @@ void Interpreter::DoLdaGlobalInsideTypeofSloppyWide(
// Load the global with name in constant pool entry <name_index> into the // Load the global with name in constant pool entry <name_index> into the
// accumulator using FeedBackVector slot <slot> in strict mode. // accumulator using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoLdaGlobalInsideTypeofStrictWide( void Interpreter::DoLdaGlobalInsideTypeofStrictWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadGlobal(ic, assembler); DoLoadGlobal(ic, assembler);
} }
void Interpreter::DoStoreGlobal(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoStoreGlobal(Callable ic,
compiler::InterpreterAssembler* assembler) {
// Get the global object. // Get the global object.
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* native_context = Node* native_context =
...@@ -369,8 +370,8 @@ void Interpreter::DoStoreGlobal(Callable ic, ...@@ -369,8 +370,8 @@ void Interpreter::DoStoreGlobal(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(1); Node* raw_slot = __ BytecodeOperandIdx(1);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
__ CallIC(ic.descriptor(), code_target, global, name, value, smi_slot, __ CallStub(ic.descriptor(), code_target, context, global, name, value,
type_feedback_vector); smi_slot, type_feedback_vector);
__ Dispatch(); __ Dispatch();
} }
...@@ -380,7 +381,7 @@ void Interpreter::DoStoreGlobal(Callable ic, ...@@ -380,7 +381,7 @@ void Interpreter::DoStoreGlobal(Callable ic,
// //
// Store the value in the accumulator into the global with name in constant pool // Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in sloppy mode. // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoStaGlobalSloppy(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoStoreGlobal(ic, assembler); DoStoreGlobal(ic, assembler);
...@@ -391,7 +392,7 @@ void Interpreter::DoStaGlobalSloppy(compiler::InterpreterAssembler* assembler) { ...@@ -391,7 +392,7 @@ void Interpreter::DoStaGlobalSloppy(compiler::InterpreterAssembler* assembler) {
// //
// Store the value in the accumulator into the global with name in constant pool // Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in strict mode. // entry <name_index> using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoStaGlobalStrict(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoStoreGlobal(ic, assembler); DoStoreGlobal(ic, assembler);
...@@ -402,8 +403,7 @@ void Interpreter::DoStaGlobalStrict(compiler::InterpreterAssembler* assembler) { ...@@ -402,8 +403,7 @@ void Interpreter::DoStaGlobalStrict(compiler::InterpreterAssembler* assembler) {
// //
// Store the value in the accumulator into the global with name in constant pool // Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in sloppy mode. // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
void Interpreter::DoStaGlobalSloppyWide( void Interpreter::DoStaGlobalSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoStoreGlobal(ic, assembler); DoStoreGlobal(ic, assembler);
...@@ -414,8 +414,7 @@ void Interpreter::DoStaGlobalSloppyWide( ...@@ -414,8 +414,7 @@ void Interpreter::DoStaGlobalSloppyWide(
// //
// Store the value in the accumulator into the global with name in constant pool // Store the value in the accumulator into the global with name in constant pool
// entry <name_index> using FeedBackVector slot <slot> in strict mode. // entry <name_index> using FeedBackVector slot <slot> in strict mode.
void Interpreter::DoStaGlobalStrictWide( void Interpreter::DoStaGlobalStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoStoreGlobal(ic, assembler); DoStoreGlobal(ic, assembler);
...@@ -425,7 +424,7 @@ void Interpreter::DoStaGlobalStrictWide( ...@@ -425,7 +424,7 @@ void Interpreter::DoStaGlobalStrictWide(
// LdaContextSlot <context> <slot_index> // LdaContextSlot <context> <slot_index>
// //
// Load the object in |slot_index| of |context| into the accumulator. // Load the object in |slot_index| of |context| into the accumulator.
void Interpreter::DoLdaContextSlot(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaContextSlot(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index); Node* context = __ LoadRegister(reg_index);
Node* slot_index = __ BytecodeOperandIdx(1); Node* slot_index = __ BytecodeOperandIdx(1);
...@@ -438,8 +437,7 @@ void Interpreter::DoLdaContextSlot(compiler::InterpreterAssembler* assembler) { ...@@ -438,8 +437,7 @@ void Interpreter::DoLdaContextSlot(compiler::InterpreterAssembler* assembler) {
// LdaContextSlotWide <context> <slot_index> // LdaContextSlotWide <context> <slot_index>
// //
// Load the object in |slot_index| of |context| into the accumulator. // Load the object in |slot_index| of |context| into the accumulator.
void Interpreter::DoLdaContextSlotWide( void Interpreter::DoLdaContextSlotWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoLdaContextSlot(assembler); DoLdaContextSlot(assembler);
} }
...@@ -447,7 +445,7 @@ void Interpreter::DoLdaContextSlotWide( ...@@ -447,7 +445,7 @@ void Interpreter::DoLdaContextSlotWide(
// StaContextSlot <context> <slot_index> // StaContextSlot <context> <slot_index>
// //
// Stores the object in the accumulator into |slot_index| of |context|. // Stores the object in the accumulator into |slot_index| of |context|.
void Interpreter::DoStaContextSlot(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStaContextSlot(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator(); Node* value = __ GetAccumulator();
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index); Node* context = __ LoadRegister(reg_index);
...@@ -460,18 +458,16 @@ void Interpreter::DoStaContextSlot(compiler::InterpreterAssembler* assembler) { ...@@ -460,18 +458,16 @@ void Interpreter::DoStaContextSlot(compiler::InterpreterAssembler* assembler) {
// StaContextSlot <context> <slot_index> // StaContextSlot <context> <slot_index>
// //
// Stores the object in the accumulator into |slot_index| of |context|. // Stores the object in the accumulator into |slot_index| of |context|.
void Interpreter::DoStaContextSlotWide( void Interpreter::DoStaContextSlotWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoStaContextSlot(assembler); DoStaContextSlot(assembler);
} }
void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id, void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* name = __ LoadConstantPoolEntry(index); Node* name = __ LoadConstantPoolEntry(index);
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* result_pair = __ CallRuntime(function_id, context, name); Node* result_pair = __ CallRuntime(function_id, context, context, name);
Node* result = __ Projection(0, result_pair); Node* result = __ Projection(0, result_pair);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
...@@ -482,7 +478,7 @@ void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id, ...@@ -482,7 +478,7 @@ void Interpreter::DoLoadLookupSlot(Runtime::FunctionId function_id,
// //
// Lookup the object with the name in constant pool entry |name_index| // Lookup the object with the name in constant pool entry |name_index|
// dynamically. // dynamically.
void Interpreter::DoLdaLookupSlot(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLdaLookupSlot(InterpreterAssembler* assembler) {
DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler); DoLoadLookupSlot(Runtime::kLoadLookupSlot, assembler);
} }
...@@ -491,8 +487,7 @@ void Interpreter::DoLdaLookupSlot(compiler::InterpreterAssembler* assembler) { ...@@ -491,8 +487,7 @@ void Interpreter::DoLdaLookupSlot(compiler::InterpreterAssembler* assembler) {
// //
// Lookup the object with the name in constant pool entry |name_index| // Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError. // dynamically without causing a NoReferenceError.
void Interpreter::DoLdaLookupSlotInsideTypeof( void Interpreter::DoLdaLookupSlotInsideTypeof(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoLoadLookupSlot(Runtime::kLoadLookupSlotNoReferenceError, assembler); DoLoadLookupSlot(Runtime::kLoadLookupSlotNoReferenceError, assembler);
} }
...@@ -501,8 +496,7 @@ void Interpreter::DoLdaLookupSlotInsideTypeof( ...@@ -501,8 +496,7 @@ void Interpreter::DoLdaLookupSlotInsideTypeof(
// //
// Lookup the object with the name in constant pool entry |name_index| // Lookup the object with the name in constant pool entry |name_index|
// dynamically. // dynamically.
void Interpreter::DoLdaLookupSlotWide( void Interpreter::DoLdaLookupSlotWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoLdaLookupSlot(assembler); DoLdaLookupSlot(assembler);
} }
...@@ -512,20 +506,19 @@ void Interpreter::DoLdaLookupSlotWide( ...@@ -512,20 +506,19 @@ void Interpreter::DoLdaLookupSlotWide(
// Lookup the object with the name in constant pool entry |name_index| // Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError. // dynamically without causing a NoReferenceError.
void Interpreter::DoLdaLookupSlotInsideTypeofWide( void Interpreter::DoLdaLookupSlotInsideTypeofWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
DoLdaLookupSlotInsideTypeof(assembler); DoLdaLookupSlotInsideTypeof(assembler);
} }
void Interpreter::DoStoreLookupSlot(LanguageMode language_mode, void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator(); Node* value = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* name = __ LoadConstantPoolEntry(index); Node* name = __ LoadConstantPoolEntry(index);
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* language_mode_node = __ NumberConstant(language_mode); Node* language_mode_node = __ NumberConstant(language_mode);
Node* result = __ CallRuntime(Runtime::kStoreLookupSlot, value, context, name, Node* result = __ CallRuntime(Runtime::kStoreLookupSlot, context, value,
language_mode_node); context, name, language_mode_node);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -535,8 +528,7 @@ void Interpreter::DoStoreLookupSlot(LanguageMode language_mode, ...@@ -535,8 +528,7 @@ void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
// //
// Store the object in accumulator to the object with the name in constant // Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in sloppy mode. // pool entry |name_index| in sloppy mode.
void Interpreter::DoStaLookupSlotSloppy( void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); DoStoreLookupSlot(LanguageMode::SLOPPY, assembler);
} }
...@@ -545,8 +537,7 @@ void Interpreter::DoStaLookupSlotSloppy( ...@@ -545,8 +537,7 @@ void Interpreter::DoStaLookupSlotSloppy(
// //
// Store the object in accumulator to the object with the name in constant // Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in strict mode. // pool entry |name_index| in strict mode.
void Interpreter::DoStaLookupSlotStrict( void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoStoreLookupSlot(LanguageMode::STRICT, assembler); DoStoreLookupSlot(LanguageMode::STRICT, assembler);
} }
...@@ -555,8 +546,7 @@ void Interpreter::DoStaLookupSlotStrict( ...@@ -555,8 +546,7 @@ void Interpreter::DoStaLookupSlotStrict(
// //
// Store the object in accumulator to the object with the name in constant // Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in sloppy mode. // pool entry |name_index| in sloppy mode.
void Interpreter::DoStaLookupSlotSloppyWide( void Interpreter::DoStaLookupSlotSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoStaLookupSlotSloppy(assembler); DoStaLookupSlotSloppy(assembler);
} }
...@@ -565,14 +555,11 @@ void Interpreter::DoStaLookupSlotSloppyWide( ...@@ -565,14 +555,11 @@ void Interpreter::DoStaLookupSlotSloppyWide(
// //
// Store the object in accumulator to the object with the name in constant // Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in strict mode. // pool entry |name_index| in strict mode.
void Interpreter::DoStaLookupSlotStrictWide( void Interpreter::DoStaLookupSlotStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoStaLookupSlotStrict(assembler); DoStaLookupSlotStrict(assembler);
} }
void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoLoadIC(Callable ic,
compiler::InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code()); Node* code_target = __ HeapConstant(ic.code());
Node* register_index = __ BytecodeOperandReg(0); Node* register_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(register_index); Node* object = __ LoadRegister(register_index);
...@@ -581,8 +568,9 @@ void Interpreter::DoLoadIC(Callable ic, ...@@ -581,8 +568,9 @@ void Interpreter::DoLoadIC(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(2); Node* raw_slot = __ BytecodeOperandIdx(2);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, Node* context = __ GetContext();
type_feedback_vector); Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
name, smi_slot, type_feedback_vector);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -592,7 +580,7 @@ void Interpreter::DoLoadIC(Callable ic, ...@@ -592,7 +580,7 @@ void Interpreter::DoLoadIC(Callable ic,
// //
// Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and
// the name at constant pool entry <name_index>. // the name at constant pool entry <name_index>.
void Interpreter::DoLoadICSloppy(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLoadICSloppy(InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadIC(ic, assembler); DoLoadIC(ic, assembler);
...@@ -603,7 +591,7 @@ void Interpreter::DoLoadICSloppy(compiler::InterpreterAssembler* assembler) { ...@@ -603,7 +591,7 @@ void Interpreter::DoLoadICSloppy(compiler::InterpreterAssembler* assembler) {
// //
// Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and
// the name at constant pool entry <name_index>. // the name at constant pool entry <name_index>.
void Interpreter::DoLoadICStrict(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLoadICStrict(InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadIC(ic, assembler); DoLoadIC(ic, assembler);
...@@ -614,8 +602,7 @@ void Interpreter::DoLoadICStrict(compiler::InterpreterAssembler* assembler) { ...@@ -614,8 +602,7 @@ void Interpreter::DoLoadICStrict(compiler::InterpreterAssembler* assembler) {
// //
// Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and
// the name at constant pool entry <name_index>. // the name at constant pool entry <name_index>.
void Interpreter::DoLoadICSloppyWide( void Interpreter::DoLoadICSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
SLOPPY, UNINITIALIZED); SLOPPY, UNINITIALIZED);
DoLoadIC(ic, assembler); DoLoadIC(ic, assembler);
...@@ -626,16 +613,13 @@ void Interpreter::DoLoadICSloppyWide( ...@@ -626,16 +613,13 @@ void Interpreter::DoLoadICSloppyWide(
// //
// Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode LoadIC at FeedBackVector slot <slot> for <object> and
// the name at constant pool entry <name_index>. // the name at constant pool entry <name_index>.
void Interpreter::DoLoadICStrictWide( void Interpreter::DoLoadICStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF, Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF,
STRICT, UNINITIALIZED); STRICT, UNINITIALIZED);
DoLoadIC(ic, assembler); DoLoadIC(ic, assembler);
} }
void Interpreter::DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoKeyedLoadIC(Callable ic,
compiler::InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code()); Node* code_target = __ HeapConstant(ic.code());
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(reg_index); Node* object = __ LoadRegister(reg_index);
...@@ -643,8 +627,9 @@ void Interpreter::DoKeyedLoadIC(Callable ic, ...@@ -643,8 +627,9 @@ void Interpreter::DoKeyedLoadIC(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(1); Node* raw_slot = __ BytecodeOperandIdx(1);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* result = __ CallIC(ic.descriptor(), code_target, object, name, smi_slot, Node* context = __ GetContext();
type_feedback_vector); Node* result = __ CallStub(ic.descriptor(), code_target, context, object,
name, smi_slot, type_feedback_vector);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -654,8 +639,7 @@ void Interpreter::DoKeyedLoadIC(Callable ic, ...@@ -654,8 +639,7 @@ void Interpreter::DoKeyedLoadIC(Callable ic,
// //
// Calls the sloppy mode KeyedLoadIC at FeedBackVector slot <slot> for <object> // Calls the sloppy mode KeyedLoadIC at FeedBackVector slot <slot> for <object>
// and the key in the accumulator. // and the key in the accumulator.
void Interpreter::DoKeyedLoadICSloppy( void Interpreter::DoKeyedLoadICSloppy(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoKeyedLoadIC(ic, assembler); DoKeyedLoadIC(ic, assembler);
...@@ -666,8 +650,7 @@ void Interpreter::DoKeyedLoadICSloppy( ...@@ -666,8 +650,7 @@ void Interpreter::DoKeyedLoadICSloppy(
// //
// Calls the strict mode KeyedLoadIC at FeedBackVector slot <slot> for <object> // Calls the strict mode KeyedLoadIC at FeedBackVector slot <slot> for <object>
// and the key in the accumulator. // and the key in the accumulator.
void Interpreter::DoKeyedLoadICStrict( void Interpreter::DoKeyedLoadICStrict(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedLoadICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::KeyedLoadICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoKeyedLoadIC(ic, assembler); DoKeyedLoadIC(ic, assembler);
...@@ -678,8 +661,7 @@ void Interpreter::DoKeyedLoadICStrict( ...@@ -678,8 +661,7 @@ void Interpreter::DoKeyedLoadICStrict(
// //
// Calls the sloppy mode KeyedLoadIC at FeedBackVector slot <slot> for <object> // Calls the sloppy mode KeyedLoadIC at FeedBackVector slot <slot> for <object>
// and the key in the accumulator. // and the key in the accumulator.
void Interpreter::DoKeyedLoadICSloppyWide( void Interpreter::DoKeyedLoadICSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::KeyedLoadICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoKeyedLoadIC(ic, assembler); DoKeyedLoadIC(ic, assembler);
...@@ -690,16 +672,13 @@ void Interpreter::DoKeyedLoadICSloppyWide( ...@@ -690,16 +672,13 @@ void Interpreter::DoKeyedLoadICSloppyWide(
// //
// Calls the strict mode KeyedLoadIC at FeedBackVector slot <slot> for <object> // Calls the strict mode KeyedLoadIC at FeedBackVector slot <slot> for <object>
// and the key in the accumulator. // and the key in the accumulator.
void Interpreter::DoKeyedLoadICStrictWide( void Interpreter::DoKeyedLoadICStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedLoadICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::KeyedLoadICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoKeyedLoadIC(ic, assembler); DoKeyedLoadIC(ic, assembler);
} }
void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoStoreIC(Callable ic,
compiler::InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code()); Node* code_target = __ HeapConstant(ic.code());
Node* object_reg_index = __ BytecodeOperandReg(0); Node* object_reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg_index); Node* object = __ LoadRegister(object_reg_index);
...@@ -709,8 +688,9 @@ void Interpreter::DoStoreIC(Callable ic, ...@@ -709,8 +688,9 @@ void Interpreter::DoStoreIC(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(2); Node* raw_slot = __ BytecodeOperandIdx(2);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
__ CallIC(ic.descriptor(), code_target, object, name, value, smi_slot, Node* context = __ GetContext();
type_feedback_vector); __ CallStub(ic.descriptor(), code_target, context, object, name, value,
smi_slot, type_feedback_vector);
__ Dispatch(); __ Dispatch();
} }
...@@ -720,7 +700,7 @@ void Interpreter::DoStoreIC(Callable ic, ...@@ -720,7 +700,7 @@ void Interpreter::DoStoreIC(Callable ic,
// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the // the name in constant pool entry <name_index> with the value in the
// accumulator. // accumulator.
void Interpreter::DoStoreICSloppy(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoStoreIC(ic, assembler); DoStoreIC(ic, assembler);
...@@ -732,7 +712,7 @@ void Interpreter::DoStoreICSloppy(compiler::InterpreterAssembler* assembler) { ...@@ -732,7 +712,7 @@ void Interpreter::DoStoreICSloppy(compiler::InterpreterAssembler* assembler) {
// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the // the name in constant pool entry <name_index> with the value in the
// accumulator. // accumulator.
void Interpreter::DoStoreICStrict(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoStoreIC(ic, assembler); DoStoreIC(ic, assembler);
...@@ -744,8 +724,7 @@ void Interpreter::DoStoreICStrict(compiler::InterpreterAssembler* assembler) { ...@@ -744,8 +724,7 @@ void Interpreter::DoStoreICStrict(compiler::InterpreterAssembler* assembler) {
// Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the // the name in constant pool entry <name_index> with the value in the
// accumulator. // accumulator.
void Interpreter::DoStoreICSloppyWide( void Interpreter::DoStoreICSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoStoreIC(ic, assembler); DoStoreIC(ic, assembler);
...@@ -757,16 +736,13 @@ void Interpreter::DoStoreICSloppyWide( ...@@ -757,16 +736,13 @@ void Interpreter::DoStoreICSloppyWide(
// Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
// the name in constant pool entry <name_index> with the value in the // the name in constant pool entry <name_index> with the value in the
// accumulator. // accumulator.
void Interpreter::DoStoreICStrictWide( void Interpreter::DoStoreICStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoStoreIC(ic, assembler); DoStoreIC(ic, assembler);
} }
void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) {
void Interpreter::DoKeyedStoreIC(Callable ic,
compiler::InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code()); Node* code_target = __ HeapConstant(ic.code());
Node* object_reg_index = __ BytecodeOperandReg(0); Node* object_reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg_index); Node* object = __ LoadRegister(object_reg_index);
...@@ -776,8 +752,9 @@ void Interpreter::DoKeyedStoreIC(Callable ic, ...@@ -776,8 +752,9 @@ void Interpreter::DoKeyedStoreIC(Callable ic,
Node* raw_slot = __ BytecodeOperandIdx(2); Node* raw_slot = __ BytecodeOperandIdx(2);
Node* smi_slot = __ SmiTag(raw_slot); Node* smi_slot = __ SmiTag(raw_slot);
Node* type_feedback_vector = __ LoadTypeFeedbackVector(); Node* type_feedback_vector = __ LoadTypeFeedbackVector();
__ CallIC(ic.descriptor(), code_target, object, name, value, smi_slot, Node* context = __ GetContext();
type_feedback_vector); __ CallStub(ic.descriptor(), code_target, context, object, name, value,
smi_slot, type_feedback_vector);
__ Dispatch(); __ Dispatch();
} }
...@@ -786,8 +763,7 @@ void Interpreter::DoKeyedStoreIC(Callable ic, ...@@ -786,8 +763,7 @@ void Interpreter::DoKeyedStoreIC(Callable ic,
// //
// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator. // and the key <key> with the value in the accumulator.
void Interpreter::DoKeyedStoreICSloppy( void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoKeyedStoreIC(ic, assembler); DoKeyedStoreIC(ic, assembler);
...@@ -798,8 +774,7 @@ void Interpreter::DoKeyedStoreICSloppy( ...@@ -798,8 +774,7 @@ void Interpreter::DoKeyedStoreICSloppy(
// //
// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator. // and the key <key> with the value in the accumulator.
void Interpreter::DoKeyedStoreICStrict( void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoKeyedStoreIC(ic, assembler); DoKeyedStoreIC(ic, assembler);
...@@ -810,8 +785,7 @@ void Interpreter::DoKeyedStoreICStrict( ...@@ -810,8 +785,7 @@ void Interpreter::DoKeyedStoreICStrict(
// //
// Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator. // and the key <key> with the value in the accumulator.
void Interpreter::DoKeyedStoreICSloppyWide( void Interpreter::DoKeyedStoreICSloppyWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
DoKeyedStoreIC(ic, assembler); DoKeyedStoreIC(ic, assembler);
...@@ -822,8 +796,7 @@ void Interpreter::DoKeyedStoreICSloppyWide( ...@@ -822,8 +796,7 @@ void Interpreter::DoKeyedStoreICSloppyWide(
// //
// Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
// and the key <key> with the value in the accumulator. // and the key <key> with the value in the accumulator.
void Interpreter::DoKeyedStoreICStrictWide( void Interpreter::DoKeyedStoreICStrictWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Callable ic = Callable ic =
CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
DoKeyedStoreIC(ic, assembler); DoKeyedStoreIC(ic, assembler);
...@@ -833,7 +806,7 @@ void Interpreter::DoKeyedStoreICStrictWide( ...@@ -833,7 +806,7 @@ void Interpreter::DoKeyedStoreICStrictWide(
// //
// Saves the current context in <context>, and pushes the accumulator as the // Saves the current context in <context>, and pushes the accumulator as the
// new current context. // new current context.
void Interpreter::DoPushContext(compiler::InterpreterAssembler* assembler) { void Interpreter::DoPushContext(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* new_context = __ GetAccumulator(); Node* new_context = __ GetAccumulator();
Node* old_context = __ GetContext(); Node* old_context = __ GetContext();
...@@ -846,22 +819,22 @@ void Interpreter::DoPushContext(compiler::InterpreterAssembler* assembler) { ...@@ -846,22 +819,22 @@ void Interpreter::DoPushContext(compiler::InterpreterAssembler* assembler) {
// PopContext <context> // PopContext <context>
// //
// Pops the current context and sets <context> as the new context. // Pops the current context and sets <context> as the new context.
void Interpreter::DoPopContext(compiler::InterpreterAssembler* assembler) { void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ LoadRegister(reg_index); Node* context = __ LoadRegister(reg_index);
__ SetContext(context); __ SetContext(context);
__ Dispatch(); __ Dispatch();
} }
void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
// TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized
// operations, instead of calling builtins directly. // operations, instead of calling builtins directly.
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* lhs = __ LoadRegister(reg_index); Node* lhs = __ LoadRegister(reg_index);
Node* rhs = __ GetAccumulator(); Node* rhs = __ GetAccumulator();
Node* result = __ CallRuntime(function_id, lhs, rhs); Node* context = __ GetContext();
Node* result = __ CallRuntime(function_id, context, lhs, rhs);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -870,7 +843,7 @@ void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, ...@@ -870,7 +843,7 @@ void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
// Add <src> // Add <src>
// //
// Add register <src> to accumulator. // Add register <src> to accumulator.
void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { void Interpreter::DoAdd(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kAdd, assembler); DoBinaryOp(Runtime::kAdd, assembler);
} }
...@@ -878,7 +851,7 @@ void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) { ...@@ -878,7 +851,7 @@ void Interpreter::DoAdd(compiler::InterpreterAssembler* assembler) {
// Sub <src> // Sub <src>
// //
// Subtract register <src> from accumulator. // Subtract register <src> from accumulator.
void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) { void Interpreter::DoSub(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kSubtract, assembler); DoBinaryOp(Runtime::kSubtract, assembler);
} }
...@@ -886,7 +859,7 @@ void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) { ...@@ -886,7 +859,7 @@ void Interpreter::DoSub(compiler::InterpreterAssembler* assembler) {
// Mul <src> // Mul <src>
// //
// Multiply accumulator by register <src>. // Multiply accumulator by register <src>.
void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) { void Interpreter::DoMul(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kMultiply, assembler); DoBinaryOp(Runtime::kMultiply, assembler);
} }
...@@ -894,7 +867,7 @@ void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) { ...@@ -894,7 +867,7 @@ void Interpreter::DoMul(compiler::InterpreterAssembler* assembler) {
// Div <src> // Div <src>
// //
// Divide register <src> by accumulator. // Divide register <src> by accumulator.
void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) { void Interpreter::DoDiv(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kDivide, assembler); DoBinaryOp(Runtime::kDivide, assembler);
} }
...@@ -902,7 +875,7 @@ void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) { ...@@ -902,7 +875,7 @@ void Interpreter::DoDiv(compiler::InterpreterAssembler* assembler) {
// Mod <src> // Mod <src>
// //
// Modulo register <src> by accumulator. // Modulo register <src> by accumulator.
void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { void Interpreter::DoMod(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kModulus, assembler); DoBinaryOp(Runtime::kModulus, assembler);
} }
...@@ -910,7 +883,7 @@ void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) { ...@@ -910,7 +883,7 @@ void Interpreter::DoMod(compiler::InterpreterAssembler* assembler) {
// BitwiseOr <src> // BitwiseOr <src>
// //
// BitwiseOr register <src> to accumulator. // BitwiseOr register <src> to accumulator.
void Interpreter::DoBitwiseOr(compiler::InterpreterAssembler* assembler) { void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseOr, assembler); DoBinaryOp(Runtime::kBitwiseOr, assembler);
} }
...@@ -918,7 +891,7 @@ void Interpreter::DoBitwiseOr(compiler::InterpreterAssembler* assembler) { ...@@ -918,7 +891,7 @@ void Interpreter::DoBitwiseOr(compiler::InterpreterAssembler* assembler) {
// BitwiseXor <src> // BitwiseXor <src>
// //
// BitwiseXor register <src> to accumulator. // BitwiseXor register <src> to accumulator.
void Interpreter::DoBitwiseXor(compiler::InterpreterAssembler* assembler) { void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseXor, assembler); DoBinaryOp(Runtime::kBitwiseXor, assembler);
} }
...@@ -926,7 +899,7 @@ void Interpreter::DoBitwiseXor(compiler::InterpreterAssembler* assembler) { ...@@ -926,7 +899,7 @@ void Interpreter::DoBitwiseXor(compiler::InterpreterAssembler* assembler) {
// BitwiseAnd <src> // BitwiseAnd <src>
// //
// BitwiseAnd register <src> to accumulator. // BitwiseAnd register <src> to accumulator.
void Interpreter::DoBitwiseAnd(compiler::InterpreterAssembler* assembler) { void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kBitwiseAnd, assembler); DoBinaryOp(Runtime::kBitwiseAnd, assembler);
} }
...@@ -937,7 +910,7 @@ void Interpreter::DoBitwiseAnd(compiler::InterpreterAssembler* assembler) { ...@@ -937,7 +910,7 @@ void Interpreter::DoBitwiseAnd(compiler::InterpreterAssembler* assembler) {
// Register <src> is converted to an int32 and the accumulator to uint32 // Register <src> is converted to an int32 and the accumulator to uint32
// before the operation. 5 lsb bits from the accumulator are used as count // before the operation. 5 lsb bits from the accumulator are used as count
// i.e. <src> << (accumulator & 0x1F). // i.e. <src> << (accumulator & 0x1F).
void Interpreter::DoShiftLeft(compiler::InterpreterAssembler* assembler) { void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftLeft, assembler); DoBinaryOp(Runtime::kShiftLeft, assembler);
} }
...@@ -948,7 +921,7 @@ void Interpreter::DoShiftLeft(compiler::InterpreterAssembler* assembler) { ...@@ -948,7 +921,7 @@ void Interpreter::DoShiftLeft(compiler::InterpreterAssembler* assembler) {
// Result is sign extended. Register <src> is converted to an int32 and the // Result is sign extended. Register <src> is converted to an int32 and the
// accumulator to uint32 before the operation. 5 lsb bits from the accumulator // accumulator to uint32 before the operation. 5 lsb bits from the accumulator
// are used as count i.e. <src> >> (accumulator & 0x1F). // are used as count i.e. <src> >> (accumulator & 0x1F).
void Interpreter::DoShiftRight(compiler::InterpreterAssembler* assembler) { void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftRight, assembler); DoBinaryOp(Runtime::kShiftRight, assembler);
} }
...@@ -959,17 +932,16 @@ void Interpreter::DoShiftRight(compiler::InterpreterAssembler* assembler) { ...@@ -959,17 +932,16 @@ void Interpreter::DoShiftRight(compiler::InterpreterAssembler* assembler) {
// Result is zero-filled. The accumulator and register <src> are converted to // Result is zero-filled. The accumulator and register <src> are converted to
// uint32 before the operation 5 lsb bits from the accumulator are used as // uint32 before the operation 5 lsb bits from the accumulator are used as
// count i.e. <src> << (accumulator & 0x1F). // count i.e. <src> << (accumulator & 0x1F).
void Interpreter::DoShiftRightLogical( void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftRightLogical, assembler); DoBinaryOp(Runtime::kShiftRightLogical, assembler);
} }
void Interpreter::DoCountOp(Runtime::FunctionId function_id, void Interpreter::DoCountOp(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator(); Node* value = __ GetAccumulator();
Node* one = __ NumberConstant(1); Node* one = __ NumberConstant(1);
Node* result = __ CallRuntime(function_id, value, one); Node* context = __ GetContext();
Node* result = __ CallRuntime(function_id, context, value, one);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -978,7 +950,7 @@ void Interpreter::DoCountOp(Runtime::FunctionId function_id, ...@@ -978,7 +950,7 @@ void Interpreter::DoCountOp(Runtime::FunctionId function_id,
// Inc // Inc
// //
// Increments value in the accumulator by one. // Increments value in the accumulator by one.
void Interpreter::DoInc(compiler::InterpreterAssembler* assembler) { void Interpreter::DoInc(InterpreterAssembler* assembler) {
DoCountOp(Runtime::kAdd, assembler); DoCountOp(Runtime::kAdd, assembler);
} }
...@@ -986,7 +958,7 @@ void Interpreter::DoInc(compiler::InterpreterAssembler* assembler) { ...@@ -986,7 +958,7 @@ void Interpreter::DoInc(compiler::InterpreterAssembler* assembler) {
// Dec // Dec
// //
// Decrements value in the accumulator by one. // Decrements value in the accumulator by one.
void Interpreter::DoDec(compiler::InterpreterAssembler* assembler) { void Interpreter::DoDec(InterpreterAssembler* assembler) {
DoCountOp(Runtime::kSubtract, assembler); DoCountOp(Runtime::kSubtract, assembler);
} }
...@@ -995,9 +967,11 @@ void Interpreter::DoDec(compiler::InterpreterAssembler* assembler) { ...@@ -995,9 +967,11 @@ void Interpreter::DoDec(compiler::InterpreterAssembler* assembler) {
// //
// Perform logical-not on the accumulator, first casting the // Perform logical-not on the accumulator, first casting the
// accumulator to a boolean value if required. // accumulator to a boolean value if required.
void Interpreter::DoLogicalNot(compiler::InterpreterAssembler* assembler) { void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* result = __ CallRuntime(Runtime::kInterpreterLogicalNot, accumulator); Node* context = __ GetContext();
Node* result =
__ CallRuntime(Runtime::kInterpreterLogicalNot, context, accumulator);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1007,20 +981,22 @@ void Interpreter::DoLogicalNot(compiler::InterpreterAssembler* assembler) { ...@@ -1007,20 +981,22 @@ void Interpreter::DoLogicalNot(compiler::InterpreterAssembler* assembler) {
// //
// Load the accumulator with the string representating type of the // Load the accumulator with the string representating type of the
// object in the accumulator. // object in the accumulator.
void Interpreter::DoTypeOf(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* result = __ CallRuntime(Runtime::kInterpreterTypeOf, accumulator); Node* context = __ GetContext();
Node* result =
__ CallRuntime(Runtime::kInterpreterTypeOf, context, accumulator);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
void Interpreter::DoDelete(Runtime::FunctionId function_id, void Interpreter::DoDelete(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0); Node* reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(reg_index); Node* object = __ LoadRegister(reg_index);
Node* key = __ GetAccumulator(); Node* key = __ GetAccumulator();
Node* result = __ CallRuntime(function_id, object, key); Node* context = __ GetContext();
Node* result = __ CallRuntime(function_id, context, object, key);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1030,8 +1006,7 @@ void Interpreter::DoDelete(Runtime::FunctionId function_id, ...@@ -1030,8 +1006,7 @@ void Interpreter::DoDelete(Runtime::FunctionId function_id,
// //
// Delete the property specified in the accumulator from the object // Delete the property specified in the accumulator from the object
// referenced by the register operand following strict mode semantics. // referenced by the register operand following strict mode semantics.
void Interpreter::DoDeletePropertyStrict( void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoDelete(Runtime::kDeleteProperty_Strict, assembler); DoDelete(Runtime::kDeleteProperty_Strict, assembler);
} }
...@@ -1040,8 +1015,7 @@ void Interpreter::DoDeletePropertyStrict( ...@@ -1040,8 +1015,7 @@ void Interpreter::DoDeletePropertyStrict(
// //
// Delete the property specified in the accumulator from the object // Delete the property specified in the accumulator from the object
// referenced by the register operand following sloppy mode semantics. // referenced by the register operand following sloppy mode semantics.
void Interpreter::DoDeletePropertySloppy( void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
} }
...@@ -1050,17 +1024,16 @@ void Interpreter::DoDeletePropertySloppy( ...@@ -1050,17 +1024,16 @@ void Interpreter::DoDeletePropertySloppy(
// //
// Delete the variable with the name specified in the accumulator by dynamically // Delete the variable with the name specified in the accumulator by dynamically
// looking it up. // looking it up.
void Interpreter::DoDeleteLookupSlot( void Interpreter::DoDeleteLookupSlot(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* name = __ GetAccumulator(); Node* name = __ GetAccumulator();
Node* context = __ GetContext(); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kDeleteLookupSlot, context, name); Node* result =
__ CallRuntime(Runtime::kDeleteLookupSlot, context, context, name);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
void Interpreter::DoJSCall(InterpreterAssembler* assembler) {
void Interpreter::DoJSCall(compiler::InterpreterAssembler* assembler) {
Node* function_reg = __ BytecodeOperandReg(0); Node* function_reg = __ BytecodeOperandReg(0);
Node* function = __ LoadRegister(function_reg); Node* function = __ LoadRegister(function_reg);
Node* receiver_reg = __ BytecodeOperandReg(1); Node* receiver_reg = __ BytecodeOperandReg(1);
...@@ -1068,8 +1041,9 @@ void Interpreter::DoJSCall(compiler::InterpreterAssembler* assembler) { ...@@ -1068,8 +1041,9 @@ void Interpreter::DoJSCall(compiler::InterpreterAssembler* assembler) {
Node* receiver_args_count = __ BytecodeOperandCount(2); Node* receiver_args_count = __ BytecodeOperandCount(2);
Node* receiver_count = __ Int32Constant(1); Node* receiver_count = __ Int32Constant(1);
Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
// TODO(rmcilroy): Use the call type feedback slot to call via CallIC. Node* context = __ GetContext();
Node* result = __ CallJS(function, receiver_arg, args_count); // TODO(rmcilroy): Use the call type feedback slot to call via CallStub.
Node* result = __ CallJS(function, context, receiver_arg, args_count);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1079,7 +1053,7 @@ void Interpreter::DoJSCall(compiler::InterpreterAssembler* assembler) { ...@@ -1079,7 +1053,7 @@ void Interpreter::DoJSCall(compiler::InterpreterAssembler* assembler) {
// //
// Call a JSfunction or Callable in |callable| with the |receiver| and // Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers. // |arg_count| arguments in subsequent registers.
void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCall(InterpreterAssembler* assembler) {
DoJSCall(assembler); DoJSCall(assembler);
} }
...@@ -1088,18 +1062,17 @@ void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) { ...@@ -1088,18 +1062,17 @@ void Interpreter::DoCall(compiler::InterpreterAssembler* assembler) {
// //
// Call a JSfunction or Callable in |callable| with the |receiver| and // Call a JSfunction or Callable in |callable| with the |receiver| and
// |arg_count| arguments in subsequent registers. // |arg_count| arguments in subsequent registers.
void Interpreter::DoCallWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCallWide(InterpreterAssembler* assembler) {
DoJSCall(assembler); DoJSCall(assembler);
} }
void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
void Interpreter::DoCallRuntimeCommon(
compiler::InterpreterAssembler* assembler) {
Node* function_id = __ BytecodeOperandIdx(0); Node* function_id = __ BytecodeOperandIdx(0);
Node* first_arg_reg = __ BytecodeOperandReg(1); Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(first_arg_reg); Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount(2); Node* args_count = __ BytecodeOperandCount(2);
Node* result = __ CallRuntime(function_id, first_arg, args_count); Node* context = __ GetContext();
Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1110,7 +1083,7 @@ void Interpreter::DoCallRuntimeCommon( ...@@ -1110,7 +1083,7 @@ void Interpreter::DoCallRuntimeCommon(
// Call the runtime function |function_id| with the first argument in // Call the runtime function |function_id| with the first argument in
// register |first_arg| and |arg_count| arguments in subsequent // register |first_arg| and |arg_count| arguments in subsequent
// registers. // registers.
void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
DoCallRuntimeCommon(assembler); DoCallRuntimeCommon(assembler);
} }
...@@ -1120,19 +1093,19 @@ void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) { ...@@ -1120,19 +1093,19 @@ void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) {
// Call the runtime function |function_id| with the first argument in // Call the runtime function |function_id| with the first argument in
// register |first_arg| and |arg_count| arguments in subsequent // register |first_arg| and |arg_count| arguments in subsequent
// registers. // registers.
void Interpreter::DoCallRuntimeWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCallRuntimeWide(InterpreterAssembler* assembler) {
DoCallRuntimeCommon(assembler); DoCallRuntimeCommon(assembler);
} }
void Interpreter::DoCallRuntimeForPairCommon(InterpreterAssembler* assembler) {
void Interpreter::DoCallRuntimeForPairCommon(
compiler::InterpreterAssembler* assembler) {
// Call the runtime function. // Call the runtime function.
Node* function_id = __ BytecodeOperandIdx(0); Node* function_id = __ BytecodeOperandIdx(0);
Node* first_arg_reg = __ BytecodeOperandReg(1); Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(first_arg_reg); Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount(2); Node* args_count = __ BytecodeOperandCount(2);
Node* result_pair = __ CallRuntime(function_id, first_arg, args_count, 2); Node* context = __ GetContext();
Node* result_pair =
__ CallRuntimeN(function_id, context, first_arg, args_count, 2);
// Store the results in <first_return> and <first_return + 1> // Store the results in <first_return> and <first_return + 1>
Node* first_return_reg = __ BytecodeOperandReg(3); Node* first_return_reg = __ BytecodeOperandReg(3);
...@@ -1151,8 +1124,7 @@ void Interpreter::DoCallRuntimeForPairCommon( ...@@ -1151,8 +1124,7 @@ void Interpreter::DoCallRuntimeForPairCommon(
// first argument in register |first_arg| and |arg_count| arguments in // first argument in register |first_arg| and |arg_count| arguments in
// subsequent registers. Returns the result in <first_return> and // subsequent registers. Returns the result in <first_return> and
// <first_return + 1> // <first_return + 1>
void Interpreter::DoCallRuntimeForPair( void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCallRuntimeForPairCommon(assembler); DoCallRuntimeForPairCommon(assembler);
} }
...@@ -1163,14 +1135,11 @@ void Interpreter::DoCallRuntimeForPair( ...@@ -1163,14 +1135,11 @@ void Interpreter::DoCallRuntimeForPair(
// first argument in register |first_arg| and |arg_count| arguments in // first argument in register |first_arg| and |arg_count| arguments in
// subsequent registers. Returns the result in <first_return> and // subsequent registers. Returns the result in <first_return> and
// <first_return + 1> // <first_return + 1>
void Interpreter::DoCallRuntimeForPairWide( void Interpreter::DoCallRuntimeForPairWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCallRuntimeForPairCommon(assembler); DoCallRuntimeForPairCommon(assembler);
} }
void Interpreter::DoCallJSRuntimeCommon(InterpreterAssembler* assembler) {
void Interpreter::DoCallJSRuntimeCommon(
compiler::InterpreterAssembler* assembler) {
Node* context_index = __ BytecodeOperandIdx(0); Node* context_index = __ BytecodeOperandIdx(0);
Node* receiver_reg = __ BytecodeOperandReg(1); Node* receiver_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(receiver_reg); Node* first_arg = __ RegisterLocation(receiver_reg);
...@@ -1185,7 +1154,7 @@ void Interpreter::DoCallJSRuntimeCommon( ...@@ -1185,7 +1154,7 @@ void Interpreter::DoCallJSRuntimeCommon(
Node* function = __ LoadContextSlot(native_context, context_index); Node* function = __ LoadContextSlot(native_context, context_index);
// Call the function. // Call the function.
Node* result = __ CallJS(function, first_arg, args_count); Node* result = __ CallJS(function, context, first_arg, args_count);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1195,7 +1164,7 @@ void Interpreter::DoCallJSRuntimeCommon( ...@@ -1195,7 +1164,7 @@ void Interpreter::DoCallJSRuntimeCommon(
// //
// Call the JS runtime function that has the |context_index| with the receiver // Call the JS runtime function that has the |context_index| with the receiver
// in register |receiver| and |arg_count| arguments in subsequent registers. // in register |receiver| and |arg_count| arguments in subsequent registers.
void Interpreter::DoCallJSRuntime(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
DoCallJSRuntimeCommon(assembler); DoCallJSRuntimeCommon(assembler);
} }
...@@ -1204,21 +1173,20 @@ void Interpreter::DoCallJSRuntime(compiler::InterpreterAssembler* assembler) { ...@@ -1204,21 +1173,20 @@ void Interpreter::DoCallJSRuntime(compiler::InterpreterAssembler* assembler) {
// //
// Call the JS runtime function that has the |context_index| with the receiver // Call the JS runtime function that has the |context_index| with the receiver
// in register |receiver| and |arg_count| arguments in subsequent registers. // in register |receiver| and |arg_count| arguments in subsequent registers.
void Interpreter::DoCallJSRuntimeWide( void Interpreter::DoCallJSRuntimeWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCallJSRuntimeCommon(assembler); DoCallJSRuntimeCommon(assembler);
} }
void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
void Interpreter::DoCallConstruct(compiler::InterpreterAssembler* assembler) {
Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
Node* constructor_reg = __ BytecodeOperandReg(0); Node* constructor_reg = __ BytecodeOperandReg(0);
Node* constructor = __ LoadRegister(constructor_reg); Node* constructor = __ LoadRegister(constructor_reg);
Node* first_arg_reg = __ BytecodeOperandReg(1); Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(first_arg_reg); Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount(2); Node* args_count = __ BytecodeOperandCount(2);
Node* result = Node* context = __ GetContext();
__ CallConstruct(constructor, constructor, first_arg, args_count); Node* result = __ CallConstruct(constructor, context, constructor, first_arg,
args_count);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1229,7 +1197,7 @@ void Interpreter::DoCallConstruct(compiler::InterpreterAssembler* assembler) { ...@@ -1229,7 +1197,7 @@ void Interpreter::DoCallConstruct(compiler::InterpreterAssembler* assembler) {
// Call operator new with |constructor| and the first argument in // Call operator new with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent // register |first_arg| and |arg_count| arguments in subsequent
// //
void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) { void Interpreter::DoNew(InterpreterAssembler* assembler) {
DoCallConstruct(assembler); DoCallConstruct(assembler);
} }
...@@ -1239,7 +1207,7 @@ void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) { ...@@ -1239,7 +1207,7 @@ void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) {
// Call operator new with |constructor| and the first argument in // Call operator new with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent // register |first_arg| and |arg_count| arguments in subsequent
// //
void Interpreter::DoNewWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoNewWide(InterpreterAssembler* assembler) {
DoCallConstruct(assembler); DoCallConstruct(assembler);
} }
...@@ -1247,7 +1215,7 @@ void Interpreter::DoNewWide(compiler::InterpreterAssembler* assembler) { ...@@ -1247,7 +1215,7 @@ void Interpreter::DoNewWide(compiler::InterpreterAssembler* assembler) {
// TestEqual <src> // TestEqual <src>
// //
// Test if the value in the <src> register equals the accumulator. // Test if the value in the <src> register equals the accumulator.
void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterEquals, assembler); DoBinaryOp(Runtime::kInterpreterEquals, assembler);
} }
...@@ -1255,7 +1223,7 @@ void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { ...@@ -1255,7 +1223,7 @@ void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) {
// TestNotEqual <src> // TestNotEqual <src>
// //
// Test if the value in the <src> register is not equal to the accumulator. // Test if the value in the <src> register is not equal to the accumulator.
void Interpreter::DoTestNotEqual(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterNotEquals, assembler); DoBinaryOp(Runtime::kInterpreterNotEquals, assembler);
} }
...@@ -1263,7 +1231,7 @@ void Interpreter::DoTestNotEqual(compiler::InterpreterAssembler* assembler) { ...@@ -1263,7 +1231,7 @@ void Interpreter::DoTestNotEqual(compiler::InterpreterAssembler* assembler) {
// TestEqualStrict <src> // TestEqualStrict <src>
// //
// Test if the value in the <src> register is strictly equal to the accumulator. // Test if the value in the <src> register is strictly equal to the accumulator.
void Interpreter::DoTestEqualStrict(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterStrictEquals, assembler); DoBinaryOp(Runtime::kInterpreterStrictEquals, assembler);
} }
...@@ -1272,8 +1240,7 @@ void Interpreter::DoTestEqualStrict(compiler::InterpreterAssembler* assembler) { ...@@ -1272,8 +1240,7 @@ void Interpreter::DoTestEqualStrict(compiler::InterpreterAssembler* assembler) {
// //
// Test if the value in the <src> register is not strictly equal to the // Test if the value in the <src> register is not strictly equal to the
// accumulator. // accumulator.
void Interpreter::DoTestNotEqualStrict( void Interpreter::DoTestNotEqualStrict(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterStrictNotEquals, assembler); DoBinaryOp(Runtime::kInterpreterStrictNotEquals, assembler);
} }
...@@ -1281,7 +1248,7 @@ void Interpreter::DoTestNotEqualStrict( ...@@ -1281,7 +1248,7 @@ void Interpreter::DoTestNotEqualStrict(
// TestLessThan <src> // TestLessThan <src>
// //
// Test if the value in the <src> register is less than the accumulator. // Test if the value in the <src> register is less than the accumulator.
void Interpreter::DoTestLessThan(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterLessThan, assembler); DoBinaryOp(Runtime::kInterpreterLessThan, assembler);
} }
...@@ -1289,7 +1256,7 @@ void Interpreter::DoTestLessThan(compiler::InterpreterAssembler* assembler) { ...@@ -1289,7 +1256,7 @@ void Interpreter::DoTestLessThan(compiler::InterpreterAssembler* assembler) {
// TestGreaterThan <src> // TestGreaterThan <src>
// //
// Test if the value in the <src> register is greater than the accumulator. // Test if the value in the <src> register is greater than the accumulator.
void Interpreter::DoTestGreaterThan(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterGreaterThan, assembler); DoBinaryOp(Runtime::kInterpreterGreaterThan, assembler);
} }
...@@ -1298,8 +1265,7 @@ void Interpreter::DoTestGreaterThan(compiler::InterpreterAssembler* assembler) { ...@@ -1298,8 +1265,7 @@ void Interpreter::DoTestGreaterThan(compiler::InterpreterAssembler* assembler) {
// //
// Test if the value in the <src> register is less than or equal to the // Test if the value in the <src> register is less than or equal to the
// accumulator. // accumulator.
void Interpreter::DoTestLessThanOrEqual( void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterLessThanOrEqual, assembler); DoBinaryOp(Runtime::kInterpreterLessThanOrEqual, assembler);
} }
...@@ -1308,8 +1274,7 @@ void Interpreter::DoTestLessThanOrEqual( ...@@ -1308,8 +1274,7 @@ void Interpreter::DoTestLessThanOrEqual(
// //
// Test if the value in the <src> register is greater than or equal to the // Test if the value in the <src> register is greater than or equal to the
// accumulator. // accumulator.
void Interpreter::DoTestGreaterThanOrEqual( void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInterpreterGreaterThanOrEqual, assembler); DoBinaryOp(Runtime::kInterpreterGreaterThanOrEqual, assembler);
} }
...@@ -1318,7 +1283,7 @@ void Interpreter::DoTestGreaterThanOrEqual( ...@@ -1318,7 +1283,7 @@ void Interpreter::DoTestGreaterThanOrEqual(
// //
// Test if the object referenced by the register operand is a property of the // Test if the object referenced by the register operand is a property of the
// object referenced by the accumulator. // object referenced by the accumulator.
void Interpreter::DoTestIn(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kHasProperty, assembler); DoBinaryOp(Runtime::kHasProperty, assembler);
} }
...@@ -1327,7 +1292,7 @@ void Interpreter::DoTestIn(compiler::InterpreterAssembler* assembler) { ...@@ -1327,7 +1292,7 @@ void Interpreter::DoTestIn(compiler::InterpreterAssembler* assembler) {
// //
// Test if the object referenced by the <src> register is an an instance of type // Test if the object referenced by the <src> register is an an instance of type
// referenced by the accumulator. // referenced by the accumulator.
void Interpreter::DoTestInstanceOf(compiler::InterpreterAssembler* assembler) { void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kInstanceOf, assembler); DoBinaryOp(Runtime::kInstanceOf, assembler);
} }
...@@ -1335,9 +1300,10 @@ void Interpreter::DoTestInstanceOf(compiler::InterpreterAssembler* assembler) { ...@@ -1335,9 +1300,10 @@ void Interpreter::DoTestInstanceOf(compiler::InterpreterAssembler* assembler) {
// ToName // ToName
// //
// Cast the object referenced by the accumulator to a name. // Cast the object referenced by the accumulator to a name.
void Interpreter::DoToName(compiler::InterpreterAssembler* assembler) { void Interpreter::DoToName(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* result = __ CallRuntime(Runtime::kToName, accumulator); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kToName, context, accumulator);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1346,9 +1312,10 @@ void Interpreter::DoToName(compiler::InterpreterAssembler* assembler) { ...@@ -1346,9 +1312,10 @@ void Interpreter::DoToName(compiler::InterpreterAssembler* assembler) {
// ToNumber // ToNumber
// //
// Cast the object referenced by the accumulator to a number. // Cast the object referenced by the accumulator to a number.
void Interpreter::DoToNumber(compiler::InterpreterAssembler* assembler) { void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* result = __ CallRuntime(Runtime::kToNumber, accumulator); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kToNumber, context, accumulator);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1357,9 +1324,10 @@ void Interpreter::DoToNumber(compiler::InterpreterAssembler* assembler) { ...@@ -1357,9 +1324,10 @@ void Interpreter::DoToNumber(compiler::InterpreterAssembler* assembler) {
// ToObject // ToObject
// //
// Cast the object referenced by the accumulator to a JSObject. // Cast the object referenced by the accumulator to a JSObject.
void Interpreter::DoToObject(compiler::InterpreterAssembler* assembler) { void Interpreter::DoToObject(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* result = __ CallRuntime(Runtime::kToObject, accumulator); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kToObject, context, accumulator);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1368,7 +1336,7 @@ void Interpreter::DoToObject(compiler::InterpreterAssembler* assembler) { ...@@ -1368,7 +1336,7 @@ void Interpreter::DoToObject(compiler::InterpreterAssembler* assembler) {
// Jump <imm8> // Jump <imm8>
// //
// Jump by number of bytes represented by the immediate operand |imm8|. // Jump by number of bytes represented by the immediate operand |imm8|.
void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJump(InterpreterAssembler* assembler) {
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
__ Jump(relative_jump); __ Jump(relative_jump);
} }
...@@ -1377,7 +1345,7 @@ void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) { ...@@ -1377,7 +1345,7 @@ void Interpreter::DoJump(compiler::InterpreterAssembler* assembler) {
// JumpConstant <idx8> // JumpConstant <idx8>
// //
// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool. // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool.
void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpConstant(InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
Node* relative_jump = __ SmiUntag(constant); Node* relative_jump = __ SmiUntag(constant);
...@@ -1389,8 +1357,7 @@ void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) { ...@@ -1389,8 +1357,7 @@ void Interpreter::DoJumpConstant(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes in the Smi in the |idx16| entry in the // Jump by number of bytes in the Smi in the |idx16| entry in the
// constant pool. // constant pool.
void Interpreter::DoJumpConstantWide( void Interpreter::DoJumpConstantWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoJumpConstant(assembler); DoJumpConstant(assembler);
} }
...@@ -1399,7 +1366,7 @@ void Interpreter::DoJumpConstantWide( ...@@ -1399,7 +1366,7 @@ void Interpreter::DoJumpConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the // Jump by number of bytes represented by an immediate operand if the
// accumulator contains true. // accumulator contains true.
void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfTrue(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
Node* true_value = __ BooleanConstant(true); Node* true_value = __ BooleanConstant(true);
...@@ -1411,8 +1378,7 @@ void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) { ...@@ -1411,8 +1378,7 @@ void Interpreter::DoJumpIfTrue(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
// if the accumulator contains true. // if the accumulator contains true.
void Interpreter::DoJumpIfTrueConstant( void Interpreter::DoJumpIfTrueConstant(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
...@@ -1426,8 +1392,7 @@ void Interpreter::DoJumpIfTrueConstant( ...@@ -1426,8 +1392,7 @@ void Interpreter::DoJumpIfTrueConstant(
// //
// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
// if the accumulator contains true. // if the accumulator contains true.
void Interpreter::DoJumpIfTrueConstantWide( void Interpreter::DoJumpIfTrueConstantWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoJumpIfTrueConstant(assembler); DoJumpIfTrueConstant(assembler);
} }
...@@ -1436,7 +1401,7 @@ void Interpreter::DoJumpIfTrueConstantWide( ...@@ -1436,7 +1401,7 @@ void Interpreter::DoJumpIfTrueConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the // Jump by number of bytes represented by an immediate operand if the
// accumulator contains false. // accumulator contains false.
void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfFalse(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
Node* false_value = __ BooleanConstant(false); Node* false_value = __ BooleanConstant(false);
...@@ -1448,8 +1413,7 @@ void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) { ...@@ -1448,8 +1413,7 @@ void Interpreter::DoJumpIfFalse(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
// if the accumulator contains false. // if the accumulator contains false.
void Interpreter::DoJumpIfFalseConstant( void Interpreter::DoJumpIfFalseConstant(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
...@@ -1463,8 +1427,7 @@ void Interpreter::DoJumpIfFalseConstant( ...@@ -1463,8 +1427,7 @@ void Interpreter::DoJumpIfFalseConstant(
// //
// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
// if the accumulator contains false. // if the accumulator contains false.
void Interpreter::DoJumpIfFalseConstantWide( void Interpreter::DoJumpIfFalseConstantWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoJumpIfFalseConstant(assembler); DoJumpIfFalseConstant(assembler);
} }
...@@ -1473,11 +1436,11 @@ void Interpreter::DoJumpIfFalseConstantWide( ...@@ -1473,11 +1436,11 @@ void Interpreter::DoJumpIfFalseConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is true when the object is cast to boolean. // referenced by the accumulator is true when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanTrue( void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* context = __ GetContext();
Node* to_boolean_value = Node* to_boolean_value =
__ CallRuntime(Runtime::kInterpreterToBoolean, accumulator); __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
Node* true_value = __ BooleanConstant(true); Node* true_value = __ BooleanConstant(true);
__ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
...@@ -1490,10 +1453,11 @@ void Interpreter::DoJumpIfToBooleanTrue( ...@@ -1490,10 +1453,11 @@ void Interpreter::DoJumpIfToBooleanTrue(
// if the object referenced by the accumulator is true when the object is cast // if the object referenced by the accumulator is true when the object is cast
// to boolean. // to boolean.
void Interpreter::DoJumpIfToBooleanTrueConstant( void Interpreter::DoJumpIfToBooleanTrueConstant(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* context = __ GetContext();
Node* to_boolean_value = Node* to_boolean_value =
__ CallRuntime(Runtime::kInterpreterToBoolean, accumulator); __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
Node* relative_jump = __ SmiUntag(constant); Node* relative_jump = __ SmiUntag(constant);
...@@ -1508,7 +1472,7 @@ void Interpreter::DoJumpIfToBooleanTrueConstant( ...@@ -1508,7 +1472,7 @@ void Interpreter::DoJumpIfToBooleanTrueConstant(
// if the object referenced by the accumulator is true when the object is cast // if the object referenced by the accumulator is true when the object is cast
// to boolean. // to boolean.
void Interpreter::DoJumpIfToBooleanTrueConstantWide( void Interpreter::DoJumpIfToBooleanTrueConstantWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
DoJumpIfToBooleanTrueConstant(assembler); DoJumpIfToBooleanTrueConstant(assembler);
} }
...@@ -1517,11 +1481,11 @@ void Interpreter::DoJumpIfToBooleanTrueConstantWide( ...@@ -1517,11 +1481,11 @@ void Interpreter::DoJumpIfToBooleanTrueConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is false when the object is cast to boolean. // referenced by the accumulator is false when the object is cast to boolean.
void Interpreter::DoJumpIfToBooleanFalse( void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* context = __ GetContext();
Node* to_boolean_value = Node* to_boolean_value =
__ CallRuntime(Runtime::kInterpreterToBoolean, accumulator); __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
Node* false_value = __ BooleanConstant(false); Node* false_value = __ BooleanConstant(false);
__ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
...@@ -1534,10 +1498,11 @@ void Interpreter::DoJumpIfToBooleanFalse( ...@@ -1534,10 +1498,11 @@ void Interpreter::DoJumpIfToBooleanFalse(
// if the object referenced by the accumulator is false when the object is cast // if the object referenced by the accumulator is false when the object is cast
// to boolean. // to boolean.
void Interpreter::DoJumpIfToBooleanFalseConstant( void Interpreter::DoJumpIfToBooleanFalseConstant(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* context = __ GetContext();
Node* to_boolean_value = Node* to_boolean_value =
__ CallRuntime(Runtime::kInterpreterToBoolean, accumulator); __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator);
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant = __ LoadConstantPoolEntry(index); Node* constant = __ LoadConstantPoolEntry(index);
Node* relative_jump = __ SmiUntag(constant); Node* relative_jump = __ SmiUntag(constant);
...@@ -1552,7 +1517,7 @@ void Interpreter::DoJumpIfToBooleanFalseConstant( ...@@ -1552,7 +1517,7 @@ void Interpreter::DoJumpIfToBooleanFalseConstant(
// if the object referenced by the accumulator is false when the object is cast // if the object referenced by the accumulator is false when the object is cast
// to boolean. // to boolean.
void Interpreter::DoJumpIfToBooleanFalseConstantWide( void Interpreter::DoJumpIfToBooleanFalseConstantWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
DoJumpIfToBooleanFalseConstant(assembler); DoJumpIfToBooleanFalseConstant(assembler);
} }
...@@ -1561,7 +1526,7 @@ void Interpreter::DoJumpIfToBooleanFalseConstantWide( ...@@ -1561,7 +1526,7 @@ void Interpreter::DoJumpIfToBooleanFalseConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the null constant. // referenced by the accumulator is the null constant.
void Interpreter::DoJumpIfNull(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfNull(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
...@@ -1573,8 +1538,7 @@ void Interpreter::DoJumpIfNull(compiler::InterpreterAssembler* assembler) { ...@@ -1573,8 +1538,7 @@ void Interpreter::DoJumpIfNull(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
// if the object referenced by the accumulator is the null constant. // if the object referenced by the accumulator is the null constant.
void Interpreter::DoJumpIfNullConstant( void Interpreter::DoJumpIfNullConstant(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
...@@ -1588,8 +1552,7 @@ void Interpreter::DoJumpIfNullConstant( ...@@ -1588,8 +1552,7 @@ void Interpreter::DoJumpIfNullConstant(
// //
// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
// if the object referenced by the accumulator is the null constant. // if the object referenced by the accumulator is the null constant.
void Interpreter::DoJumpIfNullConstantWide( void Interpreter::DoJumpIfNullConstantWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoJumpIfNullConstant(assembler); DoJumpIfNullConstant(assembler);
} }
...@@ -1597,7 +1560,7 @@ void Interpreter::DoJumpIfNullConstantWide( ...@@ -1597,7 +1560,7 @@ void Interpreter::DoJumpIfNullConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the undefined constant. // referenced by the accumulator is the undefined constant.
void Interpreter::DoJumpIfUndefined(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfUndefined(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* undefined_value = Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value()); __ HeapConstant(isolate_->factory()->undefined_value());
...@@ -1610,8 +1573,7 @@ void Interpreter::DoJumpIfUndefined(compiler::InterpreterAssembler* assembler) { ...@@ -1610,8 +1573,7 @@ void Interpreter::DoJumpIfUndefined(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes in the Smi in the |idx8| entry in the constant pool // Jump by number of bytes in the Smi in the |idx8| entry in the constant pool
// if the object referenced by the accumulator is the undefined constant. // if the object referenced by the accumulator is the undefined constant.
void Interpreter::DoJumpIfUndefinedConstant( void Interpreter::DoJumpIfUndefinedConstant(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* undefined_value = Node* undefined_value =
__ HeapConstant(isolate_->factory()->undefined_value()); __ HeapConstant(isolate_->factory()->undefined_value());
...@@ -1627,7 +1589,7 @@ void Interpreter::DoJumpIfUndefinedConstant( ...@@ -1627,7 +1589,7 @@ void Interpreter::DoJumpIfUndefinedConstant(
// Jump by number of bytes in the Smi in the |idx16| entry in the constant pool // Jump by number of bytes in the Smi in the |idx16| entry in the constant pool
// if the object referenced by the accumulator is the undefined constant. // if the object referenced by the accumulator is the undefined constant.
void Interpreter::DoJumpIfUndefinedConstantWide( void Interpreter::DoJumpIfUndefinedConstantWide(
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
DoJumpIfUndefinedConstant(assembler); DoJumpIfUndefinedConstant(assembler);
} }
...@@ -1635,7 +1597,7 @@ void Interpreter::DoJumpIfUndefinedConstantWide( ...@@ -1635,7 +1597,7 @@ void Interpreter::DoJumpIfUndefinedConstantWide(
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is the hole. // referenced by the accumulator is the hole.
void Interpreter::DoJumpIfHole(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfHole(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
...@@ -1646,7 +1608,7 @@ void Interpreter::DoJumpIfHole(compiler::InterpreterAssembler* assembler) { ...@@ -1646,7 +1608,7 @@ void Interpreter::DoJumpIfHole(compiler::InterpreterAssembler* assembler) {
// //
// Jump by number of bytes represented by an immediate operand if the object // Jump by number of bytes represented by an immediate operand if the object
// referenced by the accumulator is not the hole. // referenced by the accumulator is not the hole.
void Interpreter::DoJumpIfNotHole(compiler::InterpreterAssembler* assembler) { void Interpreter::DoJumpIfNotHole(InterpreterAssembler* assembler) {
Node* accumulator = __ GetAccumulator(); Node* accumulator = __ GetAccumulator();
Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
Node* relative_jump = __ BytecodeOperandImm(0); Node* relative_jump = __ BytecodeOperandImm(0);
...@@ -1654,7 +1616,7 @@ void Interpreter::DoJumpIfNotHole(compiler::InterpreterAssembler* assembler) { ...@@ -1654,7 +1616,7 @@ void Interpreter::DoJumpIfNotHole(compiler::InterpreterAssembler* assembler) {
} }
void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler) { InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* constant_elements = __ LoadConstantPoolEntry(index); Node* constant_elements = __ LoadConstantPoolEntry(index);
Node* literal_index_raw = __ BytecodeOperandIdx(1); Node* literal_index_raw = __ BytecodeOperandIdx(1);
...@@ -1662,7 +1624,8 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, ...@@ -1662,7 +1624,8 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
Node* flags_raw = __ BytecodeOperandImm(2); Node* flags_raw = __ BytecodeOperandImm(2);
Node* flags = __ SmiTag(flags_raw); Node* flags = __ SmiTag(flags_raw);
Node* closure = __ LoadRegister(Register::function_closure()); Node* closure = __ LoadRegister(Register::function_closure());
Node* result = __ CallRuntime(function_id, closure, literal_index, Node* context = __ GetContext();
Node* result = __ CallRuntime(function_id, context, closure, literal_index,
constant_elements, flags); constant_elements, flags);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
...@@ -1673,8 +1636,7 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id, ...@@ -1673,8 +1636,7 @@ void Interpreter::DoCreateLiteral(Runtime::FunctionId function_id,
// //
// Creates a regular expression literal for literal index <literal_idx> with // Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>. // <flags> and the pattern in <pattern_idx>.
void Interpreter::DoCreateRegExpLiteral( void Interpreter::DoCreateRegExpLiteral(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler); DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
} }
...@@ -1683,8 +1645,7 @@ void Interpreter::DoCreateRegExpLiteral( ...@@ -1683,8 +1645,7 @@ void Interpreter::DoCreateRegExpLiteral(
// //
// Creates a regular expression literal for literal index <literal_idx> with // Creates a regular expression literal for literal index <literal_idx> with
// <flags> and the pattern in <pattern_idx>. // <flags> and the pattern in <pattern_idx>.
void Interpreter::DoCreateRegExpLiteralWide( void Interpreter::DoCreateRegExpLiteralWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler); DoCreateLiteral(Runtime::kCreateRegExpLiteral, assembler);
} }
...@@ -1693,8 +1654,7 @@ void Interpreter::DoCreateRegExpLiteralWide( ...@@ -1693,8 +1654,7 @@ void Interpreter::DoCreateRegExpLiteralWide(
// //
// Creates an array literal for literal index <literal_idx> with flags <flags> // Creates an array literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>. // and constant elements in <element_idx>.
void Interpreter::DoCreateArrayLiteral( void Interpreter::DoCreateArrayLiteral(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler); DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
} }
...@@ -1703,8 +1663,7 @@ void Interpreter::DoCreateArrayLiteral( ...@@ -1703,8 +1663,7 @@ void Interpreter::DoCreateArrayLiteral(
// //
// Creates an array literal for literal index <literal_idx> with flags <flags> // Creates an array literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>. // and constant elements in <element_idx>.
void Interpreter::DoCreateArrayLiteralWide( void Interpreter::DoCreateArrayLiteralWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler); DoCreateLiteral(Runtime::kCreateArrayLiteral, assembler);
} }
...@@ -1713,8 +1672,7 @@ void Interpreter::DoCreateArrayLiteralWide( ...@@ -1713,8 +1672,7 @@ void Interpreter::DoCreateArrayLiteralWide(
// //
// Creates an object literal for literal index <literal_idx> with flags <flags> // Creates an object literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>. // and constant elements in <element_idx>.
void Interpreter::DoCreateObjectLiteral( void Interpreter::DoCreateObjectLiteral(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler); DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
} }
...@@ -1723,8 +1681,7 @@ void Interpreter::DoCreateObjectLiteral( ...@@ -1723,8 +1681,7 @@ void Interpreter::DoCreateObjectLiteral(
// //
// Creates an object literal for literal index <literal_idx> with flags <flags> // Creates an object literal for literal index <literal_idx> with flags <flags>
// and constant elements in <element_idx>. // and constant elements in <element_idx>.
void Interpreter::DoCreateObjectLiteralWide( void Interpreter::DoCreateObjectLiteralWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler); DoCreateLiteral(Runtime::kCreateObjectLiteral, assembler);
} }
...@@ -1733,15 +1690,16 @@ void Interpreter::DoCreateObjectLiteralWide( ...@@ -1733,15 +1690,16 @@ void Interpreter::DoCreateObjectLiteralWide(
// //
// Creates a new closure for SharedFunctionInfo at position |index| in the // Creates a new closure for SharedFunctionInfo at position |index| in the
// constant pool and with the PretenureFlag <tenured>. // constant pool and with the PretenureFlag <tenured>.
void Interpreter::DoCreateClosure(compiler::InterpreterAssembler* assembler) { void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
// TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of // TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of
// calling into the runtime. // calling into the runtime.
Node* index = __ BytecodeOperandIdx(0); Node* index = __ BytecodeOperandIdx(0);
Node* shared = __ LoadConstantPoolEntry(index); Node* shared = __ LoadConstantPoolEntry(index);
Node* tenured_raw = __ BytecodeOperandImm(1); Node* tenured_raw = __ BytecodeOperandImm(1);
Node* tenured = __ SmiTag(tenured_raw); Node* tenured = __ SmiTag(tenured_raw);
Node* context = __ GetContext();
Node* result = Node* result =
__ CallRuntime(Runtime::kInterpreterNewClosure, shared, tenured); __ CallRuntime(Runtime::kInterpreterNewClosure, context, shared, tenured);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1751,8 +1709,7 @@ void Interpreter::DoCreateClosure(compiler::InterpreterAssembler* assembler) { ...@@ -1751,8 +1709,7 @@ void Interpreter::DoCreateClosure(compiler::InterpreterAssembler* assembler) {
// //
// Creates a new closure for SharedFunctionInfo at position |index| in the // Creates a new closure for SharedFunctionInfo at position |index| in the
// constant pool and with the PretenureFlag <tenured>. // constant pool and with the PretenureFlag <tenured>.
void Interpreter::DoCreateClosureWide( void Interpreter::DoCreateClosureWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
return DoCreateClosure(assembler); return DoCreateClosure(assembler);
} }
...@@ -1760,10 +1717,11 @@ void Interpreter::DoCreateClosureWide( ...@@ -1760,10 +1717,11 @@ void Interpreter::DoCreateClosureWide(
// CreateMappedArguments // CreateMappedArguments
// //
// Creates a new mapped arguments object. // Creates a new mapped arguments object.
void Interpreter::DoCreateMappedArguments( void Interpreter::DoCreateMappedArguments(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* closure = __ LoadRegister(Register::function_closure()); Node* closure = __ LoadRegister(Register::function_closure());
Node* result = __ CallRuntime(Runtime::kNewSloppyArguments_Generic, closure); Node* context = __ GetContext();
Node* result =
__ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1772,10 +1730,11 @@ void Interpreter::DoCreateMappedArguments( ...@@ -1772,10 +1730,11 @@ void Interpreter::DoCreateMappedArguments(
// CreateUnmappedArguments // CreateUnmappedArguments
// //
// Creates a new unmapped arguments object. // Creates a new unmapped arguments object.
void Interpreter::DoCreateUnmappedArguments( void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
Node* closure = __ LoadRegister(Register::function_closure()); Node* closure = __ LoadRegister(Register::function_closure());
Node* result = __ CallRuntime(Runtime::kNewStrictArguments_Generic, closure); Node* context = __ GetContext();
Node* result =
__ CallRuntime(Runtime::kNewStrictArguments_Generic, context, closure);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1783,11 +1742,11 @@ void Interpreter::DoCreateUnmappedArguments( ...@@ -1783,11 +1742,11 @@ void Interpreter::DoCreateUnmappedArguments(
// CreateRestParameter // CreateRestParameter
// //
// Creates a new rest parameter array. // Creates a new rest parameter array.
void Interpreter::DoCreateRestParameter( void Interpreter::DoCreateRestParameter(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
// TODO(ignition): Use FastNewRestParameterStub here. // TODO(ignition): Use FastNewRestParameterStub here.
Node* closure = __ LoadRegister(Register::function_closure()); Node* closure = __ LoadRegister(Register::function_closure());
Node* result = __ CallRuntime(Runtime::kNewRestParameter, closure); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kNewRestParameter, context, closure);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1795,7 +1754,7 @@ void Interpreter::DoCreateRestParameter( ...@@ -1795,7 +1754,7 @@ void Interpreter::DoCreateRestParameter(
// StackCheck // StackCheck
// //
// Performs a stack guard check. // Performs a stack guard check.
void Interpreter::DoStackCheck(compiler::InterpreterAssembler* assembler) { void Interpreter::DoStackCheck(InterpreterAssembler* assembler) {
__ StackCheck(); __ StackCheck();
__ Dispatch(); __ Dispatch();
} }
...@@ -1803,9 +1762,10 @@ void Interpreter::DoStackCheck(compiler::InterpreterAssembler* assembler) { ...@@ -1803,9 +1762,10 @@ void Interpreter::DoStackCheck(compiler::InterpreterAssembler* assembler) {
// Throw // Throw
// //
// Throws the exception in the accumulator. // Throws the exception in the accumulator.
void Interpreter::DoThrow(compiler::InterpreterAssembler* assembler) { void Interpreter::DoThrow(InterpreterAssembler* assembler) {
Node* exception = __ GetAccumulator(); Node* exception = __ GetAccumulator();
__ CallRuntime(Runtime::kThrow, exception); Node* context = __ GetContext();
__ CallRuntime(Runtime::kThrow, context, exception);
// We shouldn't ever return from a throw. // We shouldn't ever return from a throw.
__ Abort(kUnexpectedReturnFromThrow); __ Abort(kUnexpectedReturnFromThrow);
} }
...@@ -1814,9 +1774,10 @@ void Interpreter::DoThrow(compiler::InterpreterAssembler* assembler) { ...@@ -1814,9 +1774,10 @@ void Interpreter::DoThrow(compiler::InterpreterAssembler* assembler) {
// ReThrow // ReThrow
// //
// Re-throws the exception in the accumulator. // Re-throws the exception in the accumulator.
void Interpreter::DoReThrow(compiler::InterpreterAssembler* assembler) { void Interpreter::DoReThrow(InterpreterAssembler* assembler) {
Node* exception = __ GetAccumulator(); Node* exception = __ GetAccumulator();
__ CallRuntime(Runtime::kReThrow, exception); Node* context = __ GetContext();
__ CallRuntime(Runtime::kReThrow, context, exception);
// We shouldn't ever return from a throw. // We shouldn't ever return from a throw.
__ Abort(kUnexpectedReturnFromThrow); __ Abort(kUnexpectedReturnFromThrow);
} }
...@@ -1825,15 +1786,16 @@ void Interpreter::DoReThrow(compiler::InterpreterAssembler* assembler) { ...@@ -1825,15 +1786,16 @@ void Interpreter::DoReThrow(compiler::InterpreterAssembler* assembler) {
// Return // Return
// //
// Return the value in the accumulator. // Return the value in the accumulator.
void Interpreter::DoReturn(compiler::InterpreterAssembler* assembler) { void Interpreter::DoReturn(InterpreterAssembler* assembler) {
__ Return(); __ InterpreterReturn();
} }
// Debugger // Debugger
// //
// Call runtime to handle debugger statement. // Call runtime to handle debugger statement.
void Interpreter::DoDebugger(compiler::InterpreterAssembler* assembler) { void Interpreter::DoDebugger(InterpreterAssembler* assembler) {
__ CallRuntime(Runtime::kHandleDebuggerStatement); Node* context = __ GetContext();
__ CallRuntime(Runtime::kHandleDebuggerStatement, context);
__ Dispatch(); __ Dispatch();
} }
...@@ -1843,9 +1805,10 @@ void Interpreter::DoDebugger(compiler::InterpreterAssembler* assembler) { ...@@ -1843,9 +1805,10 @@ void Interpreter::DoDebugger(compiler::InterpreterAssembler* assembler) {
// accumulator. The result is output in registers |cache_info_triple| to // accumulator. The result is output in registers |cache_info_triple| to
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array, // |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively. // and cache_length respectively.
void Interpreter::DoForInPrepare(compiler::InterpreterAssembler* assembler) { void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Node* object = __ GetAccumulator(); Node* object = __ GetAccumulator();
Node* result_triple = __ CallRuntime(Runtime::kForInPrepare, object); Node* context = __ GetContext();
Node* result_triple = __ CallRuntime(Runtime::kForInPrepare, context, object);
// Set output registers: // Set output registers:
// 0 == cache_type, 1 == cache_array, 2 == cache_length // 0 == cache_type, 1 == cache_array, 2 == cache_length
...@@ -1865,8 +1828,7 @@ void Interpreter::DoForInPrepare(compiler::InterpreterAssembler* assembler) { ...@@ -1865,8 +1828,7 @@ void Interpreter::DoForInPrepare(compiler::InterpreterAssembler* assembler) {
// accumulator. The result is output in registers |cache_info_triple| to // accumulator. The result is output in registers |cache_info_triple| to
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array, // |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively. // and cache_length respectively.
void Interpreter::DoForInPrepareWide( void Interpreter::DoForInPrepareWide(InterpreterAssembler* assembler) {
compiler::InterpreterAssembler* assembler) {
DoForInPrepare(assembler); DoForInPrepare(assembler);
} }
...@@ -1874,7 +1836,7 @@ void Interpreter::DoForInPrepareWide( ...@@ -1874,7 +1836,7 @@ void Interpreter::DoForInPrepareWide(
// ForInNext <receiver> <index> <cache_info_pair> // ForInNext <receiver> <index> <cache_info_pair>
// //
// Returns the next enumerable property in the the accumulator. // Returns the next enumerable property in the the accumulator.
void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) { void Interpreter::DoForInNext(InterpreterAssembler* assembler) {
Node* receiver_reg = __ BytecodeOperandReg(0); Node* receiver_reg = __ BytecodeOperandReg(0);
Node* receiver = __ LoadRegister(receiver_reg); Node* receiver = __ LoadRegister(receiver_reg);
Node* index_reg = __ BytecodeOperandReg(1); Node* index_reg = __ BytecodeOperandReg(1);
...@@ -1883,8 +1845,9 @@ void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) { ...@@ -1883,8 +1845,9 @@ void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) {
Node* cache_type = __ LoadRegister(cache_type_reg); Node* cache_type = __ LoadRegister(cache_type_reg);
Node* cache_array_reg = __ NextRegister(cache_type_reg); Node* cache_array_reg = __ NextRegister(cache_type_reg);
Node* cache_array = __ LoadRegister(cache_array_reg); Node* cache_array = __ LoadRegister(cache_array_reg);
Node* result = __ CallRuntime(Runtime::kForInNext, receiver, cache_array, Node* context = __ GetContext();
cache_type, index); Node* result = __ CallRuntime(Runtime::kForInNext, context, receiver,
cache_array, cache_type, index);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1893,7 +1856,7 @@ void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) { ...@@ -1893,7 +1856,7 @@ void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) {
// ForInNextWide <receiver> <index> <cache_info_pair> // ForInNextWide <receiver> <index> <cache_info_pair>
// //
// Returns the next enumerable property in the the accumulator. // Returns the next enumerable property in the the accumulator.
void Interpreter::DoForInNextWide(compiler::InterpreterAssembler* assembler) { void Interpreter::DoForInNextWide(InterpreterAssembler* assembler) {
return DoForInNext(assembler); return DoForInNext(assembler);
} }
...@@ -1901,13 +1864,15 @@ void Interpreter::DoForInNextWide(compiler::InterpreterAssembler* assembler) { ...@@ -1901,13 +1864,15 @@ void Interpreter::DoForInNextWide(compiler::InterpreterAssembler* assembler) {
// ForInDone <index> <cache_length> // ForInDone <index> <cache_length>
// //
// Returns true if the end of the enumerable properties has been reached. // Returns true if the end of the enumerable properties has been reached.
void Interpreter::DoForInDone(compiler::InterpreterAssembler* assembler) { void Interpreter::DoForInDone(InterpreterAssembler* assembler) {
// TODO(oth): Implement directly rather than making a runtime call. // TODO(oth): Implement directly rather than making a runtime call.
Node* index_reg = __ BytecodeOperandReg(0); Node* index_reg = __ BytecodeOperandReg(0);
Node* index = __ LoadRegister(index_reg); Node* index = __ LoadRegister(index_reg);
Node* cache_length_reg = __ BytecodeOperandReg(1); Node* cache_length_reg = __ BytecodeOperandReg(1);
Node* cache_length = __ LoadRegister(cache_length_reg); Node* cache_length = __ LoadRegister(cache_length_reg);
Node* result = __ CallRuntime(Runtime::kForInDone, index, cache_length); Node* context = __ GetContext();
Node* result =
__ CallRuntime(Runtime::kForInDone, context, index, cache_length);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
...@@ -1917,11 +1882,12 @@ void Interpreter::DoForInDone(compiler::InterpreterAssembler* assembler) { ...@@ -1917,11 +1882,12 @@ void Interpreter::DoForInDone(compiler::InterpreterAssembler* assembler) {
// //
// Increments the loop counter in register |index| and stores the result // Increments the loop counter in register |index| and stores the result
// in the accumulator. // in the accumulator.
void Interpreter::DoForInStep(compiler::InterpreterAssembler* assembler) { void Interpreter::DoForInStep(InterpreterAssembler* assembler) {
// TODO(oth): Implement directly rather than making a runtime call. // TODO(oth): Implement directly rather than making a runtime call.
Node* index_reg = __ BytecodeOperandReg(0); Node* index_reg = __ BytecodeOperandReg(0);
Node* index = __ LoadRegister(index_reg); Node* index = __ LoadRegister(index_reg);
Node* result = __ CallRuntime(Runtime::kForInStep, index); Node* context = __ GetContext();
Node* result = __ CallRuntime(Runtime::kForInStep, context, index);
__ SetAccumulator(result); __ SetAccumulator(result);
__ Dispatch(); __ Dispatch();
} }
......
...@@ -21,12 +21,10 @@ class Isolate; ...@@ -21,12 +21,10 @@ class Isolate;
class Callable; class Callable;
class CompilationInfo; class CompilationInfo;
namespace compiler {
class InterpreterAssembler;
}
namespace interpreter { namespace interpreter {
class InterpreterAssembler;
class Interpreter { class Interpreter {
public: public:
explicit Interpreter(Isolate* isolate); explicit Interpreter(Isolate* isolate);
...@@ -41,6 +39,8 @@ class Interpreter { ...@@ -41,6 +39,8 @@ class Interpreter {
// GC support. // GC support.
void IterateDispatchTable(ObjectVisitor* v); void IterateDispatchTable(ObjectVisitor* v);
void TraceCodegen(Handle<Code> code, const char* name);
Address dispatch_table_address() { Address dispatch_table_address() {
return reinterpret_cast<Address>(&dispatch_table_[0]); return reinterpret_cast<Address>(&dispatch_table_[0]);
} }
...@@ -48,74 +48,73 @@ class Interpreter { ...@@ -48,74 +48,73 @@ class Interpreter {
private: private:
// Bytecode handler generator functions. // Bytecode handler generator functions.
#define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \ #define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \
void Do##Name(compiler::InterpreterAssembler* assembler); void Do##Name(InterpreterAssembler* assembler);
BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR) BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
#undef DECLARE_BYTECODE_HANDLER_GENERATOR #undef DECLARE_BYTECODE_HANDLER_GENERATOR
// Generates code to perform the binary operations via |function_id|. // Generates code to perform the binary operations via |function_id|.
void DoBinaryOp(Runtime::FunctionId function_id, void DoBinaryOp(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
// Generates code to perform the count operations via |function_id|. // Generates code to perform the count operations via |function_id|.
void DoCountOp(Runtime::FunctionId function_id, void DoCountOp(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
// Generates code to perform the comparison operation associated with // Generates code to perform the comparison operation associated with
// |compare_op|. // |compare_op|.
void DoCompareOp(Token::Value compare_op, void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);
compiler::InterpreterAssembler* assembler);
// Generates code to load a constant from the constant pool. // Generates code to load a constant from the constant pool.
void DoLoadConstant(compiler::InterpreterAssembler* assembler); void DoLoadConstant(InterpreterAssembler* assembler);
// Generates code to perform a global load via |ic|. // Generates code to perform a global load via |ic|.
void DoLoadGlobal(Callable ic, compiler::InterpreterAssembler* assembler); void DoLoadGlobal(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a global store via |ic|. // Generates code to perform a global store via |ic|.
void DoStoreGlobal(Callable ic, compiler::InterpreterAssembler* assembler); void DoStoreGlobal(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a named property load via |ic|. // Generates code to perform a named property load via |ic|.
void DoLoadIC(Callable ic, compiler::InterpreterAssembler* assembler); void DoLoadIC(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a keyed property load via |ic|. // Generates code to perform a keyed property load via |ic|.
void DoKeyedLoadIC(Callable ic, compiler::InterpreterAssembler* assembler); void DoKeyedLoadIC(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a namedproperty store via |ic|. // Generates code to perform a namedproperty store via |ic|.
void DoStoreIC(Callable ic, compiler::InterpreterAssembler* assembler); void DoStoreIC(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a keyed property store via |ic|. // Generates code to perform a keyed property store via |ic|.
void DoKeyedStoreIC(Callable ic, compiler::InterpreterAssembler* assembler); void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
// Generates code to perform a JS call. // Generates code to perform a JS call.
void DoJSCall(compiler::InterpreterAssembler* assembler); void DoJSCall(InterpreterAssembler* assembler);
// Generates code to perform a runtime call. // Generates code to perform a runtime call.
void DoCallRuntimeCommon(compiler::InterpreterAssembler* assembler); void DoCallRuntimeCommon(InterpreterAssembler* assembler);
// Generates code to perform a runtime call returning a pair. // Generates code to perform a runtime call returning a pair.
void DoCallRuntimeForPairCommon(compiler::InterpreterAssembler* assembler); void DoCallRuntimeForPairCommon(InterpreterAssembler* assembler);
// Generates code to perform a JS runtime call. // Generates code to perform a JS runtime call.
void DoCallJSRuntimeCommon(compiler::InterpreterAssembler* assembler); void DoCallJSRuntimeCommon(InterpreterAssembler* assembler);
// Generates code to perform a constructor call.. // Generates code to perform a constructor call..
void DoCallConstruct(compiler::InterpreterAssembler* assembler); void DoCallConstruct(InterpreterAssembler* assembler);
// Generates code ro create a literal via |function_id|. // Generates code ro create a literal via |function_id|.
void DoCreateLiteral(Runtime::FunctionId function_id, void DoCreateLiteral(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
// Generates code to perform delete via function_id. // Generates code to perform delete via function_id.
void DoDelete(Runtime::FunctionId function_id, void DoDelete(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
// Generates code to perform a lookup slot load via |function_id|. // Generates code to perform a lookup slot load via |function_id|.
void DoLoadLookupSlot(Runtime::FunctionId function_id, void DoLoadLookupSlot(Runtime::FunctionId function_id,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
// Generates code to perform a lookup slot store depending on |language_mode|. // Generates code to perform a lookup slot store depending on |language_mode|.
void DoStoreLookupSlot(LanguageMode language_mode, void DoStoreLookupSlot(LanguageMode language_mode,
compiler::InterpreterAssembler* assembler); InterpreterAssembler* assembler);
bool IsDispatchTableInitialized(); bool IsDispatchTableInitialized();
......
...@@ -406,6 +406,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -406,6 +406,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -417,7 +425,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -417,7 +425,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -429,7 +436,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -429,7 +436,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -406,6 +406,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -406,6 +406,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -417,7 +425,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -417,7 +425,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -429,7 +436,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -429,7 +436,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -404,6 +404,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -404,6 +404,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -415,7 +423,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -415,7 +423,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -427,7 +434,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -427,7 +434,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -405,6 +405,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -405,6 +405,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -416,7 +424,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -416,7 +424,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -428,7 +435,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -428,7 +435,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -410,6 +410,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific( ...@@ -410,6 +410,14 @@ void ApiAccessorDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
kInterpreterDispatchTableRegister};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
...@@ -421,7 +429,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific( ...@@ -421,7 +429,6 @@ void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
...@@ -433,7 +440,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific( ...@@ -433,7 +440,6 @@ void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers); data->InitializePlatformSpecific(arraysize(registers), registers);
} }
void InterpreterCEntryDescriptor::InitializePlatformSpecific( void InterpreterCEntryDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = { Register registers[] = {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "test/unittests/compiler/interpreter-assembler-unittest.h" #include "test/unittests/interpreter/interpreter-assembler-unittest.h"
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
...@@ -16,7 +16,10 @@ using ::testing::_; ...@@ -16,7 +16,10 @@ using ::testing::_;
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler {
using namespace compiler;
namespace interpreter {
const interpreter::Bytecode kBytecodes[] = { const interpreter::Bytecode kBytecodes[] = {
#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,
...@@ -24,55 +27,47 @@ const interpreter::Bytecode kBytecodes[] = { ...@@ -24,55 +27,47 @@ const interpreter::Bytecode kBytecodes[] = {
#undef DEFINE_BYTECODE #undef DEFINE_BYTECODE
}; };
Matcher<Node*> IsIntPtrConstant(const intptr_t value) { Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value)) return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value))
: IsInt32Constant(static_cast<int32_t>(value)); : IsInt32Constant(static_cast<int32_t>(value));
} }
Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher)
: IsInt32Add(lhs_matcher, rhs_matcher); : IsInt32Add(lhs_matcher, rhs_matcher);
} }
Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher)
: IsInt32Sub(lhs_matcher, rhs_matcher); : IsInt32Sub(lhs_matcher, rhs_matcher);
} }
Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher)
: IsWord32Shl(lhs_matcher, rhs_matcher); : IsWord32Shl(lhs_matcher, rhs_matcher);
} }
Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher)
: IsWord32Sar(lhs_matcher, rhs_matcher); : IsWord32Sar(lhs_matcher, rhs_matcher);
} }
Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) { const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher) return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
: IsWord32Or(lhs_matcher, rhs_matcher); : IsWord32Or(lhs_matcher, rhs_matcher);
} }
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad(
const Matcher<LoadRepresentation>& rep_matcher, const Matcher<LoadRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) {
return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _); return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _);
} }
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
const Matcher<StoreRepresentation>& rep_matcher, const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
...@@ -81,52 +76,57 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( ...@@ -81,52 +76,57 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
value_matcher, _, _); value_matcher, _, _);
} }
Matcher<Node*> Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand(
int offset) { int offset) {
return IsLoad( return IsLoad(
MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset))); IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset)));
} }
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
IsBytecodeOperandSignExtended(int offset) { IsBytecodeOperandSignExtended(int offset) {
Matcher<Node*> load_matcher = IsLoad( Matcher<Node*> load_matcher = IsLoad(
MachineType::Int8(), MachineType::Int8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset))); IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset)));
if (kPointerSize == 8) { if (kPointerSize == 8) {
load_matcher = IsChangeInt32ToInt64(load_matcher); load_matcher = IsChangeInt32ToInt64(load_matcher);
} }
return load_matcher; return load_matcher;
} }
Matcher<Node*> Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort(
int offset) { int offset) {
if (TargetSupportsUnalignedAccess()) { if (TargetSupportsUnalignedAccess()) {
return IsLoad( return IsLoad(
MachineType::Uint16(), MachineType::Uint16(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset)));
} else { } else {
Matcher<Node*> first_byte = IsLoad( Matcher<Node*> first_byte = IsLoad(
MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset)));
Matcher<Node*> second_byte = IsLoad( Matcher<Node*> second_byte = IsLoad(
MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset + 1))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset + 1)));
#if V8_TARGET_LITTLE_ENDIAN #if V8_TARGET_LITTLE_ENDIAN
return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)), return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)),
first_byte); first_byte);
...@@ -139,16 +139,17 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( ...@@ -139,16 +139,17 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort(
} }
} }
Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
IsBytecodeOperandShortSignExtended(int offset) { IsBytecodeOperandShortSignExtended(int offset) {
Matcher<Node*> load_matcher; Matcher<Node*> load_matcher;
if (TargetSupportsUnalignedAccess()) { if (TargetSupportsUnalignedAccess()) {
load_matcher = IsLoad( load_matcher = IsLoad(
MachineType::Int16(), MachineType::Int16(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(offset))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(offset)));
} else { } else {
#if V8_TARGET_LITTLE_ENDIAN #if V8_TARGET_LITTLE_ENDIAN
int hi_byte_offset = offset + 1; int hi_byte_offset = offset + 1;
...@@ -162,15 +163,19 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: ...@@ -162,15 +163,19 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
#endif #endif
Matcher<Node*> hi_byte = IsLoad( Matcher<Node*> hi_byte = IsLoad(
MachineType::Int8(), MachineType::Int8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(hi_byte_offset))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(hi_byte_offset)));
hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte)); hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte));
Matcher<Node*> lo_byte = IsLoad( Matcher<Node*> lo_byte = IsLoad(
MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsIntPtrAdd(
IsInt32Constant(lo_byte_offset))); IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(lo_byte_offset)));
load_matcher = IsWord32Or(hi_byte, lo_byte); load_matcher = IsWord32Or(hi_byte, lo_byte);
} }
...@@ -180,7 +185,6 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: ...@@ -180,7 +185,6 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::
return load_matcher; return load_matcher;
} }
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);
...@@ -191,34 +195,33 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { ...@@ -191,34 +195,33 @@ 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_offset_matcher = Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); IsInt32Constant(interpreter::Bytecodes::Size(bytecode)));
Matcher<Node*> target_bytecode_matcher = Matcher<Node*> target_bytecode_matcher = m.IsLoad(
m.IsLoad(MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
next_bytecode_offset_matcher); next_bytecode_offset_matcher);
Matcher<Node*> code_target_matcher = Matcher<Node*> code_target_matcher = m.IsLoad(
m.IsLoad(MachineType::Pointer(), MachineType::Pointer(),
IsParameter(Linkage::kInterpreterDispatchTableParameter), IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
IsWord32Shl(target_bytecode_matcher, IsWord32Shl(target_bytecode_matcher,
IsInt32Constant(kPointerSizeLog2))); IsInt32Constant(kPointerSizeLog2)));
EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
EXPECT_THAT( EXPECT_THAT(
tail_call_node, tail_call_node,
IsTailCall(m.call_descriptor(), code_target_matcher, IsTailCall(
IsParameter(Linkage::kInterpreterAccumulatorParameter), _, code_target_matcher,
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
next_bytecode_offset_matcher, IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), next_bytecode_offset_matcher,
IsParameter(Linkage::kInterpreterDispatchTableParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, Jump) { TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
int jump_offsets[] = {-9710, -77, 0, +3, +97109}; int jump_offsets[] = {-9710, -77, 0, +3, +97109};
TRACED_FOREACH(int, jump_offset, jump_offsets) { TRACED_FOREACH(int, jump_offset, jump_offsets) {
...@@ -230,35 +233,37 @@ TARGET_TEST_F(InterpreterAssemblerTest, Jump) { ...@@ -230,35 +233,37 @@ TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
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_offset_matcher = Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(jump_offset)); IsInt32Constant(jump_offset));
Matcher<Node*> target_bytecode_matcher = Matcher<Node*> target_bytecode_matcher = m.IsLoad(
m.IsLoad(MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
next_bytecode_offset_matcher); next_bytecode_offset_matcher);
Matcher<Node*> code_target_matcher = Matcher<Node*> code_target_matcher = m.IsLoad(
m.IsLoad(MachineType::Pointer(), MachineType::Pointer(),
IsParameter(Linkage::kInterpreterDispatchTableParameter), IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
IsWord32Shl(target_bytecode_matcher, IsWord32Shl(target_bytecode_matcher,
IsInt32Constant(kPointerSizeLog2))); IsInt32Constant(kPointerSizeLog2)));
EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
EXPECT_THAT( EXPECT_THAT(
tail_call_node, tail_call_node,
IsTailCall(m.call_descriptor(), code_target_matcher, IsTailCall(
IsParameter(Linkage::kInterpreterAccumulatorParameter), _, code_target_matcher,
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
next_bytecode_offset_matcher, IsParameter(
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), InterpreterDispatchDescriptor::kRegisterFileParameter),
IsParameter(Linkage::kInterpreterDispatchTableParameter), next_bytecode_offset_matcher,
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(
InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsParameter(
InterpreterDispatchDescriptor::kDispatchTableParameter),
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_));
} }
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
static const int kJumpIfTrueOffset = 73; static const int kJumpIfTrueOffset = 73;
...@@ -276,61 +281,65 @@ TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { ...@@ -276,61 +281,65 @@ TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
int jump_offsets[] = {kJumpIfTrueOffset, int jump_offsets[] = {kJumpIfTrueOffset,
interpreter::Bytecodes::Size(bytecode)}; interpreter::Bytecodes::Size(bytecode)};
for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) { for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) {
Matcher<Node*> next_bytecode_offset_matcher = Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsInt32Constant(jump_offsets[i])); IsInt32Constant(jump_offsets[i]));
Matcher<Node*> target_bytecode_matcher = Matcher<Node*> target_bytecode_matcher = m.IsLoad(
m.IsLoad(MachineType::Uint8(), MachineType::Uint8(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
next_bytecode_offset_matcher); next_bytecode_offset_matcher);
Matcher<Node*> code_target_matcher = Matcher<Node*> code_target_matcher = m.IsLoad(
m.IsLoad(MachineType::Pointer(), MachineType::Pointer(),
IsParameter(Linkage::kInterpreterDispatchTableParameter), IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
IsWord32Shl(target_bytecode_matcher, IsWord32Shl(target_bytecode_matcher,
IsInt32Constant(kPointerSizeLog2))); IsInt32Constant(kPointerSizeLog2)));
EXPECT_THAT( EXPECT_THAT(
end->InputAt(i), end->InputAt(i),
IsTailCall(m.call_descriptor(), code_target_matcher, IsTailCall(
IsParameter(Linkage::kInterpreterAccumulatorParameter), _, code_target_matcher,
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
next_bytecode_offset_matcher, IsParameter(
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), InterpreterDispatchDescriptor::kRegisterFileParameter),
IsParameter(Linkage::kInterpreterDispatchTableParameter), next_bytecode_offset_matcher,
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(
InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsParameter(
InterpreterDispatchDescriptor::kDispatchTableParameter),
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_));
} }
// TODO(oth): test control flow paths. // TODO(oth): test control flow paths.
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) {
TARGET_TEST_F(InterpreterAssemblerTest, Return) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
m.Return(); m.InterpreterReturn();
Graph* graph = m.graph(); Graph* graph = m.graph();
Node* end = graph->end(); Node* end = graph->end();
EXPECT_EQ(1, end->InputCount()); EXPECT_EQ(1, end->InputCount());
Node* tail_call_node = end->InputAt(0); Node* tail_call_node = end->InputAt(0);
EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind());
EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots);
Handle<HeapObject> exit_trampoline = Handle<HeapObject> exit_trampoline =
isolate()->builtins()->InterpreterExitTrampoline(); isolate()->builtins()->InterpreterExitTrampoline();
EXPECT_THAT( EXPECT_THAT(
tail_call_node, tail_call_node,
IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), IsTailCall(
IsParameter(Linkage::kInterpreterAccumulatorParameter), _, IsHeapConstant(exit_trampoline),
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter),
IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(
IsParameter(Linkage::kInterpreterDispatchTableParameter), InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -382,15 +391,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { ...@@ -382,15 +391,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
// Should be incoming accumulator if not set. // Should be incoming accumulator if not set.
EXPECT_THAT(m.GetAccumulator(), EXPECT_THAT(
IsParameter(Linkage::kInterpreterAccumulatorParameter)); m.GetAccumulator(),
IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter));
// Should be set by SedtAccumulator. // Should be set by SetAccumulator.
Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef);
m.SetAccumulator(accumulator_value_1); m.SetAccumulator(accumulator_value_1);
EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); EXPECT_THAT(m.GetAccumulator(), accumulator_value_1);
...@@ -407,12 +416,10 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { ...@@ -407,12 +416,10 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
Node* tail_call_node = end->InputAt(0); Node* tail_call_node = end->InputAt(0);
EXPECT_THAT(tail_call_node, EXPECT_THAT(tail_call_node,
IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _, IsTailCall(_, _, accumulator_value_2, _, _, _, _, _, _));
_, _, _));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) { TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -422,7 +429,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) { ...@@ -422,7 +429,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -431,12 +437,11 @@ TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { ...@@ -431,12 +437,11 @@ TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
EXPECT_THAT( EXPECT_THAT(
reg_location_node, reg_location_node,
IsIntPtrAdd( IsIntPtrAdd(
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -444,13 +449,13 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { ...@@ -444,13 +449,13 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
Node* load_reg_node = m.LoadRegister(reg_index_node); Node* load_reg_node = m.LoadRegister(reg_index_node);
EXPECT_THAT( EXPECT_THAT(
load_reg_node, load_reg_node,
m.IsLoad(MachineType::AnyTagged(), m.IsLoad(
IsParameter(Linkage::kInterpreterRegisterFileParameter), MachineType::AnyTagged(),
IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2))));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -459,15 +464,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { ...@@ -459,15 +464,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); Node* store_reg_node = m.StoreRegister(store_value, reg_index_node);
EXPECT_THAT( EXPECT_THAT(
store_reg_node, store_reg_node,
m.IsStore(StoreRepresentation(MachineRepresentation::kTagged, m.IsStore(
kNoWriteBarrier), StoreRepresentation(MachineRepresentation::kTagged,
IsParameter(Linkage::kInterpreterRegisterFileParameter), kNoWriteBarrier),
IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
store_value)); IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)),
store_value));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -479,7 +484,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { ...@@ -479,7 +484,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) { TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -490,7 +494,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) { ...@@ -490,7 +494,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) { TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -501,7 +504,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) { ...@@ -501,7 +504,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, WordShl) { TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -511,7 +513,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, WordShl) { ...@@ -511,7 +513,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -519,7 +520,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { ...@@ -519,7 +520,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
Node* load_constant = m.LoadConstantPoolEntry(index); Node* load_constant = m.LoadConstantPoolEntry(index);
Matcher<Node*> constant_pool_matcher = m.IsLoad( Matcher<Node*> constant_pool_matcher = m.IsLoad(
MachineType::AnyTagged(), MachineType::AnyTagged(),
IsParameter(Linkage::kInterpreterBytecodeArrayParameter), IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag)); IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag));
EXPECT_THAT( EXPECT_THAT(
load_constant, load_constant,
...@@ -530,7 +531,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { ...@@ -530,7 +531,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) { TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -547,7 +547,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) { ...@@ -547,7 +547,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -560,7 +559,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { ...@@ -560,7 +559,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -576,7 +574,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { ...@@ -576,7 +574,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -595,21 +592,22 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { ...@@ -595,21 +592,22 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) {
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
Node* arg1 = m.Int32Constant(2); Node* arg1 = m.Int32Constant(2);
Node* arg2 = m.Int32Constant(3); Node* arg2 = m.Int32Constant(3);
Node* call_runtime = m.CallRuntime(Runtime::kAdd, arg1, arg2); Node* context =
m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2);
EXPECT_THAT( EXPECT_THAT(
call_runtime, call_runtime,
IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), IsCall(_, _, arg1, arg2, _, IsInt32Constant(2),
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
const int kResultSizes[] = {1, 2}; const int kResultSizes[] = {1, 2};
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
...@@ -620,6 +618,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { ...@@ -620,6 +618,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
Node* function_id = m.Int32Constant(0); Node* function_id = m.Int32Constant(0);
Node* first_arg = m.Int32Constant(1); Node* first_arg = m.Int32Constant(1);
Node* arg_count = m.Int32Constant(2); Node* arg_count = m.Int32Constant(2);
Node* context =
m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
Matcher<Node*> function_table = IsExternalConstant( Matcher<Node*> function_table = IsExternalConstant(
ExternalReference::runtime_function_table_address(isolate())); ExternalReference::runtime_function_table_address(isolate()));
...@@ -630,36 +630,18 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { ...@@ -630,36 +630,18 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
m.IsLoad(MachineType::Pointer(), function, m.IsLoad(MachineType::Pointer(), function,
IsInt32Constant(offsetof(Runtime::Function, entry))); IsInt32Constant(offsetof(Runtime::Function, entry)));
Node* call_runtime = Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg,
m.CallRuntime(function_id, first_arg, arg_count, result_size); arg_count, result_size);
EXPECT_THAT( EXPECT_THAT(
call_runtime, call_runtime,
IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
function_entry, function_entry,
IsParameter(Linkage::kInterpreterContextParameter), _, _)); IsParameter(InterpreterDispatchDescriptor::kContextParameter),
_, _));
} }
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, CallIC) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
LoadWithVectorDescriptor descriptor(isolate());
Node* target = m.Int32Constant(1);
Node* arg1 = m.Int32Constant(2);
Node* arg2 = m.Int32Constant(3);
Node* arg3 = m.Int32Constant(4);
Node* arg4 = m.Int32Constant(5);
Node* call_ic = m.CallIC(descriptor, target, arg1, arg2, arg3, arg4);
EXPECT_THAT(
call_ic,
IsCall(_, target, arg1, arg2, arg3, arg4,
IsParameter(Linkage::kInterpreterContextParameter), _, _));
}
}
TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
...@@ -667,26 +649,28 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { ...@@ -667,26 +649,28 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallJS) {
Node* function = m.Int32Constant(0); Node* function = m.Int32Constant(0);
Node* first_arg = m.Int32Constant(1); Node* first_arg = m.Int32Constant(1);
Node* arg_count = m.Int32Constant(2); Node* arg_count = m.Int32Constant(2);
Node* call_js = m.CallJS(function, first_arg, arg_count); Node* context =
m.Parameter(InterpreterDispatchDescriptor::kContextParameter);
Node* call_js = m.CallJS(function, context, first_arg, arg_count);
EXPECT_THAT( EXPECT_THAT(
call_js, call_js,
IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg,
function, IsParameter(Linkage::kInterpreterContextParameter), _, function,
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
_)); _));
} }
} }
TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode); InterpreterAssemblerForTest m(this, bytecode);
Node* feedback_vector = m.LoadTypeFeedbackVector(); Node* feedback_vector = m.LoadTypeFeedbackVector();
Matcher<Node*> load_function_matcher = Matcher<Node*> load_function_matcher = m.IsLoad(
m.IsLoad(MachineType::AnyTagged(), MachineType::AnyTagged(),
IsParameter(Linkage::kInterpreterRegisterFileParameter), IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
IsIntPtrConstant( IsIntPtrConstant(
InterpreterFrameConstants::kFunctionFromRegisterPointer)); InterpreterFrameConstants::kFunctionFromRegisterPointer));
Matcher<Node*> load_shared_function_info_matcher = Matcher<Node*> load_shared_function_info_matcher =
m.IsLoad(MachineType::AnyTagged(), load_function_matcher, m.IsLoad(MachineType::AnyTagged(), load_function_matcher,
IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset - IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
...@@ -700,6 +684,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { ...@@ -700,6 +684,6 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) {
} }
} }
} // namespace compiler } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -2,18 +2,17 @@ ...@@ -2,18 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ #ifndef V8_UNITTESTS_INTERPRETER_INTERPRETER_ASSEMBLER_UNITTEST_H_
#define V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ #define V8_UNITTESTS_INTERPRETER_INTERPRETER_ASSEMBLER_UNITTEST_H_
#include "src/compiler/interpreter-assembler.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/interpreter/interpreter-assembler.h"
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "testing/gmock-support.h" #include "testing/gmock-support.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace interpreter {
using ::testing::Matcher; using ::testing::Matcher;
...@@ -25,24 +24,25 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone { ...@@ -25,24 +24,25 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone {
class InterpreterAssemblerForTest final : public InterpreterAssembler { class InterpreterAssemblerForTest final : public InterpreterAssembler {
public: public:
InterpreterAssemblerForTest(InterpreterAssemblerTest* test, InterpreterAssemblerForTest(InterpreterAssemblerTest* test,
interpreter::Bytecode bytecode) Bytecode bytecode)
: InterpreterAssembler(test->isolate(), test->zone(), bytecode) {} : InterpreterAssembler(test->isolate(), test->zone(), bytecode) {}
~InterpreterAssemblerForTest() override {} ~InterpreterAssemblerForTest() override {}
Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, Matcher<compiler::Node*> IsLoad(
const Matcher<Node*>& base_matcher, const Matcher<compiler::LoadRepresentation>& rep_matcher,
const Matcher<Node*>& index_matcher); const Matcher<compiler::Node*>& base_matcher,
Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, const Matcher<compiler::Node*>& index_matcher);
const Matcher<Node*>& base_matcher, Matcher<compiler::Node*> IsStore(
const Matcher<Node*>& index_matcher, const Matcher<compiler::StoreRepresentation>& rep_matcher,
const Matcher<Node*>& value_matcher); const Matcher<compiler::Node*>& base_matcher,
const Matcher<compiler::Node*>& index_matcher,
const Matcher<compiler::Node*>& value_matcher);
Matcher<compiler::Node*> IsBytecodeOperand(int offset);
Matcher<compiler::Node*> IsBytecodeOperandSignExtended(int offset);
Matcher<compiler::Node*> IsBytecodeOperandShort(int offset);
Matcher<compiler::Node*> IsBytecodeOperandShortSignExtended(int offset);
Matcher<Node*> IsBytecodeOperand(int offset);
Matcher<Node*> IsBytecodeOperandSignExtended(int offset);
Matcher<Node*> IsBytecodeOperandShort(int offset);
Matcher<Node*> IsBytecodeOperandShortSignExtended(int offset);
using InterpreterAssembler::call_descriptor;
using InterpreterAssembler::graph; using InterpreterAssembler::graph;
private: private:
...@@ -50,8 +50,8 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone { ...@@ -50,8 +50,8 @@ class InterpreterAssemblerTest : public TestWithIsolateAndZone {
}; };
}; };
} // namespace compiler } // namespace interpreter
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ #endif // V8_UNITTESTS_INTERPRETER_INTERPRETER_ASSEMBLER_UNITTEST_H_
...@@ -60,8 +60,6 @@ ...@@ -60,8 +60,6 @@
'compiler/instruction-selector-unittest.h', 'compiler/instruction-selector-unittest.h',
'compiler/instruction-sequence-unittest.cc', 'compiler/instruction-sequence-unittest.cc',
'compiler/instruction-sequence-unittest.h', 'compiler/instruction-sequence-unittest.h',
'compiler/interpreter-assembler-unittest.cc',
'compiler/interpreter-assembler-unittest.h',
'compiler/js-builtin-reducer-unittest.cc', 'compiler/js-builtin-reducer-unittest.cc',
'compiler/js-context-relaxation-unittest.cc', 'compiler/js-context-relaxation-unittest.cc',
'compiler/js-create-lowering-unittest.cc', 'compiler/js-create-lowering-unittest.cc',
...@@ -100,6 +98,8 @@ ...@@ -100,6 +98,8 @@
'interpreter/bytecode-array-iterator-unittest.cc', 'interpreter/bytecode-array-iterator-unittest.cc',
'interpreter/bytecode-register-allocator-unittest.cc', 'interpreter/bytecode-register-allocator-unittest.cc',
'interpreter/constant-array-builder-unittest.cc', 'interpreter/constant-array-builder-unittest.cc',
'interpreter/interpreter-assembler-unittest.cc',
'interpreter/interpreter-assembler-unittest.h',
'interpreter/register-translator-unittest.cc', 'interpreter/register-translator-unittest.cc',
'libplatform/default-platform-unittest.cc', 'libplatform/default-platform-unittest.cc',
'libplatform/task-queue-unittest.cc', 'libplatform/task-queue-unittest.cc',
......
...@@ -606,8 +606,6 @@ ...@@ -606,8 +606,6 @@
'../../src/compiler/instruction.h', '../../src/compiler/instruction.h',
'../../src/compiler/int64-lowering.cc', '../../src/compiler/int64-lowering.cc',
'../../src/compiler/int64-lowering.h', '../../src/compiler/int64-lowering.h',
'../../src/compiler/interpreter-assembler.cc',
'../../src/compiler/interpreter-assembler.h',
'../../src/compiler/js-builtin-reducer.cc', '../../src/compiler/js-builtin-reducer.cc',
'../../src/compiler/js-builtin-reducer.h', '../../src/compiler/js-builtin-reducer.h',
'../../src/compiler/js-call-reducer.cc', '../../src/compiler/js-call-reducer.cc',
...@@ -945,6 +943,8 @@ ...@@ -945,6 +943,8 @@
'../../src/interpreter/handler-table-builder.h', '../../src/interpreter/handler-table-builder.h',
'../../src/interpreter/interpreter.cc', '../../src/interpreter/interpreter.cc',
'../../src/interpreter/interpreter.h', '../../src/interpreter/interpreter.h',
'../../src/interpreter/interpreter-assembler.cc',
'../../src/interpreter/interpreter-assembler.h',
'../../src/interpreter/register-translator.cc', '../../src/interpreter/register-translator.cc',
'../../src/interpreter/register-translator.h', '../../src/interpreter/register-translator.h',
'../../src/interpreter/source-position-table.cc', '../../src/interpreter/source-position-table.cc',
......
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