Commit 52c1a368 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[constant-tracking] Make class boilerplate work with CFT.

This is a hacky approach to make constant field tracking somewhat
friendly to class boilerplates - if the class boilerplate has
an on-descriptor-data field, we change the field to be
an on-instance-const-field and store it on the instance.

Bug: v8:8361
Change-Id: I5152041363bcd26568669fee93c91ff362ba8de9
Reviewed-on: https://chromium-review.googlesource.com/c/1319869
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57344}
parent f4603157
......@@ -294,8 +294,25 @@ bool AddDescriptorsByTemplate(
: ShallowCopyDictionaryTemplate(isolate,
elements_dictionary_template);
Handle<PropertyArray> property_array =
isolate->factory()->empty_property_array();
if (FLAG_track_constant_fields) {
// If we store constants in instances, count the number of properties
// that must be in the instance and create the property array to
// hold the constants.
int count = 0;
for (int i = 0; i < nof_descriptors; i++) {
PropertyDetails details = descriptors_template->GetDetails(i);
if (details.location() == kDescriptor && details.kind() == kData) {
count++;
}
}
property_array = isolate->factory()->NewPropertyArray(count);
}
// Read values from |descriptors_template| and store possibly post-processed
// values into "instantiated" |descriptors| array.
int field_index = 0;
for (int i = 0; i < nof_descriptors; i++) {
Object* value = descriptors_template->GetStrongValue(i);
if (value->IsAccessorPair()) {
......@@ -315,7 +332,6 @@ bool AddDescriptorsByTemplate(
}
details =
details.CopyWithRepresentation(value->OptimalRepresentation());
} else {
DCHECK_EQ(kAccessor, details.kind());
if (value->IsAccessorPair()) {
......@@ -333,11 +349,24 @@ bool AddDescriptorsByTemplate(
}
}
} else {
DCHECK_EQ(kField, details.location());
DCHECK(!details.representation().IsDouble());
UNREACHABLE();
}
DCHECK(value->FitsRepresentation(details.representation()));
descriptors->Set(i, name, MaybeObject::FromObject(value), details);
// With constant field tracking, we store the values in the instance.
if (FLAG_track_constant_fields && details.location() == kDescriptor &&
details.kind() == kData) {
details = PropertyDetails(details.kind(), details.attributes(), kField,
PropertyConstness::kConst,
details.representation(), field_index)
.set_pointer(details.pointer());
property_array->set(field_index, value);
field_index++;
descriptors->Set(i, name, MaybeObject::FromObject(FieldType::Any()),
details);
} else {
descriptors->Set(i, name, MaybeObject::FromObject(value), details);
}
}
map->InitializeDescriptors(*descriptors,
......@@ -355,6 +384,9 @@ bool AddDescriptorsByTemplate(
if (elements_dictionary->NumberOfElements() > 0) {
receiver->set_elements(*elements_dictionary);
}
if (property_array->length() > 0) {
receiver->SetProperties(*property_array);
}
return true;
}
......@@ -438,9 +470,20 @@ Handle<JSObject> CreateClassPrototype(Isolate* isolate) {
const int kInobjectFields = 0;
// Just use some JSObject map of certain size.
Handle<Map> map = factory->ObjectLiteralMapFromCache(
isolate->native_context(), kInobjectFields);
Handle<Map> map;
if (FLAG_track_constant_fields) {
// For constant tracking we want to avoid tha hassle of handling
// in-object properties, so create a map with no in-object
// properties.
// TODO(ishell) Support caching of zero in-object properties map
// by ObjectLiteralMapFromCache().
map = Map::Create(isolate, 0);
} else {
// Just use some JSObject map of certain size.
map = factory->ObjectLiteralMapFromCache(isolate->native_context(),
kInobjectFields);
}
return factory->NewJSObjectFromMap(map);
}
......
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