Memory

Memory

PekoScript is garbage collected. Objects are allocated on a managed heap and freed when they become unreachable. There is no free, no ownership transfer, and no borrow checker.

The collector is stop-the-world and sliding mark-compact. Two properties follow from that, and they matter as soon as you write native code:

  • Objects move. A collection can slide a live object to a new address, so an address held outside the managed world can go stale.
  • A collection can happen at any allocation. Any call that might allocate is a point where objects may move.

Managed pointers and references

pointer<T> is a managed pointer, used for buffers and interior storage. &T is a reference to a slot, produced by methods like index_ref so that a[i] = v can assign in place.

Ordinary object values are already references to managed memory, so passing an object to a function does not copy it.

Rules for native boundaries

When writing C interop or threaded code:

  • Do not hold a raw managed pointer across a call that can allocate or block. Re-read it after the call instead of caching it.
  • Park a thread around a blocking native call, so a collection can proceed while the thread sits outside managed code.
  • On Android, work on the UI thread parks the same way.

Getting this wrong produces failures far from the cause. The usual symptom is a crash inside an unrelated dispatch, because a reclaimed object's slot was reused and a vtable read landed on the wrong memory. If a crash makes no sense where it appears, suspect a stale managed pointer across an allocating call.