mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
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`.
This commit is contained in:
@@ -53,10 +53,10 @@ predicate setter(MemberVariable v, MemberFunction f, Class c) {
|
||||
v.getDeclaringType() = c and
|
||||
f.getName().matches("set%") and
|
||||
v.getAnAssignedValue().getEnclosingFunction() = f and
|
||||
not exists(MemberVariable v2 |
|
||||
v2.getDeclaringType() = c and
|
||||
v2.getAnAssignedValue().getEnclosingFunction() = f and
|
||||
v2 != v
|
||||
forall(MemberVariable v2 |
|
||||
v2.getAnAssignedValue().getEnclosingFunction() = f
|
||||
|
|
||||
v2 = v
|
||||
) and
|
||||
f.getNumberOfParameters() = 1 and
|
||||
f.getParameter(0).getType().stripType() = v.getType().stripType()
|
||||
@@ -71,10 +71,10 @@ predicate getter(MemberVariable v, MemberFunction f, Class c) {
|
||||
v.getDeclaringType() = c and
|
||||
f.getName().matches("get%") and
|
||||
v.getAnAccess().getEnclosingFunction() = f and
|
||||
not exists(MemberVariable v2 |
|
||||
v2.getDeclaringType() = c and
|
||||
v2.getAnAccess().getEnclosingFunction() = f and
|
||||
v2 != v
|
||||
forall(MemberVariable v2 |
|
||||
v2.getAnAccess().getEnclosingFunction() = f
|
||||
|
|
||||
v2 = v
|
||||
) and
|
||||
f.getNumberOfParameters() = 0 and
|
||||
f.getType().stripType() = v.getType().stripType()
|
||||
|
||||
Reference in New Issue
Block a user