mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
Added red color to indicate stack alloc
This commit is contained in:
parent
b3af3aff73
commit
fee0675fa2
3 changed files with 40 additions and 44 deletions
37
gc.c
37
gc.c
|
@ -438,10 +438,10 @@ PHASE 2 - multi-threaded mutator (IE, more than one stack thread):
|
|||
//
|
||||
// Note: will need to use atomics and/or locking to access any
|
||||
// variables shared between threads
|
||||
static int gc_color_mark = 0; // Black
|
||||
static const int gc_color_grey = 1; // TODO: appears unused, clean up
|
||||
static int gc_color_clear = 2; // White
|
||||
static const int gc_color_blue = 3;
|
||||
static int gc_color_mark = 0; // Black, is swapped during GC
|
||||
//static const int gc_color_grey = 1; // TODO: appears unused, clean up
|
||||
static int gc_color_clear = 2; // White, is swapped during GC
|
||||
// unfortunately this had to be split up; const colors are located in types.h
|
||||
|
||||
static int gc_status_col;
|
||||
static int gc_stage;
|
||||
|
@ -502,20 +502,21 @@ void gc_mark_gray(gc_thread_data *thd, object obj)
|
|||
void gc_collector_trace()
|
||||
{
|
||||
int clean = 0;
|
||||
while (!clean) {
|
||||
clean = 1;
|
||||
}
|
||||
TODO: need a list of mutators.
|
||||
could keep a buffer or linked list of them. a list may be more efficient
|
||||
also need to consider how to map thread back to its gc_thread_data,
|
||||
which we will need during GC (cooperate). maybe use a (platform-specific)
|
||||
call like below to get a unique ID for the thread, and then use a
|
||||
hashtable to get the thread info. how often will we be accessing this data?
|
||||
seems we will need to be able to access it from 2 places:
|
||||
- from mutator (can compute thread id here)
|
||||
- from collector (need to be able to iterate across all mutators)
|
||||
#include <syscall.h>
|
||||
printf("tid = %d\n", syscall(SYS_gettid));
|
||||
// while (!clean) {
|
||||
// clean = 1;
|
||||
// }
|
||||
// TODO: need a list of mutators.
|
||||
// could keep a buffer or linked list of them. a list may be more efficient
|
||||
// also need to consider how to map thread back to its gc_thread_data,
|
||||
// which we will need during GC (cooperate). maybe use a (platform-specific)
|
||||
// call like below to get a unique ID for the thread, and then use a
|
||||
// hashtable to get the thread info. how often will we be accessing this data?
|
||||
// seems we will need to be able to access it from 2 places:
|
||||
// - from mutator (can compute thread id here)
|
||||
// - from collector (need to be able to iterate across all mutators)
|
||||
// #include <syscall.h>
|
||||
// printf("tid = %d\n", syscall(SYS_gettid));
|
||||
|
||||
// note - can atomic operations be used for last read/write, to prevent
|
||||
// coarser-grained synchronization there?
|
||||
// TODO:
|
||||
|
|
|
@ -88,6 +88,12 @@ typedef enum { STAGE_CLEAR_OR_MARKING
|
|||
, STAGE_RESTING
|
||||
} gc_stage_type;
|
||||
|
||||
// Constant colors are defined here.
|
||||
// The mark/clear colors are defined in the gc module because
|
||||
// the collector swaps their values as an optimization.
|
||||
const int gc_color_blue = 3; // Unallocate memory
|
||||
const int gc_color_red = 4; // Memory on the stack
|
||||
|
||||
/* Utility functions */
|
||||
void **vpbuffer_realloc(void **buf, int *len);
|
||||
void **vpbuffer_add(void **buf, int *len, int i, void *obj);
|
||||
|
@ -212,7 +218,7 @@ typedef void (*function_type_va)(int, object, object, object, ...);
|
|||
/* Define C-variable integration type */
|
||||
typedef struct {gc_header_type hdr; tag_type tag; object *pvar;} cvar_type;
|
||||
typedef cvar_type *cvar;
|
||||
#define make_cvar(n,v) cvar_type n; n.tag = cvar_tag; n.pvar = v;
|
||||
#define make_cvar(n,v) cvar_type n; n.hdr.mark = gc_color_red; n.tag = cvar_tag; n.pvar = v;
|
||||
|
||||
/* Define boolean type. */
|
||||
typedef struct {gc_header_type hdr; const tag_type tag; const char *pname;} boolean_type;
|
||||
|
@ -233,9 +239,9 @@ static object quote_##name = nil;
|
|||
|
||||
/* Define numeric types */
|
||||
typedef struct {gc_header_type hdr; tag_type tag; int value;} integer_type;
|
||||
#define make_int(n,v) integer_type n; n.tag = integer_tag; n.value = v;
|
||||
#define make_int(n,v) integer_type n; n.hdr.mark = gc_color_red; n.tag = integer_tag; n.value = v;
|
||||
typedef struct {gc_header_type hdr; tag_type tag; double value;} double_type;
|
||||
#define make_double(n,v) double_type n; n.tag = double_tag; n.value = v;
|
||||
#define make_double(n,v) double_type n; n.hdr.mark = gc_color_red; n.tag = double_tag; n.value = v;
|
||||
|
||||
#define integer_value(x) (((integer_type *) x)->value)
|
||||
#define double_value(x) (((double_type *) x)->value)
|
||||
|
@ -246,30 +252,18 @@ typedef struct {gc_header_type hdr; tag_type tag; int len; char *str;} string_ty
|
|||
//// all functions that allocate strings, the GC, cgen, and maybe more.
|
||||
//// Because these strings are (at least for now) allocaed on the stack.
|
||||
#define make_string(cs, s) string_type cs; \
|
||||
{ int len = strlen(s); cs.tag = string_tag; cs.len = len; \
|
||||
{ int len = strlen(s); cs.tag = string_tag; cs.len = len; cs.hdr.mark = gc_color_red; \
|
||||
cs.str = alloca(sizeof(char) * (len + 1)); \
|
||||
memcpy(cs.str, s, len + 1);}
|
||||
#define make_string_with_len(cs, s, length) string_type cs; \
|
||||
#define make_string_with_len(cs, s, length) string_type cs; cs.hdr.mark = gc_color_red; \
|
||||
{ int len = length; \
|
||||
cs.tag = string_tag; cs.len = len; \
|
||||
cs.str = alloca(sizeof(char) * (len + 1)); \
|
||||
memcpy(cs.str, s, len); \
|
||||
cs.str[len] = '\0';}
|
||||
#define make_string_noalloc(cs, s, length) string_type cs; \
|
||||
#define make_string_noalloc(cs, s, length) string_type cs; cs.hdr.mark = gc_color_red; \
|
||||
{ cs.tag = string_tag; cs.len = length; \
|
||||
cs.str = s; }
|
||||
// TODO: all of the dhalloc below needs to go away...
|
||||
//#define make_string(cv,s) string_type cv; cv.tag = string_tag; \
|
||||
//{ int len = strlen(s); cv.str = dhallocp; \
|
||||
// if ((dhallocp + len + 1) >= dhbottom + global_heap_size) { \
|
||||
// printf("Fatal error: data heap overflow\n"); exit(1); } \
|
||||
// memcpy(dhallocp, s, len + 1); dhallocp += len + 1; }
|
||||
//#define make_stringn(cv,s,len) string_type cv; cv.tag = string_tag; \
|
||||
//{ cv.str = dhallocp; \
|
||||
// if ((dhallocp + len + 1) >= dhbottom + global_heap_size) { \
|
||||
// printf("Fatal error: data heap overflow\n"); exit(1); } \
|
||||
// memcpy(dhallocp, s, len); dhallocp += len; \
|
||||
// *dhallocp = '\0'; dhallocp += 1;}
|
||||
|
||||
#define string_len(x) (((string_type *) x)->len)
|
||||
#define string_str(x) (((string_type *) x)->str)
|
||||
|
@ -281,14 +275,14 @@ typedef struct {gc_header_type hdr; tag_type tag; int len; char *str;} string_ty
|
|||
// TODO: a simple wrapper around FILE may not be good enough long-term
|
||||
// TODO: how exactly mode will be used. need to know r/w, bin/txt
|
||||
typedef struct {gc_header_type hdr; tag_type tag; FILE *fp; int mode;} port_type;
|
||||
#define make_port(p,f,m) port_type p; p.tag = port_tag; p.fp = f; p.mode = m;
|
||||
#define make_port(p,f,m) port_type p; p.hdr.mark = gc_color_red; p.tag = port_tag; p.fp = f; p.mode = m;
|
||||
|
||||
/* Vector type */
|
||||
|
||||
typedef struct {gc_header_type hdr; tag_type tag; int num_elt; object *elts;} vector_type;
|
||||
typedef vector_type *vector;
|
||||
|
||||
#define make_empty_vector(v) vector_type v; v.tag = vector_tag; v.num_elt = 0; v.elts = NULL;
|
||||
#define make_empty_vector(v) vector_type v; v.hdr.mark = gc_color_red; v.tag = vector_tag; v.num_elt = 0; v.elts = NULL;
|
||||
|
||||
/* Define cons type. */
|
||||
|
||||
|
@ -348,15 +342,15 @@ typedef closureN_type *closureN;
|
|||
typedef closure0_type *closure;
|
||||
typedef closure0_type *macro;
|
||||
|
||||
#define mmacro(c,f) macro_type c; c.tag = macro_tag; c.fn = f; c.num_args = -1;
|
||||
#define mclosure0(c,f) closure0_type c; c.tag = closure0_tag; c.fn = f; c.num_args = -1;
|
||||
#define mclosure1(c,f,a) closure1_type c; c.tag = closure1_tag; \
|
||||
#define mmacro(c,f) macro_type c; c.hdr.mark = gc_color_red; c.tag = macro_tag; c.fn = f; c.num_args = -1;
|
||||
#define mclosure0(c,f) closure0_type c; c.hdr.mark = gc_color_red; c.tag = closure0_tag; c.fn = f; c.num_args = -1;
|
||||
#define mclosure1(c,f,a) closure1_type c; c.hdr.mark = gc_color_red; c.tag = closure1_tag; \
|
||||
c.fn = f; c.num_args = -1; c.elt1 = a;
|
||||
#define mclosure2(c,f,a1,a2) closure2_type c; c.tag = closure2_tag; \
|
||||
#define mclosure2(c,f,a1,a2) closure2_type c; c.hdr.mark = gc_color_red; c.tag = closure2_tag; \
|
||||
c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2;
|
||||
#define mclosure3(c,f,a1,a2,a3) closure3_type c; c.tag = closure3_tag; \
|
||||
#define mclosure3(c,f,a1,a2,a3) closure3_type c; c.hdr.mark = gc_color_red; c.tag = closure3_tag; \
|
||||
c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2; c.elt3 = a3;
|
||||
#define mclosure4(c,f,a1,a2,a3,a4) closure4_type c; c.tag = closure4_tag; \
|
||||
#define mclosure4(c,f,a1,a2,a3,a4) closure4_type c; c.hdr.mark = gc_color_red; c.tag = closure4_tag; \
|
||||
c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2; c.elt3 = a3; c.elt4 = a4;
|
||||
|
||||
#define mlist1(e1) (mcons(e1,nil))
|
||||
|
|
|
@ -996,6 +996,7 @@
|
|||
(create-nclosure (lambda ()
|
||||
(string-append
|
||||
"closureN_type " cv-name ";\n"
|
||||
cv-name ".hdr.mark = gc_color_red;\n "
|
||||
cv-name ".tag = closureN_tag;\n "
|
||||
cv-name ".fn = (function_type)__lambda_" (number->string lid) ";\n"
|
||||
cv-name ".num_args = " (number->string (compute-num-args lam)) ";\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue