In addition to borrowed-references, Cone also supports region-managed references. Region-managed references are also pointers to values and are constrained by permissions, both static and lock.
The key difference is that every region-managed reference belongs to a memory region in the heap which manages the ways its values are allocated and freed. This is in contrast to a borrowed reference, which has no idea which memory region holds the value it points to.
What is a Region?
Until now, the values we have worked with have all been stored in global and local variables:
- All global variable values are stored at fixed memory locations, established by the linker.
- Local variable values are allocated and de-allocated within an execution stack in LIFO order. Each execution thread has its own stack.
When we want to dynamically allocate memory for a value during runtime that we need to survive beyond the scope it is allocated in, neither global and local variables can handle this requirement. This is when we need to make use of the "heap", the large amount of free memory available to use outside of what has been reserved for global variables, code and any stacks.
Unusual among languages, Cone conceptually partitions the heap into regions. Each region has its own strategy for allocating and automatically reclaiming memory that holds values. Every program value on the heap is wholly located within and governed by its owning region.
The reason Cone supports multiple regions is because there is no one perfect strategy for allocating and automatically freeing memory. Each strategy (e.g., tracing GC, ref-counting, single-owner, pools or arenas) carries different trade-offs in terms of throughput, latency/responsiveness, memory use and leakage, data structure flexibility, and programmer convenience.
Instead of restricting a program to the limitations of only one memory management strategy, as most languages do, Cone dynamically partitions memory into regions, each with its own approach to memory allocation and collection. For every new data object, Cone allows the programmer to specify, at allocation time, which region the object belongs to, according to how well it matches the object's usage profile.
Owning vs. Weak References
There are two kinds of region-managed references:
- Owning references. When you allocate a new value within a region, you get back an owning reference that points to the new object. For some regions, multiple alias copies may be created which are also owning references. For safety reasons, a region's automatic memory management strategy ensures that the object's memory is freed only when when the last owning reference to the object expires. This timing ensures that an owning reference is always safe to de-reference and that an object will only be freed once.
- Weak references. A weak reference points to an object that may or may not still exist in the region's memory. Before we can de-reference a weak reference, we first need to confirm it still exists.