5-MOAD scan: pcsx2 2 defects, wine 1 defect + 1 MOAD-0004, thunderbird unavailable
PCSX2: - pcsx2-0001: Patch::ReloadEnabledLists 4x std::find on vector O(N^2) MEDIUM 6-12x - pcsx2-0002: GSCapture codec dedup std::find_if O(N^2) LOW 11x - MOAD-0002/0003/0004/0005: CLEAN Wine: - wine-0001: ntdll/loader.c find_module_dependency O(D) linked-list dedup HIGH 7x - MOAD-0004: ChangeServiceConfig logs password via debugstr_w MEDIUM - MOAD-0002/0003/0005: CLEAN Thunderbird: source unavailable (nicholasb2101/gecko-dev repo inaccessible)
This commit is contained in:
parent
4d2d38fe6e
commit
f2d7a3127e
2 changed files with 105 additions and 0 deletions
6
defects/thunderbird-0001/CLEAN.md
Normal file
6
defects/thunderbird-0001/CLEAN.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Thunderbird: Source Unavailable
|
||||
|
||||
Repository `https://github.com/nicholasb2101/gecko-dev` is not accessible
|
||||
(authentication required or repo does not exist). Both clone attempts failed.
|
||||
|
||||
All 5 MOADs: SKIPPED.
|
||||
99
defects/wine-0001/test/LoaderDependencyDedupTest.java
Normal file
99
defects/wine-0001/test/LoaderDependencyDedupTest.java
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for Wine wine-0001: ntdll/loader.c find_module_dependency
|
||||
* performs O(D) linear scan on a circular singly-linked list to check if a
|
||||
* DLL dependency already exists before adding it. Called for every import
|
||||
* during fixup_imports, giving O(I*D) per module.
|
||||
*
|
||||
* Fix: maintain a HashSet alongside the linked list for O(1) dedup.
|
||||
*
|
||||
* Defect file: dlls/ntdll/loader.c lines 860-873
|
||||
*/
|
||||
public class LoaderDependencyDedupTest {
|
||||
|
||||
// --- Defective: linear scan to find existing dependency ---
|
||||
static class DdagNodeDefective {
|
||||
List<Object> dependencies = new LinkedList<>();
|
||||
|
||||
boolean hasDependency(Object to) {
|
||||
for (Object dep : dependencies) {
|
||||
if (dep == to) return true; // O(D) scan
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addDependency(Object to) {
|
||||
if (!hasDependency(to)) { // O(D) per call
|
||||
dependencies.add(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Fixed: hash set for O(1) dedup ---
|
||||
static class DdagNodeFixed {
|
||||
List<Object> dependencies = new LinkedList<>();
|
||||
Set<Object> dependencySet = new HashSet<>();
|
||||
|
||||
void addDependency(Object to) {
|
||||
if (dependencySet.add(to)) { // O(1) dedup
|
||||
dependencies.add(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int N = 500;
|
||||
|
||||
// Simulate modules being imported
|
||||
Object[] modules = new Object[N];
|
||||
for (int i = 0; i < N; i++) modules[i] = new Object();
|
||||
|
||||
// Defective: add all, then try to add all again (worst case dedup)
|
||||
DdagNodeDefective defNode = new DdagNodeDefective();
|
||||
DdagNodeFixed fixNode = new DdagNodeFixed();
|
||||
|
||||
// Correctness: both should add N unique deps
|
||||
for (Object m : modules) { defNode.addDependency(m); fixNode.addDependency(m); }
|
||||
assert defNode.dependencies.size() == N : "Defective size wrong";
|
||||
assert fixNode.dependencies.size() == N : "Fixed size wrong";
|
||||
|
||||
// Re-add (all duplicates)
|
||||
for (Object m : modules) { defNode.addDependency(m); fixNode.addDependency(m); }
|
||||
assert defNode.dependencies.size() == N : "Defective re-add size wrong";
|
||||
assert fixNode.dependencies.size() == N : "Fixed re-add size wrong";
|
||||
|
||||
// Warmup
|
||||
for (int w = 0; w < 200; w++) {
|
||||
DdagNodeDefective d = new DdagNodeDefective();
|
||||
DdagNodeFixed f = new DdagNodeFixed();
|
||||
for (Object m : modules) { d.addDependency(m); f.addDependency(m); }
|
||||
for (Object m : modules) { d.addDependency(m); f.addDependency(m); }
|
||||
}
|
||||
|
||||
// Benchmark
|
||||
int ITER = 500;
|
||||
long t0 = System.nanoTime();
|
||||
for (int i = 0; i < ITER; i++) {
|
||||
DdagNodeDefective d = new DdagNodeDefective();
|
||||
for (Object m : modules) d.addDependency(m);
|
||||
for (Object m : modules) d.addDependency(m); // dedup pass
|
||||
}
|
||||
long defectNs = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
for (int i = 0; i < ITER; i++) {
|
||||
DdagNodeFixed f = new DdagNodeFixed();
|
||||
for (Object m : modules) f.addDependency(m);
|
||||
for (Object m : modules) f.addDependency(m); // dedup pass
|
||||
}
|
||||
long fixedNs = System.nanoTime() - t0;
|
||||
|
||||
double ratio = (double) defectNs / fixedNs;
|
||||
System.out.printf("DLL dependency dedup N=%d defect=%.1fms fixed=%.1fms ratio=%.1fx%n",
|
||||
N, defectNs / 1e6, fixedNs / 1e6, ratio);
|
||||
|
||||
assert ratio > 2.0 : "Expected >2x speedup, got " + ratio;
|
||||
System.out.println("PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue