[ptr-compr][cleanup] Prepare for improving literals creation
Create[Array|Object]Literal were simply extracted from Helper classes. Bug: v8:9353 Change-Id: I8a97a7d5151c324db4a924cbfe1720444a1529aa Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1683992 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#62474}
This commit is contained in:
parent
6f41bff276
commit
0c2cd56551
@ -324,135 +324,159 @@ MaybeHandle<JSObject> DeepCopy(Handle<JSObject> object,
|
||||
return copy;
|
||||
}
|
||||
|
||||
Handle<JSObject> CreateObjectLiteral(
|
||||
Isolate* isolate,
|
||||
Handle<ObjectBoilerplateDescription> object_boilerplate_description,
|
||||
int flags, AllocationType allocation);
|
||||
|
||||
Handle<JSObject> CreateArrayLiteral(
|
||||
Isolate* isolate,
|
||||
Handle<ArrayBoilerplateDescription> array_boilerplate_description,
|
||||
AllocationType allocation);
|
||||
|
||||
struct ObjectLiteralHelper {
|
||||
static Handle<JSObject> Create(Isolate* isolate,
|
||||
Handle<HeapObject> description, int flags,
|
||||
AllocationType allocation) {
|
||||
Handle<NativeContext> native_context = isolate->native_context();
|
||||
static inline Handle<JSObject> Create(Isolate* isolate,
|
||||
Handle<HeapObject> description,
|
||||
int flags, AllocationType allocation) {
|
||||
Handle<ObjectBoilerplateDescription> object_boilerplate_description =
|
||||
Handle<ObjectBoilerplateDescription>::cast(description);
|
||||
bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
|
||||
bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0;
|
||||
|
||||
// In case we have function literals, we want the object to be in
|
||||
// slow properties mode for now. We don't go in the map cache because
|
||||
// maps with constant functions can't be shared if the functions are
|
||||
// not the same (which is the common case).
|
||||
int number_of_properties =
|
||||
object_boilerplate_description->backing_store_size();
|
||||
|
||||
// Ignoring number_of_properties for force dictionary map with
|
||||
// __proto__:null.
|
||||
Handle<Map> map =
|
||||
has_null_prototype
|
||||
? handle(native_context->slow_object_with_null_prototype_map(),
|
||||
isolate)
|
||||
: isolate->factory()->ObjectLiteralMapFromCache(
|
||||
native_context, number_of_properties);
|
||||
|
||||
Handle<JSObject> boilerplate =
|
||||
isolate->factory()->NewFastOrSlowJSObjectFromMap(
|
||||
map, number_of_properties, allocation);
|
||||
|
||||
// Normalize the elements of the boilerplate to save space if needed.
|
||||
if (!use_fast_elements) JSObject::NormalizeElements(boilerplate);
|
||||
|
||||
// Add the constant properties to the boilerplate.
|
||||
int length = object_boilerplate_description->size();
|
||||
// TODO(verwaest): Support tracking representations in the boilerplate.
|
||||
for (int index = 0; index < length; index++) {
|
||||
Handle<Object> key(object_boilerplate_description->name(index), isolate);
|
||||
Handle<Object> value(object_boilerplate_description->value(index),
|
||||
isolate);
|
||||
|
||||
if (value->IsObjectBoilerplateDescription() ||
|
||||
value->IsArrayBoilerplateDescription()) {
|
||||
value = InnerCreateBoilerplate(isolate, value, allocation);
|
||||
}
|
||||
uint32_t element_index = 0;
|
||||
if (key->ToArrayIndex(&element_index)) {
|
||||
// Array index (uint32).
|
||||
if (value->IsUninitialized(isolate)) {
|
||||
value = handle(Smi::kZero, isolate);
|
||||
}
|
||||
JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index,
|
||||
value, NONE)
|
||||
.Check();
|
||||
} else {
|
||||
Handle<String> name = Handle<String>::cast(key);
|
||||
DCHECK(!name->AsArrayIndex(&element_index));
|
||||
JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE)
|
||||
.Check();
|
||||
}
|
||||
}
|
||||
|
||||
if (map->is_dictionary_map() && !has_null_prototype) {
|
||||
// TODO(cbruni): avoid making the boilerplate fast again, the clone stub
|
||||
// supports dict-mode objects directly.
|
||||
JSObject::MigrateSlowToFast(boilerplate,
|
||||
boilerplate->map().UnusedPropertyFields(),
|
||||
"FastLiteral");
|
||||
}
|
||||
return boilerplate;
|
||||
return CreateObjectLiteral(isolate, object_boilerplate_description, flags,
|
||||
allocation);
|
||||
}
|
||||
};
|
||||
|
||||
struct ArrayLiteralHelper {
|
||||
static Handle<JSObject> Create(Isolate* isolate,
|
||||
Handle<HeapObject> description, int flags,
|
||||
AllocationType allocation) {
|
||||
static inline Handle<JSObject> Create(Isolate* isolate,
|
||||
Handle<HeapObject> description,
|
||||
int flags_not_used,
|
||||
AllocationType allocation) {
|
||||
Handle<ArrayBoilerplateDescription> array_boilerplate_description =
|
||||
Handle<ArrayBoilerplateDescription>::cast(description);
|
||||
return CreateArrayLiteral(isolate, array_boilerplate_description,
|
||||
allocation);
|
||||
}
|
||||
};
|
||||
|
||||
ElementsKind constant_elements_kind =
|
||||
array_boilerplate_description->elements_kind();
|
||||
Handle<JSObject> CreateObjectLiteral(
|
||||
Isolate* isolate,
|
||||
Handle<ObjectBoilerplateDescription> object_boilerplate_description,
|
||||
int flags, AllocationType allocation) {
|
||||
Handle<NativeContext> native_context = isolate->native_context();
|
||||
bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
|
||||
bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0;
|
||||
|
||||
Handle<FixedArrayBase> constant_elements_values(
|
||||
array_boilerplate_description->constant_elements(), isolate);
|
||||
// In case we have function literals, we want the object to be in
|
||||
// slow properties mode for now. We don't go in the map cache because
|
||||
// maps with constant functions can't be shared if the functions are
|
||||
// not the same (which is the common case).
|
||||
int number_of_properties =
|
||||
object_boilerplate_description->backing_store_size();
|
||||
|
||||
// Create the JSArray.
|
||||
Handle<FixedArrayBase> copied_elements_values;
|
||||
if (IsDoubleElementsKind(constant_elements_kind)) {
|
||||
copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
|
||||
Handle<FixedDoubleArray>::cast(constant_elements_values));
|
||||
// Ignoring number_of_properties for force dictionary map with
|
||||
// __proto__:null.
|
||||
Handle<Map> map =
|
||||
has_null_prototype
|
||||
? handle(native_context->slow_object_with_null_prototype_map(),
|
||||
isolate)
|
||||
: isolate->factory()->ObjectLiteralMapFromCache(native_context,
|
||||
number_of_properties);
|
||||
|
||||
Handle<JSObject> boilerplate =
|
||||
isolate->factory()->NewFastOrSlowJSObjectFromMap(
|
||||
map, number_of_properties, allocation);
|
||||
|
||||
// Normalize the elements of the boilerplate to save space if needed.
|
||||
if (!use_fast_elements) JSObject::NormalizeElements(boilerplate);
|
||||
|
||||
// Add the constant properties to the boilerplate.
|
||||
int length = object_boilerplate_description->size();
|
||||
// TODO(verwaest): Support tracking representations in the boilerplate.
|
||||
for (int index = 0; index < length; index++) {
|
||||
Handle<Object> key(object_boilerplate_description->name(index), isolate);
|
||||
Handle<Object> value(object_boilerplate_description->value(index), isolate);
|
||||
|
||||
if (value->IsObjectBoilerplateDescription() ||
|
||||
value->IsArrayBoilerplateDescription()) {
|
||||
value = InnerCreateBoilerplate(isolate, value, allocation);
|
||||
}
|
||||
uint32_t element_index = 0;
|
||||
if (key->ToArrayIndex(&element_index)) {
|
||||
// Array index (uint32).
|
||||
if (value->IsUninitialized(isolate)) {
|
||||
value = handle(Smi::kZero, isolate);
|
||||
}
|
||||
JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index, value,
|
||||
NONE)
|
||||
.Check();
|
||||
} else {
|
||||
DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind));
|
||||
const bool is_cow = (constant_elements_values->map() ==
|
||||
ReadOnlyRoots(isolate).fixed_cow_array_map());
|
||||
if (is_cow) {
|
||||
copied_elements_values = constant_elements_values;
|
||||
#if DEBUG
|
||||
Handle<String> name = Handle<String>::cast(key);
|
||||
DCHECK(!name->AsArrayIndex(&element_index));
|
||||
JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE)
|
||||
.Check();
|
||||
}
|
||||
}
|
||||
|
||||
if (map->is_dictionary_map() && !has_null_prototype) {
|
||||
// TODO(cbruni): avoid making the boilerplate fast again, the clone stub
|
||||
// supports dict-mode objects directly.
|
||||
JSObject::MigrateSlowToFast(
|
||||
boilerplate, boilerplate->map().UnusedPropertyFields(), "FastLiteral");
|
||||
}
|
||||
return boilerplate;
|
||||
}
|
||||
|
||||
Handle<JSObject> CreateArrayLiteral(
|
||||
Isolate* isolate,
|
||||
Handle<ArrayBoilerplateDescription> array_boilerplate_description,
|
||||
AllocationType allocation) {
|
||||
ElementsKind constant_elements_kind =
|
||||
array_boilerplate_description->elements_kind();
|
||||
|
||||
Handle<FixedArrayBase> constant_elements_values(
|
||||
array_boilerplate_description->constant_elements(), isolate);
|
||||
|
||||
// Create the JSArray.
|
||||
Handle<FixedArrayBase> copied_elements_values;
|
||||
if (IsDoubleElementsKind(constant_elements_kind)) {
|
||||
copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
|
||||
Handle<FixedDoubleArray>::cast(constant_elements_values));
|
||||
} else {
|
||||
DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind));
|
||||
const bool is_cow = (constant_elements_values->map() ==
|
||||
ReadOnlyRoots(isolate).fixed_cow_array_map());
|
||||
if (is_cow) {
|
||||
copied_elements_values = constant_elements_values;
|
||||
if (DEBUG_BOOL) {
|
||||
Handle<FixedArray> fixed_array_values =
|
||||
Handle<FixedArray>::cast(copied_elements_values);
|
||||
for (int i = 0; i < fixed_array_values->length(); i++) {
|
||||
DCHECK(!fixed_array_values->get(i).IsFixedArray());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
Handle<FixedArray> fixed_array_values =
|
||||
Handle<FixedArray>::cast(constant_elements_values);
|
||||
Handle<FixedArray> fixed_array_values_copy =
|
||||
isolate->factory()->CopyFixedArray(fixed_array_values);
|
||||
copied_elements_values = fixed_array_values_copy;
|
||||
FOR_WITH_HANDLE_SCOPE(
|
||||
isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
|
||||
Handle<Object> value(fixed_array_values->get(i), isolate);
|
||||
|
||||
if (value->IsArrayBoilerplateDescription() ||
|
||||
value->IsObjectBoilerplateDescription()) {
|
||||
Handle<Object> result =
|
||||
InnerCreateBoilerplate(isolate, value, allocation);
|
||||
fixed_array_values_copy->set(i, *result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Handle<FixedArray> fixed_array_values =
|
||||
Handle<FixedArray>::cast(constant_elements_values);
|
||||
Handle<FixedArray> fixed_array_values_copy =
|
||||
isolate->factory()->CopyFixedArray(fixed_array_values);
|
||||
copied_elements_values = fixed_array_values_copy;
|
||||
FOR_WITH_HANDLE_SCOPE(
|
||||
isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
|
||||
Handle<Object> value(fixed_array_values->get(i), isolate);
|
||||
|
||||
return isolate->factory()->NewJSArrayWithElements(
|
||||
copied_elements_values, constant_elements_kind,
|
||||
copied_elements_values->length(), allocation);
|
||||
if (value->IsArrayBoilerplateDescription() ||
|
||||
value->IsObjectBoilerplateDescription()) {
|
||||
Handle<Object> result =
|
||||
InnerCreateBoilerplate(isolate, value, allocation);
|
||||
fixed_array_values_copy->set(i, *result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return isolate->factory()->NewJSArrayWithElements(
|
||||
copied_elements_values, constant_elements_kind,
|
||||
copied_elements_values->length(), allocation);
|
||||
}
|
||||
|
||||
Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
|
||||
Handle<Object> description,
|
||||
@ -554,6 +578,7 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
|
||||
usage_context.ExitScope(site, boilerplate);
|
||||
return copy;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
|
||||
|
Loading…
Reference in New Issue
Block a user