Commit 94add18b authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Add Construct node

Similar approach as Call (from RegisterList).

Bug: v8:7700
Change-Id: Ifc94e2bf53f40a8f556d30d85c2354f8d3a2af1b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3616502
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80275}
parent c7dfa3fa
...@@ -57,6 +57,7 @@ class MaglevCodeGenState { ...@@ -57,6 +57,7 @@ class MaglevCodeGenState {
} }
inline void DefineSafepointStackSlots( inline void DefineSafepointStackSlots(
SafepointTableBuilder::Safepoint& safepoint) const; SafepointTableBuilder::Safepoint& safepoint) const;
inline void DefineLazyDeoptPoint(LazyDeoptInfo* info);
compiler::NativeContextRef native_context() const { compiler::NativeContextRef native_context() const {
return broker()->target_native_context(); return broker()->target_native_context();
...@@ -162,6 +163,14 @@ inline void MaglevCodeGenState::DefineSafepointStackSlots( ...@@ -162,6 +163,14 @@ inline void MaglevCodeGenState::DefineSafepointStackSlots(
} }
} }
inline void MaglevCodeGenState::DefineLazyDeoptPoint(LazyDeoptInfo* info) {
info->deopting_call_return_pc = masm()->pc_offset_for_safepoint();
PushLazyDeopt(info);
SafepointTableBuilder::Safepoint safepoint =
safepoint_table_builder()->DefineSafepoint(masm());
DefineSafepointStackSlots(safepoint);
}
} // namespace maglev } // namespace maglev
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -947,7 +947,26 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntime) ...@@ -947,7 +947,26 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntime)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntimeForPair) MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntimeForPair)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallJSRuntime) MAGLEV_UNIMPLEMENTED_BYTECODE(CallJSRuntime)
MAGLEV_UNIMPLEMENTED_BYTECODE(InvokeIntrinsic) MAGLEV_UNIMPLEMENTED_BYTECODE(InvokeIntrinsic)
MAGLEV_UNIMPLEMENTED_BYTECODE(Construct)
void MaglevGraphBuilder::VisitConstruct() {
ValueNode* new_target = GetAccumulatorTagged();
ValueNode* constructor = LoadRegisterTagged(0);
interpreter::RegisterList args = iterator_.GetRegisterListOperand(1);
ValueNode* context = GetContext();
size_t input_count = args.register_count() + 1 + Construct::kFixedInputCount;
Construct* construct =
CreateNewNode<Construct>(input_count, constructor, new_target, context);
int arg_index = 0;
// Add undefined receiver.
construct->set_arg(arg_index++,
AddNewNode<RootConstant>({}, RootIndex::kUndefinedValue));
for (int i = 0; i < args.register_count(); i++) {
construct->set_arg(arg_index++, GetTaggedValue(args[i]));
}
SetAccumulator(AddNode(construct));
}
MAGLEV_UNIMPLEMENTED_BYTECODE(ConstructWithSpread) MAGLEV_UNIMPLEMENTED_BYTECODE(ConstructWithSpread)
void MaglevGraphBuilder::VisitTestEqual() { void MaglevGraphBuilder::VisitTestEqual() {
......
...@@ -148,6 +148,7 @@ class MaglevGraphVerifier { ...@@ -148,6 +148,7 @@ class MaglevGraphVerifier {
CheckValueInputIs(node, 1, ValueRepresentation::kFloat64); CheckValueInputIs(node, 1, ValueRepresentation::kFloat64);
break; break;
case Opcode::kCall: case Opcode::kCall:
case Opcode::kConstruct:
case Opcode::kPhi: case Opcode::kPhi:
// All inputs should be tagged. // All inputs should be tagged.
for (int i = 0; i < node->input_count(); i++) { for (int i = 0; i < node->input_count(); i++) {
......
...@@ -983,13 +983,38 @@ void Call::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -983,13 +983,38 @@ void Call::GenerateCode(MaglevCodeGenState* code_gen_state,
break; break;
} }
lazy_deopt_info()->deopting_call_return_pc = __ pc_offset_for_safepoint(); code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
code_gen_state->PushLazyDeopt(lazy_deopt_info()); }
void Construct::AllocateVreg(MaglevVregAllocationState* vreg_state,
const ProcessingState& state) {
using D = ConstructStubDescriptor;
UseFixed(function(), D::GetRegisterParameter(D::kTarget));
UseFixed(new_target(), D::GetRegisterParameter(D::kNewTarget));
UseFixed(context(), kContextRegister);
for (int i = 0; i < num_args(); i++) {
UseAny(arg(i));
}
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void Construct::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
using D = ConstructStubDescriptor;
DCHECK_EQ(ToRegister(function()), D::GetRegisterParameter(D::kTarget));
DCHECK_EQ(ToRegister(new_target()), D::GetRegisterParameter(D::kNewTarget));
DCHECK_EQ(ToRegister(context()), kContextRegister);
for (int i = num_args() - 1; i >= 0; --i) {
PushInput(code_gen_state, arg(i));
}
uint32_t arg_count = num_args();
__ Move(D::GetRegisterParameter(D::kActualArgumentsCount),
Immediate(arg_count));
__ CallBuiltin(Builtin::kConstruct);
SafepointTableBuilder::Safepoint safepoint = code_gen_state->DefineLazyDeoptPoint(lazy_deopt_info());
code_gen_state->safepoint_table_builder()->DefineSafepoint(
code_gen_state->masm());
code_gen_state->DefineSafepointStackSlots(safepoint);
} }
// --- // ---
......
...@@ -68,6 +68,7 @@ class CompactInterpreterFrameState; ...@@ -68,6 +68,7 @@ class CompactInterpreterFrameState;
#define VALUE_NODE_LIST(V) \ #define VALUE_NODE_LIST(V) \
V(Call) \ V(Call) \
V(Constant) \ V(Constant) \
V(Construct) \
V(CreateEmptyArrayLiteral) \ V(CreateEmptyArrayLiteral) \
V(InitialValue) \ V(InitialValue) \
V(LoadTaggedField) \ V(LoadTaggedField) \
...@@ -1544,6 +1545,45 @@ class Call : public ValueNodeT<Call> { ...@@ -1544,6 +1545,45 @@ class Call : public ValueNodeT<Call> {
ConvertReceiverMode receiver_mode_; ConvertReceiverMode receiver_mode_;
}; };
class Construct : public ValueNodeT<Construct> {
using Base = ValueNodeT<Construct>;
public:
// We assume function and context as fixed inputs.
static constexpr int kFunctionIndex = 0;
static constexpr int kNewTargetIndex = 1;
static constexpr int kContextIndex = 2;
static constexpr int kFixedInputCount = 3;
// This ctor is used when for variable input counts.
// Inputs must be initialized manually.
Construct(uint32_t bitfield, ValueNode* function, ValueNode* new_target,
ValueNode* context)
: Base(bitfield) {
set_input(kFunctionIndex, function);
set_input(kNewTargetIndex, new_target);
set_input(kContextIndex, context);
}
static constexpr OpProperties kProperties = OpProperties::JSCall();
Input& function() { return input(kFunctionIndex); }
const Input& function() const { return input(kFunctionIndex); }
Input& new_target() { return input(kNewTargetIndex); }
const Input& new_target() const { return input(kNewTargetIndex); }
Input& context() { return input(kContextIndex); }
const Input& context() const { return input(kContextIndex); }
int num_args() const { return input_count() - kFixedInputCount; }
Input& arg(int i) { return input(i + kFixedInputCount); }
void set_arg(int i, ValueNode* node) {
set_input(i + kFixedInputCount, node);
}
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
// Represents either a direct BasicBlock pointer, or an entry in a list of // Represents either a direct BasicBlock pointer, or an entry in a list of
// unresolved BasicBlockRefs which will be mutated (in place) at some point into // unresolved BasicBlockRefs which will be mutated (in place) at some point into
// direct BasicBlock pointers. // direct BasicBlock pointers.
......
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