upd comments

This commit is contained in:
Danya Berezun 2023-09-05 20:56:10 +02:00
parent 20cb055883
commit ec9beed470
2 changed files with 72 additions and 69 deletions

View file

@ -9,12 +9,14 @@
#define MAKE_ENQUEUED(x) (x = (((int)(x)) | 2)) #define MAKE_ENQUEUED(x) (x = (((int)(x)) | 2))
#define MAKE_DEQUEUED(x) (x = (((int)(x)) & (~2))) #define MAKE_DEQUEUED(x) (x = (((int)(x)) & (~2)))
#define RESET_MARK_BIT(x) (x = (((int)(x)) & (~1))) #define RESET_MARK_BIT(x) (x = (((int)(x)) & (~1)))
#define GET_FORWARD_ADDRESS(x) \ // since last 2 bits are used for mark-bit and enqueued-bit and due to correct
(((size_t)(x)) \ // alignment we can expect that last 2 bits don't influence address (they
& (~3)) // since last 2 bits are used for mark-bit and enqueued-bit and due to correct alignment we can expect that last 2 bits don't influence address (they should always be zero) // should always be zero)
#define SET_FORWARD_ADDRESS(x, addr) \ #define GET_FORWARD_ADDRESS(x) (((size_t)(x)) & (~3))
(x = ((x & 3) | ((int)(addr)))) // take the last two bits as they are and make all others zero // take the last two bits as they are and make all others zero
#define EXTRA_ROOM_HEAP_COEFFICIENT 2 // TODO: tune this parameter #define SET_FORWARD_ADDRESS(x, addr) (x = ((x & 3) | ((int)(addr))))
// if heap is full after gc shows in how many times it has to be extended
#define EXTRA_ROOM_HEAP_COEFFICIENT 2
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
# define MINIMUM_HEAP_CAPACITY (8) # define MINIMUM_HEAP_CAPACITY (8)
#else #else
@ -31,13 +33,12 @@ typedef struct {
} heap_iterator; } heap_iterator;
typedef struct { typedef struct {
// holds type of object, which fields we are iterating over lama_type type; // holds type of object, which fields we are iterating over
lama_type type; void *obj_ptr; // place to store a pointer to the object header
// here a pointer to the object header is stored
void *obj_ptr;
void *cur_field; void *cur_field;
} obj_field_iterator; } obj_field_iterator;
// Memory pool for linear memory allocation
typedef struct { typedef struct {
size_t *begin; size_t *begin;
size_t *end; size_t *end;
@ -45,14 +46,6 @@ typedef struct {
size_t size; size_t size;
} memory_chunk; } memory_chunk;
/* GC extra roots */
#define MAX_EXTRA_ROOTS_NUMBER 32
typedef struct {
int current_free;
void **roots[MAX_EXTRA_ROOTS_NUMBER];
} extra_roots_pool;
// the only GC-related function that should be exposed, others are useful for tests and internal implementation // the only GC-related function that should be exposed, others are useful for tests and internal implementation
// allocates object of the given size on the heap // allocates object of the given size on the heap
void *alloc(size_t); void *alloc(size_t);
@ -79,31 +72,56 @@ size_t compute_locations ();
void update_references (memory_chunk *); void update_references (memory_chunk *);
void physically_relocate (memory_chunk *); void physically_relocate (memory_chunk *);
// written in ASM // ============================================================================
extern void __gc_init ( // GC extra roots
void); // MANDATORY TO CALL BEFORE ANY INTERACTION WITH GC (apart from cases where we are working with virtual stack as happens in tests) // ============================================================================
extern void __init ( // Lama's program stack is continuous, i.e. it never interleaves with runtime
void); // should be called before interaction with GC in case of using in tests with virtual stack, otherwise it is automatically invoked by __gc_init // function's activation records. But some valid Lama's pointers can escape
extern void __shutdown ( // into runtime. Those values (theirs stack addresses) has to be registered in
void); // mostly useful for tests but basically you want to call this in case you want to deallocate all object allocated via GC // an auxiliary data structure called `extra_roots_pool`.
// written in ASM // extra_roots_pool is a simple LIFO stack. During `pop` it compares that pop's
// argument is equal to the current stack top.
#define MAX_EXTRA_ROOTS_NUMBER 32
typedef struct {
int current_free;
void **roots[MAX_EXTRA_ROOTS_NUMBER];
} extra_roots_pool;
void clear_extra_roots (void);
void push_extra_root (void **p);
void pop_extra_root (void **p);
// ============================================================================
// Implemented in GASM: see gc_runtime.s
// ============================================================================
// MANDATORY TO CALL BEFORE ANY INTERACTION WITH GC (apart from cases where we
// are working with virtual stack as happens in tests)
extern void __gc_init (void);
// should be called before interaction with GC in case of using in tests with
// virtual stack, otherwise it is automatically invoked by `__gc_init`
extern void __init (void);
// mostly useful for tests but basically you want to call this in case you want
// to deallocate all object allocated via GC
extern void __shutdown (void);
// Next two functions sets and unsets `__gc_stack_top`
// The first (`__pre_gc`) should be called in the very beginning of any runtime
// function during the execution of which garbage collection can be initiated.
// The last one is a `companion function` which has to be called at the very
// end of any function that called `__prec_gc`
extern void __pre_gc (void); extern void __pre_gc (void);
// written in ASM
extern void __post_gc (void); extern void __post_gc (void);
// invoked from ASM // ============================================================================
// invoked from GASM: see gc_runtime.s
// ============================================================================
extern void gc_test_and_mark_root (size_t **root); extern void gc_test_and_mark_root (size_t **root);
bool is_valid_heap_pointer (const size_t *); bool is_valid_heap_pointer (const size_t *);
static inline bool is_valid_pointer (const size_t *); static inline bool is_valid_pointer (const size_t *);
void clear_extra_roots (void); // ============================================================================
// Auxiliary functions for tests
void push_extra_root (void **p); // ============================================================================
void pop_extra_root (void **p);
/* Functions for tests */
#if defined(FULL_INVARIANT_CHECKS) && defined(DEBUG_VERSION) #if defined(FULL_INVARIANT_CHECKS) && defined(DEBUG_VERSION)
// makes a snapshot of current objects in heap (both alive and dead), writes these ids to object_ids_buf, // makes a snapshot of current objects in heap (both alive and dead), writes these ids to object_ids_buf,
// returns number of ids dumped // returns number of ids dumped
@ -118,11 +136,11 @@ void set_stack (size_t stack_top, size_t stack_bottom);
// function to mock extra roots (Lama specific) // function to mock extra roots (Lama specific)
void set_extra_roots (size_t extra_roots_size, void **extra_roots_ptr); void set_extra_roots (size_t extra_roots_size, void **extra_roots_ptr);
#endif #endif
/* Utility functions */ // ============================================================================
// Utility functions
// ============================================================================
// accepts pointer to the start of the region and to the end of the region // accepts pointer to the start of the region and to the end of the region
// scans it and if it meets a pointer, it should be modified in according to forward address // scans it and if it meets a pointer, it should be modified in according to forward address
void scan_and_fix_region (memory_chunk *old_heap, void *start, void *end); void scan_and_fix_region (memory_chunk *old_heap, void *start, void *end);

View file

@ -96,7 +96,7 @@ extern int LkindOf (void *p) {
return TAG(TO_DATA(p)->data_header); return TAG(TO_DATA(p)->data_header);
} }
// Compare sexprs tags // Compare s-exprs tags
extern int LcompareTags (void *p, void *q) { extern int LcompareTags (void *p, void *q) {
data *pd, *qd; data *pd, *qd;
@ -111,8 +111,8 @@ extern int LcompareTags (void *p, void *q) {
} else { } else {
failure("not a sexpr in compareTags: %d, %d\n", TAG(pd->data_header), TAG(qd->data_header)); failure("not a sexpr in compareTags: %d, %d\n", TAG(pd->data_header), TAG(qd->data_header));
} }
// dead code
return 0; // never happens return 0;
} }
// Functional synonym for built-in operator ":"; // Functional synonym for built-in operator ":";
@ -1165,8 +1165,7 @@ extern void *Lfread (char *fname) {
f = fopen(fname, "r"); f = fopen(fname, "r");
if (f) { if (f && fseek(f, 0l, SEEK_END) >= 0) {
if (fseek(f, 0l, SEEK_END) >= 0) {
long size = ftell(f); long size = ftell(f);
void *s = LmakeString(BOX(size)); void *s = LmakeString(BOX(size));
@ -1177,7 +1176,6 @@ extern void *Lfread (char *fname) {
return s; return s;
} }
} }
}
failure("fread (\"%s\"): %s\n", fname, strerror(errno)); failure("fread (\"%s\"): %s\n", fname, strerror(errno));
} }
@ -1190,16 +1188,11 @@ extern void Lfwrite (char *fname, char *contents) {
f = fopen(fname, "w"); f = fopen(fname, "w");
if (f) { if (f && !(fprintf(f, "%s", contents) < 0)) {
if (fprintf(f, "%s", contents) < 0)
;
else {
fclose(f); fclose(f);
return; } else {
}
}
failure("fwrite (\"%s\"): %s\n", fname, strerror(errno)); failure("fwrite (\"%s\"): %s\n", fname, strerror(errno));
}
} }
extern void *Lfexists (char *fname) { extern void *Lfexists (char *fname) {
@ -1287,11 +1280,3 @@ extern void set_args (int argc, char *argv[]) {
push_extra_root((void **)&global_sysargs); push_extra_root((void **)&global_sysargs);
} }
/* GC starts here */
static int enable_GC = 1;
extern void LenableGC () { enable_GC = 1; }
extern void LdisableGC () { enable_GC = 0; }