whitepaper: 398/185 — wave6d (rails-0012..16, jsc-0001/2, vtk, sm-0002, redis/valkey-0003, helm-0002/3, k8s-0003)
This commit is contained in:
parent
eb9612e4bf
commit
3735145aa5
47 changed files with 3488 additions and 33 deletions
166
defects/spidermonkey/unit/SpiderMonkeyRemapperTest.java
Normal file
166
defects/spidermonkey/unit/SpiderMonkeyRemapperTest.java
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SM-0002: MDefinitionRemapper::lookup() O(N) linear scan inside loop-unroll cloning.
|
||||
*
|
||||
* Models:
|
||||
* - SlowRemapper — Vector<Pair> linear lookup, O(V) per lookup → O(V²) per body clone
|
||||
* - FastRemapper — HashMap<K,V> lookup, O(1) per lookup → O(V) per body clone
|
||||
*
|
||||
* Compile: javac -d . *.java (from defects/spidermonkey/unit/)
|
||||
* Run: java -ea unit.SpiderMonkeyRemapperTest
|
||||
*/
|
||||
public class SpiderMonkeyRemapperTest {
|
||||
|
||||
// ---- slow path: Vector<Pair> linear scan --------------------------------
|
||||
|
||||
static class SlowRemapper {
|
||||
static long opCount;
|
||||
|
||||
static class Pair {
|
||||
final int original;
|
||||
int replacement;
|
||||
Pair(int o) { original = o; replacement = o; }
|
||||
}
|
||||
|
||||
private final List<Pair> pairs = new ArrayList<>();
|
||||
|
||||
void enregister(int original) {
|
||||
pairs.add(new Pair(original));
|
||||
}
|
||||
|
||||
int lookup(int original) {
|
||||
for (Pair p : pairs) {
|
||||
opCount++;
|
||||
if (p.original == original)
|
||||
return p.replacement;
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
void update(int original, int replacement) {
|
||||
for (Pair p : pairs) {
|
||||
if (p.original == original) {
|
||||
p.replacement = replacement;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- fast path: HashMap O(1) lookup -------------------------------------
|
||||
|
||||
static class FastRemapper {
|
||||
static long opCount;
|
||||
private final HashMap<Integer, Integer> map = new HashMap<>();
|
||||
|
||||
void enregister(int original) {
|
||||
map.put(original, original);
|
||||
}
|
||||
|
||||
int lookup(int original) {
|
||||
opCount++; // one hash lookup
|
||||
Integer v = map.get(original);
|
||||
return v == null ? -1 : v;
|
||||
}
|
||||
|
||||
void update(int original, int replacement) {
|
||||
map.put(original, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- simulate loop body clone -------------------------------------------
|
||||
// For each of V values in the mapper, clone K operands that each call lookup().
|
||||
// Operands reference value (V-1) — the last registered — to hit worst-case
|
||||
// scan length for SlowRemapper (must scan entire list every time).
|
||||
|
||||
static long simulateClone(boolean fast, int V, int K) {
|
||||
int worstCaseKey = V - 1; // last in the vector → full scan each time
|
||||
if (fast) {
|
||||
FastRemapper.opCount = 0;
|
||||
FastRemapper mapper = new FastRemapper();
|
||||
for (int i = 0; i < V; i++) mapper.enregister(i);
|
||||
// clone V instructions, each with K operands
|
||||
for (int insn = 0; insn < V; insn++) {
|
||||
for (int op = 0; op < K; op++) {
|
||||
mapper.lookup(worstCaseKey);
|
||||
}
|
||||
}
|
||||
return FastRemapper.opCount;
|
||||
} else {
|
||||
SlowRemapper.opCount = 0;
|
||||
SlowRemapper mapper = new SlowRemapper();
|
||||
for (int i = 0; i < V; i++) mapper.enregister(i);
|
||||
for (int insn = 0; insn < V; insn++) {
|
||||
for (int op = 0; op < K; op++) {
|
||||
mapper.lookup(worstCaseKey);
|
||||
}
|
||||
}
|
||||
return SlowRemapper.opCount;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- tests --------------------------------------------------------------
|
||||
|
||||
static int passed = 0;
|
||||
static int total = 0;
|
||||
|
||||
static void check(String name, boolean cond) {
|
||||
total++;
|
||||
if (cond) {
|
||||
passed++;
|
||||
} else {
|
||||
System.out.println("FAIL: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// correctness: both return same result
|
||||
{
|
||||
SlowRemapper slow = new SlowRemapper();
|
||||
FastRemapper fast = new FastRemapper();
|
||||
int[] vals = {10, 20, 30, 40, 50};
|
||||
for (int v : vals) { slow.enregister(v); fast.enregister(v); }
|
||||
slow.update(20, 99); fast.update(20, 99);
|
||||
check("slow lookup 10", slow.lookup(10) == 10);
|
||||
check("fast lookup 10", fast.lookup(10) == 10);
|
||||
check("slow lookup 20 updated", slow.lookup(20) == 99);
|
||||
check("fast lookup 20 updated", fast.lookup(20) == 99);
|
||||
check("slow lookup 50", slow.lookup(50) == 50);
|
||||
check("fast lookup 50", fast.lookup(50) == 50);
|
||||
check("slow lookup miss", slow.lookup(99) == -1);
|
||||
check("fast lookup miss", fast.lookup(99) == -1);
|
||||
}
|
||||
|
||||
// op-count scaling: V values, K=3 operands each
|
||||
int[] sizes = {10, 30, 60, 100, 150};
|
||||
int K = 3;
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("%-8s %12s %12s %8s%n", "V", "slow_ops", "fast_ops", "ratio");
|
||||
for (int V : sizes) {
|
||||
long slowOps = simulateClone(false, V, K);
|
||||
long fastOps = simulateClone(true, V, K);
|
||||
double ratio = (double) slowOps / fastOps;
|
||||
System.out.printf("%-8d %12d %12d %8.1f%n", V, slowOps, fastOps, ratio);
|
||||
|
||||
// slow ops should be O(V²): roughly V * K * V/2 on average
|
||||
// fast ops should be O(V): exactly V * K
|
||||
long expectedFast = (long) V * K;
|
||||
// slow worst-case: each lookup scans all V entries (key is last)
|
||||
long expectedSlow = (long) V * K * V;
|
||||
check("fast ops == V*K for V=" + V, fastOps == expectedFast);
|
||||
check("slow ops == V*K*V for V=" + V, slowOps == expectedSlow);
|
||||
// ratio should be exactly V (slow scans V items per lookup)
|
||||
check("slow/fast ratio == V for V=" + V, Math.abs(ratio - V) < 0.01);
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("%d/%d PASS%n", passed, total);
|
||||
if (passed != total) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue