[maglev] Support CreateArrayLiteral

Also changes CreateObjectLiteral to take the boilerplate as a constant
value, not a node.

Bug: v8:7700
Change-Id: I6852c7c4b8d361f903155c513e627ebc1af4d2f6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3758223
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81687}
This commit is contained in:
Leszek Swirski 2022-07-12 15:58:14 +02:00 committed by V8 LUCI CQ
parent e5b9fae45d
commit 8d52262b59
4 changed files with 165 additions and 43 deletions

View File

@ -1480,7 +1480,30 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(ToNumeric)
MAGLEV_UNIMPLEMENTED_BYTECODE(ToObject)
MAGLEV_UNIMPLEMENTED_BYTECODE(ToString)
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateRegExpLiteral)
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateArrayLiteral)
void MaglevGraphBuilder::VisitCreateArrayLiteral() {
compiler::HeapObjectRef constant_elements = GetRefOperand<HeapObject>(0);
FeedbackSlot slot_index = GetSlotOperand(1);
int bytecode_flags = GetFlagOperand(2);
int literal_flags =
interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
ValueNode* result;
if (interpreter::CreateArrayLiteralFlags::FastCloneSupportedBit::decode(
bytecode_flags)) {
// TODO(victorgomes): CreateShallowArrayLiteral should not need the
// boilerplate descriptor. However the current builtin checks that the
// feedback exists and fallsback to CreateArrayLiteral if it doesn't.
result = AddNewNode<CreateShallowArrayLiteral>(
{}, constant_elements, compiler::FeedbackSource{feedback(), slot_index},
literal_flags);
} else {
result = AddNewNode<CreateArrayLiteral>(
{}, constant_elements, compiler::FeedbackSource{feedback(), slot_index},
literal_flags);
}
SetAccumulator(result);
}
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateArrayFromIterable)
void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() {
@ -1491,8 +1514,8 @@ void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() {
}
void MaglevGraphBuilder::VisitCreateObjectLiteral() {
ValueNode* boilerplate_desc =
GetConstant(GetRefOperand<ObjectBoilerplateDescription>(0));
compiler::ObjectBoilerplateDescriptionRef boilerplate_desc =
GetRefOperand<ObjectBoilerplateDescription>(0);
FeedbackSlot slot_index = GetSlotOperand(1);
int bytecode_flags = GetFlagOperand(2);
int literal_flags =
@ -1504,12 +1527,12 @@ void MaglevGraphBuilder::VisitCreateObjectLiteral() {
// boilerplate descriptor. However the current builtin checks that the
// feedback exists and fallsback to CreateObjectLiteral if it doesn't.
result = AddNewNode<CreateShallowObjectLiteral>(
{boilerplate_desc}, literal_flags,
compiler::FeedbackSource{feedback(), slot_index});
{}, boilerplate_desc, compiler::FeedbackSource{feedback(), slot_index},
literal_flags);
} else {
result = AddNewNode<CreateObjectLiteral>(
{boilerplate_desc}, literal_flags,
compiler::FeedbackSource{feedback(), slot_index});
{}, boilerplate_desc, compiler::FeedbackSource{feedback(), slot_index},
literal_flags);
}
SetAccumulator(result);
}

View File

