[compiler] Verify FieldType objects are safe to read

.. in AccessInfoFactory. In order to be read safely, they must pass
the IsPendingAllocation predicate, called internally from TryMakeRef.

In a follow-up, DescriptorArrayRef methods should also be updated
similarly.

Bug: v8:7790,chromium:1236373
Change-Id: I96b59458033c327e3d2e01e8e4496e2c91609eb5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3080560
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76153}
This commit is contained in:
Jakob Gruber 2021-08-09 08:55:43 +02:00 committed by V8 LUCI CQ
parent 3f035df2bd
commit 5e90616319

View File

@ -428,6 +428,7 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
MapRef receiver_map, MapRef map, base::Optional<JSObjectRef> holder, MapRef receiver_map, MapRef map, base::Optional<JSObjectRef> holder,
InternalIndex descriptor, AccessMode access_mode) const { InternalIndex descriptor, AccessMode access_mode) const {
DCHECK(descriptor.is_found()); DCHECK(descriptor.is_found());
// TODO(jgruber,v8:7790): Use DescriptorArrayRef instead.
Handle<DescriptorArray> descriptors = map.instance_descriptors().object(); Handle<DescriptorArray> descriptors = map.instance_descriptors().object();
PropertyDetails const details = descriptors->GetDetails(descriptor); PropertyDetails const details = descriptors->GetDetails(descriptor);
int index = descriptors->GetFieldIndex(descriptor); int index = descriptors->GetFieldIndex(descriptor);
@ -450,6 +451,9 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
Handle<FieldType> descriptors_field_type = Handle<FieldType> descriptors_field_type =
broker()->CanonicalPersistentHandle( broker()->CanonicalPersistentHandle(
descriptors->GetFieldType(descriptor)); descriptors->GetFieldType(descriptor));
base::Optional<ObjectRef> descriptors_field_type_ref =
TryMakeRef<Object>(broker(), descriptors_field_type);
if (!descriptors_field_type_ref.has_value()) return Invalid();
if (details_representation.IsSmi()) { if (details_representation.IsSmi()) {
field_type = Type::SignedSmall(); field_type = Type::SignedSmall();
@ -489,7 +493,7 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
// of the access info. // of the access info.
unrecorded_dependencies.push_back( unrecorded_dependencies.push_back(
dependencies()->FieldTypeDependencyOffTheRecord( dependencies()->FieldTypeDependencyOffTheRecord(
map, descriptor, MakeRef<Object>(broker(), descriptors_field_type))); map, descriptor, descriptors_field_type_ref.value()));
PropertyConstness constness; PropertyConstness constness;
if (details.IsReadOnly() && !details.IsConfigurable()) { if (details.IsReadOnly() && !details.IsConfigurable()) {
@ -1147,8 +1151,13 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
} else if (details_representation.IsHeapObject()) { } else if (details_representation.IsHeapObject()) {
// Extract the field type from the property details (make sure its // Extract the field type from the property details (make sure its
// representation is TaggedPointer to reflect the heap object case). // representation is TaggedPointer to reflect the heap object case).
// TODO(jgruber,v8:7790): Use DescriptorArrayRef instead.
Handle<FieldType> descriptors_field_type = Handle<FieldType> descriptors_field_type =
broker()->CanonicalPersistentHandle(descriptors->GetFieldType(number)); broker()->CanonicalPersistentHandle(descriptors->GetFieldType(number));
base::Optional<ObjectRef> descriptors_field_type_ref =
TryMakeRef<Object>(broker(), descriptors_field_type);
if (!descriptors_field_type_ref.has_value()) return Invalid();
if (descriptors_field_type->IsNone()) { if (descriptors_field_type->IsNone()) {
// Store is not safe if the field type was cleared. // Store is not safe if the field type was cleared.
return Invalid(); return Invalid();