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_DEQUEUED(x) (x = (((int)(x)) & (~2)))
#define RESET_MARK_BIT(x) (x = (((int)(x)) & (~1)))
#define GET_FORWARD_ADDRESS(x) \
(((size_t)(x)) \
& (~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)
#define SET_FORWARD_ADDRESS(x, addr) \
(x = ((x & 3) | ((int)(addr)))) // take the last two bits as they are and make all others zero
#define EXTRA_ROOM_HEAP_COEFFICIENT 2 // TODO: tune this parameter
// 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)
#define GET_FORWARD_ADDRESS(x) (((size_t)(x)) & (~3))
// take the last two bits as they are and make all others zero
#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
# define MINIMUM_HEAP_CAPACITY (8)
#else
@ -31,13 +33,12 @@ typedef struct {
} heap_iterator;
typedef struct {
// holds type of object, which fields we are iterating over
lama_type type;
// here a pointer to the object header is stored
void *obj_ptr;
void *cur_field;
lama_type type; // holds type of object, which fields we are iterating over
void *obj_ptr; // place to store a pointer to the object header
void *cur_field;
} obj_field_iterator;
// Memory pool for linear memory allocation
typedef struct {
size_t *begin;
size_t *end;
@ -45,14 +46,6 @@ typedef struct {
size_t size;
} 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
// allocates object of the given size on the heap
void *alloc(size_t);
@ -79,31 +72,56 @@ size_t compute_locations ();
void update_references (memory_chunk *);
void physically_relocate (memory_chunk *);
// written in ASM
extern void __gc_init (
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 (
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 __shutdown (
void); // mostly useful for tests but basically you want to call this in case you want to deallocate all object allocated via GC
// written in ASM
// ============================================================================
// GC extra roots
// ============================================================================
// Lama's program stack is continuous, i.e. it never interleaves with runtime
// function's activation records. But some valid Lama's pointers can escape
// into runtime. Those values (theirs stack addresses) has to be registered in
// an auxiliary data structure called `extra_roots_pool`.
// 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);
// written in ASM
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);
bool is_valid_heap_pointer (const size_t *);
static inline bool is_valid_pointer (const size_t *);
void clear_extra_roots (void);
void push_extra_root (void **p);
void pop_extra_root (void **p);
/* Functions for tests */
// ============================================================================
// Auxiliary functions for tests
// ============================================================================
#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,
// 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)
void set_extra_roots (size_t extra_roots_size, void **extra_roots_ptr);
#endif
/* Utility functions */
// ============================================================================
// Utility functions
// ============================================================================
// 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
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);
}
// Compare sexprs tags
// Compare s-exprs tags
extern int LcompareTags (void *p, void *q) {
data *pd, *qd;
@ -111,8 +111,8 @@ extern int LcompareTags (void *p, void *q) {
} else {
failure("not a sexpr in compareTags: %d, %d\n", TAG(pd->data_header), TAG(qd->data_header));
}
return 0; // never happens
// dead code
return 0;
}
// Functional synonym for built-in operator ":";
@ -1165,17 +1165,15 @@ extern void *Lfread (char *fname) {
f = fopen(fname, "r");
if (f) {
if (fseek(f, 0l, SEEK_END) >= 0) {
long size = ftell(f);
void *s = LmakeString(BOX(size));
if (f && fseek(f, 0l, SEEK_END) >= 0) {
long size = ftell(f);
void *s = LmakeString(BOX(size));
rewind(f);
rewind(f);
if (fread(s, 1, size, f) == size) {
fclose(f);
return s;
}
if (fread(s, 1, size, f) == size) {
fclose(f);
return s;
}
}
@ -1190,16 +1188,11 @@ extern void Lfwrite (char *fname, char *contents) {
f = fopen(fname, "w");
if (f) {
if (fprintf(f, "%s", contents) < 0)
;
else {
fclose(f);
return;
}
if (f && !(fprintf(f, "%s", contents) < 0)) {
fclose(f);
} else {
failure("fwrite (\"%s\"): %s\n", fname, strerror(errno));
}
failure("fwrite (\"%s\"): %s\n", fname, strerror(errno));
}
extern void *Lfexists (char *fname) {
@ -1287,11 +1280,3 @@ extern void set_args (int argc, char *argv[]) {
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; }