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( ...@@ -294,8 +294,25 @@ bool AddDescriptorsByTemplate(
: ShallowCopyDictionaryTemplate(isolate, : ShallowCopyDictionaryTemplate(isolate,
elements_dictionary_template); 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 // Read values from |descriptors_template| and store possibly post-processed
// values into "instantiated" |descriptors| array. // values into "instantiated" |descriptors| array.
int field_index = 0;
for (int i = 0; i < nof_descriptors; i++) { for (int i = 0; i < nof_descriptors; i++) {
Object* value = descriptors_template->GetStrongValue(i); Object* value = descriptors_template->GetStrongValue(i);
if (value->IsAccessorPair()) { if (value->IsAccessorPair()) {
...@@ -315,7 +332,6 @@ bool AddDescriptorsByTemplate( ...@@ -315,7 +332,6 @@ bool AddDescriptorsByTemplate(
} }
details = details =
details.CopyWithRepresentation(value->OptimalRepresentation()); details.CopyWithRepresentation(value->OptimalRepresentation());
} else { } else {
DCHECK_EQ(kAccessor, details.kind()); DCHECK_EQ(kAccessor, details.kind());
if (value->IsAccessorPair()) { if (value->IsAccessorPair()) {
...@@ -333,11 +349,24 @@ bool AddDescriptorsByTemplate( ...@@ -333,11 +349,24 @@ bool AddDescriptorsByTemplate(
} }
} }
} else { } else {
DCHECK_EQ(kField, details.location()); UNREACHABLE();
DCHECK(!details.representation().IsDouble());
} }
DCHECK(value->FitsRepresentation(details.representation())); 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, map->InitializeDescriptors(*descriptors,
...@@ -355,6 +384,9 @@ bool AddDescriptorsByTemplate( ...@@ -355,6 +384,9 @@ bool AddDescriptorsByTemplate(
if (elements_dictionary->NumberOfElements() > 0) { if (elements_dictionary->NumberOfElements() > 0) {
receiver->set_elements(*elements_dictionary); receiver->set_elements(*elements_dictionary);
} }
if (property_array->length() > 0) {
receiver->SetProperties(*property_array);
}
return true; return true;
} }
...@@ -438,9 +470,20 @@ Handle<JSObject> CreateClassPrototype(Isolate* isolate) { ...@@ -438,9 +470,20 @@ Handle<JSObject> CreateClassPrototype(Isolate* isolate) {
const int kInobjectFields = 0; const int kInobjectFields = 0;
// Just use some JSObject map of certain size. Handle<Map> map;
Handle<Map> map = factory->ObjectLiteralMapFromCache( if (FLAG_track_constant_fields) {
isolate->native_context(), kInobjectFields); // 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); 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