Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions javascript/ql/src/semmle/javascript/dataflow/Configuration.qll
Original file line number Diff line number Diff line change
Expand Up @@ -474,20 +474,29 @@ pragma[nomagic]
private predicate barrierGuardBlocksEdge(
BarrierGuardNode guard, DataFlow::Node pred, DataFlow::Node succ, string label
) {
barrierGuardIsRelevant(guard) and
exists(
SsaVariable input, SsaPhiNode phi, BasicBlock bb, ConditionGuardNode cond, boolean outcome
|
bb = getADominatedBasicBlock(guard, cond) and
pred = DataFlow::ssaDefinitionNode(input) and
succ = DataFlow::ssaDefinitionNode(phi) and
input = phi.getInputFromBlock(bb) and
guard.getEnclosingExpr() = cond.getTest() and
outcome = cond.getOutcome() and
barrierGuardBlocksExpr(guard, outcome, input.getAUse(), label) and
cond.dominates(bb)
barrierGuardBlocksExpr(guard, outcome, input.getAUse(), label)
)
}

/**
* Gets a basicblock that is dominated by `cond`, where the test for `cond` cond is `guard`.
*
* This predicate exists to get a better join-order for the `barrierGuardBlocksEdge` predicate above.
*/
private BasicBlock getADominatedBasicBlock(BarrierGuardNode guard, ConditionGuardNode cond) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this perhaps be pragma[noinline] to prevent the compiler from inlining the predicate and discovering the bad join order again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe.
I prefer not to.
If the compiler is changed such that it inlines the predicate, it might also be changed such that it discovers a better join order.
If we use a pragma, we force the compiler to use the current join order, even if something better is possible in the future.

barrierGuardIsRelevant(guard) and
guard.getEnclosingExpr() = cond.getTest() and
cond.dominates(result)
}

/**
* Holds if there is a barrier edge `pred -> succ` in `cfg` either through an explicit barrier edge
* or one implied by a barrier guard.
Expand Down