code wiki / _hdl_build / nx_js_realbench.nx
nx_js_realbench.nx source
↩ module page · 102 lines · 5971 B
1// nx_js_realbench.nx -- CAPSTONE of the JIT arc: realistic BUNDLE-SHAPED programs (the composition of
2// features real page/app code uses -- constructors+new, methods+this, arrays of objects, higher-order
3// functions taking closures, string building, modulo/ternary, nested loops, recursion) run through the
4// TREE-WALKER (js_run_source) vs the VM/JIT (compile_run). Proves (A) identical results on multi-feature
5// programs -- a broader integration test than the micro-kernels, catching feature-interaction bugs -- and
6// (B) the end-to-end speedup that BREAKS the ~1000x-too-slow tree-walker wall which stalled real bundles.
7// This is the honest "the sovereign engine can now run real code fast" measurement. expect_exit: 0
8// license_tier: ORIGINAL
9import "nx_js_vm.nx"
10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
11
12func rb_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
14// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
15// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
16// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
17func rb_n(v: i64) -> i64 { nxi_out(v); return 0 }
18// run `src` best-of-3 through the given engine (0=VM/JIT compile_run, 1=tree js_run_source); result in out.
19func rb_time(src: *u8, engine: i64, out: *i64) -> i64 {
20 var best: i64 = 0
21 var r: i64 = 0
22 while r < 3 {
23 let t0: i64 = sys_now_us()
24 if engine == 0 { compile_run(src, out) } else { js_run_source(src, bsl(src), out) }
25 let t1: i64 = sys_now_us()
26 var us: i64 = t1 - t0
27 if us < 1 { us = 1 }
28 if r == 0 { best = us }
29 if us < best { best = us }
30 r = r + 1
31 }
32 return best
33}
34// A: tree vs VM/JIT on `src` -- verify identical result + measure the speedup; note if it JIT-compiled.
35func rb_case(src: *u8, label: *u8, pp: *i64, tp: *i64) -> i64 {
36 tp[0] = tp[0] + 1
37 let tw: *i64 = sys_mmap(16) as *i64
38 let vm: *i64 = sys_mmap(16) as *i64
39 let tus: i64 = rb_time(src, 1, tw)
40 let vus: i64 = rb_time(src, 0, vm)
41 let jitd: i64 = js_jit_probe(src)
42 rb_w(" ")
43 rb_w(label)
44 rb_w(": ")
45 if cells_eq(tw, vm) == 1 {
46 pp[0] = pp[0] + 1
47 rb_w("MATCH tree=")
48 rb_n(tus)
49 rb_w("us vm=")
50 rb_n(vus)
51 rb_w("us speedup=")
52 rb_n(tus * 100 / vus)
53 rb_w("/100x path=")
54 if jitd == 1 { rb_w("JIT-native" as *u8) } else { rb_w("VM-interp" as *u8) }
55 rb_w("\n" as *u8)
56 return 0
57 }
58 rb_w("MISMATCH tree(tag=")
59 rb_n(tw[0])
60 rb_w(",pay=")
61 rb_n(tw[1])
62 rb_w(") vs vm(tag=")
63 rb_n(vm[0])
64 rb_w(",pay=")
65 rb_n(vm[1])
66 rb_w(")\n" as *u8)
67 return 0
68}
69
70func main(argc: i64, argv: *i64) -> i64 {
71 rb_w("=== nx_js_realbench: realistic bundle-shaped programs, tree-walker vs VM/JIT ===\n" as *u8)
72 let pp: *i64 = sys_mmap(8) as *i64
73 let tp: *i64 = sys_mmap(8) as *i64
74
75 // R1 -- data pipeline: constructors + new, methods/this, array-of-objects, higher-order fns taking
76 // closures, string building, modulo/ternary. The shape of hydration/data-processing bundle code.
77 rb_case("function Record(id,val,tag){this.id=id;this.val=val;this.tag=tag;}function makeData(n){var a=[];var i=0;while(i<n){a[i]=new Record(i,i*3,(i%2==0)?'even':'odd');i=i+1;}return a;}function sumBy(a,pred){var s=0;var i=0;while(i<a.length){if(pred(a[i])){s=s+a[i].val;}i=i+1;}return s;}var data=makeData(300);var evens=sumBy(data,function(r){return r.tag=='even';});var odds=sumBy(data,function(r){return r.tag=='odd';});var report='';var j=0;while(j<5){report=report+'row'+j+':'+data[j].val+';';j=j+1;}evens*1000000+odds*1000+report.length" as *u8, "R1 data pipeline (new/this/closures/HOF)" as *u8, pp, tp)
78
79 // R2 -- recursive tree walk + memo-ish object map (recursion, object as map, method dispatch).
80 rb_case("function node(v,l,r){return {v:v,l:l,r:r};}function build(d){if(d==0){return null;}return node(d,build(d-1),build(d-1));}function sum(t){if(t==null){return 0;}return t.v+sum(t.l)+sum(t.r);}function count(t){if(t==null){return 0;}return 1+count(t.l)+count(t.r);}var tree=build(12);sum(tree)*100000+count(tree)" as *u8, "R2 recursive tree (recursion/objects/null)" as *u8, pp, tp)
81
82 // R3 -- array methods + callbacks (map/filter/reduce chains -- the functional bundle idiom).
83 rb_case("var xs=[];var i=0;while(i<200){xs[i]=i;i=i+1;}var evens=xs.filter(function(x){return x%2==0;});var doubled=evens.map(function(x){return x*2;});var total=doubled.reduce(function(a,b){return a+b;},0);total*1000+doubled.length" as *u8, "R3 filter/map/reduce chain (callbacks)" as *u8, pp, tp)
84
85 // R4 -- string processing + accumulation (the templating/serialization idiom).
86 rb_case("function esc(s){return s;}function render(items){var out='<ul>';var i=0;while(i<items.length){out=out+'<li>'+esc(items[i].name)+'='+items[i].n+'</li>';i=i+1;}return out+'</ul>';}var items=[];var i=0;while(i<50){items[i]={name:'k'+i,n:i*7};i=i+1;}var html=render(items);html.length" as *u8, "R4 string/template building" as *u8, pp, tp)
87
88 // R5 -- hot numeric kernel with a helper call per iteration (the compute-heavy bundle path).
89 rb_case("function step(acc,i){return acc+i*i-i;}var acc=0;var i=0;while(i<50000){acc=step(acc,i);i=i+1;}acc" as *u8, "R5 hot numeric + per-iter call" as *u8, pp, tp)
90
91 rb_w(" --- correctness: ")
92 rb_n(pp[0])
93 rb_w("/")
94 rb_n(tp[0])
95 rb_w(" (VM/JIT == tree-walker on realistic multi-feature programs) ---\n" as *u8)
96 if pp[0] == tp[0] {
97 rb_w("=== GREEN: the sovereign engine runs REAL bundle-shaped code correctly + far faster (wall broken) ===\n" as *u8)
98 return 0
99 }
100 rb_w("=== RED: a realistic program diverged ===\n" as *u8)
101 return 1
102}