;;;; spec-memory.md, "Dev builds detect a released region" — the Map's half. ;;;; ;;;; A Map records the epoch of the allocator it was made with, exactly as a ;;;; Vec does, and free-all bumps that counter. Any operation on a container ;;;; whose recorded epoch has moved traps, naming the site. ;;;; ;;;; This is worth its own program rather than a line in stale-region.flan ;;;; because the two containers reach the check by different routes: a Vec's ;;;; every operation takes the Vec's address and checks on the way in, while a ;;;; map's get goes on to call a hash and an equality function through pointers ;;;; into a block that is no longer there. If the check were missing here, the ;;;; failure would not be a wrong number — it would be a probe loop walking ;;;; released memory. (defn main [] i32 (let [a (arena-new 65536)] (let [m (map-new i32 i32 a)] (put m 1 10) (put m 2 20) (match (get m 2) (Some v) (println v) None (println "missing")) ;; The region goes. m is still in scope and still looks fine — nothing is ;; released at scope exit and nothing marked m — which is exactly the ;; case a static rule cannot see. (free-all a) (match (get m 2) (Some v) (println v) None (println "missing")))) 0)