Skip to content

Java: Improve algorithm for subtyping of parameterized types.#7088

Merged
aschackmull merged 3 commits into
github:mainfrom
aschackmull:java/parameterized-subtyping
Nov 17, 2021
Merged

Java: Improve algorithm for subtyping of parameterized types.#7088
aschackmull merged 3 commits into
github:mainfrom
aschackmull:java/parameterized-subtyping

Conversation

@aschackmull
Copy link
Copy Markdown
Contributor

This drastically improves performance when there are many instantiations of generic types with 3 or more type variables. One observed case improved from 85 minutes to less than one minute.

@aschackmull aschackmull added the no-change-note-required This PR does not need a change note label Nov 9, 2021
@aschackmull aschackmull requested a review from a team as a code owner November 9, 2021 14:52
@github-actions github-actions Bot added the Java label Nov 9, 2021
@aschackmull aschackmull requested a review from hvitved November 15, 2021 12:03
Comment on lines +171 to +173
typePrefixContains(pragma[only_bind_into](pps0), pragma[only_bind_into](ppt0)) and
pps = TTypeParam(pragma[only_bind_into](pps0), t) and
ppt = TTypeParam(ppt0, t)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth commenting what the load of pragmas intend to achieve? It looks like you want:

Take all TTypeParam(ppt0, t)
Join with all TTypeParam(pps0, t)
Restrict by typePrefixContains(pps0, ppt0)

?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that join order would be horrible (and isn't what the pragmas describe). There are two instances of canonical pragma use. The only_bind_into on pps0 means "don't join on this" and the set of only_bind_into on all the columns of typePrefixContains is the canonical use saying "put this predicate first in the pipeline". So this should be entirely standard pragma use.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I was reading the pragma as if it was only_bind_out. Oops.

ParameterizedPrefix ppt, ParameterizedPrefix ppt0, RefType s
) {
exists(GenericType g, int n, RefType t |
ppt.split(g, ppt0, t, n) and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ppt.split(g, ppt0, t, n) and
// Implies ppt = TTypeParam(ppt0, t)
ppt.split(g, ppt0, t, n) and

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in the qldoc of split. Do you think it should be repeated here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because it enables the reader to understand the whole of this predicate in one go without referring elsewhere

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread java/ql/lib/semmle/code/java/Type.qll Outdated
exists(ParameterizedPrefix pps0 |
typePrefixContains(pps0, ppt0) and
pps = TTypeParam(pps0, s) and
s instanceof Wildcard
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprising not see the wildcard condition in the algorithm outline at line 150

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because it's semantically irrelevant. It's just a piece of manual magic implied by typeArgumentContains(_, s, t, _).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case suggest adding // manual magic to make clear that's all this is doing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread java/ql/lib/semmle/code/java/Type.qll Outdated
Comment on lines +271 to +273
private predicate subtypeStarMagic1(RefType t) { t = any(Wildcard w).getUpperBound().getType() }

private predicate subtypeStarMagic2(RefType t) { t = any(Wildcard w).getLowerBound().getType() }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call them getAWildcardUpper/LowerBound?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could... But they really are pieces manual magic, so I thought these names were clearer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to s instanceof Wildcard above suggest naming them for what they are and using // manual magic to signal intent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@aschackmull aschackmull force-pushed the java/parameterized-subtyping branch from c22813b to 76606b5 Compare November 16, 2021 15:11
@smowton
Copy link
Copy Markdown
Contributor

smowton commented Nov 16, 2021

Added a commit to fix manuel-magic https://en.wikipedia.org/wiki/Manuel_(Fawlty_Towers)

@aschackmull aschackmull merged commit 1645fcf into github:main Nov 17, 2021
@aschackmull aschackmull deleted the java/parameterized-subtyping branch November 17, 2021 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Java no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants