mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
Some checks failed
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Gitleaks / gitleaks (push) Has been cancelled
Publish / Classify release event (push) Has been cancelled
Scorecard / Scorecard analysis (push) Has been cancelled
Trivy Image Scan / Trivy (gitnexus-cli) (push) Has been cancelled
Trivy Image Scan / Trivy (gitnexus-web) (push) Has been cancelled
Publish / Build & Push RC Docker images (push) Has been cancelled
Publish / RC guard (marker + release-PR skip) (push) Has been cancelled
Publish / ci (push) Has been cancelled
Publish / Publish to npm (push) Has been cancelled
* fix(zig): resolve cross-file static gates * Fix Zig workspace import alias enrichment * Handle extensionless Zig workspace imports * Reuse Zig import resolution for static gates * Document Zig workspace static gating * Harden Zig workspace reference enrichment * Benchmark Zig cross-file static gating * Enforce linear Zig benchmark scaling --------- Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
138 lines
4.7 KiB
JavaScript
138 lines
4.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Build-free scaling and correctness guard for Zig cross-file static gates.
|
|
*
|
|
* The workspace pass parses every indexed Zig file, resolves direct @import
|
|
* aliases, then applies sibling boolean constants to call sites. This bench
|
|
* makes both relevant axes explicit: file count and calls per importer. It
|
|
* also fingerprints the number of calls classified dead, so a fast no-op
|
|
* implementation cannot pass the timing gate.
|
|
*
|
|
* Usage:
|
|
* node --import tsx bench/zig-cross-file-resolution/measure.mjs
|
|
* node --import tsx bench/zig-cross-file-resolution/measure.mjs --check
|
|
*/
|
|
import { readFileSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { performance } from 'node:perf_hooks';
|
|
import { populateZigWorkspaceStaticGating } from '../../src/core/ingestion/languages/zig/workspace-static-gating.ts';
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const SMALL_MODULES = 40;
|
|
const LARGE_MODULES = 160;
|
|
const CALLS_PER_MODULE = 12;
|
|
const REPS = 7;
|
|
|
|
const range = (line, col) => ({ startLine: line, startCol: col, endLine: line, endCol: col + 4 });
|
|
|
|
function corpus(modules) {
|
|
const parsedFiles = [];
|
|
const fileContents = new Map();
|
|
for (let i = 0; i < modules; i++) {
|
|
const cfgPath = `bench/cfg${i}.zig`;
|
|
const appPath = `bench/app${i}.zig`;
|
|
fileContents.set(cfgPath, 'pub const ENABLED = false;\n');
|
|
fileContents.set(
|
|
appPath,
|
|
`const cfg = @import(\"./cfg${i}.zig\");\n` +
|
|
Array.from(
|
|
{ length: CALLS_PER_MODULE },
|
|
(_, j) => `pub fn run${j}() void { if (cfg.ENABLED) dead${j}(); }`,
|
|
).join('\n'),
|
|
);
|
|
parsedFiles.push(Object.freeze({ filePath: cfgPath, referenceSites: Object.freeze([]) }));
|
|
parsedFiles.push(
|
|
Object.freeze({
|
|
filePath: appPath,
|
|
referenceSites: Object.freeze(
|
|
Array.from({ length: CALLS_PER_MODULE }, (_, j) => ({
|
|
kind: 'call',
|
|
name: `dead${j}`,
|
|
atRange: range(j + 2, 44),
|
|
})),
|
|
),
|
|
}),
|
|
);
|
|
}
|
|
return { parsedFiles, fileContents };
|
|
}
|
|
|
|
function run(modules) {
|
|
const { parsedFiles, fileContents } = corpus(modules);
|
|
populateZigWorkspaceStaticGating(parsedFiles, { fileContents });
|
|
let gatedCalls = 0;
|
|
for (const file of parsedFiles) {
|
|
for (const site of file.referenceSites) if (site.staticGated === true) gatedCalls++;
|
|
}
|
|
return gatedCalls;
|
|
}
|
|
|
|
function measure(modules) {
|
|
run(modules);
|
|
let bestMs = Infinity;
|
|
let gatedCalls = 0;
|
|
for (let i = 0; i < REPS; i++) {
|
|
const start = performance.now();
|
|
gatedCalls = run(modules);
|
|
bestMs = Math.min(bestMs, performance.now() - start);
|
|
}
|
|
return {
|
|
modules,
|
|
calls_per_module: CALLS_PER_MODULE,
|
|
gated_calls: gatedCalls,
|
|
min_ms: Number(bestMs.toFixed(2)),
|
|
};
|
|
}
|
|
|
|
const report = { small: measure(SMALL_MODULES), large: measure(LARGE_MODULES) };
|
|
report.workload_ratio = LARGE_MODULES / SMALL_MODULES;
|
|
report.scaling_ratio = Number(
|
|
(report.large.min_ms / Math.max(report.small.min_ms, 0.01)).toFixed(3),
|
|
);
|
|
report.linear_factor = Number((report.scaling_ratio / report.workload_ratio).toFixed(3));
|
|
|
|
if (!process.argv.includes('--check')) {
|
|
console.log(JSON.stringify(report, null, 2));
|
|
process.exit(0);
|
|
}
|
|
|
|
const baseline = JSON.parse(readFileSync(join(HERE, 'baseline.json'), 'utf8'));
|
|
const failures = [];
|
|
const requirePositiveNumber = (path, value) => {
|
|
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
failures.push(`${path}: expected a finite positive number, got ${JSON.stringify(value)}`);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
for (const arm of ['small', 'large']) {
|
|
for (const key of ['modules', 'calls_per_module', 'gated_calls']) {
|
|
if (report[arm][key] !== baseline[arm][key]) {
|
|
failures.push(`${arm}.${key}: expected ${baseline[arm][key]}, got ${report[arm][key]}`);
|
|
}
|
|
}
|
|
if (
|
|
requirePositiveNumber(`${arm}.ms_budget`, baseline[arm].ms_budget) &&
|
|
report[arm].min_ms > baseline[arm].ms_budget
|
|
) {
|
|
failures.push(`${arm}.min_ms ${report[arm].min_ms} exceeds budget ${baseline[arm].ms_budget}`);
|
|
}
|
|
}
|
|
if (
|
|
requirePositiveNumber('linear_scaling_slack', baseline.linear_scaling_slack) &&
|
|
report.linear_factor > baseline.linear_scaling_slack
|
|
) {
|
|
failures.push(
|
|
`linear_factor ${report.linear_factor} exceeds slack ${baseline.linear_scaling_slack} ` +
|
|
`(runtime ${report.scaling_ratio}x for ${report.workload_ratio}x work)`,
|
|
);
|
|
}
|
|
|
|
console.log(JSON.stringify(report, null, 2));
|
|
if (failures.length > 0) {
|
|
console.error('[zig-cross-file-resolution --check] FAIL');
|
|
for (const failure of failures) console.error(` - ${failure}`);
|
|
process.exit(1);
|
|
}
|
|
console.log('[zig-cross-file-resolution --check] PASS');
|