+\ ---- Garbage Collection ---- {{{
+
+variable gc-enabled
+false gc-enabled !
+
+: gc-enable
+ true gc-enabled ! ;
+
+: gc-disable
+ false gc-enabled ! ;
+
+: gc-enabled?
+ gc-enabled @ ;
+
+: pairlike? ( obj -- obj bool )
+ pair-type istype? if true exit then
+ string-type istype? if true exit then
+ symbol-type istype? if true exit then
+ compound-proc-type istype? if true exit then
+
+ false
+;
+
+: pairlike-marked? ( obj -- obj bool )
+ over nextfrees + 0=
+;
+
+: mark-pairlike ( obj -- obj )
+ over nextfrees + 0 swap !
+;
+
+: gc-mark-obj ( obj -- )
+
+ pairlike? if
+ pairlike-marked? if 2drop exit then
+
+ mark-pairlike
+
+ 2dup
+
+ car recurse
+ cdr recurse
+ else
+ 2drop
+ then
+;
+
+: gc-sweep
+ N nextfree !
+ 0 N 1- do
+ nextfrees i + @ 0<> if
+ nextfree @ nextfrees i + !
+ i nextfree !
+ then
+ -1 +loop ;
+
+\ }}}
+