flan/test/programs/fn-in-map.flan

59 lines
1.8 KiB
Plaintext

;; A Map holding closures and a Map holding dyn values, both kept alive by the
;; collector across enough allocation that it runs many times. A Map's block is
;; walked like a Vec's: the full slots' values are marked through the value
;; type's descriptor. A lost value is a use of freed memory here, not a wrong
;; number.
(defn adder [n i32] (Fn [i32] i32)
(fn [x] (+ x n)))
;; Garbage, and plenty of it: every pass boxes and drops a vector of four.
(defn churn [n i32] ()
(dotimes [i n]
(let [junk (vec-new dyn)]
(push junk i)
(push junk "row")
(push junk 2.5)
(push junk true))))
(defn main [] i32
(let [ops (map-new str (Fn [i32] i32))
many (map-new i32 (Fn [i32] i32))
rows (map-new i32 dyn)]
(put ops "one" (adder 1))
(put ops "ten" (adder 10))
(put ops "hundred" (adder 100))
;; Each value a dyn vector the collector allocated, reachable from
;; nothing but the map.
(dotimes [i 64]
(let [row (vec-new dyn)]
(push row i)
(push row "row")
(put rows i row)))
(churn 40000)
;; Grown after the churn, so a rebuilt block is walked too.
(dotimes [i 64]
(put many i (adder i)))
(churn 40000)
(let [total 0]
(dotimes [i 64]
(set total (+ total (match (get many i) (Some f) (f 0) None 0))))
(println total))
(dotimes [i 3]
(let [name (at ["one" "ten" "hundred"] i)]
(println (match (get ops name) (Some f) (f 1) None -1))))
(let [cur (i64 0)
k 0
v (the dyn nil)
sum 0
n 0]
(while (map-next rows (addr cur) (addr k) (addr v))
(set sum (+ sum (i32 (at v 0))))
(set n (+ n 1)))
(println n)
(println sum))
(free ops)
(free many)
(free rows))
0)