diff options
Diffstat (limited to 'src/compiler/access-info.cc')
-rw-r--r-- | src/compiler/access-info.cc | 91 |
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; |