aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/access-info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/access-info.cc')
-rw-r--r--src/compiler/access-info.cc91
1 files changed, 60 insertions, 31 deletions
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index 866b0608..8fef2f07 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -52,6 +52,8 @@ std::ostream& operator<<(std::ostream& os, AccessMode access_mode) {
return os << "Load";
case AccessMode::kStore:
return os << "Store";
+ case AccessMode::kStoreInLiteral:
+ return os << "StoreInLiteral";
}
UNREACHABLE();
return os;
@@ -78,11 +80,12 @@ PropertyAccessInfo PropertyAccessInfo::DataConstant(
// static
PropertyAccessInfo PropertyAccessInfo::DataField(
- MapList const& receiver_maps, FieldIndex field_index,
- MachineRepresentation field_representation, Type* field_type,
- MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder,
+ PropertyConstness constness, MapList const& receiver_maps,
+ FieldIndex field_index, MachineRepresentation field_representation,
+ Type* field_type, MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder,
MaybeHandle<Map> transition_map) {
- return PropertyAccessInfo(holder, transition_map, field_index,
+ Kind kind = constness == kConst ? kDataConstantField : kDataField;
+ return PropertyAccessInfo(kind, holder, transition_map, field_index,
field_representation, field_type, field_map,
receiver_maps);
}
@@ -124,10 +127,10 @@ PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
field_type_(Type::Any()) {}
PropertyAccessInfo::PropertyAccessInfo(
- MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
+ Kind kind, MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map,
FieldIndex field_index, MachineRepresentation field_representation,
Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps)
- : kind_(kDataField),
+ : kind_(kind),
receiver_maps_(receiver_maps),
transition_map_(transition_map),
holder_(holder),
@@ -144,13 +147,13 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) {
case kInvalid:
break;
- case kNotFound:
- return true;
-
- case kDataField: {
+ case kDataField:
+ case kDataConstantField: {
// Check if we actually access the same field.
- if (this->transition_map_.address() == that->transition_map_.address() &&
+ if (this->kind_ == that->kind_ &&
+ this->transition_map_.address() == that->transition_map_.address() &&
this->field_index_ == that->field_index_ &&
+ this->field_map_.address() == that->field_map_.address() &&
this->field_type_->Is(that->field_type_) &&
that->field_type_->Is(this->field_type_) &&
this->field_representation_ == that->field_representation_) {
@@ -173,6 +176,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) {
}
return false;
}
+
+ case kNotFound:
case kGeneric: {
this->receiver_maps_.insert(this->receiver_maps_.end(),
that->receiver_maps_.begin(),
@@ -282,7 +287,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
int const number = descriptors->SearchWithCache(isolate(), *name, *map);
if (number != DescriptorArray::kNotFound) {
PropertyDetails const details = descriptors->GetDetails(number);
- if (access_mode == AccessMode::kStore) {
+ if (access_mode == AccessMode::kStore ||
+ access_mode == AccessMode::kStoreInLiteral) {
// Don't bother optimizing stores to read-only properties.
if (details.IsReadOnly()) {
return false;
@@ -295,14 +301,8 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
return LookupTransition(receiver_map, name, holder, access_info);
}
}
- switch (details.type()) {
- case DATA_CONSTANT: {
- *access_info = PropertyAccessInfo::DataConstant(
- MapList{receiver_map},
- handle(descriptors->GetValue(number), isolate()), holder);
- return true;
- }
- case DATA: {
+ if (details.location() == kField) {
+ if (details.kind() == kData) {
int index = descriptors->GetFieldIndex(number);
Representation details_representation = details.representation();
FieldIndex field_index = FieldIndex::ForPropertyIndex(
@@ -341,11 +341,25 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
}
}
*access_info = PropertyAccessInfo::DataField(
- MapList{receiver_map}, field_index, field_representation,
- field_type, field_map, holder);
+ details.constness(), MapList{receiver_map}, field_index,
+ field_representation, field_type, field_map, holder);
return true;
+ } else {
+ DCHECK_EQ(kAccessor, details.kind());
+ // TODO(turbofan): Add support for general accessors?
+ return false;
}
- case ACCESSOR_CONSTANT: {
+
+ } else {
+ DCHECK_EQ(kDescriptor, details.location());
+ if (details.kind() == kData) {
+ DCHECK(!FLAG_track_constant_fields);
+ *access_info = PropertyAccessInfo::DataConstant(
+ MapList{receiver_map},
+ handle(descriptors->GetValue(number), isolate()), holder);
+ return true;
+ } else {
+ DCHECK_EQ(kAccessor, details.kind());
Handle<Object> accessors(descriptors->GetValue(number), isolate());
if (!accessors->IsAccessorPair()) return false;
Handle<Object> accessor(
@@ -361,15 +375,23 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
if (optimization.api_call_info()->fast_handler()->IsCode()) {
return false;
}
+ if (V8_UNLIKELY(FLAG_runtime_stats)) return false;
+ }
+ if (access_mode == AccessMode::kLoad) {
+ Handle<Name> cached_property_name;
+ if (FunctionTemplateInfo::TryGetCachedPropertyName(isolate(),
+ accessor)
+ .ToHandle(&cached_property_name)) {
+ if (ComputePropertyAccessInfo(map, cached_property_name,
+ access_mode, access_info)) {
+ return true;
+ }
+ }
}
*access_info = PropertyAccessInfo::AccessorConstant(
MapList{receiver_map}, accessor, holder);
return true;
}
- case ACCESSOR: {
- // TODO(turbofan): Add support for general accessors?
- return false;
- }
}
UNREACHABLE();
return false;
@@ -382,6 +404,11 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
return false;
}
+ // Don't search on the prototype when storing in literals
+ if (access_mode == AccessMode::kStoreInLiteral) {
+ return LookupTransition(receiver_map, name, holder, access_info);
+ }
+
// Don't lookup private symbols on the prototype chain.
if (name->IsPrivate()) return false;
@@ -478,8 +505,9 @@ bool AccessInfoFactory::LookupSpecialFieldAccessor(
field_type = type_cache_.kJSArrayLengthType;
}
}
+ // Special fields are always mutable.
*access_info = PropertyAccessInfo::DataField(
- MapList{map}, field_index, field_representation, field_type);
+ kMutable, MapList{map}, field_index, field_representation, field_type);
return true;
}
return false;
@@ -503,7 +531,7 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
// Don't bother optimizing stores to read-only properties.
if (details.IsReadOnly()) return false;
// TODO(bmeurer): Handle transition to data constant?
- if (details.type() != DATA) return false;
+ if (details.location() != kField) return false;
int const index = details.field_index();
Representation details_representation = details.representation();
FieldIndex field_index = FieldIndex::ForPropertyIndex(
@@ -539,9 +567,10 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
}
}
dependencies()->AssumeMapNotDeprecated(transition_map);
+ // Transitioning stores are never stores to constant fields.
*access_info = PropertyAccessInfo::DataField(
- MapList{map}, field_index, field_representation, field_type, field_map,
- holder, transition_map);
+ kMutable, MapList{map}, field_index, field_representation, field_type,
+ field_map, holder, transition_map);
return true;
}
return false;