The stacks are kept in their own stack collection in the freecell_solver_instance struct. When a move function wishes to create a derived states, it first copies the state, and then marks the flags of all the stacks as cleared. (check (*Mark STACKS_COW_CLEAR *) in the code).
Later on when a stack is changed, its flag is set, and a stack is copied to a indirect stacks buffer of the hard thread. and modified there. (check (*Mark STACKS_COW_COPY_STACK*) ).
The check_and_add_state function then, when checking a
new state, ignores those stacks whose flag was not set,
and collects the stacks whose flag was set.
( (*Mark STACKS_COW_CACHING*) ). The
memory for the collected stacks is allocated compactly in
a segment, where one stack starts after the other
(check alloc.c
and alloc.h
).
If the stack was found in the collection the memory that was
allocated is freed for use by future stacks).