wave7: 433/194 — kafka/flink/pulsar, spring/micronaut/quarkus, nginx/haproxy/traefik, linux/nomad/consul, numpy/pandas/sklearn, ES/OS/pg/sqlite/rustc/cargo
This commit is contained in:
parent
3735145aa5
commit
5fe6da7cc2
69 changed files with 6793 additions and 32 deletions
219
defects/rustc/unit/TargetFeatureCallSafeAlgorithm.java
Normal file
219
defects/rustc/unit/TargetFeatureCallSafeAlgorithm.java
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Models rustc's is_target_feature_call_safe() —
|
||||
* checks whether all features required by the callee are present in the caller's body.
|
||||
*
|
||||
* SLOW: O(C × B) — for each callee feature, scan all body features linearly.
|
||||
* FAST: O(C + B) — build a HashSet from body features once, then O(1) per callee lookup.
|
||||
*
|
||||
* CWE-407: compiler/rustc_middle/src/ty/context.rs:1323-1325
|
||||
*/
|
||||
public class TargetFeatureCallSafeAlgorithm {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Slow (defective) implementation — mirrors current rustc code
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static class SlowChecker {
|
||||
long linearScans = 0;
|
||||
|
||||
/**
|
||||
* Returns true if all callee features are present in bodyFeatures.
|
||||
* O(callee.size() × body.size()) — Vec<TargetFeature> nested linear scan.
|
||||
*/
|
||||
boolean isSafe(List<String> calleeFeatures, List<String> bodyFeatures) {
|
||||
for (String callee : calleeFeatures) {
|
||||
boolean found = false;
|
||||
for (String body : bodyFeatures) {
|
||||
linearScans++;
|
||||
if (body.equals(callee)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Fast (fixed) implementation — HashSet for O(1) membership
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static class FastChecker {
|
||||
long hashLookups = 0;
|
||||
|
||||
/**
|
||||
* Returns true if all callee features are present in bodyFeatures.
|
||||
* O(C + B) — build HashSet once, then O(1) per callee feature.
|
||||
*/
|
||||
boolean isSafe(List<String> calleeFeatures, List<String> bodyFeatures) {
|
||||
Set<String> bodySet = new HashSet<>(bodyFeatures);
|
||||
for (String callee : calleeFeatures) {
|
||||
hashLookups++;
|
||||
if (!bodySet.contains(callee)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Test helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static int passed = 0;
|
||||
static int total = 0;
|
||||
|
||||
static void check(String desc, boolean cond) {
|
||||
total++;
|
||||
if (cond) {
|
||||
passed++;
|
||||
System.out.printf(" PASS %s%n", desc);
|
||||
} else {
|
||||
System.out.printf(" FAIL %s%n", desc);
|
||||
}
|
||||
}
|
||||
|
||||
/** Simulate x86-64 target features (subset of actual rustc list). */
|
||||
static List<String> buildPlatformFeatures(int count) {
|
||||
String[] base = {
|
||||
"avx512f", "avx512cd", "avx512bw", "avx512dq", "avx512vl",
|
||||
"avx512ifma", "avx512vbmi", "avx512vnni", "avx512bf16", "avx512vp2intersect",
|
||||
"avx2", "avx", "fma", "bmi1", "bmi2", "lzcnt", "popcnt",
|
||||
"sse4.1", "sse4.2", "sse4a", "ssse3", "sse3", "sse2", "sse",
|
||||
"aes", "pclmulqdq", "sha", "rdrnd", "rdseed", "adx",
|
||||
"f16c", "fxsr", "xsave", "xsaveopt", "xsavec", "xsaves",
|
||||
"cx16", "sahf", "movbe", "cmpxchg16b", "clflushopt", "clwb",
|
||||
"rtm", "hle", "tbm", "3dnow", "3dnowa", "mmx", "abm",
|
||||
"ermsb", "fsrm", "vpclmulqdq", "vaes", "gfni", "avxvnni",
|
||||
"amx-tile", "amx-int8", "amx-bf16", "amx-fp16",
|
||||
"serialize", "tsxldtrk", "uintr", "kl", "widekl",
|
||||
};
|
||||
List<String> result = new ArrayList<>();
|
||||
for (int i = 0; i < Math.min(count, base.length); i++) {
|
||||
result.add(base[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("TargetFeatureCallSafeAlgorithm — CWE-407 unit test");
|
||||
System.out.println("rustc-0003: is_target_feature_call_safe O(C×B) → O(C+B)");
|
||||
System.out.println();
|
||||
|
||||
SlowChecker slow = new SlowChecker();
|
||||
FastChecker fast = new FastChecker();
|
||||
|
||||
// --- Correctness: safe call (callee subset of body) ---
|
||||
{
|
||||
List<String> callee = List.of("avx2", "bmi1", "popcnt");
|
||||
List<String> body = List.of("avx2", "avx", "bmi1", "bmi2", "popcnt", "sse4.1");
|
||||
|
||||
boolean slowResult = slow.isSafe(callee, body);
|
||||
boolean fastResult = fast.isSafe(callee, body);
|
||||
|
||||
check("safe-call: slow returns true", slowResult);
|
||||
check("safe-call: fast returns true", fastResult);
|
||||
check("safe-call: results agree", slowResult == fastResult);
|
||||
}
|
||||
|
||||
// --- Correctness: unsafe call (callee has feature body lacks) ---
|
||||
{
|
||||
List<String> callee = List.of("avx512f", "avx512bw");
|
||||
List<String> body = List.of("avx2", "avx", "bmi1");
|
||||
|
||||
boolean slowResult = slow.isSafe(callee, body);
|
||||
boolean fastResult = fast.isSafe(callee, body);
|
||||
|
||||
check("unsafe-call: slow returns false", !slowResult);
|
||||
check("unsafe-call: fast returns false", !fastResult);
|
||||
check("unsafe-call: results agree", slowResult == fastResult);
|
||||
}
|
||||
|
||||
// --- Correctness: empty callee (always safe) ---
|
||||
{
|
||||
List<String> callee = List.of();
|
||||
List<String> body = List.of("avx2");
|
||||
|
||||
boolean slowResult = slow.isSafe(callee, body);
|
||||
boolean fastResult = fast.isSafe(callee, body);
|
||||
|
||||
check("empty-callee: slow returns true", slowResult);
|
||||
check("empty-callee: fast returns true", fastResult);
|
||||
}
|
||||
|
||||
// --- Correctness: empty body, non-empty callee (always unsafe) ---
|
||||
{
|
||||
List<String> callee = List.of("avx2");
|
||||
List<String> body = List.of();
|
||||
|
||||
boolean slowResult = slow.isSafe(callee, body);
|
||||
boolean fastResult = fast.isSafe(callee, body);
|
||||
|
||||
check("empty-body: slow returns false", !slowResult);
|
||||
check("empty-body: fast returns false", !fastResult);
|
||||
}
|
||||
|
||||
// --- Performance: O(C×B) vs O(C+B) ---
|
||||
{
|
||||
// Simulate a function with 50 callee features all present at the END of a 60-feature
|
||||
// body — forces slow checker to scan to the last position for each callee feature,
|
||||
// maximising the per-call comparison count to ~C×B.
|
||||
int C = 50;
|
||||
int B = 60;
|
||||
// callee features are the LAST C entries of the B-element body list
|
||||
List<String> fullBody = buildPlatformFeatures(B);
|
||||
List<String> body = new ArrayList<>(fullBody);
|
||||
// callee = last C elements (appear near end of body, maximise scan length)
|
||||
List<String> callee = new ArrayList<>(fullBody.subList(B - C, B));
|
||||
// Reverse body so callee features are at the back
|
||||
java.util.Collections.reverse(body);
|
||||
|
||||
// Warm up JIT
|
||||
for (int i = 0; i < 500; i++) slow.isSafe(callee, body);
|
||||
for (int i = 0; i < 500; i++) fast.isSafe(callee, body);
|
||||
|
||||
// Reset counters
|
||||
slow.linearScans = 0;
|
||||
fast.hashLookups = 0;
|
||||
|
||||
int RUNS = 20_000;
|
||||
long t0 = System.nanoTime();
|
||||
for (int i = 0; i < RUNS; i++) slow.isSafe(callee, body);
|
||||
long slowNs = System.nanoTime() - t0;
|
||||
|
||||
long t1 = System.nanoTime();
|
||||
for (int i = 0; i < RUNS; i++) fast.isSafe(callee, body);
|
||||
long fastNs = System.nanoTime() - t1;
|
||||
|
||||
double ratio = (double) slowNs / fastNs;
|
||||
|
||||
System.out.printf(" INFO C=%d B=%d slow_scans=%d fast_lookups=%d ratio=%.1fx%n",
|
||||
C, B, slow.linearScans, fast.hashLookups, ratio);
|
||||
|
||||
// Slow: each callee feature is at the back of body → scans many positions each.
|
||||
// Minimum acceptable: at least C*(B/4)*RUNS (conservative lower bound, early-exit aware)
|
||||
check("slow does >> C×RUNS comparisons (linear scan dominates)",
|
||||
slow.linearScans >= (long) C * (B / 4) * RUNS);
|
||||
// Fast: exactly C hash lookups per call
|
||||
check("fast does exactly C×RUNS hash lookups",
|
||||
fast.hashLookups == (long) C * RUNS);
|
||||
// Op ratio: slow does at least B/2 per callee feature, fast does 1
|
||||
long slowOpsPerRun = slow.linearScans / RUNS;
|
||||
long fastOpsPerRun = fast.hashLookups / RUNS;
|
||||
check("slow op count >> fast op count (>= 10x)",
|
||||
slowOpsPerRun >= fastOpsPerRun * 10);
|
||||
}
|
||||
|
||||
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