45 lines
2.5 KiB
Diff
45 lines
2.5 KiB
Diff
# UNDF: UNDF-2026-000000123
|
||
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java
|
||
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java
|
||
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java
|
||
@@ -290,9 +290,10 @@ void notifyChange(List<Type> inferredVars) {
|
||
InferenceException thrownEx = null;
|
||
+ List<Type> remainingVars = inferencevars.diff(inferredVars);
|
||
for (Map.Entry<FreeTypeListener, List<Type>> entry :
|
||
new LinkedHashMap<>(freeTypeListeners).entrySet()) {
|
||
- if (!Type.containsAny(entry.getValue(), inferencevars.diff(inferredVars))) {
|
||
+ if (!Type.containsAny(entry.getValue(), remainingVars)) {
|
||
try {
|
||
entry.getKey().typesInferred(this);
|
||
freeTypeListeners.remove(entry.getKey());
|
||
|
||
# CWE-407: O(L × N × M) → O(N×M + L×V) where V = entry.getValue() size
|
||
# InferenceContext.java line 294 — notifyChange
|
||
#
|
||
# DEFECTIVE:
|
||
# void notifyChange(List<Type> inferredVars) {
|
||
# for (Map.Entry<FreeTypeListener, List<Type>> entry : ...) {
|
||
# if (!Type.containsAny(entry.getValue(),
|
||
# inferencevars.diff(inferredVars))) { // ← O(N*M) per listener
|
||
#
|
||
# inferencevars.diff(inferredVars) calls List.diff() which iterates every element
|
||
# of inferredVars (M items) and for each does a linear scan of the current list
|
||
# (up to N items) — cost O(N × M). This is recomputed from scratch on EVERY
|
||
# iteration of the freeTypeListeners loop (L iterations).
|
||
# Total: O(L × N × M).
|
||
#
|
||
# N = inferencevars count (type variables in scope — can be 10–100 in complex
|
||
# generic method calls with nested lambdas / multi-level bounded wildcards).
|
||
# M = inferredVars count (newly resolved variables — often ≈ N in final round).
|
||
# L = freeTypeListeners count (listeners registered per inference variable —
|
||
# can be O(N) during complex overload resolution in generic API chains).
|
||
#
|
||
# This hits hard on codebases like Spring / Guava / RxJava where deeply nested
|
||
# generic method calls stack up many inference contexts.
|
||
#
|
||
# FIX: hoist diff() out of the loop. The result does not change between
|
||
# iterations (neither inferencevars nor inferredVars mutate during the loop).
|
||
#
|
||
# Complexity:
|
||
# Defective: O(L × N × M) per notifyChange call
|
||
# Fixed: O(N×M + L×V) per notifyChange call (V = avg entry.getValue() size)
|