Commit 399f36b5 authored by franzih's avatar franzih Committed by Commit bot

[runtime] Allocate space for computed property names.

Allocate space in the backing store for computed property names.

The property backing store was pre-allocated for the constant
properties up to the first non-constant (computed name) property.
To use lowering for storing data properties in literals
with computed property names effectively, a fast store is needed, i.e.,
available space in the property backing store for properties
with computed names.

backing_store_size is the number of all properties (including
computed names, but without __proto__)
that is calculated in the ast and passed to the runtime function that allocates
the property backing store. backing_store_size and
constant_properties constitute a BoilerplateDescription.

backing_store_size might be slightly too high because computed names
can evaluate to the same name, but that should be a rare
case so over-allocating is OK.

If a property is __proto__, we don't store it as a regular
property, because the map changes. Keep track of
has_seen_proto in the parser to calculate the
backing store size correctly.

BUG=v8:5625

Review-Url: https://codereview.chromium.org/2632503003
Cr-Commit-Position: refs/heads/master@{#42576}
parent 24c050e8
...@@ -582,9 +582,9 @@ void ObjectLiteral::InitDepthAndFlags() { ...@@ -582,9 +582,9 @@ void ObjectLiteral::InitDepthAndFlags() {
void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
if (!constant_properties_.is_null()) return; if (!constant_properties_.is_null()) return;
// Allocate a fixed array to hold all the constant properties. Handle<BoilerplateDescription> constant_properties =
Handle<FixedArray> constant_properties = isolate->factory()->NewBoilerplateDescription(
isolate->factory()->NewFixedArray(boilerplate_properties_ * 2, TENURED); boilerplate_properties_, properties()->length(), has_seen_proto());
int position = 0; int position = 0;
for (int i = 0; i < properties()->length(); i++) { for (int i = 0; i < properties()->length(); i++) {
......
...@@ -1402,6 +1402,9 @@ class ObjectLiteral final : public MaterializedLiteral { ...@@ -1402,6 +1402,9 @@ class ObjectLiteral final : public MaterializedLiteral {
bool has_rest_property() const { bool has_rest_property() const {
return HasRestPropertyField::decode(bit_field_); return HasRestPropertyField::decode(bit_field_);
} }
bool has_seen_proto() const {
return HasSeenProtoPropertyField::decode(bit_field_);
}
// Decide if a property should be in the object boilerplate. // Decide if a property should be in the object boilerplate.
static bool IsBoilerplateProperty(Property* property); static bool IsBoilerplateProperty(Property* property);
...@@ -1473,7 +1476,7 @@ class ObjectLiteral final : public MaterializedLiteral { ...@@ -1473,7 +1476,7 @@ class ObjectLiteral final : public MaterializedLiteral {
friend class AstNodeFactory; friend class AstNodeFactory;
ObjectLiteral(ZoneList<Property*>* properties, int literal_index, ObjectLiteral(ZoneList<Property*>* properties, int literal_index,
uint32_t boilerplate_properties, int pos, uint32_t boilerplate_properties, bool has_seen_proto, int pos,
bool has_rest_property) bool has_rest_property)
: MaterializedLiteral(literal_index, pos, kObjectLiteral), : MaterializedLiteral(literal_index, pos, kObjectLiteral),
boilerplate_properties_(boilerplate_properties), boilerplate_properties_(boilerplate_properties),
...@@ -1481,7 +1484,8 @@ class ObjectLiteral final : public MaterializedLiteral { ...@@ -1481,7 +1484,8 @@ class ObjectLiteral final : public MaterializedLiteral {
bit_field_ |= FastElementsField::encode(false) | bit_field_ |= FastElementsField::encode(false) |
HasElementsField::encode(false) | HasElementsField::encode(false) |
MayStoreDoublesField::encode(false) | MayStoreDoublesField::encode(false) |
HasRestPropertyField::encode(has_rest_property); HasRestPropertyField::encode(has_rest_property) |
HasSeenProtoPropertyField::encode(has_seen_proto);
} }
static int parent_num_ids() { return MaterializedLiteral::num_ids(); } static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
...@@ -1499,6 +1503,8 @@ class ObjectLiteral final : public MaterializedLiteral { ...@@ -1499,6 +1503,8 @@ class ObjectLiteral final : public MaterializedLiteral {
: public BitField<bool, HasElementsField::kNext, 1> {}; : public BitField<bool, HasElementsField::kNext, 1> {};
class HasRestPropertyField class HasRestPropertyField
: public BitField<bool, MayStoreDoublesField::kNext, 1> {}; : public BitField<bool, MayStoreDoublesField::kNext, 1> {};
class HasSeenProtoPropertyField
: public BitField<bool, HasRestPropertyField::kNext, 1> {};
}; };
...@@ -3337,10 +3343,11 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3337,10 +3343,11 @@ class AstNodeFactory final BASE_EMBEDDED {
ObjectLiteral* NewObjectLiteral( ObjectLiteral* NewObjectLiteral(
ZoneList<ObjectLiteral::Property*>* properties, int literal_index, ZoneList<ObjectLiteral::Property*>* properties, int literal_index,
uint32_t boilerplate_properties, int pos, bool has_rest_property) { uint32_t boilerplate_properties, bool has_seen_proto, int pos,
bool has_rest_property) {
return new (zone_) return new (zone_)
ObjectLiteral(properties, literal_index, boilerplate_properties, pos, ObjectLiteral(properties, literal_index, boilerplate_properties,
has_rest_property); has_seen_proto, pos, has_rest_property);
} }
ObjectLiteral::Property* NewObjectLiteralProperty( ObjectLiteral::Property* NewObjectLiteralProperty(
......
...@@ -391,7 +391,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo( ...@@ -391,7 +391,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
// Don't search on the prototype when storing in literals // Don't search on the prototype when storing in literals
if (access_mode == AccessMode::kStoreInLiteral) { if (access_mode == AccessMode::kStoreInLiteral) {
return false; return LookupTransition(receiver_map, name, holder, access_info);
} }
// Don't lookup private symbols on the prototype chain. // Don't lookup private symbols on the prototype chain.
......
...@@ -1137,7 +1137,8 @@ JSNativeContextSpecialization::BuildPropertyAccess( ...@@ -1137,7 +1137,8 @@ JSNativeContextSpecialization::BuildPropertyAccess(
value = effect = graph()->NewNode(simplified()->LoadField(field_access), value = effect = graph()->NewNode(simplified()->LoadField(field_access),
storage, effect, control); storage, effect, control);
} else { } else {
DCHECK_EQ(AccessMode::kStore, access_mode); DCHECK(access_mode == AccessMode::kStore ||
access_mode == AccessMode::kStoreInLiteral);
switch (field_representation) { switch (field_representation) {
case MachineRepresentation::kFloat64: { case MachineRepresentation::kFloat64: {
value = effect = graph()->NewNode(simplified()->CheckNumber(), value, value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
......
...@@ -185,6 +185,31 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { ...@@ -185,6 +185,31 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
FixedArray); FixedArray);
} }
Handle<BoilerplateDescription> Factory::NewBoilerplateDescription(
int boilerplate, int all_properties, bool has_seen_proto) {
DCHECK_GE(all_properties, boilerplate);
int backing_store_size = all_properties - (has_seen_proto ? 1 : 0);
DCHECK_GE(backing_store_size, 0);
bool has_different_size_backing_store = boilerplate != backing_store_size;
// Space for name and value for every boilerplate property.
int size = 2 * boilerplate;
if (has_different_size_backing_store) {
// An extra entry for the backing store size.
size++;
}
Handle<BoilerplateDescription> description =
Handle<BoilerplateDescription>::cast(NewFixedArray(size, TENURED));
if (has_different_size_backing_store) {
DCHECK((boilerplate != all_properties) || has_seen_proto);
description->set_backing_store_size(isolate(), backing_store_size);
}
return description;
}
Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size, Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size,
PretenureFlag pretenure) { PretenureFlag pretenure) {
......
...@@ -48,6 +48,12 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -48,6 +48,12 @@ class V8_EXPORT_PRIVATE Factory final {
// Allocates an uninitialized fixed array. It must be filled by the caller. // Allocates an uninitialized fixed array. It must be filled by the caller.
Handle<FixedArray> NewUninitializedFixedArray(int size); Handle<FixedArray> NewUninitializedFixedArray(int size);
// Allocates a fixed array for name-value pairs of boilerplate properties and
// calculates the number of properties we need to store in the backing store.
Handle<BoilerplateDescription> NewBoilerplateDescription(int boilerplate,
int all_properties,
bool has_seen_proto);
// Allocate a new uninitialized fixed double array. // Allocate a new uninitialized fixed double array.
// The function returns a pre-allocated empty fixed array for capacity = 0, // The function returns a pre-allocated empty fixed array for capacity = 0,
// so the return type must be the general fixed array class. // so the return type must be the general fixed array class.
......
...@@ -196,6 +196,8 @@ bool HeapObject::IsFixedArray() const { ...@@ -196,6 +196,8 @@ bool HeapObject::IsFixedArray() const {
instance_type == TRANSITION_ARRAY_TYPE; instance_type == TRANSITION_ARRAY_TYPE;
} }
bool HeapObject::IsBoilerplateDescription() const { return IsFixedArray(); }
// External objects are not extensible, so the map check is enough. // External objects are not extensible, so the map check is enough.
bool HeapObject::IsExternal() const { bool HeapObject::IsExternal() const {
return map() == GetHeap()->external_map(); return map() == GetHeap()->external_map();
...@@ -615,6 +617,7 @@ bool Object::IsMinusZero() const { ...@@ -615,6 +617,7 @@ bool Object::IsMinusZero() const {
CAST_ACCESSOR(AbstractCode) CAST_ACCESSOR(AbstractCode)
CAST_ACCESSOR(ArrayList) CAST_ACCESSOR(ArrayList)
CAST_ACCESSOR(BoilerplateDescription)
CAST_ACCESSOR(Bool16x8) CAST_ACCESSOR(Bool16x8)
CAST_ACCESSOR(Bool32x4) CAST_ACCESSOR(Bool32x4)
CAST_ACCESSOR(Bool8x16) CAST_ACCESSOR(Bool8x16)
......
...@@ -9835,6 +9835,45 @@ void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { ...@@ -9835,6 +9835,45 @@ void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
} }
} }
Object* BoilerplateDescription::name(int index) const {
// get() already checks for out of bounds access, but we do not want to allow
// access to the last element, if it is the number of properties.
DCHECK_NE(size(), index);
return get(2 * index);
}
Object* BoilerplateDescription::value(int index) const {
return get(2 * index + 1);
}
int BoilerplateDescription::size() const {
DCHECK_EQ(0, (length() - (this->has_number_of_properties() ? 1 : 0)) % 2);
// Rounding is intended.
return length() / 2;
}
int BoilerplateDescription::backing_store_size() const {
if (has_number_of_properties()) {
// If present, the last entry contains the number of properties.
return Smi::cast(this->get(length() - 1))->value();
}
// If the number is not given explicitly, we assume there are no
// properties with computed names.
return size();
}
void BoilerplateDescription::set_backing_store_size(Isolate* isolate,
int backing_store_size) {
DCHECK(has_number_of_properties());
DCHECK_NE(size(), backing_store_size);
Handle<Object> backing_store_size_obj =
isolate->factory()->NewNumberFromInt(backing_store_size);
set(length() - 1, *backing_store_size_obj);
}
bool BoilerplateDescription::has_number_of_properties() const {
return length() % 2 != 0;
}
#ifdef DEBUG #ifdef DEBUG
bool FixedArray::IsEqualTo(FixedArray* other) { bool FixedArray::IsEqualTo(FixedArray* other) {
......
...@@ -1058,6 +1058,7 @@ template <class C> inline bool Is(Object* obj); ...@@ -1058,6 +1058,7 @@ template <class C> inline bool Is(Object* obj);
V(DependentCode) \ V(DependentCode) \
V(HandlerTable) \ V(HandlerTable) \
V(FixedArray) \ V(FixedArray) \
V(BoilerplateDescription) \
V(FixedDoubleArray) \ V(FixedDoubleArray) \
V(WeakFixedArray) \ V(WeakFixedArray) \
V(ArrayList) \ V(ArrayList) \
...@@ -2914,6 +2915,29 @@ class FixedArray: public FixedArrayBase { ...@@ -2914,6 +2915,29 @@ class FixedArray: public FixedArrayBase {
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
}; };
// BoilerplateDescription is a list of properties consisting of name value
// pairs. In addition to the properties, it provides the projected number
// of properties in the backing store. This number includes properties with
// computed names that are not
// in the list.
class BoilerplateDescription : public FixedArray {
public:
Object* name(int index) const;
Object* value(int index) const;
// The number of boilerplate properties.
int size() const;
// Number of boilerplate properties and properties with computed names.
int backing_store_size() const;
void set_backing_store_size(Isolate* isolate, int backing_store_size);
DECLARE_CAST(BoilerplateDescription)
private:
bool has_number_of_properties() const;
};
// FixedDoubleArray describes fixed-sized arrays with element type double. // FixedDoubleArray describes fixed-sized arrays with element type double.
class FixedDoubleArray: public FixedArrayBase { class FixedDoubleArray: public FixedArrayBase {
...@@ -6345,7 +6369,6 @@ class Map: public HeapObject { ...@@ -6345,7 +6369,6 @@ class Map: public HeapObject {
static const int kInstanceTypeAndBitFieldOffset = static const int kInstanceTypeAndBitFieldOffset =
kInstanceAttributesOffset + 0; kInstanceAttributesOffset + 0;
static const int kBitField2Offset = kInstanceAttributesOffset + 2; static const int kBitField2Offset = kInstanceAttributesOffset + 2;
static const int kUnusedPropertyFieldsByte = 3;
static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3; static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
STATIC_ASSERT(kInstanceTypeAndBitFieldOffset == STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
......
...@@ -2552,6 +2552,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( ...@@ -2552,6 +2552,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
typename Types::ObjectPropertyList properties = typename Types::ObjectPropertyList properties =
impl()->NewObjectPropertyList(4); impl()->NewObjectPropertyList(4);
int number_of_boilerplate_properties = 0; int number_of_boilerplate_properties = 0;
bool has_seen_proto = false;
bool has_computed_names = false; bool has_computed_names = false;
bool has_rest_property = false; bool has_rest_property = false;
ObjectLiteralChecker checker(this); ObjectLiteralChecker checker(this);
...@@ -2574,10 +2576,14 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( ...@@ -2574,10 +2576,14 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
has_rest_property = true; has_rest_property = true;
} }
// Count CONSTANT or COMPUTED properties to maintain the enumeration order. if (!impl()->IsBoilerplateProperty(property)) {
if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { has_seen_proto = true;
} else if (!has_computed_names) {
// Count CONSTANT or COMPUTED properties to maintain the enumeration
// order.
number_of_boilerplate_properties++; number_of_boilerplate_properties++;
} }
properties->Add(property, zone()); properties->Add(property, zone());
if (peek() != Token::RBRACE) { if (peek() != Token::RBRACE) {
...@@ -2593,8 +2599,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( ...@@ -2593,8 +2599,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
int literal_index = function_state_->NextMaterializedLiteralIndex(); int literal_index = function_state_->NextMaterializedLiteralIndex();
return factory()->NewObjectLiteral(properties, literal_index, return factory()->NewObjectLiteral(properties, literal_index,
number_of_boilerplate_properties, pos, number_of_boilerplate_properties,
has_rest_property); has_seen_proto, pos, has_rest_property);
} }
template <typename Impl> template <typename Impl>
......
...@@ -595,7 +595,8 @@ class PreParserFactory { ...@@ -595,7 +595,8 @@ class PreParserFactory {
} }
PreParserExpression NewObjectLiteral(PreParserExpressionList properties, PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
int literal_index, int literal_index,
int boilerplate_properties, int pos, int boilerplate_properties,
bool has_seen_proto, int pos,
bool has_rest_property) { bool has_rest_property) {
return PreParserExpression::ObjectLiteral(properties.variables_); return PreParserExpression::ObjectLiteral(properties.variables_);
} }
......
...@@ -15,13 +15,13 @@ namespace v8 { ...@@ -15,13 +15,13 @@ namespace v8 {
namespace internal { namespace internal {
static Handle<Map> ComputeObjectLiteralMap( static Handle<Map> ComputeObjectLiteralMap(
Handle<Context> context, Handle<FixedArray> constant_properties, Handle<Context> context,
Handle<BoilerplateDescription> boilerplate_description,
bool* is_result_from_cache) { bool* is_result_from_cache) {
int properties_length = constant_properties->length(); int number_of_properties = boilerplate_description->backing_store_size();
int number_of_properties = properties_length / 2;
for (int p = 0; p != properties_length; p += 2) { for (int index = 0; index < boilerplate_description->size(); index++) {
Object* key = constant_properties->get(p); Object* key = boilerplate_description->name(index);
uint32_t element_index = 0; uint32_t element_index = 0;
if (key->ToArrayIndex(&element_index)) { if (key->ToArrayIndex(&element_index)) {
// An index key does not require space in the property backing store. // An index key does not require space in the property backing store.
...@@ -35,11 +35,12 @@ static Handle<Map> ComputeObjectLiteralMap( ...@@ -35,11 +35,12 @@ static Handle<Map> ComputeObjectLiteralMap(
MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals, Isolate* isolate, Handle<LiteralsArray> literals,
Handle<FixedArray> constant_properties); Handle<BoilerplateDescription> boilerplate_description);
MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals, Isolate* isolate, Handle<LiteralsArray> literals,
Handle<FixedArray> constant_properties, bool should_have_fast_elements) { Handle<BoilerplateDescription> boilerplate_description,
bool should_have_fast_elements) {
Handle<Context> context = isolate->native_context(); Handle<Context> context = isolate->native_context();
// In case we have function literals, we want the object to be in // In case we have function literals, we want the object to be in
...@@ -47,7 +48,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( ...@@ -47,7 +48,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
// maps with constant functions can't be shared if the functions are // maps with constant functions can't be shared if the functions are
// not the same (which is the common case). // not the same (which is the common case).
bool is_result_from_cache = false; bool is_result_from_cache = false;
Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties, Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description,
&is_result_from_cache); &is_result_from_cache);
PretenureFlag pretenure_flag = PretenureFlag pretenure_flag =
...@@ -60,26 +61,27 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( ...@@ -60,26 +61,27 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
// Add the constant properties to the boilerplate. // Add the constant properties to the boilerplate.
int length = constant_properties->length(); int length = boilerplate_description->size();
bool should_transform = bool should_transform =
!is_result_from_cache && boilerplate->HasFastProperties(); !is_result_from_cache && boilerplate->HasFastProperties();
bool should_normalize = should_transform; bool should_normalize = should_transform;
if (should_normalize) { if (should_normalize) {
// TODO(verwaest): We might not want to ever normalize here. // TODO(verwaest): We might not want to ever normalize here.
JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length,
length / 2, "Boilerplate"); "Boilerplate");
} }
// TODO(verwaest): Support tracking representations in the boilerplate. // TODO(verwaest): Support tracking representations in the boilerplate.
for (int index = 0; index < length; index += 2) { for (int index = 0; index < length; index++) {
Handle<Object> key(constant_properties->get(index + 0), isolate); Handle<Object> key(boilerplate_description->name(index), isolate);
Handle<Object> value(constant_properties->get(index + 1), isolate); Handle<Object> value(boilerplate_description->value(index), isolate);
if (value->IsFixedArray()) { if (value->IsBoilerplateDescription()) {
// The value contains the constant_properties of a // The value contains the boilerplate properties of a
// simple object or array literal. // simple object or array literal.
Handle<FixedArray> array = Handle<FixedArray>::cast(value); Handle<BoilerplateDescription> boilerplate =
Handle<BoilerplateDescription>::cast(value);
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, CreateLiteralBoilerplate(isolate, literals, array), isolate, value,
Object); CreateLiteralBoilerplate(isolate, literals, boilerplate), Object);
} }
MaybeHandle<Object> maybe_result; MaybeHandle<Object> maybe_result;
uint32_t element_index = 0; uint32_t element_index = 0;
...@@ -161,15 +163,16 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( ...@@ -161,15 +163,16 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
copied_elements_values = fixed_array_values_copy; copied_elements_values = fixed_array_values_copy;
FOR_WITH_HANDLE_SCOPE( FOR_WITH_HANDLE_SCOPE(
isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
if (fixed_array_values->get(i)->IsFixedArray()) { if (fixed_array_values->get(i)->IsBoilerplateDescription()) {
// The value contains the constant_properties of a // The value contains the boilerplate properties of a
// simple object or array literal. // simple object or array literal.
Handle<FixedArray> fa( Handle<BoilerplateDescription> boilerplate(
FixedArray::cast(fixed_array_values->get(i))); BoilerplateDescription::cast(fixed_array_values->get(i)));
Handle<Object> result; Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, result, isolate, result,
CreateLiteralBoilerplate(isolate, literals, fa), Object); CreateLiteralBoilerplate(isolate, literals, boilerplate),
Object);
fixed_array_values_copy->set(i, *result); fixed_array_values_copy->set(i, *result);
} }
}); });
...@@ -184,15 +187,17 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( ...@@ -184,15 +187,17 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
Isolate* isolate, Handle<LiteralsArray> literals, Isolate* isolate, Handle<LiteralsArray> literals,
Handle<FixedArray> array) { Handle<BoilerplateDescription> array) {
Handle<HeapObject> elements = CompileTimeValue::GetElements(array); Handle<HeapObject> elements = CompileTimeValue::GetElements(array);
switch (CompileTimeValue::GetLiteralType(array)) { switch (CompileTimeValue::GetLiteralType(array)) {
case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: {
Handle<FixedArray> props = Handle<FixedArray>::cast(elements); Handle<BoilerplateDescription> props =
Handle<BoilerplateDescription>::cast(elements);
return CreateObjectLiteralBoilerplate(isolate, literals, props, true); return CreateObjectLiteralBoilerplate(isolate, literals, props, true);
} }
case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: {
Handle<FixedArray> props = Handle<FixedArray>::cast(elements); Handle<BoilerplateDescription> props =
Handle<BoilerplateDescription>::cast(elements);
return CreateObjectLiteralBoilerplate(isolate, literals, props, false); return CreateObjectLiteralBoilerplate(isolate, literals, props, false);
} }
case CompileTimeValue::ARRAY_LITERAL: { case CompileTimeValue::ARRAY_LITERAL: {
...@@ -231,7 +236,8 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { ...@@ -231,7 +236,8 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
DCHECK_EQ(4, args.length()); DCHECK_EQ(4, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_SMI_ARG_CHECKED(literals_index, 1);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description,
2);
CONVERT_SMI_ARG_CHECKED(flags, 3); CONVERT_SMI_ARG_CHECKED(flags, 3);
Handle<LiteralsArray> literals(closure->literals(), isolate); Handle<LiteralsArray> literals(closure->literals(), isolate);
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
...@@ -248,7 +254,8 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { ...@@ -248,7 +254,8 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
Handle<Object> raw_boilerplate; Handle<Object> raw_boilerplate;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, raw_boilerplate, isolate, raw_boilerplate,
CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, CreateObjectLiteralBoilerplate(isolate, literals,
boilerplate_description,
should_have_fast_elements)); should_have_fast_elements));
boilerplate = Handle<JSObject>::cast(raw_boilerplate); boilerplate = Handle<JSObject>::cast(raw_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