Skip to content

C#: Speedup Implements.qll#1011

Merged
semmle-qlci merged 2 commits into
github:rc/1.20from
hvitved:csharp/implements-performance
Mar 4, 2019
Merged

C#: Speedup Implements.qll#1011
semmle-qlci merged 2 commits into
github:rc/1.20from
hvitved:csharp/implements-performance

Conversation

@hvitved

@hvitved hvitved commented Feb 28, 2019

Copy link
Copy Markdown
Contributor

This PR addresses a timeout on nhibernate-core; performance report here (internal link).

@hvitved hvitved added the C# label Feb 28, 2019
@hvitved hvitved requested a review from calumgrant February 28, 2019 20:37
@hvitved hvitved marked this pull request as ready for review February 28, 2019 20:37
@hvitved hvitved requested a review from a team as a code owner February 28, 2019 20:37

@calumgrant calumgrant left a comment

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.

Overall, looks good, but have a few general questions.

j = -1
or
result = getACompatibleInterfaceIndexer0(i, j - 1) and
convIdentity(i.getParameter(j).getType(), result.getParameter(j).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.

Why not use Gvn here?

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.

Because indexers cannot have type arguments.


private Indexer getACompatibleInterfaceIndexer0(Indexer i, int j) {
result = getACompatibleInterfaceIndexerCandidate(i) and
convIdentity(i.getType(), result.getType()) 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.

Why not use Gvn here?

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.

Because indexers cannot have type arguments.

}

private Method getACompatibleInterfaceMethod(Method m) {
result = getACompatibleInterfaceMethod0(m, m.getNumberOfParameters())

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.

m.getNumberOfParameters() - 1 ?

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.

Actually no, because getArgumentOrReturnType ranges from 0 to m.getNumberOfParameters().

// Recursive case
(
t1 instanceof PointerType and t2 instanceof PointerType
module Gvn {

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.

If I understand correctly, this entire module is a speedup for convIdentity/2. Therefore, would it not make sense to put this module into Conversion.qll (or even better, a separate file), and to make convIdentity/2 an inline predicate that basically wraps Gvn::getGlobalValueNumber(t1) = Gvn::getGlobalValueNumber(t2). The underlying convIdentity/2 could then be made private.

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.

This does seem like a complicated way to achieve this speedup, given that the net gains are fairly modest apart from fixing the timeout. Is there any way of addressing the timeout more directly?

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 does a bit more than just identity conversion, it also maps method type parameters at the same index to the same value. The reason that we need this is because we need to find compatible interface implementations:

interface I
{
    void M<T>(T[] x);
}

class A
{
    void M<T>(T[] x) { }
}

class B : A, I { }

The overrides relation generated by the extractor does not give us that A.M() may be a target in a call to I.M(), so we need to match the name and parameter types. If we do this with ordinary equality, A.M() will not match I.M(), because the two type parameters T in I.M() and A.M() are two different entities.


private newtype TGvnType =
TLeafGvnType(int i) { id(_, i) } or
TMethodTypeParameterGvnType(int i) { i = any(MethodTypeParameter p).getIndex() } or

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.

I'm not 100% convinced that it's correct to project all method type params down to their index. Besides, why are method type params treated differently to type type params?

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.

See my comment above.

private class LeafType extends Type {
LeafType() {
not exists(this.getAChild()) and
not this instanceof MethodTypeParameter

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.

Why are MethodTypeParameter and TypeTypeParameter handled differently? You could have a constructed type having a type parameter that is a type parameter (from another unbound generic type).

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.

Again, see my comment above.

@hvitved hvitved changed the base branch from master to rc/1.20 March 2, 2019 14:24
@hvitved hvitved added this to the 1.20 milestone Mar 2, 2019
@hvitved hvitved force-pushed the csharp/implements-performance branch from 00c7a98 to 6135b5b Compare March 4, 2019 12:19

@calumgrant calumgrant left a comment

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.

Thanks for answering my questions. I agree that this really is specific to Implements and should live in this file. Great work!

@semmle-qlci semmle-qlci merged commit 08e7499 into github:rc/1.20 Mar 4, 2019
@hvitved hvitved deleted the csharp/implements-performance branch March 4, 2019 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants