Commit 8d52262b authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[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: 's avatarVictor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81687}
parent e5b9fae4
...@@ -1480,7 +1480,30 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(ToNumeric) ...@@ -1480,7 +1480,30 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(ToNumeric)
MAGLEV_UNIMPLEMENTED_BYTECODE(ToObject) MAGLEV_UNIMPLEMENTED_BYTECODE(ToObject)
MAGLEV_UNIMPLEMENTED_BYTECODE(ToString) MAGLEV_UNIMPLEMENTED_BYTECODE(ToString)
MAGLEV_UNIMPLEMENTED_BYTECODE(CreateRegExpLiteral) 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) MAGLEV_UNIMPLEMENTED_BYTECODE(CreateArrayFromIterable)
void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() { void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() {
...@@ -1491,8 +1514,8 @@ void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() { ...@@ -1491,8 +1514,8 @@ void MaglevGraphBuilder::VisitCreateEmptyArrayLiteral() {
} }
void MaglevGraphBuilder::VisitCreateObjectLiteral() { void MaglevGraphBuilder::VisitCreateObjectLiteral() {
ValueNode* boilerplate_desc = compiler::ObjectBoilerplateDescriptionRef boilerplate_desc =
GetConstant(GetRefOperand<ObjectBoilerplateDescription>(0)); GetRefOperand<ObjectBoilerplateDescription>(0);
FeedbackSlot slot_index = GetSlotOperand(1); FeedbackSlot slot_index = GetSlotOperand(1);
int bytecode_flags = GetFlagOperand(2); int bytecode_flags = GetFlagOperand(2);
int literal_flags = int literal_flags =
...@@ -1504,12 +1527,12 @@ void MaglevGraphBuilder::VisitCreateObjectLiteral() { ...@@ -1504,12 +1527,12 @@ void MaglevGraphBuilder::VisitCreateObjectLiteral() {
// boilerplate descriptor. However the current builtin checks that the // boilerplate descriptor. However the current builtin checks that the
// feedback exists and fallsback to CreateObjectLiteral if it doesn't. // feedback exists and fallsback to CreateObjectLiteral if it doesn't.
result = AddNewNode<CreateShallowObjectLiteral>( result = AddNewNode<CreateShallowObjectLiteral>(
{boilerplate_desc}, literal_flags, {}, boilerplate_desc, compiler::FeedbackSource{feedback(), slot_index},
compiler::FeedbackSource{feedback(), slot_index}); literal_flags);
} else { } else {
result = AddNewNode<CreateObjectLiteral>( result = AddNewNode<CreateObjectLiteral>(
{boilerplate_desc}, literal_flags, {}, boilerplate_desc, compiler::FeedbackSource{feedback(), slot_index},
compiler::FeedbackSource{feedback(), slot_index}); literal_flags);
} }
SetAccumulator(result); SetAccumulator(result);
} }
......
...@@ -63,6 +63,10 @@ class MaglevGraphVerifier { ...@@ -63,6 +63,10 @@ class MaglevGraphVerifier {
case Opcode::kConstant: case Opcode::kConstant:
case Opcode::kConstantGapMove: case Opcode::kConstantGapMove:
case Opcode::kCreateEmptyArrayLiteral: case Opcode::kCreateEmptyArrayLiteral:
case Opcode::kCreateArrayLiteral:
case Opcode::kCreateShallowArrayLiteral:
case Opcode::kCreateObjectLiteral:
case Opcode::kCreateShallowObjectLiteral:
case Opcode::kDeopt: case Opcode::kDeopt:
case Opcode::kFloat64Constant: case Opcode::kFloat64Constant:
case Opcode::kGapMove: case Opcode::kGapMove:
...@@ -98,8 +102,6 @@ class MaglevGraphVerifier { ...@@ -98,8 +102,6 @@ class MaglevGraphVerifier {
case Opcode::kBranchIfToBooleanTrue: case Opcode::kBranchIfToBooleanTrue:
case Opcode::kBranchIfTrue: case Opcode::kBranchIfTrue:
case Opcode::kCheckedFloat64Unbox: case Opcode::kCheckedFloat64Unbox:
case Opcode::kCreateObjectLiteral:
case Opcode::kCreateShallowObjectLiteral:
case Opcode::kCreateFunctionContext: case Opcode::kCreateFunctionContext:
case Opcode::kCreateClosure: case Opcode::kCreateClosure:
case Opcode::kFastCreateClosure: case Opcode::kFastCreateClosure:
......
...@@ -604,35 +604,62 @@ void CreateEmptyArrayLiteral::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -604,35 +604,62 @@ void CreateEmptyArrayLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
__ CallBuiltin(Builtin::kCreateEmptyArrayLiteral); __ 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) { void CreateObjectLiteral::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(boilerplate_descriptor());
DefineAsFixed(vreg_state, this, kReturnRegister0); DefineAsFixed(vreg_state, this, kReturnRegister0);
} }
void CreateObjectLiteral::GenerateCode(MaglevCodeGenState* code_gen_state, void CreateObjectLiteral::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
__ Move(kContextRegister, code_gen_state->native_context().object()); __ Move(kContextRegister, code_gen_state->native_context().object());
__ Push(feedback().vector); __ Push(feedback().vector);
__ Push(Smi::FromInt(feedback().index())); __ Push(TaggedIndex::FromIntptr(feedback().index()));
__ Push(ToRegister(boilerplate_descriptor())); __ Push(boilerplate_descriptor().object());
__ Push(Smi::FromInt(flags())); __ Push(Smi::FromInt(flags()));
__ CallRuntime(Runtime::kCreateObjectLiteral); __ CallRuntime(Runtime::kCreateObjectLiteral);
} }
void CreateShallowObjectLiteral::AllocateVreg( void CreateShallowObjectLiteral::AllocateVreg(
MaglevVregAllocationState* vreg_state) { MaglevVregAllocationState* vreg_state) {
using D = CreateShallowObjectLiteralDescriptor;
UseFixed(boilerplate_descriptor(), D::GetRegisterParameter(D::kDesc));
DefineAsFixed(vreg_state, this, kReturnRegister0); DefineAsFixed(vreg_state, this, kReturnRegister0);
} }
void CreateShallowObjectLiteral::GenerateCode( void CreateShallowObjectLiteral::GenerateCode(
MaglevCodeGenState* code_gen_state, const ProcessingState& state) { MaglevCodeGenState* code_gen_state, const ProcessingState& state) {
using D = CreateShallowObjectLiteralDescriptor; using D = CreateShallowObjectLiteralDescriptor;
DCHECK_EQ(ToRegister(boilerplate_descriptor()), __ Move(D::ContextRegister(), code_gen_state->native_context().object());
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::GetRegisterParameter(D::kMaybeFeedbackVector), feedback().vector); __ 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); __ CallBuiltin(Builtin::kCreateShallowObjectLiteral);
} }
......
...@@ -118,6 +118,8 @@ class CompactInterpreterFrameState; ...@@ -118,6 +118,8 @@ class CompactInterpreterFrameState;
V(Call) \ V(Call) \
V(Construct) \ V(Construct) \
V(CreateEmptyArrayLiteral) \ V(CreateEmptyArrayLiteral) \
V(CreateArrayLiteral) \
V(CreateShallowArrayLiteral) \
V(CreateObjectLiteral) \ V(CreateObjectLiteral) \
V(CreateShallowObjectLiteral) \ V(CreateShallowObjectLiteral) \
V(CreateFunctionContext) \ V(CreateFunctionContext) \
...@@ -1657,22 +1659,52 @@ class CreateEmptyArrayLiteral ...@@ -1657,22 +1659,52 @@ class CreateEmptyArrayLiteral
const compiler::FeedbackSource feedback_; const compiler::FeedbackSource feedback_;
}; };
class CreateObjectLiteral class CreateArrayLiteral : public FixedInputValueNodeT<0, CreateArrayLiteral> {
: public FixedInputValueNodeT<1, CreateObjectLiteral> { using Base = FixedInputValueNodeT<0, CreateArrayLiteral>;
using Base = FixedInputValueNodeT<1, CreateObjectLiteral>;
public: public:
explicit CreateObjectLiteral(uint64_t bitfield, int flags, explicit CreateArrayLiteral(uint64_t bitfield,
const compiler::FeedbackSource& feedback) const compiler::HeapObjectRef& constant_elements,
: Base(bitfield), flags_(flags), feedback_(feedback) {} const compiler::FeedbackSource& feedback,
int flags)
static constexpr int kObjectBoilerplateDescription = 0; : Base(bitfield),
Input& boilerplate_descriptor() { constant_elements_(constant_elements),
return input(kObjectBoilerplateDescription); feedback_(feedback),
} flags_(flags) {}
compiler::HeapObjectRef constant_elements() { return constant_elements_; }
compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; } 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 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_; } compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime. // The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call(); static constexpr OpProperties kProperties = OpProperties::Call();
...@@ -1682,28 +1714,65 @@ class CreateObjectLiteral ...@@ -1682,28 +1714,65 @@ class CreateObjectLiteral
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private: private:
const compiler::HeapObjectRef constant_elements_;
const compiler::FeedbackSource feedback_;
const int flags_; 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 compiler::FeedbackSource feedback_;
const int flags_;
}; };
class CreateShallowObjectLiteral class CreateShallowObjectLiteral
: public FixedInputValueNodeT<1, CreateShallowObjectLiteral> { : public FixedInputValueNodeT<0, CreateShallowObjectLiteral> {
using Base = FixedInputValueNodeT<1, CreateShallowObjectLiteral>; using Base = FixedInputValueNodeT<0, CreateShallowObjectLiteral>;
public: public:
explicit CreateShallowObjectLiteral(uint64_t bitfield, int flags, explicit CreateShallowObjectLiteral(
const compiler::FeedbackSource& feedback) uint64_t bitfield,
: Base(bitfield), flags_(flags), feedback_(feedback) {} 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 // TODO(victorgomes): We should not need a boilerplate descriptor in
// CreateShallowObjectLiteral. // CreateShallowObjectLiteral.
static constexpr int kObjectBoilerplateDescription = 0; compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor() {
Input& boilerplate_descriptor() { return boilerplate_descriptor_;
return input(kObjectBoilerplateDescription);
} }
int flags() const { return flags_; }
compiler::FeedbackSource feedback() const { return feedback_; } compiler::FeedbackSource feedback() const { return feedback_; }
int flags() const { return flags_; }
// The implementation currently calls runtime. // The implementation currently calls runtime.
static constexpr OpProperties kProperties = OpProperties::Call(); static constexpr OpProperties kProperties = OpProperties::Call();
...@@ -1713,8 +1782,9 @@ class CreateShallowObjectLiteral ...@@ -1713,8 +1782,9 @@ class CreateShallowObjectLiteral
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
private: private:
const int flags_; const compiler::ObjectBoilerplateDescriptionRef boilerplate_descriptor_;
const compiler::FeedbackSource feedback_; const compiler::FeedbackSource feedback_;
const int flags_;
}; };
class CreateFunctionContext class CreateFunctionContext
......
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