Next: objects memory alloc, Previous: objects memory segments, Up: objects memory [Index]
In this section we discuss some private fields of the C data structure
ikpcb_t
, the Process Control Block, related to memory allocation
and garbage collection.
ikptr_t memory_base
ikptr_t memory_end
Untagged pointers updated (if needed) after every memory mapped allocation to be lower and greater than all the memory used by Scheme programs.
Scheme used memory |.......................| |--------------------------------------| system memory ^ ^ memory_base memory_end
They are used for garbage collection purposes: every Vicare page between this range of pointers is described by a slot in the segments vector and the dirty vector.
The pointers memory_base
and memory_end
always reference
the first machine word in a logic memory segment (see objects memory segments).
uint32_t * segment_vector_base
uint32_t * segment_vector
The segments vector contains a slot for every Vicare page in the region
of memory delimited by the fields memory_base
and
memory_end
; it is used to register the destination use of every
page (heap, stack, unused, etc.), along with the garbage collection
generation the page belongs to.
segment_vector_base
references the first allocated slot; access
to the vector with zero–based indexes is performed through
segment_vector
.
segment vector |.................|--------------------|.......| system memory ^ ^ segment_vector segment_vector_base
The first slot referenced by segment_vector_base
has index
different from zero; its index is computed with IK_PAGE_INDEX()
:
pcb->segment_vector[IK_PAGE_INDEX(memory_pointer)]
to loop over all the slots we can do:
ikuword_t lo_idx = IK_PAGE_INDEX(pcb->memory_base); ikuword_t hi_idx = IK_PAGE_INDEX(pcb->memory_end); ikuword_t page_idx; for (page_idx = lo_idx; page_idx < hi_idx; ++page_idx) { pcb->segment_vector[page_idx]; }
Notice that the segments vector is not itself registered in the
segments vector and dirty vector: if the segments vector falls inside
the region delimited by memory_base
and memory_end
, it is
marked as unused and pure.
uint32_t * dirty_vector_base
ikptr_t dirty_vector
The dirty vector contains a slot for every Vicare page in the region of
memory delimited by the fields memory_base
and memory_end
;
it is used to keep track of pages that were mutated at runtime; it
allows the garbage collector to do the right thing when a Scheme object
in an old generation is mutated to reference a Scheme object in a new
generation.
When a Scheme object in a memory page is mutated at run–time: such page is said to be “dirty”; otherwise it is “pure”.
dirty_vector_base
references the first allocated slot; access to
the vector with zero–based indexes is performed through the field
dirty_vector
(which is also accessible from Scheme code).
dirty vector |.................|--------------------|.......| system memory ^ ^ dirty_vector dirty_vector_base
The first slot referenced by dirty_vector_base
has index
different from zero; its index is computed with IK_PAGE_INDEX()
:
((uint32_t *)(pcb->dirty_vector))[IK_PAGE_INDEX(memory_pointer)]
to loop over all the slots we can do:
ikuword_t lo_idx = IK_PAGE_INDEX(pcb->memory_base); ikuword_t hi_idx = IK_PAGE_INDEX(pcb->memory_end); ikuword_t page_idx; for (page_idx = lo_idx; page_idx < hi_idx; ++page_idx) { ((uint32_t *)(pcb->dirty_vector))[page_idx]; }
Notice that the dirty vector is not itself registered in the
segments vector and dirty vector: if the dirty vector falls inside the
region delimited by memory_base
and memory_end
, the pages
it uses are marked as unused and pure.
Scheme objects created by a Scheme program are allocated on the heap. We can think of the Scheme heap as the union of the nursery and a set of generational pages.
The nursery is a set of memory blocks in which new Scheme objects are
allocated; it is the generation 0
. The nursery starts with a
single “hot” memory block in which new Scheme objects are allocated;
whenever the hot block is full:
This is the case of: Scheme object allocation from C language code,
through the C function ik_unsafe_alloc()
.
This is the case of: Scheme object allocation from C language code,
through the C function ik_unsafe_alloc()
.
This is the case of: common Scheme object allocation from Scheme code;
common Scheme object allocation from C language code, through the C
function ik_safe_alloc()
.
This is the case of: common Scheme object allocation from Scheme code;
common Scheme object allocation from C language code, through the C
function ik_safe_alloc()
.
The generational pages are a set of Vicare pages, described by the segments vector and dirty vector, in which objects are moved after they survive a garbage collection; every generational page is tagged in the segments vector with the index of the generation it belongs to.
While nursery segments hold Scheme objects of any type, each generational page holds objects of a single “category”: pairs; symbols; vectors, structs, records, ratnums, compnums, cflonums; code objects; bytevectors, strings, flonums, bignums.
ikptr_t heap_nursery_hot_block_base
ikuword_t heap_nursery_hot_block_size
Pointer and size in bytes of the current nursery’s hot memory block; new Scheme objects are allocated here. About the size of the hot block:
IK_HEAPSIZE
bytes; this size is customisable (see iklib runtime).
ik_unsafe_alloc()
is performed:
IK_HEAPSIZE
bytes:
the hot block is set to a memory mapped block of size IK_HEAPSIZE
bytes.
IK_HEAPSIZE
bytes: the hot block is set to a memory mapped block of size wide enough
to hold the requested, aligned, size (with a couple of
IK_PAGESIZE
more, rounded to the next page size).
ikptr_t allocation_pointer
Pointer to the first word of available data in the nursery’s hot memory block; the next Scheme object to be allocated will start there.
ikptr_t allocation_redline
Pointer to a word towards the end of the heap hot memory block; when the allocation of a Scheme object crosses this pointer, the hot block is considered full.
ikmemblock_t full_heap_nursery_segments
Pointer to the first node in a linked list of memory blocks that once
were nursery’s hot memory, and are now fully used; initialised to
NULL
when building the PCB.
Next: objects memory alloc, Previous: objects memory segments, Up: objects memory [Index]