Commit ff24879a authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[CSA] TNodify dispatch, RegisterFile and context methods

TNodified:
 * code-assembler
   * TailCallBytecodeDispatch
 * interpreter-assembler
   * GetContextAtDepth
   * ExportParametersAndRegisterFile
   * ImportRegisterFile
   * Dispatch
   * DispatchToBytecode
   * DispatchToBytecodeHandlerEntry
   * DispatchWide
   * return type of Jump (Jumps are coming in another CL)
   * LoadBytecode

Removed DispatchToBytecodeHandler since it was unused.
Removed target_bytecode parameter of DispatchToBytecodeHandlerEntry
since it was unused.

Bug: v8:6949
Change-Id: Icd3ded28cc1fd1dc528219dd83cf646e67c9b878
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1782838
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63577}
parent f56b9236
......@@ -1369,7 +1369,7 @@ Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode,
inputs.data());
}
Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
void CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
std::initializer_list<Node*> args) {
constexpr size_t kMaxNumArgs = 6;
......@@ -1389,33 +1389,33 @@ Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
for (auto arg : args) inputs.Add(arg);
inputs.Add(context);
return raw_assembler()->TailCallN(call_descriptor, inputs.size(),
inputs.data());
raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
}
template <class... TArgs>
Node* CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, TArgs... args) {
void CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target,
TArgs... args) {
DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args));
auto call_descriptor = Linkage::GetBytecodeDispatchCallDescriptor(
zone(), descriptor, descriptor.GetStackParameterCount());
Node* nodes[] = {target, args...};
CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes));
return raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
}
// Instantiate TailCallBytecodeDispatch() for argument counts used by
// CSA-generated code
template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, TNode<Object>,
Node*, TNode<BytecodeArray>, TNode<ExternalReference>);
TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code,
TNode<Context> context,
TNode<JSFunction> function,
TNode<Object> new_target,
TNode<Int32T> arg_count) {
template V8_EXPORT_PRIVATE void CodeAssembler::TailCallBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target,
TNode<Object>, TNode<IntPtrT>, TNode<BytecodeArray>,
TNode<ExternalReference>);
void CodeAssembler::TailCallJSCode(TNode<Code> code, TNode<Context> context,
TNode<JSFunction> function,
TNode<Object> new_target,
TNode<Int32T> arg_count) {
JSTrampolineDescriptor descriptor;
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, descriptor.GetStackParameterCount(),
......@@ -1423,8 +1423,7 @@ TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code,
Node* nodes[] = {code, function, new_target, arg_count, context};
CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
return UncheckedCast<Object>(
raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes));
raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
}
Node* CodeAssembler::CallCFunctionN(Signature<MachineType>* signature,
......
......@@ -1367,26 +1367,26 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void TailCallStub(Callable const& callable, SloppyTNode<Object> context,
TArgs... args) {
TNode<Code> target = HeapConstant(callable.code());
return TailCallStub(callable.descriptor(), target, context, args...);
TailCallStub(callable.descriptor(), target, context, args...);
}
template <class... TArgs>
void TailCallStub(const CallInterfaceDescriptor& descriptor,
SloppyTNode<Code> target, SloppyTNode<Object> context,
TArgs... args) {
return TailCallStubImpl(descriptor, target, context, {args...});
TailCallStubImpl(descriptor, target, context, {args...});
}
template <class... TArgs>
Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
Node* target, TArgs... args);
void TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
TNode<RawPtrT> target, TArgs... args);
template <class... TArgs>
Node* TailCallStubThenBytecodeDispatch(
void TailCallStubThenBytecodeDispatch(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
TArgs... args) {
return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
{args...});
TailCallStubThenBytecodeDispatchImpl(descriptor, target, context,
{args...});
}
// Tailcalls to the given code object with JSCall linkage. The JS arguments
......@@ -1396,10 +1396,9 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Note that no arguments adaption is going on here - all the JavaScript
// arguments are left on the stack unmodified. Therefore, this tail call can
// only be used after arguments adaptation has been performed already.
TNode<Object> TailCallJSCode(TNode<Code> code, TNode<Context> context,
TNode<JSFunction> function,
TNode<Object> new_target,
TNode<Int32T> arg_count);
void TailCallJSCode(TNode<Code> code, TNode<Context> context,
TNode<JSFunction> function, TNode<Object> new_target,
TNode<Int32T> arg_count);
template <class... TArgs>
Node* CallJS(Callable const& callable, Node* context, Node* function,
......@@ -1515,7 +1514,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<Code> target, TNode<Object> context,
std::initializer_list<Node*> args);
Node* TailCallStubThenBytecodeDispatchImpl(
void TailCallStubThenBytecodeDispatchImpl(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
std::initializer_list<Node*> args);
......
......@@ -690,15 +690,14 @@ Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* call_descriptor,
return AddNode(common()->Call(call_descriptor), input_count, inputs);
}
Node* RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor,
int input_count, Node* const* inputs) {
void RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor,
int input_count, Node* const* inputs) {
// +1 is for target.
DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1);
Node* tail_call =
MakeNode(common()->TailCall(call_descriptor), input_count, inputs);
schedule()->AddTailCall(CurrentBlock(), tail_call);
current_block_ = nullptr;
return tail_call;
}
namespace {
......
......@@ -965,8 +965,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
// Tail call a given call descriptor and the given arguments.
// The call target is passed as part of the {inputs} array.
Node* TailCallN(CallDescriptor* call_descriptor, int input_count,
Node* const* inputs);
void TailCallN(CallDescriptor* call_descriptor, int input_count,
Node* const* inputs);
// Type representing C function argument with type info.
using CFunctionArg = std::pair<MachineType, Node*>;
......
......@@ -174,15 +174,16 @@ void InterpreterAssembler::SetContext(TNode<Context> value) {
StoreRegister(value, Register::current_context());
}
Node* InterpreterAssembler::GetContextAtDepth(TNode<Context> context,
TNode<Uint32T> depth) {
TNode<Context> InterpreterAssembler::GetContextAtDepth(TNode<Context> context,
TNode<Uint32T> depth) {
TVARIABLE(Context, cur_context, context);
TVARIABLE(Uint32T, cur_depth, depth);
Label context_found(this);
Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context};
Label context_search(this, 2, context_search_loop_variables);
VariableList context_search_loop_variables({&cur_depth, &cur_context},
zone());
Label context_search(this, context_search_loop_variables);
// Fast path if the depth is 0.
Branch(Word32Equal(depth, Int32Constant(0)), &context_found, &context_search);
......@@ -1340,20 +1341,19 @@ TNode<IntPtrT> InterpreterAssembler::Advance(SloppyTNode<IntPtrT> delta,
return next_offset;
}
Node* InterpreterAssembler::Jump(Node* delta, bool backward) {
void InterpreterAssembler::Jump(Node* delta, bool backward) {
DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_));
UpdateInterruptBudget(TruncateIntPtrToInt32(delta), backward);
Node* new_bytecode_offset = Advance(delta, backward);
TNode<WordT> target_bytecode = LoadBytecode(new_bytecode_offset);
return DispatchToBytecode(target_bytecode, new_bytecode_offset);
TNode<IntPtrT> new_bytecode_offset = Advance(delta, backward);
TNode<RawPtrT> target_bytecode =
UncheckedCast<RawPtrT>(LoadBytecode(new_bytecode_offset));
DispatchToBytecode(target_bytecode, new_bytecode_offset);
}
Node* InterpreterAssembler::Jump(Node* delta) { return Jump(delta, false); }
void InterpreterAssembler::Jump(Node* delta) { Jump(delta, false); }
Node* InterpreterAssembler::JumpBackward(Node* delta) {
return Jump(delta, true);
}
void InterpreterAssembler::JumpBackward(Node* delta) { Jump(delta, true); }
void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) {
Label match(this), no_match(this);
......@@ -1376,9 +1376,10 @@ void InterpreterAssembler::JumpIfTaggedNotEqual(TNode<Object> lhs,
JumpConditional(TaggedNotEqual(lhs, rhs), delta);
}
TNode<WordT> InterpreterAssembler::LoadBytecode(Node* bytecode_offset) {
Node* bytecode =
Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), bytecode_offset);
TNode<WordT> InterpreterAssembler::LoadBytecode(
TNode<IntPtrT> bytecode_offset) {
TNode<Uint8T> bytecode =
Load<Uint8T>(BytecodeArrayTaggedPointer(), bytecode_offset);
return ChangeUint32ToWord(bytecode);
}
......@@ -1424,50 +1425,39 @@ void InterpreterAssembler::InlineStar() {
accumulator_use_ = previous_acc_use;
}
Node* InterpreterAssembler::Dispatch() {
void InterpreterAssembler::Dispatch() {
Comment("========= Dispatch");
DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_);
Node* target_offset = Advance();
TNode<IntPtrT> target_offset = Advance();
TNode<WordT> target_bytecode = LoadBytecode(target_offset);
if (Bytecodes::IsStarLookahead(bytecode_, operand_scale_)) {
target_bytecode = StarDispatchLookahead(target_bytecode);
}
return DispatchToBytecode(target_bytecode, BytecodeOffset());
DispatchToBytecode(target_bytecode, BytecodeOffset());
}
Node* InterpreterAssembler::DispatchToBytecode(Node* target_bytecode,
Node* new_bytecode_offset) {
void InterpreterAssembler::DispatchToBytecode(
TNode<WordT> target_bytecode, TNode<IntPtrT> new_bytecode_offset) {
if (FLAG_trace_ignition_dispatches) {
TraceBytecodeDispatch(target_bytecode);
}
Node* target_code_entry = Load(MachineType::Pointer(), DispatchTablePointer(),
TimesSystemPointerSize(target_bytecode));
return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset,
target_bytecode);
}
TNode<RawPtrT> target_code_entry = Load<RawPtrT>(
DispatchTablePointer(), TimesSystemPointerSize(target_bytecode));
Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler,
Node* bytecode_offset,
Node* target_bytecode) {
// TODO(ishell): Add CSA::CodeEntryPoint(code).
TNode<IntPtrT> handler_entry =
IntPtrAdd(BitcastTaggedToWord(handler),
IntPtrConstant(Code::kHeaderSize - kHeapObjectTag));
return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset,
target_bytecode);
DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset);
}
Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry(
Node* handler_entry, Node* bytecode_offset, Node* target_bytecode) {
void InterpreterAssembler::DispatchToBytecodeHandlerEntry(
TNode<RawPtrT> handler_entry, TNode<IntPtrT> bytecode_offset) {
// Propagate speculation poisoning.
TNode<WordT> poisoned_handler_entry = WordPoisonOnSpeculation(handler_entry);
return TailCallBytecodeDispatch(
InterpreterDispatchDescriptor{}, poisoned_handler_entry,
GetAccumulatorUnchecked(), bytecode_offset, BytecodeArrayTaggedPointer(),
DispatchTablePointer());
TNode<RawPtrT> poisoned_handler_entry =
UncheckedCast<RawPtrT>(WordPoisonOnSpeculation(handler_entry));
TailCallBytecodeDispatch(InterpreterDispatchDescriptor{},
poisoned_handler_entry, GetAccumulatorUnchecked(),
bytecode_offset, BytecodeArrayTaggedPointer(),
DispatchTablePointer());
}
void InterpreterAssembler::DispatchWide(OperandScale operand_scale) {
......@@ -1479,7 +1469,7 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) {
// Indices 256-511 correspond to bytecodes with operand_scale == 1
// Indices 512-767 correspond to bytecodes with operand_scale == 2
DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_);
Node* next_bytecode_offset = Advance(1);
TNode<IntPtrT> next_bytecode_offset = Advance(1);
TNode<WordT> next_bytecode = LoadBytecode(next_bytecode_offset);
if (FLAG_trace_ignition_dispatches) {
......@@ -1498,11 +1488,10 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) {
UNREACHABLE();
}
TNode<WordT> target_index = IntPtrAdd(base_index, next_bytecode);
Node* target_code_entry = Load(MachineType::Pointer(), DispatchTablePointer(),
TimesSystemPointerSize(target_index));
TNode<RawPtrT> target_code_entry = Load<RawPtrT>(
DispatchTablePointer(), TimesSystemPointerSize(target_index));
DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset,
next_bytecode);
DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset);
}
void InterpreterAssembler::UpdateInterruptBudgetOnReturn() {
......@@ -1637,7 +1626,7 @@ void InterpreterAssembler::AbortIfRegisterCountInvalid(
BIND(&ok);
}
Node* InterpreterAssembler::ExportParametersAndRegisterFile(
TNode<FixedArray> InterpreterAssembler::ExportParametersAndRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count) {
// Store the formal parameters (without receiver) followed by the
......@@ -1653,8 +1642,8 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
}
{
Variable var_index(this, MachineType::PointerRepresentation());
var_index.Bind(IntPtrConstant(0));
TVARIABLE(WordT, var_index);
var_index = IntPtrConstant(0);
// Iterate over parameters and write them into the array.
Label loop(this, &var_index), done_loop(this);
......@@ -1666,7 +1655,7 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
Goto(&loop);
BIND(&loop);
{
Node* index = var_index.value();
TNode<WordT> index = var_index.value();
GotoIfNot(UintPtrLessThan(index, formal_parameter_count_intptr),
&done_loop);
......@@ -1675,7 +1664,7 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
StoreFixedArrayElement(array, index, value);
var_index.Bind(IntPtrAdd(index, IntPtrConstant(1)));
var_index = IntPtrAdd(index, IntPtrConstant(1));
Goto(&loop);
}
BIND(&done_loop);
......@@ -1685,14 +1674,14 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
// Iterate over register file and write values into array.
// The mapping of register to array index must match that used in
// BytecodeGraphBuilder::VisitResumeGenerator.
Variable var_index(this, MachineType::PointerRepresentation());
var_index.Bind(IntPtrConstant(0));
TVARIABLE(WordT, var_index);
var_index = IntPtrConstant(0);
Label loop(this, &var_index), done_loop(this);
Goto(&loop);
BIND(&loop);
{
Node* index = var_index.value();
TNode<WordT> index = var_index.value();
GotoIfNot(UintPtrLessThan(index, register_count), &done_loop);
TNode<WordT> reg_index =
......@@ -1703,7 +1692,7 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
IntPtrAdd(formal_parameter_count_intptr, index);
StoreFixedArrayElement(array, array_index, value);
var_index.Bind(IntPtrAdd(index, IntPtrConstant(1)));
var_index = IntPtrAdd(index, IntPtrConstant(1));
Goto(&loop);
}
BIND(&done_loop);
......@@ -1712,7 +1701,7 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile(
return array;
}
Node* InterpreterAssembler::ImportRegisterFile(
TNode<FixedArray> InterpreterAssembler::ImportRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count) {
TNode<IntPtrT> formal_parameter_count_intptr =
......
......@@ -75,8 +75,8 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
void SetContext(compiler::TNode<Context> value);
// Context at |depth| in the context chain starting at |context|.
compiler::Node* GetContextAtDepth(compiler::TNode<Context> context,
compiler::TNode<Uint32T> depth);
compiler::TNode<Context> GetContextAtDepth(compiler::TNode<Context> context,
compiler::TNode<Uint32T> depth);
// Goto the given |target| if the context chain starting at |context| has any
// extensions up to the given |depth|.
......@@ -105,12 +105,12 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// - Suspend copies arguments and registers to the generator.
// - Resume copies only the registers from the generator, the arguments
// are copied by the ResumeGenerator trampoline.
compiler::Node* ExportParametersAndRegisterFile(
compiler::TNode<FixedArray> ExportParametersAndRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
compiler::TNode<FixedArray> ImportRegisterFile(
TNode<FixedArray> array, const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
compiler::Node* ImportRegisterFile(TNode<FixedArray> array,
const RegListNodePair& registers,
TNode<Int32T> formal_parameter_count);
// Loads from and stores to the interpreter register file.
compiler::TNode<Object> LoadRegister(Register reg);
......@@ -221,10 +221,10 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
int return_size = 1);
// Jump forward relative to the current bytecode by the |jump_offset|.
compiler::Node* Jump(compiler::Node* jump_offset);
void Jump(compiler::Node* jump_offset);
// Jump backward relative to the current bytecode by the |jump_offset|.
compiler::Node* JumpBackward(compiler::Node* jump_offset);
void JumpBackward(compiler::Node* jump_offset);
// Jump forward relative to the current bytecode by |jump_offset| if the
// word values |lhs| and |rhs| are equal.
......@@ -245,15 +245,15 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
compiler::Node* LoadOsrNestingLevel();
// Dispatch to the bytecode.
compiler::Node* Dispatch();
void Dispatch();
// Dispatch bytecode as wide operand variant.
void DispatchWide(OperandScale operand_scale);
// Dispatch to |target_bytecode| at |new_bytecode_offset|.
// |target_bytecode| should be equivalent to loading from the offset.
compiler::Node* DispatchToBytecode(compiler::Node* target_bytecode,
compiler::Node* new_bytecode_offset);
void DispatchToBytecode(compiler::TNode<WordT> target_bytecode,
compiler::TNode<IntPtrT> new_bytecode_offset);
// Abort with the given abort reason.
void Abort(AbortReason abort_reason);
......@@ -376,7 +376,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Jump relative to the current bytecode by the |jump_offset|. If |backward|,
// then jump backward (subtract the offset), otherwise jump forward (add the
// offset). Helper function for Jump and JumpBackward.
compiler::Node* Jump(compiler::Node* jump_offset, bool backward);
void Jump(compiler::Node* jump_offset, bool backward);
// Jump forward relative to the current bytecode by |jump_offset| if the
// |condition| is true. Helper function for JumpIfTaggedEqual and
......@@ -398,7 +398,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
TNode<IntPtrT> Advance(SloppyTNode<IntPtrT> delta, bool backward = false);
// Load the bytecode at |bytecode_offset|.
compiler::TNode<WordT> LoadBytecode(compiler::Node* bytecode_offset);
compiler::TNode<WordT> LoadBytecode(compiler::TNode<IntPtrT> bytecode_offset);
// Look ahead for Star and inline it in a branch. Returns a new target
// bytecode node for dispatch.
......@@ -409,15 +409,9 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// next dispatch offset.
void InlineStar();
// Dispatch to the bytecode handler with code offset |handler|.
compiler::Node* DispatchToBytecodeHandler(compiler::Node* handler,
compiler::Node* bytecode_offset,
compiler::Node* target_bytecode);
// Dispatch to the bytecode handler with code entry point |handler_entry|.
compiler::Node* DispatchToBytecodeHandlerEntry(
compiler::Node* handler_entry, compiler::Node* bytecode_offset,
compiler::Node* target_bytecode);
void DispatchToBytecodeHandlerEntry(compiler::TNode<RawPtrT> handler_entry,
compiler::TNode<IntPtrT> bytecode_offset);
int CurrentBytecodeSize() const;
......
......@@ -310,44 +310,6 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoadRegisterOperand(
LoadSensitivity::kCritical));
}
TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
// If debug code is enabled we emit extra code in Jump.
if (FLAG_debug_code) return;
int jump_offsets[] = {-9710, -77, 0, +3, +97109};
TRACED_FOREACH(int, jump_offset, jump_offsets) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
if (!interpreter::Bytecodes::IsJump(bytecode)) return;
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset));
Matcher<Node*> next_bytecode_offset_matcher = c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
c::IsIntPtrConstant(jump_offset));
Matcher<Node*> target_bytecode_matcher =
m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher);
target_bytecode_matcher =
c::IsChangeUint32ToWord(target_bytecode_matcher);
Matcher<Node*> code_target_matcher = m.IsLoad(
MachineType::Pointer(),
c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable),
c::IsWordShl(target_bytecode_matcher,
c::IsIntPtrConstant(kSystemPointerSizeLog2)));
EXPECT_THAT(
tail_call_node,
c::IsTailCall(
_, code_target_matcher,
c::IsParameter(InterpreterDispatchDescriptor::kAccumulator),
next_bytecode_offset_matcher, _,
c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable), _,
_));
}
}
}
TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
static const OperandScale kOperandScales[] = {
OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple};
......
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