Index: src/compiler/access-info.cc |
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc |
index ecb9482c113698a2dd26e9cbec06164147208dc4..5fba6f53e90f8b96ffbcb809af87dd5ca2c452db 100644 |
--- a/src/compiler/access-info.cc |
+++ b/src/compiler/access-info.cc |
@@ -75,7 +75,7 @@ PropertyAccessInfo PropertyAccessInfo::NotFound(MapList const& receiver_maps, |
PropertyAccessInfo PropertyAccessInfo::DataConstant( |
MapList const& receiver_maps, Handle<Object> constant, |
MaybeHandle<JSObject> holder) { |
- return PropertyAccessInfo(holder, constant, receiver_maps); |
+ return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); |
} |
// static |
@@ -86,6 +86,13 @@ PropertyAccessInfo PropertyAccessInfo::DataField( |
receiver_maps); |
} |
+// static |
+PropertyAccessInfo PropertyAccessInfo::AccessorConstant( |
+ MapList const& receiver_maps, Handle<Object> constant, |
+ MaybeHandle<JSObject> holder) { |
+ return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); |
+} |
+ |
PropertyAccessInfo::PropertyAccessInfo() |
: kind_(kInvalid), field_type_(Type::Any()) {} |
@@ -96,10 +103,10 @@ PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, |
holder_(holder), |
field_type_(Type::Any()) {} |
-PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder, |
+PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder, |
Handle<Object> constant, |
MapList const& receiver_maps) |
- : kind_(kDataConstant), |
+ : kind_(kind), |
receiver_maps_(receiver_maps), |
constant_(constant), |
holder_(holder), |
@@ -141,7 +148,8 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { |
return false; |
} |
- case kDataConstant: { |
+ case kDataConstant: |
+ case kAccessorConstant: { |
// Check if we actually access the same constant. |
if (this->constant_.address() == that->constant_.address()) { |
this->receiver_maps_.insert(this->receiver_maps_.end(), |
@@ -288,50 +296,73 @@ bool AccessInfoFactory::ComputePropertyAccessInfo( |
return LookupTransition(receiver_map, name, holder, access_info); |
} |
} |
- if (details.type() == DATA_CONSTANT) { |
- *access_info = PropertyAccessInfo::DataConstant( |
- MapList{receiver_map}, |
- handle(descriptors->GetValue(number), isolate()), holder); |
- return true; |
- } else if (details.type() == DATA) { |
- int index = descriptors->GetFieldIndex(number); |
- Representation field_representation = details.representation(); |
- FieldIndex field_index = FieldIndex::ForPropertyIndex( |
- *map, index, field_representation.IsDouble()); |
- Type* field_type = Type::Tagged(); |
- if (field_representation.IsSmi()) { |
- field_type = type_cache_.kSmi; |
- } else if (field_representation.IsDouble()) { |
- field_type = type_cache_.kFloat64; |
- } else if (field_representation.IsHeapObject()) { |
- // Extract the field type from the property details (make sure its |
- // representation is TaggedPointer to reflect the heap object case). |
- field_type = Type::Intersect( |
- descriptors->GetFieldType(number)->Convert(zone()), |
- Type::TaggedPointer(), zone()); |
- if (field_type->Is(Type::None())) { |
- // Store is not safe if the field type was cleared. |
- if (access_mode == AccessMode::kStore) return false; |
- |
- // The field type was cleared by the GC, so we don't know anything |
- // about the contents now. |
- // TODO(bmeurer): It would be awesome to make this saner in the |
- // runtime/GC interaction. |
- field_type = Type::TaggedPointer(); |
- } else if (!Type::Any()->Is(field_type)) { |
- // Add proper code dependencies in case of stable field map(s). |
- Handle<Map> field_owner_map(map->FindFieldOwner(number), isolate()); |
- dependencies()->AssumeFieldType(field_owner_map); |
+ switch (details.type()) { |
+ case DATA_CONSTANT: { |
+ *access_info = PropertyAccessInfo::DataConstant( |
+ MapList{receiver_map}, |
+ handle(descriptors->GetValue(number), isolate()), holder); |
+ return true; |
+ } |
+ case DATA: { |
+ int index = descriptors->GetFieldIndex(number); |
+ Representation field_representation = details.representation(); |
+ FieldIndex field_index = FieldIndex::ForPropertyIndex( |
+ *map, index, field_representation.IsDouble()); |
+ Type* field_type = Type::Tagged(); |
+ if (field_representation.IsSmi()) { |
+ field_type = type_cache_.kSmi; |
+ } else if (field_representation.IsDouble()) { |
+ field_type = type_cache_.kFloat64; |
+ } else if (field_representation.IsHeapObject()) { |
+ // Extract the field type from the property details (make sure its |
+ // representation is TaggedPointer to reflect the heap object case). |
+ field_type = Type::Intersect( |
+ descriptors->GetFieldType(number)->Convert(zone()), |
+ Type::TaggedPointer(), zone()); |
+ if (field_type->Is(Type::None())) { |
+ // Store is not safe if the field type was cleared. |
+ if (access_mode == AccessMode::kStore) return false; |
+ |
+ // The field type was cleared by the GC, so we don't know anything |
+ // about the contents now. |
+ // TODO(bmeurer): It would be awesome to make this saner in the |
+ // runtime/GC interaction. |
+ field_type = Type::TaggedPointer(); |
+ } else if (!Type::Any()->Is(field_type)) { |
+ // Add proper code dependencies in case of stable field map(s). |
+ Handle<Map> field_owner_map(map->FindFieldOwner(number), |
+ isolate()); |
+ dependencies()->AssumeFieldType(field_owner_map); |
+ } |
+ DCHECK(field_type->Is(Type::TaggedPointer())); |
} |
- DCHECK(field_type->Is(Type::TaggedPointer())); |
+ *access_info = PropertyAccessInfo::DataField( |
+ MapList{receiver_map}, field_index, field_type, holder); |
+ return true; |
+ } |
+ case ACCESSOR_CONSTANT: { |
+ Handle<Object> accessors(descriptors->GetValue(number), isolate()); |
+ if (!accessors->IsAccessorPair()) return false; |
+ Handle<Object> accessor( |
+ access_mode == AccessMode::kLoad |
+ ? Handle<AccessorPair>::cast(accessors)->getter() |
+ : Handle<AccessorPair>::cast(accessors)->setter(), |
+ isolate()); |
+ if (!accessor->IsJSFunction()) { |
+ // TODO(turbofan): Add support for API accessors. |
+ return false; |
+ } |
+ *access_info = PropertyAccessInfo::AccessorConstant( |
+ MapList{receiver_map}, accessor, holder); |
+ return true; |
+ } |
+ case ACCESSOR: { |
+ // TODO(turbofan): Add support for general accessors? |
+ return false; |
} |
- *access_info = PropertyAccessInfo::DataField( |
- MapList{receiver_map}, field_index, field_type, holder); |
- return true; |
- } else { |
- // TODO(bmeurer): Add support for accessors. |
- return false; |
} |
+ UNREACHABLE(); |
+ return false; |
} |
// Don't search on the prototype chain for special indices in case of |