Skip to content

Commit b941f6f

Browse files
fishythefishCommit Queue
authored andcommitted
[dart2js] Add modifiable/growable bits to powerset.
Change-Id: Ic8abbe3729a4c3b41fde0a37d8b6afe84bd9ba48 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/407920 Reviewed-by: Stephen Adams <[email protected]>
1 parent 327f619 commit b941f6f

File tree

174 files changed

+3866
-3771
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+3866
-3771
lines changed

pkg/compiler/lib/src/inferrer/abstract_value_domain.dart

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -320,22 +320,18 @@ mixin AbstractValueDomain {
320320
/// string, array, native HTML list or `null` at runtime.
321321
AbstractBool isIndexablePrimitive(covariant AbstractValue value);
322322

323-
/// Returns an [AbstractBool] that describes whether [value] is a fixed-size
324-
/// or constant JavaScript array or `null` at runtime.
325-
AbstractBool isFixedArray(covariant AbstractValue value);
326-
327-
/// Returns an [AbstractBool] that describes whether [value] is a growable
328-
/// JavaScript array or `null` at runtime.
329-
AbstractBool isExtendableArray(covariant AbstractValue value);
330-
331-
/// Returns an [AbstractBool] that describes whether [value] is a mutable
332-
/// JavaScript array or `null` at runtime.
333-
AbstractBool isMutableArray(covariant AbstractValue value);
334-
335323
/// Returns an [AbstractBool] that describes whether [value] is a mutable
336324
/// JavaScript array, native HTML list or `null` at runtime.
337325
AbstractBool isMutableIndexable(covariant AbstractValue value);
338326

327+
/// Returns an [AbstractBool] that describes whether [value] is a modifiable
328+
/// array.
329+
AbstractBool isModifiableArray(covariant AbstractValue value);
330+
331+
/// Returns an [AbstractBool] that describes whether [value] is a growable
332+
/// array.
333+
AbstractBool isGrowableArray(covariant AbstractValue value);
334+
339335
/// Returns an [AbstractBool] that describes whether [value] is a JavaScript
340336
/// array or `null` at runtime.
341337
AbstractBool isArray(covariant AbstractValue value);

pkg/compiler/lib/src/inferrer/computable.dart

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,16 @@ class ComputableAbstractValueDomain with AbstractValueDomain {
286286
_wrappedDomain.isIndexablePrimitive(_unwrap(value));
287287

288288
@override
289-
AbstractBool isFixedArray(covariant ComputableAbstractValue value) =>
290-
_wrappedDomain.isFixedArray(_unwrap(value));
291-
292-
@override
293-
AbstractBool isExtendableArray(covariant ComputableAbstractValue value) =>
294-
_wrappedDomain.isExtendableArray(_unwrap(value));
289+
AbstractBool isMutableIndexable(covariant ComputableAbstractValue value) =>
290+
_wrappedDomain.isMutableIndexable(_unwrap(value));
295291

296292
@override
297-
AbstractBool isMutableArray(covariant ComputableAbstractValue value) =>
298-
_wrappedDomain.isMutableArray(_unwrap(value));
293+
AbstractBool isModifiableArray(covariant ComputableAbstractValue value) =>
294+
_wrappedDomain.isModifiableArray(_unwrap(value));
299295

300296
@override
301-
AbstractBool isMutableIndexable(covariant ComputableAbstractValue value) =>
302-
_wrappedDomain.isMutableIndexable(_unwrap(value));
297+
AbstractBool isGrowableArray(covariant ComputableAbstractValue value) =>
298+
_wrappedDomain.isGrowableArray(_unwrap(value));
303299

304300
@override
305301
AbstractBool isArray(covariant ComputableAbstractValue value) =>

pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ class PowersetBitsDomain {
283283

284284
AbstractBool isArray(int value) => isOther(value);
285285

286+
AbstractBool isGrowableArray(int value) => isOther(value);
287+
288+
AbstractBool isModifiableArray(int value) => isOther(value);
289+
286290
AbstractBool isMutableIndexable(int value) => isOther(value);
287291

288292
AbstractBool isMutableArray(int value) => isOther(value);

pkg/compiler/lib/src/inferrer/powersets/powersets.dart

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -619,31 +619,24 @@ class PowersetDomain with AbstractValueDomain {
619619
);
620620

621621
@override
622-
AbstractBool isMutableIndexable(covariant PowersetValue value) =>
623-
AbstractBool.strengthen(
624-
_powersetBitsDomain.isMutableIndexable(value._powersetBits),
625-
_abstractValueDomain.isMutableIndexable(value._abstractValue),
626-
);
627-
628-
@override
629-
AbstractBool isMutableArray(covariant PowersetValue value) =>
622+
AbstractBool isGrowableArray(covariant PowersetValue value) =>
630623
AbstractBool.strengthen(
631-
_powersetBitsDomain.isMutableArray(value._powersetBits),
632-
_abstractValueDomain.isMutableArray(value._abstractValue),
624+
_powersetBitsDomain.isGrowableArray(value._powersetBits),
625+
_abstractValueDomain.isGrowableArray(value._abstractValue),
633626
);
634627

635628
@override
636-
AbstractBool isExtendableArray(covariant PowersetValue value) =>
629+
AbstractBool isModifiableArray(covariant PowersetValue value) =>
637630
AbstractBool.strengthen(
638-
_powersetBitsDomain.isExtendableArray(value._powersetBits),
639-
_abstractValueDomain.isExtendableArray(value._abstractValue),
631+
_powersetBitsDomain.isModifiableArray(value._powersetBits),
632+
_abstractValueDomain.isModifiableArray(value._abstractValue),
640633
);
641634

642635
@override
643-
AbstractBool isFixedArray(covariant PowersetValue value) =>
636+
AbstractBool isMutableIndexable(covariant PowersetValue value) =>
644637
AbstractBool.strengthen(
645-
_powersetBitsDomain.isFixedArray(value._powersetBits),
646-
_abstractValueDomain.isFixedArray(value._abstractValue),
638+
_powersetBitsDomain.isMutableIndexable(value._powersetBits),
639+
_abstractValueDomain.isMutableIndexable(value._abstractValue),
647640
);
648641

649642
@override

pkg/compiler/lib/src/inferrer/trivial.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,13 @@ class TrivialAbstractValueDomain with AbstractValueDomain {
291291
AbstractBool isArray(AbstractValue value) => AbstractBool.maybe;
292292

293293
@override
294-
AbstractBool isMutableIndexable(AbstractValue value) => AbstractBool.maybe;
295-
296-
@override
297-
AbstractBool isMutableArray(AbstractValue value) => AbstractBool.maybe;
294+
AbstractBool isGrowableArray(AbstractValue value) => AbstractBool.maybe;
298295

299296
@override
300-
AbstractBool isExtendableArray(AbstractValue value) => AbstractBool.maybe;
297+
AbstractBool isModifiableArray(AbstractValue value) => AbstractBool.maybe;
301298

302299
@override
303-
AbstractBool isFixedArray(AbstractValue value) => AbstractBool.maybe;
300+
AbstractBool isMutableIndexable(AbstractValue value) => AbstractBool.maybe;
304301

305302
@override
306303
AbstractBool isIndexablePrimitive(AbstractValue value) => AbstractBool.maybe;

pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,7 @@ class FlatTypeMask extends TypeMask {
847847
bool operator ==(var other) {
848848
if (identical(this, other)) return true;
849849
if (other is! FlatTypeMask) return false;
850-
FlatTypeMask otherMask = other;
851-
return (_flags == otherMask._flags) && (base == otherMask.base);
850+
return (_flags == other._flags) && (base == other.base);
852851
}
853852

854853
@override
@@ -876,33 +875,61 @@ class FlatTypeMask extends TypeMask {
876875
typedef _CachedPowersets = ({Bitset exact, Bitset subclass, Bitset subtype});
877876

878877
class _PowersetCache {
879-
final ClassHierarchy _classHierarchy;
878+
final JClosedWorld _closedWorld;
880879
final Set<ClassEntity> _interceptorCone;
881880
final Map<ClassEntity, _CachedPowersets> _cache = {};
882881

883-
_PowersetCache(JClosedWorld closedWorld)
884-
: _classHierarchy = closedWorld.classHierarchy,
885-
_interceptorCone =
886-
closedWorld.classHierarchy
887-
.subclassesOf(closedWorld.commonElements.jsInterceptorClass)
882+
_PowersetCache(this._closedWorld)
883+
: _interceptorCone =
884+
_closedWorld.classHierarchy
885+
.subclassesOf(_closedWorld.commonElements.jsInterceptorClass)
888886
.toSet();
889887

890-
_CachedPowersets operator [](ClassEntity cls) => _cache.putIfAbsent(cls, () {
891-
var exactPowerset = Bitset.empty();
892-
exactPowerset = _interceptorDomain.add(
893-
exactPowerset,
888+
Bitset _computeExactPowerset(ClassEntity cls) {
889+
var powerset = Bitset.empty();
890+
if (!_closedWorld.classHierarchy.isExplicitlyInstantiated(cls)) {
891+
return powerset;
892+
}
893+
894+
powerset = _interceptorDomain.add(
895+
powerset,
894896
_interceptorCone.contains(cls)
895897
? TypeMaskInterceptorProperty.interceptor
896898
: TypeMaskInterceptorProperty.notInterceptor,
897899
);
898900

901+
// TODO(sra): Set any other [TypeMaskArrayProperty] bits.
902+
if (cls == _closedWorld.commonElements.jsExtendableArrayClass) {
903+
powerset = _arrayDomain.add(powerset, TypeMaskArrayProperty.growable);
904+
} else if (cls == _closedWorld.commonElements.jsFixedArrayClass) {
905+
powerset = _arrayDomain.add(powerset, TypeMaskArrayProperty.fixedLength);
906+
} else if (cls == _closedWorld.commonElements.jsUnmodifiableArrayClass) {
907+
powerset = _arrayDomain.add(powerset, TypeMaskArrayProperty.unmodifiable);
908+
} else if (cls == _closedWorld.commonElements.jsArrayClass) {
909+
powerset = _arrayDomain.addAll(powerset, const [
910+
TypeMaskArrayProperty.growable,
911+
TypeMaskArrayProperty.fixedLength,
912+
TypeMaskArrayProperty.unmodifiable,
913+
]);
914+
} else {
915+
powerset = _arrayDomain.add(powerset, TypeMaskArrayProperty.other);
916+
}
917+
918+
return powerset;
919+
}
920+
921+
_CachedPowersets operator [](ClassEntity cls) => _cache.putIfAbsent(cls, () {
922+
final exactPowerset = _computeExactPowerset(cls);
923+
899924
var subclassPowerset = exactPowerset;
900-
for (final subclass in _classHierarchy.strictSubclassesOf(cls)) {
925+
for (final subclass in _closedWorld.classHierarchy.strictSubclassesOf(
926+
cls,
927+
)) {
901928
subclassPowerset = subclassPowerset.union(this[subclass].subclass);
902929
}
903930

904931
var subtypePowerset = exactPowerset;
905-
for (final subtype in _classHierarchy.strictSubtypesOf(cls)) {
932+
for (final subtype in _closedWorld.classHierarchy.strictSubtypesOf(cls)) {
906933
subtypePowerset = subtypePowerset.union(this[subtype].subtype);
907934
}
908935

pkg/compiler/lib/src/inferrer/typemasks/masks.dart

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -576,33 +576,48 @@ class CommonMasks with AbstractValueDomain {
576576
}
577577

578578
@override
579-
AbstractBool isFixedArray(TypeMask value) {
580-
// TODO(sra): Recognize the union of these types as well.
579+
AbstractBool isMutableIndexable(TypeMask value) {
581580
return AbstractBool.trueOrMaybe(
582-
_containsOnlyType(value, commonElements.jsFixedArrayClass) ||
583-
_containsOnlyType(value, commonElements.jsUnmodifiableArrayClass),
581+
_isInstanceOfOrNull(value, commonElements.jsMutableIndexableClass),
584582
);
585583
}
586584

587585
@override
588-
AbstractBool isExtendableArray(TypeMask value) {
589-
return AbstractBool.trueOrMaybe(
590-
_containsOnlyType(value, commonElements.jsExtendableArrayClass),
591-
);
592-
}
586+
AbstractBool isModifiableArray(TypeMask value) {
587+
final powerset = value.powerset;
593588

594-
@override
595-
AbstractBool isMutableArray(TypeMask value) {
596-
return AbstractBool.trueOrMaybe(
597-
_isInstanceOfOrNull(value, commonElements.jsMutableArrayClass),
598-
);
589+
if (_arrayDomain.contains(powerset, TypeMaskArrayProperty.other)) {
590+
return AbstractBool.maybe;
591+
}
592+
593+
if (!powerset.intersects(TypeMaskArrayProperty._modifiableMask)) {
594+
return AbstractBool.false_;
595+
}
596+
597+
if (!powerset.intersects(TypeMaskArrayProperty._unmodifiableMask)) {
598+
return AbstractBool.true_;
599+
}
600+
601+
return AbstractBool.maybe;
599602
}
600603

601604
@override
602-
AbstractBool isMutableIndexable(TypeMask value) {
603-
return AbstractBool.trueOrMaybe(
604-
_isInstanceOfOrNull(value, commonElements.jsMutableIndexableClass),
605-
);
605+
AbstractBool isGrowableArray(TypeMask value) {
606+
final powerset = value.powerset;
607+
608+
if (_arrayDomain.contains(powerset, TypeMaskArrayProperty.other)) {
609+
return AbstractBool.maybe;
610+
}
611+
612+
if (!powerset.intersects(TypeMaskArrayProperty._growableMask)) {
613+
return AbstractBool.false_;
614+
}
615+
616+
if (!powerset.intersects(TypeMaskArrayProperty._fixedLengthMask)) {
617+
return AbstractBool.true_;
618+
}
619+
620+
return AbstractBool.maybe;
606621
}
607622

608623
@override
@@ -908,15 +923,17 @@ class CommonMasks with AbstractValueDomain {
908923

909924
@override
910925
AbstractBool isInterceptor(TypeMask value) {
926+
final powerset = value.powerset;
927+
911928
if (!_interceptorDomain.contains(
912-
value.powerset,
929+
powerset,
913930
TypeMaskInterceptorProperty.interceptor,
914931
)) {
915932
return AbstractBool.false_;
916933
}
917934

918935
if (!_interceptorDomain.contains(
919-
value.powerset,
936+
powerset,
920937
TypeMaskInterceptorProperty.notInterceptor,
921938
)) {
922939
return AbstractBool.true_;

pkg/compiler/lib/src/inferrer/typemasks/record_type_mask.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class RecordTypeMask extends TypeMask {
4040
powerset,
4141
TypeMaskInterceptorProperty.notInterceptor,
4242
);
43+
powerset = _arrayDomain.add(powerset, TypeMaskArrayProperty.other);
4344
return createRecordWithPowerset(domain, types, shape, powerset);
4445
}
4546

0 commit comments

Comments
 (0)