mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
New write barrier implementation
This commit is contained in:
parent
c8878e749a
commit
33447ebc57
3 changed files with 39 additions and 28 deletions
35
gc.c
35
gc.c
|
@ -821,13 +821,12 @@ void gc_mut_update(gc_thread_data *thd, object old_obj, object value)
|
|||
gc_mark_gray(thd, old_obj);
|
||||
// Check if value is on the heap. If so, mark gray right now,
|
||||
// otherwise set it to be marked after moved to heap by next GC
|
||||
// if (gc_is_stack_obj(thd, value)) {
|
||||
// grayed(value) = 1;
|
||||
// } else {
|
||||
// gc_mark_gray(thd, value);
|
||||
// }
|
||||
if (gc_is_stack_obj(thd, value)) {
|
||||
grayed(value) = 1;
|
||||
} else {
|
||||
gc_mark_gray(thd, value);
|
||||
}
|
||||
pthread_mutex_unlock(&(thd->lock));
|
||||
gc_stack_mark_gray(thd, value); // TODO: this line will be replace with above block
|
||||
} else if (stage == STAGE_TRACING) {
|
||||
//fprintf(stderr, "DEBUG - GC async tracing marking heap obj %p ", old_obj);
|
||||
//Cyc_display(old_obj, stderr);
|
||||
|
@ -877,12 +876,20 @@ gc_stack_mark_gray(thd, value); // TODO: this line will be replace with above bl
|
|||
void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
||||
{
|
||||
int i, status = ATOMIC_GET(&gc_status_col);
|
||||
|
||||
// Handle any pending marks from write barrier
|
||||
pthread_mutex_lock(&(thd->lock));
|
||||
thd->last_write += thd->pending_writes;
|
||||
thd->pending_writes = 0;
|
||||
pthread_mutex_unlock(&(thd->lock));
|
||||
|
||||
if (thd->gc_status != status) {
|
||||
if (thd->gc_status == STATUS_ASYNC) {
|
||||
// Async is done, so clean up old mark data from the last collection
|
||||
pthread_mutex_lock(&(thd->lock));
|
||||
thd->last_write = 0;
|
||||
thd->last_read = 0;
|
||||
thd->pending_writes = 0;
|
||||
pthread_mutex_unlock(&(thd->lock));
|
||||
}
|
||||
else if (thd->gc_status == STATUS_SYNC2) {
|
||||
|
@ -941,6 +948,17 @@ void gc_mark_gray(gc_thread_data *thd, object obj)
|
|||
}
|
||||
}
|
||||
|
||||
void gc_mark_gray2(gc_thread_data *thd, object obj)
|
||||
{
|
||||
if (is_object_type(obj) && mark(obj) == gc_color_clear) {
|
||||
thd->mark_buffer = vpbuffer_add(thd->mark_buffer,
|
||||
&(thd->mark_buffer_len),
|
||||
(thd->last_write + thd->pending_writes),
|
||||
obj);
|
||||
thd->pending_writes++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: before doing this, may want to debug a bit and see what is
|
||||
// being passed to gc_mut_update. see if those objects tend to have
|
||||
// any heap refs. may need to add debug code to do that...
|
||||
|
@ -1003,7 +1021,10 @@ void gc_collector_trace()
|
|||
if (clean) {
|
||||
pthread_mutex_lock(&(m->lock));
|
||||
if (m->last_read < m->last_write) {
|
||||
printf("JAE DEBUG - might have exited trace early\n");
|
||||
fprintf(stderr, "JAE DEBUG - might have exited trace early\n");
|
||||
clean = 0;
|
||||
}
|
||||
else if (m->pending_writes) {
|
||||
clean = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&(m->lock));
|
||||
|
|
|
@ -56,6 +56,7 @@ struct gc_thread_data_t {
|
|||
int gc_status;
|
||||
int last_write;
|
||||
int last_read;
|
||||
int pending_writes;
|
||||
void **mark_buffer;
|
||||
int mark_buffer_len;
|
||||
pthread_mutex_t lock;
|
||||
|
@ -164,6 +165,7 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len);
|
|||
void gc_stack_mark_refs_gray(gc_thread_data *thd, object obj, int depth);
|
||||
void gc_stack_mark_gray(gc_thread_data *thd, object obj);
|
||||
void gc_mark_gray(gc_thread_data *thd, object obj);
|
||||
void gc_mark_gray2(gc_thread_data *thd, object obj);
|
||||
void gc_collector_trace();
|
||||
void gc_mark_black(object obj);
|
||||
void gc_collector_mark_gray(object parent, object obj);
|
||||
|
|
30
runtime.c
30
runtime.c
|
@ -2452,35 +2452,24 @@ void gc_mark_globals()
|
|||
}
|
||||
}
|
||||
|
||||
char *gc_fixup_moved_obj(gc_thread_data *thd, int *alloci, int *num_grayed, char *obj, object hp)
|
||||
char *gc_fixup_moved_obj(gc_thread_data *thd, int *alloci, char *obj, object hp)
|
||||
{
|
||||
if (grayed(obj)) {
|
||||
pthread_mutex_lock(&(thd->lock));
|
||||
gc_mark_gray2(thd, hp);
|
||||
pthread_mutex_unlock(&(thd->lock));
|
||||
}
|
||||
|
||||
// hp ==> new heap object, point to it from old stack object
|
||||
forward(obj) = hp;
|
||||
type_of(obj) = forward_tag;
|
||||
// keep track of each allocation so we can scan/move
|
||||
// the whole live object 'tree'
|
||||
gc_thr_add_to_move_buffer(thd, alloci, hp);
|
||||
|
||||
// TODO: if grayed(obj) then - do a deferred gc_mark_gray on hp
|
||||
// you know, one possibility would be to add it to the thread mark buffer
|
||||
// but now increment the read (write?) variable. instead increment another
|
||||
// one and wait until the end of minor GC to set read (write?) to the
|
||||
// appropriate value. just need to make sure we have the lock before
|
||||
// updating it.
|
||||
// that should avoid race conditions and the need for an additional buffer
|
||||
|
||||
if (TODO){
|
||||
lock
|
||||
gc_mark_gray - but WITHOUT incrementing write (read?)
|
||||
unlock
|
||||
(*num_grayed)++;
|
||||
}
|
||||
|
||||
|
||||
return (char *)hp;
|
||||
}
|
||||
|
||||
char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown, int *num_grayed) {
|
||||
char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) {
|
||||
if (!is_object_type(obj)) return obj;
|
||||
switch(type_of(obj)){
|
||||
case cons_tag: {
|
||||
|
@ -2562,7 +2551,7 @@ char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown, int
|
|||
temp = obj; \
|
||||
if (check_overflow(low_limit, temp) && \
|
||||
check_overflow(temp, high_limit)){ \
|
||||
(obj) = (object) gc_move(temp, (gc_thread_data *)data, &alloci, &heap_grown, &num_grayed); \
|
||||
(obj) = (object) gc_move(temp, (gc_thread_data *)data, &alloci, &heap_grown); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -2575,7 +2564,6 @@ void GC(void *data, closure cont, object *args, int num_args)
|
|||
int i;
|
||||
int scani = 0, alloci = 0;
|
||||
int heap_grown = 0;
|
||||
int num_grayed = 0;
|
||||
|
||||
//fprintf(stdout, "DEBUG, started minor GC\n"); // JAE DEBUG
|
||||
// Prevent overrunning buffer
|
||||
|
|
Loading…
Add table
Reference in a new issue