Skip to content

Commit 2a6000c

Browse files
committed
C++: getter/setter performance in StructLikeClass
The predicates `getter` and `setter` in `StructLikeClass.qll` were very slow on some snapshots. On https://github.com/dotnet/coreclr they had this performance: StructLikeClass::getter#fff#antijoin_rhs ........... 3m55s Variable::Variable::getAnAssignedValue_dispred#bb .. 3m36s StructLikeClass::setter#fff#antijoin_rhs ........... 20.5s The `getAnAssignedValue_dispred` predicate in the middle was slow due to magic propagated from `setter`. With this commit, performance is instead: StructLikeClass::getter#fff#antijoin_rhs ........... 497ms Variable::Variable::getAnAssignedValue_dispred#ff .. 617ms StructLikeClass::setter#fff#antijoin_rhs ........... 158ms Instead of hand-optimizing the QL for performance, I simplified `setter` and `getter` to require slightly stronger conditions. Previously, a function was only considered a setter if it had no writes to other fields on the same class. That requirement is now relaxed by dropping the "on the same class" part. I made the corresponding change for what defines a getter. I think that still captures the spirit of what getters and setters are. I also changed the double-negation with `exists` into a `forall`.
1 parent 5ad0b39 commit 2a6000c

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

cpp/ql/src/semmle/code/cpp/commons/StructLikeClass.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ predicate setter(MemberVariable v, MemberFunction f, Class c) {
5353
v.getDeclaringType() = c and
5454
f.getName().matches("set%") and
5555
v.getAnAssignedValue().getEnclosingFunction() = f and
56-
not exists(MemberVariable v2 |
57-
v2.getDeclaringType() = c and
58-
v2.getAnAssignedValue().getEnclosingFunction() = f and
59-
v2 != v
56+
forall(MemberVariable v2 |
57+
v2.getAnAssignedValue().getEnclosingFunction() = f
58+
|
59+
v2 = v
6060
) and
6161
f.getNumberOfParameters() = 1 and
6262
f.getParameter(0).getType().stripType() = v.getType().stripType()
@@ -71,10 +71,10 @@ predicate getter(MemberVariable v, MemberFunction f, Class c) {
7171
v.getDeclaringType() = c and
7272
f.getName().matches("get%") and
7373
v.getAnAccess().getEnclosingFunction() = f and
74-
not exists(MemberVariable v2 |
75-
v2.getDeclaringType() = c and
76-
v2.getAnAccess().getEnclosingFunction() = f and
77-
v2 != v
74+
forall(MemberVariable v2 |
75+
v2.getAnAccess().getEnclosingFunction() = f
76+
|
77+
v2 = v
7878
) and
7979
f.getNumberOfParameters() = 0 and
8080
f.getType().stripType() = v.getType().stripType()

0 commit comments

Comments
 (0)