v8-0004 + jsc-0003: Maglev KnownMapsMerger O(P×R) std::find, IntegerRangeOpt liveAtHead O(50×B×R×L); 2+2 PASS; count 606→608
This commit is contained in:
parent
ae91f05bf3
commit
87099aaaac
9 changed files with 328 additions and 8 deletions
|
|
@ -0,0 +1,55 @@
|
|||
# UNDF: UNDF-2026-000000579
|
||||
# jsc-0003: DFGIntegerRangeOptimizationPhase liveAtHead Vector::contains O(50×B×R×L) → O(50×B×R) with HashSet
|
||||
|
||||
## Classification
|
||||
|
||||
| Field | Value |
|
||||
|-------------|-------|
|
||||
| CWE | CWE-407 Inefficient Algorithmic Complexity |
|
||||
| Severity | MEDIUM |
|
||||
| Component | `Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp:1996` |
|
||||
| Function | `performForBasicBlock` fixed-point loop |
|
||||
| Hot path | Integer range optimization pass — once per DFG compile for each function with integer ops |
|
||||
| Status | PATCHED (unit test PASS) |
|
||||
|
||||
## Defect
|
||||
|
||||
The integer range optimization phase runs a fixed-point loop (up to 50 iterations) over
|
||||
all basic blocks. Inside the loop, for each block, it iterates over `relationshipMap`
|
||||
entries (R relationships) and calls `liveAtHead.contains(node)` — an O(L) linear scan
|
||||
of a `WTF::Vector<NodeFlowProjection>`:
|
||||
|
||||
```cpp
|
||||
// DFGIntegerRangeOptimizationPhase.cpp:1996
|
||||
Vector<NodeFlowProjection> liveAtHead = ...; // L live nodes at block head
|
||||
|
||||
for (unsigned i = 50; i--;) { // 50 fixed-point iterations
|
||||
for (BasicBlock* block : ...) { // B blocks
|
||||
for (auto& entry : relationshipMap) { // R relationships
|
||||
if (liveAtHead.contains(node)) // O(L) linear scan per check
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With 50 iterations × B=20 blocks × R=30 relationships × L=40 live nodes:
|
||||
**1,200,000 comparisons per compile** for a medium-sized function with integer-heavy loops.
|
||||
|
||||
## Fix
|
||||
|
||||
Replace `Vector<NodeFlowProjection> liveAtHead` with `UncheckedKeyHashSet<NodeFlowProjection>`.
|
||||
`NodeFlowProjection` already has a usable hash (it wraps a `Node*` + projection kind):
|
||||
|
||||
```cpp
|
||||
UncheckedKeyHashSet<NodeFlowProjection> liveAtHead;
|
||||
|
||||
// Populate once per block:
|
||||
for (NodeFlowProjection proj : computeLiveAtHead(block))
|
||||
liveAtHead.add(proj);
|
||||
|
||||
// Contains check: O(1)
|
||||
if (liveAtHead.contains(node)) { ... }
|
||||
```
|
||||
|
||||
Speedup: ~40× at L=40 (1.2M → 30K comparisons for 50×B=20×R=30).
|
||||
Loading…
Add table
Add a link
Reference in a new issue