[Interpreter] No longer require context machine register in bytecode handlers
The current context is stored as a stack slot on the interpreter frame and therefore we don't need to also maintain a machine register for the context. Removes this register from bytecode handlers. In the process modifies this frees up a register on ia32 to keep the dispatch table pointer in a register rather than on a stack slot on ia32. BUG=v8:4280 LOG=N Review URL: https://codereview.chromium.org/1887493004 Cr-Commit-Position: refs/heads/master@{#35511}
This commit is contained in:
parent
0e8d220e8b
commit
6dca319395
@ -1139,11 +1139,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ ldr(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ ldr(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -1088,11 +1088,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ Ldr(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ Ldr(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -409,12 +409,9 @@ CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor(
|
||||
int stack_parameter_count) {
|
||||
const int register_parameter_count = descriptor.GetRegisterParameterCount();
|
||||
const int parameter_count = register_parameter_count + stack_parameter_count;
|
||||
const int context_count = 1;
|
||||
const size_t parameter_and_context_count =
|
||||
static_cast<size_t>(parameter_count + context_count);
|
||||
|
||||
LocationSignature::Builder locations(zone, 0, parameter_and_context_count);
|
||||
MachineSignature::Builder types(zone, 0, parameter_and_context_count);
|
||||
LocationSignature::Builder locations(zone, 0, parameter_count);
|
||||
MachineSignature::Builder types(zone, 0, parameter_count);
|
||||
|
||||
// Add parameters in registers and on the stack.
|
||||
for (int i = 0; i < parameter_count; i++) {
|
||||
@ -432,9 +429,6 @@ CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor(
|
||||
types.AddParam(MachineType::AnyTagged());
|
||||
}
|
||||
}
|
||||
// Add context.
|
||||
locations.AddParam(regloc(kContextRegister));
|
||||
types.AddParam(MachineType::AnyTagged());
|
||||
|
||||
// The target for interpreter dispatches is a code entry address.
|
||||
MachineType target_type = MachineType::Pointer();
|
||||
|
@ -308,7 +308,7 @@ std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k);
|
||||
// Call[CodeStub] code, arg 1, arg 2, [...], context
|
||||
// Call[JSFunction] function, rcvr, arg 1, [...], new, #arg, context
|
||||
// Call[Runtime] CEntryStub, arg 1, arg 2, [...], fun, #arg, context
|
||||
// Call[BytecodeDispatch] address, arg 1, arg 2, [...], context
|
||||
// Call[BytecodeDispatch] address, arg 1, arg 2, [...]
|
||||
class Linkage : public ZoneObject {
|
||||
public:
|
||||
explicit Linkage(CallDescriptor* incoming) : incoming_(incoming) {}
|
||||
|
@ -597,21 +597,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
|
||||
__ mov(kInterpreterBytecodeOffsetRegister,
|
||||
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
|
||||
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Push dispatch table as a stack located parameter to the bytecode handler.
|
||||
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
|
||||
__ push(ebx);
|
||||
__ mov(kInterpreterDispatchTableRegister,
|
||||
Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Dispatch to the first bytecode handler for the function.
|
||||
__ movzx_b(eax, Operand(kInterpreterBytecodeArrayRegister,
|
||||
__ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterBytecodeOffsetRegister, times_1, 0));
|
||||
__ mov(ebx, Operand(ebx, eax, times_pointer_size, 0));
|
||||
// Restore undefined_value in accumulator (eax)
|
||||
// TODO(rmcilroy): Remove this once we move the dispatch table back into a
|
||||
// register.
|
||||
__ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
|
||||
__ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
|
||||
times_pointer_size, 0));
|
||||
__ call(ebx);
|
||||
|
||||
// Even though the first bytecode handler was called, we will never return.
|
||||
@ -737,10 +731,13 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
|
||||
|
||||
static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
// Initialize register file register.
|
||||
// Initialize register file register and dispatch table register.
|
||||
__ mov(kInterpreterRegisterFileRegister, ebp);
|
||||
__ add(kInterpreterRegisterFileRegister,
|
||||
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
|
||||
__ mov(kInterpreterDispatchTableRegister,
|
||||
Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ mov(kInterpreterBytecodeArrayRegister,
|
||||
@ -762,23 +759,11 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
|
||||
__ SmiUntag(kInterpreterBytecodeOffsetRegister);
|
||||
|
||||
// Push dispatch table as a stack located parameter to the bytecode handler.
|
||||
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
|
||||
__ Pop(esi);
|
||||
__ Push(ebx);
|
||||
__ Push(esi);
|
||||
|
||||
// Dispatch to the target bytecode.
|
||||
__ movzx_b(esi, Operand(kInterpreterBytecodeArrayRegister,
|
||||
__ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterBytecodeOffsetRegister, times_1, 0));
|
||||
__ mov(ebx, Operand(ebx, esi, times_pointer_size, 0));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ mov(kContextRegister,
|
||||
Operand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
__ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
|
||||
times_pointer_size, 0));
|
||||
__ jmp(ebx);
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,8 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
|
||||
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister };
|
||||
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,12 @@ const Register kInterpreterAccumulatorRegister = {Register::kCode_eax};
|
||||
const Register kInterpreterRegisterFileRegister = {Register::kCode_edx};
|
||||
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_ecx};
|
||||
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_edi};
|
||||
const Register kInterpreterDispatchTableRegister = {Register::kCode_esi};
|
||||
const Register kJavaScriptCallArgCountRegister = {Register::kCode_eax};
|
||||
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_edx};
|
||||
const Register kRuntimeCallFunctionRegister = {Register::kCode_ebx};
|
||||
const Register kRuntimeCallArgCountRegister = {Register::kCode_eax};
|
||||
|
||||
// Spill slots used by interpreter dispatch calling convention.
|
||||
const int kInterpreterDispatchTableSpillSlot = -1;
|
||||
|
||||
// Convenience for platform-independent signatures. We do not normally
|
||||
// distinguish memory operands from other operands on ia32.
|
||||
typedef Operand MemOperand;
|
||||
|
@ -33,13 +33,11 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
|
||||
operand_scale_(operand_scale),
|
||||
accumulator_(this, MachineRepresentation::kTagged),
|
||||
accumulator_use_(AccumulatorUse::kNone),
|
||||
context_(this, MachineRepresentation::kTagged),
|
||||
bytecode_array_(this, MachineRepresentation::kTagged),
|
||||
disable_stack_check_across_call_(false),
|
||||
stack_pointer_before_call_(nullptr) {
|
||||
accumulator_.Bind(
|
||||
Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter));
|
||||
context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter));
|
||||
bytecode_array_.Bind(
|
||||
Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter));
|
||||
if (FLAG_trace_ignition) {
|
||||
@ -70,11 +68,12 @@ void InterpreterAssembler::SetAccumulator(Node* value) {
|
||||
accumulator_.Bind(value);
|
||||
}
|
||||
|
||||
Node* InterpreterAssembler::GetContext() { return context_.value(); }
|
||||
Node* InterpreterAssembler::GetContext() {
|
||||
return LoadRegister(Register::current_context());
|
||||
}
|
||||
|
||||
void InterpreterAssembler::SetContext(Node* value) {
|
||||
StoreRegister(value, Register::current_context());
|
||||
context_.Bind(value);
|
||||
}
|
||||
|
||||
Node* InterpreterAssembler::BytecodeOffset() {
|
||||
@ -103,7 +102,7 @@ Node* InterpreterAssembler::LoadRegister(int offset) {
|
||||
}
|
||||
|
||||
Node* InterpreterAssembler::LoadRegister(Register reg) {
|
||||
return LoadRegister(IntPtrConstant(-reg.index()));
|
||||
return LoadRegister(-reg.index() << kPointerSizeLog2);
|
||||
}
|
||||
|
||||
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
|
||||
@ -581,8 +580,8 @@ void InterpreterAssembler::DispatchToBytecodeHandlerEntry(
|
||||
|
||||
InterpreterDispatchDescriptor descriptor(isolate());
|
||||
Node* args[] = {GetAccumulatorUnchecked(), RegisterFileRawPointer(),
|
||||
bytecode_offset, BytecodeArrayTaggedPointer(),
|
||||
DispatchTableRawPointer(), GetContext()};
|
||||
bytecode_offset, BytecodeArrayTaggedPointer(),
|
||||
DispatchTableRawPointer()};
|
||||
TailCallBytecodeDispatch(descriptor, handler_entry, args);
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,6 @@ class InterpreterAssembler : public compiler::CodeStubAssembler {
|
||||
OperandScale operand_scale_;
|
||||
CodeStubAssembler::Variable accumulator_;
|
||||
AccumulatorUse accumulator_use_;
|
||||
CodeStubAssembler::Variable context_;
|
||||
CodeStubAssembler::Variable bytecode_array_;
|
||||
|
||||
bool disable_stack_check_across_call_;
|
||||
|
@ -1135,11 +1135,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ lw(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ lw(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -1124,11 +1124,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ ld(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ ld(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -1150,11 +1150,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ LoadP(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ LoadP(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -1141,11 +1141,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
Operand(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ LoadP(kContextRegister,
|
||||
MemOperand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ LoadP(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -812,11 +812,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
kInterpreterDispatchTableRegister,
|
||||
ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ movp(kContextRegister,
|
||||
Operand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ movp(
|
||||
kInterpreterBytecodeArrayRegister,
|
||||
|
@ -600,21 +600,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
|
||||
__ mov(kInterpreterBytecodeOffsetRegister,
|
||||
Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
|
||||
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Push dispatch table as a stack located parameter to the bytecode handler.
|
||||
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
|
||||
__ push(ebx);
|
||||
__ mov(kInterpreterDispatchTableRegister,
|
||||
Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Dispatch to the first bytecode handler for the function.
|
||||
__ movzx_b(eax, Operand(kInterpreterBytecodeArrayRegister,
|
||||
__ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterBytecodeOffsetRegister, times_1, 0));
|
||||
__ mov(ebx, Operand(ebx, eax, times_pointer_size, 0));
|
||||
// Restore undefined_value in accumulator (eax)
|
||||
// TODO(rmcilroy): Remove this once we move the dispatch table back into a
|
||||
// register.
|
||||
__ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
|
||||
__ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
|
||||
times_pointer_size, 0));
|
||||
// TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
|
||||
// and header removal.
|
||||
__ add(ebx, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
@ -743,10 +737,13 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
|
||||
|
||||
|
||||
static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
// Initialize register file register.
|
||||
// Initialize register file register and dispatch table register.
|
||||
__ mov(kInterpreterRegisterFileRegister, ebp);
|
||||
__ add(kInterpreterRegisterFileRegister,
|
||||
Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
|
||||
__ mov(kInterpreterDispatchTableRegister,
|
||||
Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
|
||||
// Get the bytecode array pointer from the frame.
|
||||
__ mov(kInterpreterBytecodeArrayRegister,
|
||||
@ -768,23 +765,11 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
|
||||
InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
|
||||
__ SmiUntag(kInterpreterBytecodeOffsetRegister);
|
||||
|
||||
// Push dispatch table as a stack located parameter to the bytecode handler.
|
||||
__ mov(ebx, Immediate(ExternalReference::interpreter_dispatch_table_address(
|
||||
masm->isolate())));
|
||||
DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
|
||||
__ Pop(esi);
|
||||
__ Push(ebx);
|
||||
__ Push(esi);
|
||||
|
||||
// Dispatch to the target bytecode.
|
||||
__ movzx_b(esi, Operand(kInterpreterBytecodeArrayRegister,
|
||||
__ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterBytecodeOffsetRegister, times_1, 0));
|
||||
__ mov(ebx, Operand(ebx, esi, times_pointer_size, 0));
|
||||
|
||||
// Get the context from the frame.
|
||||
__ mov(kContextRegister,
|
||||
Operand(kInterpreterRegisterFileRegister,
|
||||
InterpreterFrameConstants::kContextFromRegisterPointer));
|
||||
__ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
|
||||
times_pointer_size, 0));
|
||||
|
||||
// TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
|
||||
// and header removal.
|
||||
|
@ -381,7 +381,8 @@ void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
|
||||
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister};
|
||||
kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
|
||||
kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ const Register kInterpreterAccumulatorRegister = {Register::kCode_eax};
|
||||
const Register kInterpreterRegisterFileRegister = {Register::kCode_edx};
|
||||
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_ecx};
|
||||
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_edi};
|
||||
const Register kInterpreterDispatchTableRegister = {Register::kCode_esi};
|
||||
const Register kJavaScriptCallArgCountRegister = {Register::kCode_eax};
|
||||
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_edx};
|
||||
const Register kRuntimeCallFunctionRegister = {Register::kCode_ebx};
|
||||
|
@ -346,8 +346,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) {
|
||||
next_bytecode_offset_matcher,
|
||||
IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter),
|
||||
IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
|
||||
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
|
||||
_));
|
||||
_, _));
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,8 +389,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
|
||||
next_bytecode_offset_matcher, _,
|
||||
IsParameter(
|
||||
InterpreterDispatchDescriptor::kDispatchTableParameter),
|
||||
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
|
||||
_));
|
||||
_, _));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,8 +439,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) {
|
||||
next_bytecode_offset_matcher, _,
|
||||
IsParameter(
|
||||
InterpreterDispatchDescriptor::kDispatchTableParameter),
|
||||
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
|
||||
_));
|
||||
_, _));
|
||||
}
|
||||
|
||||
// TODO(oth): test control flow paths.
|
||||
@ -477,8 +474,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) {
|
||||
InterpreterDispatchDescriptor::kBytecodeOffsetParameter),
|
||||
_,
|
||||
IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter),
|
||||
IsParameter(InterpreterDispatchDescriptor::kContextParameter), _,
|
||||
_));
|
||||
_, _));
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,12 +566,16 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
|
||||
TARGET_TEST_F(InterpreterAssemblerTest, GetContext) {
|
||||
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
|
||||
InterpreterAssemblerForTest m(this, bytecode);
|
||||
Node* context_node = m.Int32Constant(100);
|
||||
m.SetContext(context_node);
|
||||
EXPECT_THAT(m.GetContext(), context_node);
|
||||
EXPECT_THAT(
|
||||
m.GetContext(),
|
||||
m.IsLoad(
|
||||
MachineType::AnyTagged(),
|
||||
IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter),
|
||||
IsIntPtrConstant(-Register::current_context().index()
|
||||
<< kPointerSizeLog2)));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user