Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Unified Diff: src/objects.cc

Issue 2598543003: [runtime][ic] Constant field tracking support. (Closed)
Patch Set: Addressing comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 403b470edf638435f638f19e805e04276638bad5..bcceb841af0738578ff770cc0fdf61d5561dce9a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3368,6 +3368,7 @@ FieldType* Map::UnwrapFieldType(Object* wrapped_type) {
MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
Handle<FieldType> type,
PropertyAttributes attributes,
+ PropertyConstness constness,
Representation representation,
TransitionFlag flag) {
DCHECK(DescriptorArray::kNotFound ==
@@ -3391,7 +3392,8 @@ MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, Handle<Name> name,
Handle<Object> wrapped_type(WrapFieldType(type));
- Descriptor d = Descriptor::DataField(name, index, attributes, kMutable,
+ DCHECK_IMPLIES(!FLAG_track_constant_fields, constness == kMutable);
+ Descriptor d = Descriptor::DataField(name, index, attributes, constness,
representation, wrapped_type);
Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
int unused_property_fields = new_map->unused_property_fields() - 1;
@@ -3413,9 +3415,18 @@ MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
return MaybeHandle<Map>();
}
- // Allocate new instance descriptors with (name, constant) added.
- Descriptor d = Descriptor::DataConstant(name, constant, attributes);
- return Map::CopyAddDescriptor(map, &d, flag);
+ if (FLAG_track_constant_fields) {
+ Isolate* isolate = map->GetIsolate();
+ Representation representation = constant->OptimalRepresentation();
+ Handle<FieldType> type = constant->OptimalType(isolate, representation);
+ return CopyWithField(map, name, type, attributes, kConst, representation,
+ flag);
+ } else {
+ // Allocate new instance descriptors with (name, constant) added.
+ Descriptor d = Descriptor::DataConstant(name, 0, constant, attributes);
+ Handle<Map> new_map = Map::CopyAddDescriptor(map, &d, flag);
+ return new_map;
+ }
}
const char* Representation::Mnemonic() const {
@@ -3923,6 +3934,7 @@ void DescriptorArray::GeneralizeAllFields() {
details = details.CopyWithRepresentation(Representation::Tagged());
if (details.location() == kField) {
DCHECK_EQ(kData, details.kind());
+ details = details.CopyWithConstness(kMutable);
SetValue(i, FieldType::Any());
}
set(ToDetailsIndex(i), details.AsSmi());
@@ -3950,7 +3962,8 @@ Handle<Map> Map::CopyGeneralizeAllFields(Handle<Map> map,
// Unless the instance is being migrated, ensure that modify_index is a field.
if (modify_index >= 0) {
PropertyDetails details = descriptors->GetDetails(modify_index);
- if (details.location() != kField || details.attributes() != attributes) {
+ if (details.constness() != kMutable || details.location() != kField ||
+ details.attributes() != attributes) {
int field_index = details.location() == kField
? details.field_index()
: new_map->NumberOfFields();
@@ -4059,8 +4072,8 @@ Map* Map::FindFieldOwner(int descriptor) {
return result;
}
-
void Map::UpdateFieldType(int descriptor, Handle<Name> name,
+ PropertyConstness new_constness,
Representation new_representation,
Handle<Object> new_wrapped_type) {
DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
@@ -4087,15 +4100,19 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
DescriptorArray* descriptors = current->instance_descriptors();
PropertyDetails details = descriptors->GetDetails(descriptor);
+ // Currently constness change implies map change.
+ DCHECK_EQ(new_constness, details.constness());
+
// It is allowed to change representation here only from None to something.
DCHECK(details.representation().Equals(new_representation) ||
details.representation().IsNone());
// Skip if already updated the shared descriptor.
if (descriptors->GetValue(descriptor) != *new_wrapped_type) {
+ DCHECK_IMPLIES(!FLAG_track_constant_fields, new_constness == kMutable);
Descriptor d = Descriptor::DataField(
name, descriptors->GetFieldIndex(descriptor), details.attributes(),
- kMutable, new_representation, new_wrapped_type);
+ new_constness, new_representation, new_wrapped_type);
descriptors->Replace(descriptor, &d);
}
}
@@ -4126,18 +4143,21 @@ Handle<FieldType> Map::GeneralizeFieldType(Representation rep1,
// static
void Map::GeneralizeField(Handle<Map> map, int modify_index,
+ PropertyConstness new_constness,
Representation new_representation,
Handle<FieldType> new_field_type) {
Isolate* isolate = map->GetIsolate();
// Check if we actually need to generalize the field type at all.
Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
- Representation old_representation =
- old_descriptors->GetDetails(modify_index).representation();
+ PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
+ PropertyConstness old_constness = old_details.constness();
+ Representation old_representation = old_details.representation();
Handle<FieldType> old_field_type(old_descriptors->GetFieldType(modify_index),
isolate);
- if (old_representation.Equals(new_representation) &&
+ if (old_constness == new_constness &&
+ old_representation.Equals(new_representation) &&
!FieldTypeIsCleared(new_representation, *new_field_type) &&
// Checking old_field_type for being cleared is not necessary because
// the NowIs check below would fail anyway in that case.
@@ -4162,8 +4182,8 @@ void Map::GeneralizeField(Handle<Map> map, int modify_index,
Handle<Name> name(descriptors->GetKey(modify_index));
Handle<Object> wrapped_type(WrapFieldType(new_field_type));
- field_owner->UpdateFieldType(modify_index, name, new_representation,
- wrapped_type);
+ field_owner->UpdateFieldType(modify_index, name, new_constness,
+ new_representation, wrapped_type);
field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
isolate, DependentCode::kFieldOwnerGroup);
@@ -4185,7 +4205,7 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index,
Handle<FieldType> new_field_type) {
DCHECK_EQ(kData, new_kind); // Only kData case is supported.
MapUpdater mu(map->GetIsolate(), map);
- return mu.ReconfigureToDataField(modify_index, new_attributes,
+ return mu.ReconfigureToDataField(modify_index, new_attributes, kConst,
new_representation, new_field_type);
}
@@ -4208,7 +4228,7 @@ Handle<Map> Map::GeneralizeAllFields(Handle<Map> map) {
if (details.location() == kField) {
DCHECK_EQ(kData, details.kind());
MapUpdater mu(isolate, map);
- map = mu.ReconfigureToDataField(i, details.attributes(),
+ map = mu.ReconfigureToDataField(i, details.attributes(), kMutable,
Representation::Tagged(), any_type);
}
}
@@ -4286,6 +4306,7 @@ Map* Map::TryReplayPropertyTransitions(Map* old_map) {
}
} else {
DCHECK_EQ(kDescriptor, old_details.location());
+ DCHECK(!FLAG_track_constant_fields);
Object* old_value = old_descriptors->GetValue(i);
if (!new_type->NowContains(old_value)) {
return nullptr;
@@ -4608,7 +4629,7 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
it->PrepareForDataProperty(to_assign);
// Write the property value.
- it->WriteDataValue(to_assign);
+ it->WriteDataValue(to_assign, false);
#if VERIFY_HEAP
if (FLAG_verify_heap) {
@@ -4682,7 +4703,7 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
it->ApplyTransitionToDataProperty(receiver);
// Write the property value.
- it->WriteDataValue(value);
+ it->WriteDataValue(value, true);
#if VERIFY_HEAP
if (FLAG_verify_heap) {
@@ -5716,9 +5737,13 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
PropertyKind kind = dictionary->DetailsAt(index).kind();
if (kind == kData) {
- Object* value = dictionary->ValueAt(index);
- if (!value->IsJSFunction()) {
+ if (FLAG_track_constant_fields) {
number_of_fields += 1;
+ } else {
+ Object* value = dictionary->ValueAt(index);
+ if (!value->IsJSFunction()) {
+ number_of_fields += 1;
+ }
}
}
}
@@ -5789,14 +5814,14 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
Descriptor d;
if (details.kind() == kData) {
- if (value->IsJSFunction()) {
+ if (!FLAG_track_constant_fields && value->IsJSFunction()) {
d = Descriptor::DataConstant(key, handle(value, isolate),
details.attributes());
} else {
d = Descriptor::DataField(
- key, current_offset, details.attributes(),
+ key, current_offset, details.attributes(), kDefaultFieldConstness,
// TODO(verwaest): value->OptimalRepresentation();
- Representation::Tagged());
+ Representation::Tagged(), FieldType::Any(isolate));
}
} else {
DCHECK_EQ(kAccessor, details.kind());
@@ -7007,7 +7032,7 @@ Maybe<bool> JSProxy::SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
if (it.IsFound()) {
DCHECK_EQ(LookupIterator::DATA, it.state());
DCHECK_EQ(DONT_ENUM, it.property_attributes());
- it.WriteDataValue(value);
+ it.WriteDataValue(value, false);
return Just(true);
}
@@ -9160,16 +9185,16 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
namespace {
-bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) {
+bool CanHoldValue(DescriptorArray* descriptors, int descriptor,
+ PropertyConstness constness, Object* value) {
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.location() == kField) {
- DCHECK_EQ(kMutable, details.constness());
if (details.kind() == kData) {
- return value->FitsRepresentation(details.representation()) &&
+ return IsGeneralizableTo(constness, details.constness()) &&
+ value->FitsRepresentation(details.representation()) &&
descriptors->GetFieldType(descriptor)->NowContains(value);
} else {
DCHECK_EQ(kAccessor, details.kind());
- UNREACHABLE();
return false;
}
@@ -9177,6 +9202,7 @@ bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) {
DCHECK_EQ(kDescriptor, details.location());
DCHECK_EQ(kConst, details.constness());
if (details.kind() == kData) {
+ DCHECK(!FLAG_track_constant_fields);
DCHECK(descriptors->GetValue(descriptor) != value ||
value->FitsRepresentation(details.representation()));
return descriptors->GetValue(descriptor) == value;
@@ -9190,8 +9216,12 @@ bool CanHoldValue(DescriptorArray* descriptors, int descriptor, Object* value) {
}
Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
+ PropertyConstness constness,
Handle<Object> value) {
- if (CanHoldValue(map->instance_descriptors(), descriptor, *value)) return map;
+ if (CanHoldValue(map->instance_descriptors(), descriptor, constness,
+ *value)) {
+ return map;
+ }
Isolate* isolate = map->GetIsolate();
PropertyAttributes attributes =
@@ -9200,8 +9230,8 @@ Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
Handle<FieldType> type = value->OptimalType(isolate, representation);
MapUpdater mu(isolate, map);
- Handle<Map> new_map =
- mu.ReconfigureToDataField(descriptor, attributes, representation, type);
+ Handle<Map> new_map = mu.ReconfigureToDataField(
+ descriptor, attributes, constness, representation, type);
new_map->set_migration_target(true);
return new_map;
}
@@ -9210,17 +9240,18 @@ Handle<Map> UpdateDescriptorForValue(Handle<Map> map, int descriptor,
// static
Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
+ PropertyConstness constness,
Handle<Object> value) {
// Dictionaries can store any property value.
DCHECK(!map->is_dictionary_map());
// Update to the newest map before storing the property.
- return UpdateDescriptorForValue(Update(map), descriptor, value);
+ return UpdateDescriptorForValue(Update(map), descriptor, constness, value);
}
-
Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
+ PropertyConstness constness,
StoreFromKeyed store_mode) {
RuntimeCallTimerScope stats_scope(
*map, map->is_prototype_map()
@@ -9243,19 +9274,19 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
->GetDetails(descriptor)
.attributes());
- return UpdateDescriptorForValue(transition, descriptor, value);
+ return UpdateDescriptorForValue(transition, descriptor, constness, value);
}
TransitionFlag flag = INSERT_TRANSITION;
MaybeHandle<Map> maybe_map;
- if (value->IsJSFunction()) {
+ if (!FLAG_track_constant_fields && value->IsJSFunction()) {
maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
} else if (!map->TooManyFastProperties(store_mode)) {
Isolate* isolate = name->GetIsolate();
Representation representation = value->OptimalRepresentation();
Handle<FieldType> type = value->OptimalType(isolate, representation);
- maybe_map =
- Map::CopyWithField(map, name, type, attributes, representation, flag);
+ maybe_map = Map::CopyWithField(map, name, type, attributes, constness,
+ representation, flag);
}
Handle<Map> result;
@@ -9300,7 +9331,8 @@ Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor,
MapUpdater mu(isolate, map);
DCHECK_EQ(kData, kind); // Only kData case is supported so far.
Handle<Map> new_map = mu.ReconfigureToDataField(
- descriptor, attributes, Representation::None(), FieldType::None(isolate));
+ descriptor, attributes, kDefaultFieldConstness, Representation::None(),
+ FieldType::None(isolate));
return new_map;
}
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698