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_baseikptr_t memory_endUntagged 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_baseuint32_t * segment_vectorThe 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_baseikptr_t dirty_vectorThe 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_baseikuword_t heap_nursery_hot_block_sizePointer 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_pointerPointer 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_redlinePointer 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_segmentsPointer 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]