added guardians primitives, not tested
This commit is contained in:
		
							parent
							
								
									3d2d52fe58
								
							
						
					
					
						commit
						8dac92a512
					
				
							
								
								
									
										
											BIN
										
									
								
								bin/ikarus
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								bin/ikarus
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -68,7 +68,7 @@ static unsigned int meta_mt[meta_count] = {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct{
 | 
			
		||||
typedef struct gc_t{
 | 
			
		||||
  meta_t meta[generation_count][meta_count];
 | 
			
		||||
  qupages_t* queues [meta_count];
 | 
			
		||||
  ikpcb* pcb;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +78,7 @@ typedef struct{
 | 
			
		|||
  ikp tconc_ep;
 | 
			
		||||
  ikp tconc_base;
 | 
			
		||||
  ikpages* tconc_queue;
 | 
			
		||||
  ik_guardian_table* final_guardians;
 | 
			
		||||
} gc_t;
 | 
			
		||||
 | 
			
		||||
static unsigned int 
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +246,7 @@ static void collect_loop(gc_t*);
 | 
			
		|||
static void guardians_loop(gc_t*);
 | 
			
		||||
static void fix_weak_pointers(gc_t*);
 | 
			
		||||
static void gc_add_tconcs(gc_t*);
 | 
			
		||||
static void gc_add_guardians(gc_t*);
 | 
			
		||||
 | 
			
		||||
/* ik_collect is called from scheme under the following conditions:
 | 
			
		||||
 * 1. An attempt is made to allocate a small object and the ap is above
 | 
			
		||||
| 
						 | 
				
			
			@ -333,6 +335,7 @@ ik_collect(int mem_req, ikpcb* pcb){
 | 
			
		|||
  fix_new_pages(&gc);
 | 
			
		||||
  pcb->allocation_pointer = pcb->heap_base;
 | 
			
		||||
  gc_add_tconcs(&gc);
 | 
			
		||||
  gc_add_guardians(&gc);
 | 
			
		||||
  pcb->weak_pairs_ap = 0;
 | 
			
		||||
  pcb->weak_pairs_ep = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -417,11 +420,219 @@ ik_collect(int mem_req, ikpcb* pcb){
 | 
			
		|||
  return pcb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_live(ikp x, gc_t* gc){
 | 
			
		||||
  if(is_fixnum(x)){ 
 | 
			
		||||
    return 1;
 | 
			
		||||
  } 
 | 
			
		||||
  int tag = tagof(x);
 | 
			
		||||
  if(tag == immediate_tag){
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  if(ref(x, -tag) == forward_ptr){
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  unsigned int t = gc->segment_vector[page_index(x)];
 | 
			
		||||
  int gen = t & gen_mask;
 | 
			
		||||
  if(gen > gc->collect_gen){
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ik_guardian_table*
 | 
			
		||||
move_guardian(ikp tc, ikp obj, ik_guardian_table* t){
 | 
			
		||||
  if(t && (t->count < ik_guardian_table_size)){
 | 
			
		||||
    ik_guardian_pair* p = &t->p[t->count];
 | 
			
		||||
    p->tc = tc;
 | 
			
		||||
    p->obj = obj;
 | 
			
		||||
    t->count++;
 | 
			
		||||
    return t;
 | 
			
		||||
  } else {
 | 
			
		||||
    ik_guardian_table* nt = 
 | 
			
		||||
      (ik_guardian_table*)ik_mmap(sizeof(ik_guardian_table));
 | 
			
		||||
    nt->next = t;
 | 
			
		||||
    nt->count = 1;
 | 
			
		||||
    nt->p[0].tc = tc;
 | 
			
		||||
    nt->p[0].obj = obj;
 | 
			
		||||
    return nt;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int 
 | 
			
		||||
next_gen(int i){
 | 
			
		||||
  return ((i == generation_count) ? generation_count : (i+1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void  
 | 
			
		||||
guardians_loop(gc_t* gc){
 | 
			
		||||
  ikpcb* pcb = gc->pcb;
 | 
			
		||||
  int gen = gc->collect_gen;
 | 
			
		||||
  ik_guardian_table* pending_hold[generation_count]; 
 | 
			
		||||
  ik_guardian_table* pending_final = 0;
 | 
			
		||||
  ik_guardian_table* final = 0;
 | 
			
		||||
  /* reset all pending_hold and pending_fina lists. */
 | 
			
		||||
  { 
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i=0; i<=gen; i++){
 | 
			
		||||
      pending_hold[i] = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /* move all guardian tc/objects to either pending_hold */
 | 
			
		||||
  /* or pending_fina depending on whether the object is  */
 | 
			
		||||
  /* live or dead respectively.                          */
 | 
			
		||||
  {
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i=0; i<=gen; i++){
 | 
			
		||||
      ik_guardian_table* t = pcb->guardians[i];
 | 
			
		||||
      while(t){
 | 
			
		||||
        int j;
 | 
			
		||||
        int c = t->count;
 | 
			
		||||
        for(j=0; j<c; j++){
 | 
			
		||||
          ikp obj = t->p[j].obj;
 | 
			
		||||
          if(is_live(obj, gc)){
 | 
			
		||||
            pending_hold[i] =
 | 
			
		||||
              move_guardian(t->p[j].tc, obj, pending_hold[i]);
 | 
			
		||||
          } else {
 | 
			
		||||
            pending_final =
 | 
			
		||||
              move_guardian(t->p[j].tc, obj, pending_final);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        ik_guardian_table* next = t->next;
 | 
			
		||||
        ik_munmap(t, sizeof(ik_guardian_table));
 | 
			
		||||
        t = next;
 | 
			
		||||
      }
 | 
			
		||||
      pcb->guardians[i] = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  int more;
 | 
			
		||||
  do{
 | 
			
		||||
    /* for each tc/obj in pending_final, if tc is live, then */
 | 
			
		||||
    /* we add  tc/obj to final list. */
 | 
			
		||||
    ik_guardian_table* t = pending_final;
 | 
			
		||||
    more = 0;
 | 
			
		||||
    while(t){
 | 
			
		||||
      int j;
 | 
			
		||||
      int k=0;
 | 
			
		||||
      int count = t->count;
 | 
			
		||||
      for(j=0; j < count; j++){
 | 
			
		||||
        ikp tc = t->p[j].tc;
 | 
			
		||||
        ikp obj = t->p[j].obj;
 | 
			
		||||
        if(is_live(tc, gc)){
 | 
			
		||||
          final = move_guardian(tc, obj, final);
 | 
			
		||||
        } 
 | 
			
		||||
        else {
 | 
			
		||||
          t->p[k].tc = tc;
 | 
			
		||||
          t->p[k].obj = obj;
 | 
			
		||||
          k++;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if(k != count){
 | 
			
		||||
        t->count = k;
 | 
			
		||||
        more = 1;
 | 
			
		||||
      }
 | 
			
		||||
      t = t->next;
 | 
			
		||||
    }
 | 
			
		||||
    if(more){
 | 
			
		||||
      ik_guardian_table* t = final;
 | 
			
		||||
      while(t){
 | 
			
		||||
        int i;
 | 
			
		||||
        int count = final->count;
 | 
			
		||||
        for(i=0; i<count; i++){
 | 
			
		||||
          gc->final_guardians = move_guardian(
 | 
			
		||||
            add_object(gc, final->p[i].tc, "guardian_tc"),
 | 
			
		||||
            add_object(gc, final->p[i].obj, "guardian_obj"),
 | 
			
		||||
            gc->final_guardians);
 | 
			
		||||
        }
 | 
			
		||||
        t = t->next;
 | 
			
		||||
      }
 | 
			
		||||
      while(final){
 | 
			
		||||
        t = final->next;
 | 
			
		||||
        ik_munmap(final, sizeof(ik_guardian_table));
 | 
			
		||||
        final = t;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    collect_loop(gc);
 | 
			
		||||
  } while (more);
 | 
			
		||||
  /* */
 | 
			
		||||
  while(pending_final){
 | 
			
		||||
    ik_guardian_table* next = pending_final->next;
 | 
			
		||||
    ik_munmap(pending_final, sizeof(ik_guardian_table));
 | 
			
		||||
    pending_final = next;
 | 
			
		||||
  }
 | 
			
		||||
  /* */
 | 
			
		||||
  {
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i=0; i<=gen; i++){
 | 
			
		||||
      int ni = next_gen(i);
 | 
			
		||||
      ik_guardian_table* t = pending_hold[i];
 | 
			
		||||
      while(t){
 | 
			
		||||
        int count = t->count;
 | 
			
		||||
        int j;
 | 
			
		||||
        for(j=0; j<count; j++){
 | 
			
		||||
          ikp tc = t->p[j].tc;
 | 
			
		||||
          ikp obj = t->p[j].obj;
 | 
			
		||||
          if(is_live(tc, gc)){
 | 
			
		||||
            pcb->guardians[ni] = move_guardian(
 | 
			
		||||
              add_object(gc, tc, "guardian_tc2"),
 | 
			
		||||
              add_object(gc, obj, "guardian_obj2"),
 | 
			
		||||
              pcb->guardians[ni]);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        ik_guardian_table* next = t->next;
 | 
			
		||||
        ik_munmap(t, sizeof(ik_guardian_table));
 | 
			
		||||
        t = next;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  while(1){
 | 
			
		||||
    int i;
 | 
			
		||||
    /* for every tc/obj in the queues, 
 | 
			
		||||
       - if tc is live and obj is live, move them to guard_move
 | 
			
		||||
       - if tc is live and obj is dead, move them to guard_dead
 | 
			
		||||
       - else keep tc, obj in guard_wait.
 | 
			
		||||
     */
 | 
			
		||||
    for(i=0; i<=gen; i++){
 | 
			
		||||
      ik_guardian_table* t = guard_wait[i];
 | 
			
		||||
      while (t){
 | 
			
		||||
        int j = 0;
 | 
			
		||||
        int k = 0;
 | 
			
		||||
        int count = t->count;
 | 
			
		||||
        while(j < count){
 | 
			
		||||
          ikp tc = t->p[j].tc;
 | 
			
		||||
          ikp obj = t->p[j].obj;
 | 
			
		||||
          if(is_live(tc, gc)){
 | 
			
		||||
            if(is_live(obj, gc)){
 | 
			
		||||
              guard_move[i] = move_guardian(tc, obj, guard_move[i]);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
              guard_dead[i] = move_guardian(tc, obj, guard_dead[i]);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            t->p[k].tc = tc;
 | 
			
		||||
            t->p[k].obj = obj;
 | 
			
		||||
            k++;
 | 
			
		||||
          }
 | 
			
		||||
          j++;
 | 
			
		||||
        }
 | 
			
		||||
        t->count = k;
 | 
			
		||||
        t = t->next;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    /* now all things in guard_move are moved to next-gen's
 | 
			
		||||
     * guardians */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define disp_frame_offset -13
 | 
			
		||||
#define disp_multivalue_rp -9
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1434,3 +1645,31 @@ gc_add_tconcs(gc_t* gc){
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gc_add_guardians(gc_t* gc){
 | 
			
		||||
  ik_guardian_table* t = gc->final_guardians;
 | 
			
		||||
  ikpcb* pcb = gc->pcb;
 | 
			
		||||
  while(t){
 | 
			
		||||
    int i;
 | 
			
		||||
    int count = t->count;
 | 
			
		||||
    for(i=0; i<count; i++){
 | 
			
		||||
      ikp tc = t->p[i].tc;
 | 
			
		||||
      ikp obj = t->p[i].obj;
 | 
			
		||||
      assert(tagof(tc) == pair_tag);
 | 
			
		||||
      ikp d = ref(tc, off_cdr);
 | 
			
		||||
      assert(tagof(d) == pair_tag);
 | 
			
		||||
      ikp new_pair = ik_alloc(pcb, pair_size) + pair_tag;
 | 
			
		||||
      ref(d, off_car) = obj;
 | 
			
		||||
      ref(d, off_cdr) = new_pair;
 | 
			
		||||
      ref(new_pair, off_car) = false_object;
 | 
			
		||||
      ref(new_pair, off_cdr) = false_object;
 | 
			
		||||
      ref(tc, off_cdr) = new_pair;
 | 
			
		||||
      pcb->dirty_vector[page_index(tc)] = -1;
 | 
			
		||||
      pcb->dirty_vector[page_index(d)] = -1;
 | 
			
		||||
    }
 | 
			
		||||
    ik_guardian_table* next = t->next;
 | 
			
		||||
    ik_munmap(t, sizeof(ik_guardian_table));
 | 
			
		||||
    t = next;
 | 
			
		||||
  }
 | 
			
		||||
  gc->final_guardians = 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ typedef struct ik_guardian_table{
 | 
			
		|||
} ik_guardian_table;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
typedef struct ikpcb{
 | 
			
		||||
  /* the first locations may be accessed by some     */
 | 
			
		||||
  /* compiled code to perform overflow/underflow ops */
 | 
			
		||||
  ikp   allocation_pointer;           /* offset =  0 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								src/ikarus.boot
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								src/ikarus.boot
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -82,7 +82,9 @@
 | 
			
		|||
    with-input-from-file call-with-input-file date-string
 | 
			
		||||
    file-exists? delete-file + - add1 sub1 * expt 
 | 
			
		||||
    quotient+remainder quotient remainder number? positive?
 | 
			
		||||
    negative? zero? number->string logand = < > <= >=))
 | 
			
		||||
    negative? zero? number->string logand = < > <= >=
 | 
			
		||||
    make-guardian
 | 
			
		||||
    ))
 | 
			
		||||
 | 
			
		||||
(define system-primitives
 | 
			
		||||
  '(
 | 
			
		||||
| 
						 | 
				
			
			@ -213,6 +215,7 @@
 | 
			
		|||
    ["librecord.ss"     #t  "librecord.fasl"]
 | 
			
		||||
    ["libcxr.ss"        #t  "libcxr.fasl"]
 | 
			
		||||
    ["libnumerics.ss"   #t  "libnumerics.fasl"]
 | 
			
		||||
    ["libguardians.ss"  #t  "libguardians.fasl"]
 | 
			
		||||
    ["libcore.ss"       #t  "libcore.fasl"]
 | 
			
		||||
    ["libchezio.ss"     #t  "libchezio.fasl"]
 | 
			
		||||
    ["libhash.ss"       #t  "libhash.fasl"]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue