# UNDF: UNDF-2026-000000588
# 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).
