Next: , Previous: , Up: objects memory   [Index]


13.3.3 Interesting PCB fields

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:

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:

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: , Previous: , Up: objects memory   [Index]