Skip to content

Commit a18d9d8

Browse files
committed
8326616: tools/javac/patterns/Exhaustiveness.java intermittently Timeout signalled after 480 seconds
Reviewed-by: abimpoudis
1 parent 79d7613 commit a18d9d8

File tree

2 files changed

+40
-54
lines changed

2 files changed

+40
-54
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -827,30 +827,33 @@ private boolean exhausts(JCExpression selector, List<JCCase> cases) {
827827
}
828828
}
829829
Set<PatternDescription> patterns = patternSet;
830-
boolean genericPatternsExpanded = false;
830+
boolean useHashes = true;
831831
try {
832832
boolean repeat = true;
833833
while (repeat) {
834834
Set<PatternDescription> updatedPatterns;
835835
updatedPatterns = reduceBindingPatterns(selector.type, patterns);
836-
updatedPatterns = reduceNestedPatterns(updatedPatterns);
836+
updatedPatterns = reduceNestedPatterns(updatedPatterns, useHashes);
837837
updatedPatterns = reduceRecordPatterns(updatedPatterns);
838838
updatedPatterns = removeCoveredRecordPatterns(updatedPatterns);
839839
repeat = !updatedPatterns.equals(patterns);
840840
if (checkCovered(selector.type, patterns)) {
841841
return true;
842842
}
843-
if (!repeat && !genericPatternsExpanded) {
843+
if (!repeat) {
844844
//there may be situation like:
845-
//class B extends S1, S2
845+
//class B permits S1, S2
846846
//patterns: R(S1, B), R(S2, S2)
847-
//this should be joined to R(B, S2),
847+
//this might be joined to R(B, S2), as B could be rewritten to S2
848848
//but hashing in reduceNestedPatterns will not allow that
849-
//attempt to once expand all types to their transitive permitted types,
850-
//on all depth of nesting:
851-
updatedPatterns = expandGenericPatterns(updatedPatterns);
852-
genericPatternsExpanded = true;
853-
repeat = !updatedPatterns.equals(patterns);
849+
//disable the use of hashing, and use subtyping in
850+
//reduceNestedPatterns to handle situations like this:
851+
repeat = useHashes;
852+
useHashes = false;
853+
} else {
854+
//if a reduction happened, make sure hashing in reduceNestedPatterns
855+
//is enabled, as the hashing speeds up the process significantly:
856+
useHashes = true;
854857
}
855858
patterns = updatedPatterns;
856859
}
@@ -1023,8 +1026,15 @@ private List<ClassSymbol> baseClasses(TypeSymbol root) {
10231026
* simplify the pattern. If that succeeds, the original found sub-set
10241027
* of patterns is replaced with a new set of patterns of the form:
10251028
* $record($prefix$, $resultOfReduction, $suffix$)
1029+
*
1030+
* useHashes: when true, patterns will be subject to exact equivalence;
1031+
* when false, two binding patterns will be considered equivalent
1032+
* if one of them is more generic than the other one;
1033+
* when false, the processing will be significantly slower,
1034+
* as pattern hashes cannot be used to speed up the matching process
10261035
*/
1027-
private Set<PatternDescription> reduceNestedPatterns(Set<PatternDescription> patterns) {
1036+
private Set<PatternDescription> reduceNestedPatterns(Set<PatternDescription> patterns,
1037+
boolean useHashes) {
10281038
/* implementation note:
10291039
* finding a sub-set of patterns that only differ in a single
10301040
* column is time-consuming task, so this method speeds it up by:
@@ -1049,13 +1059,13 @@ private Set<PatternDescription> reduceNestedPatterns(Set<PatternDescription> pat
10491059
mismatchingCandidate < nestedPatternsCount;
10501060
mismatchingCandidate++) {
10511061
int mismatchingCandidateFin = mismatchingCandidate;
1052-
var groupByHashes =
1062+
var groupEquivalenceCandidates =
10531063
current
10541064
.stream()
10551065
//error recovery, ignore patterns with incorrect number of nested patterns:
10561066
.filter(pd -> pd.nested.length == nestedPatternsCount)
1057-
.collect(groupingBy(pd -> pd.hashCode(mismatchingCandidateFin)));
1058-
for (var candidates : groupByHashes.values()) {
1067+
.collect(groupingBy(pd -> useHashes ? pd.hashCode(mismatchingCandidateFin) : 0));
1068+
for (var candidates : groupEquivalenceCandidates.values()) {
10591069
var candidatesArr = candidates.toArray(RecordPattern[]::new);
10601070

10611071
for (int firstCandidate = 0;
@@ -1076,24 +1086,35 @@ private Set<PatternDescription> reduceNestedPatterns(Set<PatternDescription> pat
10761086
RecordPattern rpOther = candidatesArr[nextCandidate];
10771087
if (rpOne.recordType.tsym == rpOther.recordType.tsym) {
10781088
for (int i = 0; i < rpOne.nested.length; i++) {
1079-
if (i != mismatchingCandidate &&
1080-
!rpOne.nested[i].equals(rpOther.nested[i])) {
1081-
continue NEXT_PATTERN;
1089+
if (i != mismatchingCandidate) {
1090+
if (!rpOne.nested[i].equals(rpOther.nested[i])) {
1091+
if (useHashes ||
1092+
//when not using hashes,
1093+
//check if rpOne.nested[i] is
1094+
//a subtype of rpOther.nested[i]:
1095+
!(rpOne.nested[i] instanceof BindingPattern bpOne) ||
1096+
!(rpOther.nested[i] instanceof BindingPattern bpOther) ||
1097+
!types.isSubtype(types.erasure(bpOne.type), types.erasure(bpOther.type))) {
1098+
continue NEXT_PATTERN;
1099+
}
1100+
}
10821101
}
10831102
}
10841103
join.append(rpOther);
10851104
}
10861105
}
10871106

10881107
var nestedPatterns = join.stream().map(rp -> rp.nested[mismatchingCandidateFin]).collect(Collectors.toSet());
1089-
var updatedPatterns = reduceNestedPatterns(nestedPatterns);
1108+
var updatedPatterns = reduceNestedPatterns(nestedPatterns, useHashes);
10901109

10911110
updatedPatterns = reduceRecordPatterns(updatedPatterns);
10921111
updatedPatterns = removeCoveredRecordPatterns(updatedPatterns);
10931112
updatedPatterns = reduceBindingPatterns(rpOne.fullComponentTypes()[mismatchingCandidateFin], updatedPatterns);
10941113

10951114
if (!nestedPatterns.equals(updatedPatterns)) {
1096-
current.removeAll(join);
1115+
if (useHashes) {
1116+
current.removeAll(join);
1117+
}
10971118

10981119
for (PatternDescription nested : updatedPatterns) {
10991120
PatternDescription[] newNested =
@@ -1169,40 +1190,6 @@ private PatternDescription reduceRecordPattern(PatternDescription pattern) {
11691190
return pattern;
11701191
}
11711192

1172-
private Set<PatternDescription> expandGenericPatterns(Set<PatternDescription> patterns) {
1173-
var newPatterns = new HashSet<PatternDescription>(patterns);
1174-
boolean modified;
1175-
do {
1176-
modified = false;
1177-
for (PatternDescription pd : patterns) {
1178-
if (pd instanceof RecordPattern rpOne) {
1179-
for (int i = 0; i < rpOne.nested.length; i++) {
1180-
Set<PatternDescription> toExpand = Set.of(rpOne.nested[i]);
1181-
Set<PatternDescription> expanded = expandGenericPatterns(toExpand);
1182-
if (expanded != toExpand) {
1183-
expanded.removeAll(toExpand);
1184-
for (PatternDescription exp : expanded) {
1185-
PatternDescription[] newNested = Arrays.copyOf(rpOne.nested, rpOne.nested.length);
1186-
newNested[i] = exp;
1187-
modified |= newPatterns.add(new RecordPattern(rpOne.recordType(), rpOne.fullComponentTypes(), newNested));
1188-
}
1189-
}
1190-
}
1191-
} else if (pd instanceof BindingPattern bp) {
1192-
Set<Symbol> permittedSymbols = allPermittedSubTypes(bp.type.tsym, cs -> true);
1193-
1194-
if (!permittedSymbols.isEmpty()) {
1195-
for (Symbol permitted : permittedSymbols) {
1196-
//TODO infer.instantiatePatternType(selectorType, csym); (?)
1197-
modified |= newPatterns.add(new BindingPattern(permitted.type));
1198-
}
1199-
}
1200-
}
1201-
}
1202-
} while (modified);
1203-
return newPatterns;
1204-
}
1205-
12061193
private Set<PatternDescription> removeCoveredRecordPatterns(Set<PatternDescription> patterns) {
12071194
Set<Symbol> existingBindings = patterns.stream()
12081195
.filter(pd -> pd instanceof BindingPattern)

test/langtools/ProblemList.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java
6161
tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java 8057687 generic-all emit correct byte code an attributes for type annotations
6262
tools/javac/warnings/suppress/TypeAnnotations.java 8057683 generic-all improve ordering of errors with type annotations
6363
tools/javac/modules/SourceInSymlinkTest.java 8180263 windows-all fails when run on a subst drive
64-
tools/javac/patterns/Exhaustiveness.java 8326616 generic-all intermittently timeout
6564

6665
###########################################################################
6766
#

0 commit comments

Comments
 (0)