needs tests/harness mem/cons testbegin \test cons GC mechanism gc conscnt const floorcnt 42 43 cons \ hold onto it in PS 44 45 cons consref myref gc conscnt floorcnt 2+ #eq : dofill 0 do 0 0 cons drop loop ; CONSCNT conscnt - 1- dofill conscnt CONSCNT 1- #eq 54 54 cons dup iscons? #true isgccons? #true \ last cons before GC conscnt CONSCNT #eq 54 54 cons dup iscons? #true isgccons? #true \ GC should have run conscnt floorcnt 3 + #eq ( that cons held onto PS from earlier ) carcdr 43 #eq 42 #eq myref carcdr 45 #eq 44 #eq 64 ?single #true 64 #eq 42 0 cons ?single #true 42 #eq 1 0 cons 2 swap cons dup ?single not #true #eq \ Clear everything 0 to myref gc conscnt floorcnt #eq \test list and appending to lists 42 0 cons ( list ) dup 54 append drop ( list ) dup length 2 #eq dup car 42 #eq tail cdrcar 54 #eq 0 #eq \test can append to a null list 0 42 append cdrcar 42 #eq 0 #eq \test leak 42 54 cons leak ( cons ) dup isgccons? not #true dup iscons? #true cdrcar 42 #eq 54 #eq gc conscnt floorcnt #eq \test leak handles circular references 1 n"REPL" cons ( c1 ) 2 over cons 3 swap cons ( c1 c3 ) over to cdr ( c1 ) \ this is a 3 cons circle gc \ just make sure the GC behaves well with c1 held leak dup iscons? #true dup isgccons? not #true ( leakedc1 ) dup cdrcar 1 #eq cdrcar 3 #eq cdrcar 2 #eq #eq ( ) gc conscnt floorcnt #eq \test now let's do the same on the "car" side \ The GC used to end up in an infinite loops on such circles n"REPL" 1 cons dup 2 cons 3 cons ( c1 c3 ) over to car ( c1 ) \ this is a 3 cons circle on the "car" side gc \ just make sure the GC behaves well with c1 held leak dup iscons? #true dup isgccons? not #true ( leakedc1 ) dup carcdr 1 #eq carcdr 3 #eq carcdr 2 #eq #eq ( ) gc conscnt floorcnt #eq testend