Commit f4367724 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[compiler] Make FixedArrays bg-serializable

Drive-by: Fix type hierarchies of a few FixedArray-related classes.
Done in this CL because it's based on the changes to FixedArrayData.
Drive-by: Allow AllocateFastLiteral (now TryAllocateFastLiteral) to
fail. Needed since currently ObjectRef creation may fail.

Bug: v8:7790
Change-Id: I1f8cf35a16408ed0e327f12602c832838254bb03
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2853592
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74265}
parent b286b100
...@@ -638,20 +638,6 @@ class ArrayBoilerplateDescriptionData : public HeapObjectData { ...@@ -638,20 +638,6 @@ class ArrayBoilerplateDescriptionData : public HeapObjectData {
int const constants_elements_length_; int const constants_elements_length_;
}; };
class ObjectBoilerplateDescriptionData : public HeapObjectData {
public:
ObjectBoilerplateDescriptionData(JSHeapBroker* broker, ObjectData** storage,
Handle<ObjectBoilerplateDescription> object)
: HeapObjectData(broker, storage, object), size_(object->size()) {
DCHECK(!broker->is_concurrent_inlining());
}
int size() const { return size_; }
private:
int const size_;
};
class JSDataViewData : public JSObjectData { class JSDataViewData : public JSObjectData {
public: public:
JSDataViewData(JSHeapBroker* broker, ObjectData** storage, JSDataViewData(JSHeapBroker* broker, ObjectData** storage,
...@@ -1108,14 +1094,6 @@ class BigIntData : public HeapObjectData { ...@@ -1108,14 +1094,6 @@ class BigIntData : public HeapObjectData {
const uint64_t as_uint64_; const uint64_t as_uint64_;
}; };
// Only used in JSNativeContextSpecialization.
class ScriptContextTableData : public HeapObjectData {
public:
ScriptContextTableData(JSHeapBroker* broker, ObjectData** storage,
Handle<ScriptContextTable> object)
: HeapObjectData(broker, storage, object) {}
};
struct PropertyDescriptor { struct PropertyDescriptor {
ObjectData* key = nullptr; ObjectData* key = nullptr;
ObjectData* value = nullptr; ObjectData* value = nullptr;
...@@ -1706,16 +1684,32 @@ class FixedArrayBaseData : public HeapObjectData { ...@@ -1706,16 +1684,32 @@ class FixedArrayBaseData : public HeapObjectData {
class FixedArrayData : public FixedArrayBaseData { class FixedArrayData : public FixedArrayBaseData {
public: public:
FixedArrayData(JSHeapBroker* broker, ObjectData** storage, FixedArrayData(JSHeapBroker* broker, ObjectData** storage,
Handle<FixedArray> object); Handle<FixedArray> object, ObjectDataKind kind)
: FixedArrayBaseData(broker, storage, object, kind) {}
};
// Creates all elements of the fixed array. class ObjectBoilerplateDescriptionData : public FixedArrayData {
void SerializeContents(JSHeapBroker* broker); public:
ObjectBoilerplateDescriptionData(
JSHeapBroker* broker, ObjectData** storage,
Handle<ObjectBoilerplateDescription> object,
ObjectDataKind kind = ObjectDataKind::kSerializedHeapObject)
: FixedArrayData(broker, storage, object, kind), size_(object->size()) {
DCHECK(!broker->is_concurrent_inlining());
}
ObjectData* Get(int i) const; int size() const { return size_; }
private: private:
bool serialized_contents_ = false; int const size_;
ZoneVector<ObjectData*> contents_; };
// Only used in JSNativeContextSpecialization.
class ScriptContextTableData : public FixedArrayData {
public:
ScriptContextTableData(JSHeapBroker* broker, ObjectData** storage,
Handle<ScriptContextTable> object, ObjectDataKind kind)
: FixedArrayData(broker, storage, object, kind) {}
}; };
JSDataViewData::JSDataViewData(JSHeapBroker* broker, ObjectData** storage, JSDataViewData::JSDataViewData(JSHeapBroker* broker, ObjectData** storage,
...@@ -1762,9 +1756,6 @@ bool JSBoundFunctionData::Serialize(JSHeapBroker* broker) { ...@@ -1762,9 +1756,6 @@ bool JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
DCHECK_NULL(bound_arguments_); DCHECK_NULL(bound_arguments_);
bound_arguments_ = broker->GetOrCreateData(function->bound_arguments()); bound_arguments_ = broker->GetOrCreateData(function->bound_arguments());
if (!bound_arguments_->should_access_heap()) {
bound_arguments_->AsFixedArray()->SerializeContents(broker);
}
DCHECK_NULL(bound_this_); DCHECK_NULL(bound_this_);
bound_this_ = broker->GetOrCreateData(function->bound_this()); bound_this_ = broker->GetOrCreateData(function->bound_this());
...@@ -1780,29 +1771,6 @@ JSObjectData::JSObjectData(JSHeapBroker* broker, ObjectData** storage, ...@@ -1780,29 +1771,6 @@ JSObjectData::JSObjectData(JSHeapBroker* broker, ObjectData** storage,
own_constant_elements_(broker->zone()), own_constant_elements_(broker->zone()),
own_properties_(broker->zone()) {} own_properties_(broker->zone()) {}
FixedArrayData::FixedArrayData(JSHeapBroker* broker, ObjectData** storage,
Handle<FixedArray> object)
: FixedArrayBaseData(broker, storage, object,
ObjectDataKind::kSerializedHeapObject),
contents_(broker->zone()) {}
void FixedArrayData::SerializeContents(JSHeapBroker* broker) {
if (serialized_contents_) return;
serialized_contents_ = true;
TraceScope tracer(broker, this, "FixedArrayData::SerializeContents");
Handle<FixedArray> array = Handle<FixedArray>::cast(object());
CHECK_EQ(array->length(), length());
CHECK(contents_.empty());
contents_.reserve(static_cast<size_t>(length()));
for (int i = 0; i < length(); i++) {
Handle<Object> value(array->get(i), broker->isolate());
contents_.push_back(broker->GetOrCreateData(value));
}
TRACE(broker, "Copied " << contents_.size() << " elements");
}
class FixedDoubleArrayData : public FixedArrayBaseData { class FixedDoubleArrayData : public FixedArrayBaseData {
public: public:
FixedDoubleArrayData( FixedDoubleArrayData(
...@@ -2427,7 +2395,6 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, ...@@ -2427,7 +2395,6 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker,
// do not need to be serialized because we only need to store the elements // do not need to be serialized because we only need to store the elements
// reference to the allocated object. // reference to the allocated object.
} else if (boilerplate->HasSmiOrObjectElements()) { } else if (boilerplate->HasSmiOrObjectElements()) {
elements_->AsFixedArray()->SerializeContents(broker);
Handle<FixedArray> fast_elements = Handle<FixedArray> fast_elements =
Handle<FixedArray>::cast(elements_object); Handle<FixedArray>::cast(elements_object);
int length = elements_object->length(); int length = elements_object->length();
...@@ -3252,12 +3219,13 @@ int ArrayBoilerplateDescriptionRef::constants_elements_length() const { ...@@ -3252,12 +3219,13 @@ int ArrayBoilerplateDescriptionRef::constants_elements_length() const {
return data()->AsArrayBoilerplateDescription()->constants_elements_length(); return data()->AsArrayBoilerplateDescription()->constants_elements_length();
} }
ObjectRef FixedArrayRef::get(int i) const { ObjectRef FixedArrayRef::get(int i) const { return TryGet(i).value(); }
if (data_->should_access_heap()) {
return ObjectRef(broker(), base::Optional<ObjectRef> FixedArrayRef::TryGet(int i) const {
broker()->CanonicalPersistentHandle(object()->get(i))); ObjectData* data = broker()->TryGetOrCreateData(
} broker()->CanonicalPersistentHandle(object()->get(i, kRelaxedLoad)));
return ObjectRef(broker(), data()->AsFixedArray()->Get(i)); if (data == nullptr) return {};
return ObjectRef{broker(), data};
} }
Float64 FixedDoubleArrayRef::GetFromImmutableFixedDoubleArray(int i) const { Float64 FixedDoubleArrayRef::GetFromImmutableFixedDoubleArray(int i) const {
...@@ -4169,12 +4137,6 @@ int FixedArrayBaseRef::length() const { ...@@ -4169,12 +4137,6 @@ int FixedArrayBaseRef::length() const {
return data()->AsFixedArrayBase()->length(); return data()->AsFixedArrayBase()->length();
} }
ObjectData* FixedArrayData::Get(int i) const {
CHECK_LT(i, static_cast<int>(contents_.size()));
CHECK_NOT_NULL(contents_[i]);
return contents_[i];
}
PropertyDetails DescriptorArrayRef::GetPropertyDetails( PropertyDetails DescriptorArrayRef::GetPropertyDetails(
InternalIndex descriptor_index) const { InternalIndex descriptor_index) const {
if (data_->should_access_heap()) { if (data_->should_access_heap()) {
...@@ -4260,18 +4222,9 @@ bool NameRef::IsUniqueName() const { ...@@ -4260,18 +4222,9 @@ bool NameRef::IsUniqueName() const {
} }
void RegExpBoilerplateDescriptionRef::Serialize() { void RegExpBoilerplateDescriptionRef::Serialize() {
if (data_->should_access_heap()) { if (data_->should_access_heap()) return;
// Even if the regexp boilerplate object itself is no longer serialized, CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
// the `data` still is and thus we need to make sure to visit it. HeapObjectRef::data()->AsRegExpBoilerplateDescription()->Serialize(broker());
// TODO(jgruber,v8:7790): Remove once it is no longer a serialized type.
STATIC_ASSERT(IsSerializedRef<FixedArray>());
FixedArrayRef data_ref{
broker(), broker()->CanonicalPersistentHandle(object()->data())};
} else {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
HeapObjectRef::data()->AsRegExpBoilerplateDescription()->Serialize(
broker());
}
} }
Handle<Object> ObjectRef::object() const { Handle<Object> ObjectRef::object() const {
......
...@@ -91,15 +91,13 @@ enum class RefSerializationKind { ...@@ -91,15 +91,13 @@ enum class RefSerializationKind {
/* Subtypes of Context */ \ /* Subtypes of Context */ \
V(NativeContext, RefSerializationKind::kSerialized) \ V(NativeContext, RefSerializationKind::kSerialized) \
/* Subtypes of FixedArray */ \ /* Subtypes of FixedArray */ \
V(Context, RefSerializationKind::kSerialized) \
V(ObjectBoilerplateDescription, RefSerializationKind::kNeverSerialized) \ V(ObjectBoilerplateDescription, RefSerializationKind::kNeverSerialized) \
V(ScopeInfo, RefSerializationKind::kNeverSerialized) \ V(ScriptContextTable, RefSerializationKind::kBackgroundSerialized) \
V(ScriptContextTable, RefSerializationKind::kSerialized) \
/* Subtypes of String */ \ /* Subtypes of String */ \
V(InternalizedString, RefSerializationKind::kNeverSerialized) \ V(InternalizedString, RefSerializationKind::kNeverSerialized) \
/* Subtypes of FixedArrayBase */ \ /* Subtypes of FixedArrayBase */ \
V(BytecodeArray, RefSerializationKind::kNeverSerialized) \ V(BytecodeArray, RefSerializationKind::kNeverSerialized) \
V(FixedArray, RefSerializationKind::kSerialized) \ V(FixedArray, RefSerializationKind::kBackgroundSerialized) \
V(FixedDoubleArray, RefSerializationKind::kNeverSerialized) \ V(FixedDoubleArray, RefSerializationKind::kNeverSerialized) \
/* Subtypes of Name */ \ /* Subtypes of Name */ \
V(String, RefSerializationKind::kNeverSerialized) \ V(String, RefSerializationKind::kNeverSerialized) \
...@@ -114,6 +112,7 @@ enum class RefSerializationKind { ...@@ -114,6 +112,7 @@ enum class RefSerializationKind {
V(CallHandlerInfo, RefSerializationKind::kNeverSerialized) \ V(CallHandlerInfo, RefSerializationKind::kNeverSerialized) \
V(Cell, RefSerializationKind::kNeverSerialized) \ V(Cell, RefSerializationKind::kNeverSerialized) \
V(Code, RefSerializationKind::kNeverSerialized) \ V(Code, RefSerializationKind::kNeverSerialized) \
V(Context, RefSerializationKind::kSerialized) \
V(DescriptorArray, RefSerializationKind::kNeverSerialized) \ V(DescriptorArray, RefSerializationKind::kNeverSerialized) \
V(FeedbackCell, RefSerializationKind::kNeverSerialized) \ V(FeedbackCell, RefSerializationKind::kNeverSerialized) \
V(FeedbackVector, RefSerializationKind::kNeverSerialized) \ V(FeedbackVector, RefSerializationKind::kNeverSerialized) \
...@@ -125,6 +124,7 @@ enum class RefSerializationKind { ...@@ -125,6 +124,7 @@ enum class RefSerializationKind {
V(Name, RefSerializationKind::kNeverSerialized) \ V(Name, RefSerializationKind::kNeverSerialized) \
V(PropertyCell, RefSerializationKind::kBackgroundSerialized) \ V(PropertyCell, RefSerializationKind::kBackgroundSerialized) \
V(RegExpBoilerplateDescription, RefSerializationKind::kNeverSerialized) \ V(RegExpBoilerplateDescription, RefSerializationKind::kNeverSerialized) \
V(ScopeInfo, RefSerializationKind::kNeverSerialized) \
V(SharedFunctionInfo, RefSerializationKind::kNeverSerialized) \ V(SharedFunctionInfo, RefSerializationKind::kNeverSerialized) \
V(SourceTextModule, RefSerializationKind::kSerialized) \ V(SourceTextModule, RefSerializationKind::kSerialized) \
V(TemplateObjectDescription, RefSerializationKind::kNeverSerialized) \ V(TemplateObjectDescription, RefSerializationKind::kNeverSerialized) \
...@@ -538,13 +538,6 @@ class NameRef : public HeapObjectRef { ...@@ -538,13 +538,6 @@ class NameRef : public HeapObjectRef {
bool IsUniqueName() const; bool IsUniqueName() const;
}; };
class ScriptContextTableRef : public HeapObjectRef {
public:
DEFINE_REF_CONSTRUCTOR(ScriptContextTable, HeapObjectRef)
Handle<ScriptContextTable> object() const;
};
class DescriptorArrayRef : public HeapObjectRef { class DescriptorArrayRef : public HeapObjectRef {
public: public:
DEFINE_REF_CONSTRUCTOR(DescriptorArray, HeapObjectRef) DEFINE_REF_CONSTRUCTOR(DescriptorArray, HeapObjectRef)
...@@ -763,14 +756,6 @@ class ArrayBoilerplateDescriptionRef : public HeapObjectRef { ...@@ -763,14 +756,6 @@ class ArrayBoilerplateDescriptionRef : public HeapObjectRef {
int constants_elements_length() const; int constants_elements_length() const;
}; };
class ObjectBoilerplateDescriptionRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
Handle<ObjectBoilerplateDescription> object() const;
int size() const;
};
class FixedArrayRef : public FixedArrayBaseRef { class FixedArrayRef : public FixedArrayBaseRef {
public: public:
DEFINE_REF_CONSTRUCTOR(FixedArray, FixedArrayBaseRef) DEFINE_REF_CONSTRUCTOR(FixedArray, FixedArrayBaseRef)
...@@ -778,6 +763,12 @@ class FixedArrayRef : public FixedArrayBaseRef { ...@@ -778,6 +763,12 @@ class FixedArrayRef : public FixedArrayBaseRef {
Handle<FixedArray> object() const; Handle<FixedArray> object() const;
ObjectRef get(int i) const; ObjectRef get(int i) const;
// As above but may fail if Ref construction is not possible (e.g. for
// serialized types on the background thread).
// TODO(jgruber): Remove once all Ref types are never-serialized or
// background-serialized and can thus be created on background threads.
base::Optional<ObjectRef> TryGet(int i) const;
}; };
class FixedDoubleArrayRef : public FixedArrayBaseRef { class FixedDoubleArrayRef : public FixedArrayBaseRef {
...@@ -813,6 +804,22 @@ class BytecodeArrayRef : public FixedArrayBaseRef { ...@@ -813,6 +804,22 @@ class BytecodeArrayRef : public FixedArrayBaseRef {
int handler_table_size() const; int handler_table_size() const;
}; };
class ScriptContextTableRef : public FixedArrayRef {
public:
DEFINE_REF_CONSTRUCTOR(ScriptContextTable, FixedArrayRef)
Handle<ScriptContextTable> object() const;
};
class ObjectBoilerplateDescriptionRef : public FixedArrayRef {
public:
DEFINE_REF_CONSTRUCTOR(ObjectBoilerplateDescription, FixedArrayRef)
Handle<ObjectBoilerplateDescription> object() const;
int size() const;
};
class JSArrayRef : public JSObjectRef { class JSArrayRef : public JSObjectRef {
public: public:
DEFINE_REF_CONSTRUCTOR(JSArray, JSObjectRef) DEFINE_REF_CONSTRUCTOR(JSArray, JSObjectRef)
......
...@@ -4130,6 +4130,21 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -4130,6 +4130,21 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
? ConvertReceiverMode::kNullOrUndefined ? ConvertReceiverMode::kNullOrUndefined
: ConvertReceiverMode::kNotNullOrUndefined; : ConvertReceiverMode::kNotNullOrUndefined;
// TODO(jgruber): Inline this block below once TryGet is guaranteed to
// succeed.
FixedArrayRef bound_arguments = function.bound_arguments();
const int bound_arguments_length = bound_arguments.length();
static constexpr int kInlineSize = 16; // Arbitrary.
base::SmallVector<Node*, kInlineSize> args;
for (int i = 0; i < bound_arguments_length; ++i) {
base::Optional<ObjectRef> maybe_arg = bound_arguments.TryGet(i);
if (!maybe_arg.has_value()) {
TRACE_BROKER_MISSING(broker(), "bound argument");
return NoChange();
}
args.emplace_back(jsgraph()->Constant(maybe_arg.value()));
}
// Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]]. // Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]].
NodeProperties::ReplaceValueInput( NodeProperties::ReplaceValueInput(
node, jsgraph()->Constant(function.bound_target_function()), node, jsgraph()->Constant(function.bound_target_function()),
...@@ -4138,10 +4153,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -4138,10 +4153,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
JSCallNode::ReceiverIndex()); JSCallNode::ReceiverIndex());
// Insert the [[BoundArguments]] for {node}. // Insert the [[BoundArguments]] for {node}.
FixedArrayRef bound_arguments = function.bound_arguments(); for (int i = 0; i < bound_arguments_length; ++i) {
for (int i = 0; i < bound_arguments.length(); ++i) { node->InsertInput(graph()->zone(), i + 2, args[i]);
node->InsertInput(graph()->zone(), i + 2,
jsgraph()->Constant(bound_arguments.get(i)));
arity++; arity++;
} }
...@@ -4828,6 +4841,20 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -4828,6 +4841,20 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
ObjectRef bound_target_function = function.bound_target_function(); ObjectRef bound_target_function = function.bound_target_function();
FixedArrayRef bound_arguments = function.bound_arguments(); FixedArrayRef bound_arguments = function.bound_arguments();
const int bound_arguments_length = bound_arguments.length();
// TODO(jgruber): Inline this block below once TryGet is guaranteed to
// succeed.
static constexpr int kInlineSize = 16; // Arbitrary.
base::SmallVector<Node*, kInlineSize> args;
for (int i = 0; i < bound_arguments_length; ++i) {
base::Optional<ObjectRef> maybe_arg = bound_arguments.TryGet(i);
if (!maybe_arg.has_value()) {
TRACE_BROKER_MISSING(broker(), "bound argument");
return NoChange();
}
args.emplace_back(jsgraph()->Constant(maybe_arg.value()));
}
// Patch {node} to use [[BoundTargetFunction]]. // Patch {node} to use [[BoundTargetFunction]].
node->ReplaceInput(n.TargetIndex(), node->ReplaceInput(n.TargetIndex(),
...@@ -4844,9 +4871,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -4844,9 +4871,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
new_target)); new_target));
// Insert the [[BoundArguments]] for {node}. // Insert the [[BoundArguments]] for {node}.
for (int i = 0; i < bound_arguments.length(); ++i) { for (int i = 0; i < bound_arguments_length; ++i) {
node->InsertInput(graph()->zone(), n.ArgumentIndex(i), node->InsertInput(graph()->zone(), n.ArgumentIndex(i), args[i]);
jsgraph()->Constant(bound_arguments.get(i)));
arity++; arity++;
} }
......
...@@ -1096,14 +1096,21 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { ...@@ -1096,14 +1096,21 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
if (!feedback.IsInsufficient()) { if (!feedback.IsInsufficient()) {
AllocationSiteRef site = feedback.AsLiteral().value(); AllocationSiteRef site = feedback.AsLiteral().value();
if (site.IsFastLiteral()) { if (site.IsFastLiteral()) {
AllocationType allocation = AllocationType::kYoung; AllocationType allocation = FLAG_allocation_site_pretenuring
? site.GetAllocationType()
: AllocationType::kYoung;
JSObjectRef boilerplate = site.boilerplate().value();
base::Optional<Node*> maybe_value =
TryAllocateFastLiteral(effect, control, boilerplate, allocation);
if (!maybe_value.has_value()) {
TRACE_BROKER_MISSING(broker(), "bound argument");
return NoChange();
}
if (FLAG_allocation_site_pretenuring) { if (FLAG_allocation_site_pretenuring) {
allocation = dependencies()->DependOnPretenureMode(site); CHECK_EQ(dependencies()->DependOnPretenureMode(site), allocation);
} }
dependencies()->DependOnElementsKinds(site); dependencies()->DependOnElementsKinds(site);
JSObjectRef boilerplate = site.boilerplate().value(); Node* value = effect = maybe_value.value();
Node* value = effect =
AllocateFastLiteral(effect, control, boilerplate, allocation);
ReplaceWithValue(node, value, effect, control); ReplaceWithValue(node, value, effect, control);
return Replace(value); return Replace(value);
} }
...@@ -1646,9 +1653,9 @@ Node* JSCreateLowering::AllocateElements(Node* effect, Node* control, ...@@ -1646,9 +1653,9 @@ Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
return a.Finish(); return a.Finish();
} }
Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control, base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(
JSObjectRef boilerplate, Node* effect, Node* control, JSObjectRef boilerplate,
AllocationType allocation) { AllocationType allocation) {
// Compute the in-object properties to store first (might have effects). // Compute the in-object properties to store first (might have effects).
MapRef boilerplate_map = boilerplate.map(); MapRef boilerplate_map = boilerplate.map();
ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone()); ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
...@@ -1682,8 +1689,10 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control, ...@@ -1682,8 +1689,10 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
Node* value; Node* value;
if (boilerplate_value.IsJSObject()) { if (boilerplate_value.IsJSObject()) {
JSObjectRef boilerplate_object = boilerplate_value.AsJSObject(); JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
value = effect = base::Optional<Node*> maybe_value = TryAllocateFastLiteral(
AllocateFastLiteral(effect, control, boilerplate_object, allocation); effect, control, boilerplate_object, allocation);
if (!maybe_value.has_value()) return {};
value = effect = maybe_value.value();
} else if (property_details.representation().IsDouble()) { } else if (property_details.representation().IsDouble()) {
double number = boilerplate_value.AsHeapNumber().value(); double number = boilerplate_value.AsHeapNumber().value();
// Allocate a mutable HeapNumber box and store the value into it. // Allocate a mutable HeapNumber box and store the value into it.
...@@ -1718,8 +1727,10 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control, ...@@ -1718,8 +1727,10 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
} }
// Setup the elements backing store. // Setup the elements backing store.
Node* elements = base::Optional<Node*> maybe_elements =
AllocateFastLiteralElements(effect, control, boilerplate, allocation); TryAllocateFastLiteralElements(effect, control, boilerplate, allocation);
if (!maybe_elements.has_value()) return {};
Node* elements = maybe_elements.value();
if (elements->op()->EffectOutputCount() > 0) effect = elements; if (elements->op()->EffectOutputCount() > 0) effect = elements;
// Actually allocate and initialize the object. // Actually allocate and initialize the object.
...@@ -1742,9 +1753,9 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control, ...@@ -1742,9 +1753,9 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
return builder.Finish(); return builder.Finish();
} }
Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control, base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
JSObjectRef boilerplate, Node* effect, Node* control, JSObjectRef boilerplate,
AllocationType allocation) { AllocationType allocation) {
FixedArrayBaseRef boilerplate_elements = boilerplate.elements().value(); FixedArrayBaseRef boilerplate_elements = boilerplate.elements().value();
// Empty or copy-on-write elements just store a constant. // Empty or copy-on-write elements just store a constant.
...@@ -1773,10 +1784,14 @@ Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control, ...@@ -1773,10 +1784,14 @@ Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control,
} else { } else {
FixedArrayRef elements = boilerplate_elements.AsFixedArray(); FixedArrayRef elements = boilerplate_elements.AsFixedArray();
for (int i = 0; i < elements_length; ++i) { for (int i = 0; i < elements_length; ++i) {
ObjectRef element_value = elements.get(i); base::Optional<ObjectRef> maybe_element_value = elements.TryGet(i);
if (!maybe_element_value.has_value()) return {};
ObjectRef element_value = maybe_element_value.value();
if (element_value.IsJSObject()) { if (element_value.IsJSObject()) {
elements_values[i] = effect = AllocateFastLiteral( base::Optional<Node*> maybe_value = TryAllocateFastLiteral(
effect, control, element_value.AsJSObject(), allocation); effect, control, element_value.AsJSObject(), allocation);
if (!maybe_value.has_value()) return {};
elements_values[i] = effect = maybe_value.value();
} else { } else {
elements_values[i] = jsgraph()->Constant(element_value); elements_values[i] = jsgraph()->Constant(element_value);
} }
......
...@@ -97,6 +97,12 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -97,6 +97,12 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
Node* arguments_length, Node* arguments_length,
const SharedFunctionInfoRef& shared, const SharedFunctionInfoRef& shared,
bool* has_aliased_arguments); bool* has_aliased_arguments);
base::Optional<Node*> TryAllocateFastLiteral(Node* effect, Node* control,
JSObjectRef boilerplate,
AllocationType allocation);
base::Optional<Node*> TryAllocateFastLiteralElements(
Node* effect, Node* control, JSObjectRef boilerplate,
AllocationType allocation);
Node* AllocateElements(Node* effect, Node* control, Node* AllocateElements(Node* effect, Node* control,
ElementsKind elements_kind, int capacity, ElementsKind elements_kind, int capacity,
...@@ -107,11 +113,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -107,11 +113,6 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
ElementsKind elements_kind, ElementsKind elements_kind,
std::vector<Node*> const& values, std::vector<Node*> const& values,
AllocationType allocation); AllocationType allocation);
Node* AllocateFastLiteral(Node* effect, Node* control,
JSObjectRef boilerplate, AllocationType allocation);
Node* AllocateFastLiteralElements(Node* effect, Node* control,
JSObjectRef boilerplate,
AllocationType allocation);
Node* AllocateLiteralRegExp(Node* effect, Node* control, Node* AllocateLiteralRegExp(Node* effect, Node* control,
RegExpBoilerplateDescriptionRef boilerplate); RegExpBoilerplateDescriptionRef boilerplate);
......
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