@ -63,6 +63,10 @@ class MaglevGraphVerifier {
case Opcode::kConstant:
case Opcode::kConstantGapMove:
case Opcode::kCreateEmptyArrayLiteral:
case Opcode::kCreateArrayLiteral:
case Opcode::kCreateShallowArrayLiteral:
case Opcode::kCreateObjectLiteral:
case Opcode::kCreateShallowObjectLiteral:
case Opcode::kDeopt:
case Opcode::kFloat64Constant:
case Opcode::kGapMove:
@ -98,8 +102,6 @@ class MaglevGraphVerifier {
case Opcode::kBranchIfToBooleanTrue:
case Opcode::kBranchIfTrue:
case Opcode::kCheckedFloat64Unbox:
case Opcode::kCreateObjectLiteral:
case Opcode::kCreateShallowObjectLiteral:
case Opcode::kCreateFunctionContext:
case Opcode::kCreateClosure:
case Opcode::kFastCreateClosure:

View File

@ -604,35 +604,62 @@ void CreateEmptyArrayLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
__ CallBuiltin(Builtin::kCreateEmptyArrayLiteral);
}
void CreateArrayLiteral::AllocateVreg(MaglevVregAllocationState* vreg_state) {
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CreateArrayLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
__ Move(kContextRegister, code_gen_state->native_context().object());
__ Push(feedback().vector);
__ Push(TaggedIndex::FromIntptr(feedback().index()));
__ Push(constant_elements().object());
__ Push(Smi::FromInt(flags()));
__ CallRuntime(Runtime::kCreateArrayLiteral);
}
void CreateShallowArrayLiteral::AllocateVreg(
MaglevVregAllocationState* vreg_state) {
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CreateShallowArrayLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
using D = CreateShallowArrayLiteralDescriptor;
__ Move(D::ContextRegister(), code_gen_state->native_context().object());
__ Move(D::GetRegisterParameter(D::kMaybeFeedbackVector), feedback().vector);
__ Move(D::GetRegisterParameter(D::kSlot),
TaggedIndex::FromIntptr(feedback().index()));
__ Move(D::GetRegisterParameter(D::kConstantElements),
constant_elements().object());
__ Move(D::GetRegisterParameter(D::kFlags), Smi::FromInt(flags()));
__ CallBuiltin(Builtin::kCreateShallowArrayLiteral);
}
void CreateObjectLiteral::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(boilerplate_descriptor());
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CreateObjectLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
__ Move(kContextRegister, code_gen_state->native_context().object());
__ Push(feedback().vector);
__ Push(Smi::FromInt(feedback().index()));
__ Push(ToRegister(boilerplate_descriptor()));
__ Push(TaggedIndex::FromIntptr(feedback().index()));
__ Push(boilerplate_descriptor().object());
__ Push(Smi::FromInt(flags()));
__ CallRuntime(Runtime::kCreateObjectLiteral);
}
void CreateShallowObjectLiteral::AllocateVreg(
MaglevVregAllocationState* vreg_state) {
using D = CreateShallowObjectLiteralDescriptor;
UseFixed(boilerplate_descriptor(), D::GetRegisterParameter(D::kDesc));
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CreateShallowObjectLiteral::GenerateCode(
MaglevCodeGenState* code_gen_state, const ProcessingState& state) {
using D = CreateShallowObjectLiteralDescriptor;
DCHECK_EQ(ToRegister(boilerplate_descriptor()),
D::GetRegisterParameter(D::kDesc));
__ Move(kContextRegister, code_gen_state->native_context().object());
__ Move(D::GetRegisterParameter(D::kFlags), Smi::FromInt(flags()));
__ Move(D::GetRegisterParameter(D::kSlot), Smi::FromInt(feedback().index()));
__ Move(D::ContextRegister(), code_gen_state->native_context().object());
__ Move(D::GetRegisterParameter(D::kMaybeFeedbackVector), feedback().vector);
__ Move(D::GetRegisterParameter(D::kSlot),
TaggedIndex::FromIntptr(feedback().index()));
__ Move(D::GetRegisterParameter(D::kDesc), boilerplate_descriptor().object());
__ Move(D::GetRegisterParameter(D::kFlags), Smi::FromInt(flags()));
__ CallBuiltin(Builtin::kCreateShallowObjectLiteral);
}

View File

@ -118,6 +118,8 @@ class CompactInterpreterFrameState;
V(Call) \
V(Construct) \
V(CreateEmptyArrayLiteral) \
V(CreateArrayLiteral) \
V(CreateShallowArrayLiteral) \
V(CreateObjectLiteral) \
V(CreateShallowObjectLiteral) \
V(CreateFunctionContext) \
@ -1657,22 +1659,22 @@ class CreateEmptyArrayLiteral
const compiler::FeedbackSource feedback_;
};
class CreateObjectLiteral
: public FixedInputValueNodeT<1, CreateObjectLiteral> {
using Base = FixedInputValueNodeT<1, CreateObjectLiteral>;
class CreateArrayLiteral : public FixedInputValueNodeT<0, CreateArrayLiteral> {
using Base = FixedInputValueNodeT<0, CreateArrayLiteral>;
public:
explicit CreateObjectLiteral(uint64_t bitfield, int flags,
const compiler::FeedbackSource& feedback)
: Base(bitfield), flags_(flags), feedback_(feedback) {}
explicit CreateArrayLiteral(uint64_t bitfield,
const compiler::HeapObjectRef& constant_elements,
const compiler::FeedbackSource& feedback,
int flags)
: Base(bitfield),
constant_elements_(constant_elements),
feedback_(feedback),
flags_(flags) {}
static constexpr int kObjectBoilerplateDescription = 0;
Input& boilerplate_descriptor() {
return input(kObjectBoilerplateDescription);
}
int flags() const { return flags_; }
compiler::HeapObjectRef constant_elements() { return constant_elements_; }
compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call();
@ -1682,28 +1684,95 @@ class CreateObjectLiteral
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private:
const int flags_;
const compiler::HeapObjectRef constant_elements_;
const compiler::FeedbackSource feedback_;
const int flags_;
};
class CreateShallowArrayLiteral
: public FixedInputValueNodeT<0, CreateShallowArrayLiteral> {
using Base = FixedInputValueNodeT<0, CreateShallowArrayLiteral>;
public:
explicit CreateShallowArrayLiteral(
uint64_t bitfield, const compiler::HeapObjectRef& constant_elements,
const compiler::FeedbackSource& feedback, int flags)
: Base(bitfield),
constant_elements_(constant_elements),
feedback_(feedback),
flags_(flags) {}
compiler::HeapObjectRef constant_elements() { return constant_elements_; }
compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call();
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private:
const compiler::HeapObjectRef constant_elements_;
const compiler::FeedbackSource feedback_;
const int flags_;
};
class CreateObjectLiteral
: public FixedInputValueNodeT<0, CreateObjectLiteral> {
using Base = FixedInputValueNodeT<0, CreateObjectLiteral>;
public:
explicit CreateObjectLiteral(
uint64_t bitfield,
const compiler::ObjectBoilerplateDescriptionRef& boilerplate_descriptor,
const compiler::FeedbackSource& feedback, int flags)
: Base(bitfield),
boilerplate_descriptor_(boilerplate_descriptor),
feedback_(feedback),
flags_(flags) {}
compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor() {
return boilerplate_descriptor_;
}
compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call();
void AllocateVreg(MaglevVregAllocationState*);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private:
const compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor_;
const compiler::FeedbackSource feedback_;
const int flags_;
};
class CreateShallowObjectLiteral
: public FixedInputValueNodeT<1, CreateShallowObjectLiteral> {
using Base = FixedInputValueNodeT<1, CreateShallowObjectLiteral>;
: public FixedInputValueNodeT<0, CreateShallowObjectLiteral> {
using Base = FixedInputValueNodeT<0, CreateShallowObjectLiteral>;
public:
explicit CreateShallowObjectLiteral(uint64_t bitfield, int flags,
const compiler::FeedbackSource& feedback)
: Base(bitfield), flags_(flags), feedback_(feedback) {}
explicit CreateShallowObjectLiteral(
uint64_t bitfield,
const compiler::ObjectBoilerplateDescriptionRef& boilerplate_descriptor,
const compiler::FeedbackSource& feedback, int flags)
: Base(bitfield),
boilerplate_descriptor_(boilerplate_descriptor),
feedback_(feedback),
flags_(flags) {}
// TODO(victorgomes): We should not need a boilerplate descriptor in
// CreateShallowObjectLiteral.
static constexpr int kObjectBoilerplateDescription = 0;
Input& boilerplate_descriptor() {
return input(kObjectBoilerplateDescription);
compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor() {
return boilerplate_descriptor_;
}
int flags() const { return flags_; }
compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call();
@ -1713,8 +1782,9 @@ class CreateShallowObjectLiteral
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private:
const int flags_;
const compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor_;
const compiler::FeedbackSource feedback_;
const int flags_;
};
class CreateFunctionContext