Skip to content

Commit 31c169d

Browse files
committed
Python: Remove bad join in getCallableScope
Clause timing report had this suspicious entry ``` CommandInjection.ql-12:DataFlowPublic::Node::getCallableScope#bbf .................. 7.2s (4 evaluations with max 6.4s in DataFlowPublic::Node::getCallableScope#bbf/3@i3#119d7b) ``` which indeed was a bad join: ``` Tuple counts for DataFlowPublic::Node::getCallableScope#bbf: 293509 ~2% {3} r1 = JOIN DataFlowPublic::Node::getCallableScope#bbf#prev_delta AS L WITH DataFlowPublic::TNode#f AS R ON FIRST 1 OUTPUT L.<1>, L.<0>, L.<2> 22337162 ~0% {3} r2 = JOIN r1 WITH Scope::Scope::getEnclosingScope_dispred#ff_10#join_rhs AS R ON FIRST 1 OUTPUT r1.<1>, r1.<2>, R.<1> 22337162 ~0% {3} r3 = r2 AND NOT DataFlowPublic::Node::getCallableScope#bbf#prev AS R(r2.<0>, r2.<2>, r2.<1>) 22337162 ~0% {3} r4 = SCAN r3 OUTPUT r3.<0>, r3.<2>, r3.<1> 722 ~1% {3} r5 = JOIN r4 WITH m#DataFlowPublic::Node::getCallableScope#bbf AS R ON FIRST 2 OUTPUT r4.<0>, r4.<1>, r4.<2> 722 ~1% {3} r6 = JOIN r5 WITH m#DataFlowPublic::Node::getCallableScope#bbf AS R ON FIRST 2 OUTPUT r5.<0>, r5.<2>, r5.<1> 722 ~1% {3} r7 = r6 AND NOT project#DataFlowPrivate::DataFlowCallable::getScope_dispred#ff AS R(r6.<2>) 722 ~1% {3} r8 = SCAN r7 OUTPUT r7.<0>, r7.<2>, r7.<1> return r8 ``` In this case, the join went away by simply moving the helper predicate out of the class it was situated in (and since it doesn't mention `this`, it didn't really belong there in the first place). Result: ``` DataFlowPublic.qll-8:DataFlowPublic::getCallableScope#ff ........................... 26ms (4 evaluations with max 15ms in DataFlowPublic::getCallableScope#ff/2@i3#709a9e) ```
1 parent eb3333c commit 31c169d

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

python/ql/src/experimental/dataflow/internal/DataFlowPublic.qll

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ newtype TNode =
6262
call_unpacks(call, _, callable, name, _)
6363
}
6464

65+
/** Helper for `Node::getEnclosingCallable`. */
66+
private DataFlowCallable getCallableScope(Scope s) {
67+
result.getScope() = s
68+
or
69+
not exists(DataFlowCallable c | c.getScope() = s) and
70+
result = getCallableScope(s.getEnclosingScope())
71+
}
72+
6573
/**
6674
* An element, viewed as a node in a data flow graph. Either an SSA variable
6775
* (`EssaNode`) or a control flow node (`CfgNode`).
@@ -73,13 +81,6 @@ class Node extends TNode {
7381
/** Gets the scope of this node. */
7482
Scope getScope() { none() }
7583

76-
private DataFlowCallable getCallableScope(Scope s) {
77-
result.getScope() = s
78-
or
79-
not exists(DataFlowCallable c | c.getScope() = s) and
80-
result = getCallableScope(s.getEnclosingScope())
81-
}
82-
8384
/** Gets the enclosing callable of this node. */
8485
DataFlowCallable getEnclosingCallable() { result = getCallableScope(this.getScope()) }
8586

0 commit comments

Comments
 (0)