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
147
defects/jsc/unit/JSCBytecodeBasicBlockTest.java
Normal file
147
defects/jsc/unit/JSCBytecodeBasicBlockTest.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JSC-0001: BytecodeBasicBlock::computeImpl() O(B²×T) edge linking.
|
||||
*
|
||||
* Models the inner loop in BytecodeBasicBlock.cpp lines 181-193:
|
||||
* - SlowLinker: for each branch block, scan all B blocks and call
|
||||
* Vector::contains(jumpTargets) for each — O(B × T) per branch
|
||||
* - FastLinker: load jump targets into HashSet first — O(B + T) per branch
|
||||
*
|
||||
* Compile: javac -d . *.java (from defects/jsc/unit/)
|
||||
* Run: java -ea unit.JSCBytecodeBasicBlockTest
|
||||
*/
|
||||
public class JSCBytecodeBasicBlockTest {
|
||||
|
||||
// ---- slow path: Vector<Offset> linear contains --------------------------
|
||||
|
||||
static class SlowLinker {
|
||||
static long opCount;
|
||||
|
||||
/**
|
||||
* @param blockCount total basic blocks (B)
|
||||
* @param jumpTargets list of target offsets (size T)
|
||||
* @return number of (block, target) linkage operations found
|
||||
*/
|
||||
static int link(int blockCount, List<Integer> jumpTargets) {
|
||||
int linked = 0;
|
||||
// Simulate: for (auto& otherBlock : basicBlocks)
|
||||
for (int blockId = 0; blockId < blockCount; blockId++) {
|
||||
// Simulate: bytecodeOffsetsJumpedTo.contains(otherBlock.leaderOffset())
|
||||
for (Integer target : jumpTargets) {
|
||||
opCount++;
|
||||
if (target == blockId) {
|
||||
linked++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return linked;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- fast path: HashSet<Offset> O(1) lookup -----------------------------
|
||||
|
||||
static class FastLinker {
|
||||
static long opCount;
|
||||
|
||||
static int link(int blockCount, List<Integer> jumpTargets) {
|
||||
// Build HashSet once: O(T)
|
||||
HashSet<Integer> targetSet = new HashSet<>(jumpTargets);
|
||||
opCount += jumpTargets.size(); // insertions
|
||||
|
||||
int linked = 0;
|
||||
// Simulate: for (auto& otherBlock : basicBlocks)
|
||||
for (int blockId = 0; blockId < blockCount; blockId++) {
|
||||
opCount++; // one hash lookup
|
||||
if (targetSet.contains(blockId)) {
|
||||
linked++;
|
||||
}
|
||||
}
|
||||
return linked;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- helpers ------------------------------------------------------------
|
||||
|
||||
static List<Integer> makeTargets(int blockCount, int T) {
|
||||
// T evenly-spaced target block offsets
|
||||
List<Integer> targets = new ArrayList<>(T);
|
||||
int step = Math.max(1, blockCount / T);
|
||||
for (int i = 0; i < T && i * step < blockCount; i++)
|
||||
targets.add(i * step);
|
||||
return targets;
|
||||
}
|
||||
|
||||
// ---- 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 find same number of links
|
||||
{
|
||||
int B = 20, T = 4;
|
||||
List<Integer> targets = makeTargets(B, T);
|
||||
SlowLinker.opCount = 0;
|
||||
FastLinker.opCount = 0;
|
||||
int slowLinks = SlowLinker.link(B, targets);
|
||||
int fastLinks = FastLinker.link(B, targets);
|
||||
check("slow and fast agree on link count", slowLinks == fastLinks);
|
||||
check("linked count == T", slowLinks == T);
|
||||
}
|
||||
|
||||
// op-count scaling
|
||||
int[] blockCounts = {50, 100, 200, 500};
|
||||
int[] switchSizes = {10, 50, 200, 500};
|
||||
|
||||
System.out.println();
|
||||
System.out.printf("%-8s %-8s %14s %14s %10s%n",
|
||||
"B", "T", "slow_ops", "fast_ops", "ratio");
|
||||
|
||||
for (int B : blockCounts) {
|
||||
for (int T : switchSizes) {
|
||||
if (T > B) continue;
|
||||
List<Integer> targets = makeTargets(B, T);
|
||||
SlowLinker.opCount = 0;
|
||||
FastLinker.opCount = 0;
|
||||
int slowLinks = SlowLinker.link(B, targets);
|
||||
int fastLinks = FastLinker.link(B, targets);
|
||||
check("results agree B=" + B + " T=" + T, slowLinks == fastLinks);
|
||||
|
||||
long slow = SlowLinker.opCount;
|
||||
long fast = FastLinker.opCount;
|
||||
double ratio = (double) slow / fast;
|
||||
System.out.printf("%-8d %-8d %14d %14d %10.1f%n",
|
||||
B, T, slow, fast, ratio);
|
||||
|
||||
// slow ops ~ O(B × T), fast ops ~ O(B + T)
|
||||
// ratio should grow with min(B,T)
|
||||
int minBT = Math.min(B, T);
|
||||
check("slow > fast for B=" + B + " T=" + T, slow > fast);
|
||||
// for large T, ratio should be at least T/4
|
||||
if (T >= 50) {
|
||||
check("ratio >= T/4 for T=" + T, ratio >= (double) T / 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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