bitmap marking
This commit is contained in:
		
							parent
							
								
									3b333c2b47
								
							
						
					
					
						commit
						34d93682a9
					
				|  | @ -11,8 +11,12 @@ union header { | |||
|   } s; | ||||
| }; | ||||
| 
 | ||||
| #define BITMAP_SIZE                                                     \ | ||||
|   (PIC_HEAP_PAGE_SIZE / sizeof(union header)) / (sizeof(uint32_t) * CHAR_BIT) | ||||
| 
 | ||||
| struct heap_page { | ||||
|   union header *basep, *endp; | ||||
|   uint32_t bitmap[BITMAP_SIZE]; | ||||
|   struct heap_page *next; | ||||
| }; | ||||
| 
 | ||||
|  | @ -254,6 +258,50 @@ heap_morecore(pic_state *pic) | |||
|   pic->heap->pages = page; | ||||
| } | ||||
| 
 | ||||
| /* bitmap */ | ||||
| 
 | ||||
| static struct heap_page * | ||||
| obj2page(pic_state *pic, union header *h) | ||||
| { | ||||
|   struct heap_page *page; | ||||
| 
 | ||||
|   page = pic->heap->pages; | ||||
|   while (page) { | ||||
|     if (page->basep <= h && h < page->endp) | ||||
|       return page; | ||||
|     page = page->next; | ||||
|   } | ||||
|   PIC_UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| is_marked(pic_state *pic, struct pic_object *obj) | ||||
| { | ||||
|   union header *h = ((union header *)obj) - 1; | ||||
|   struct heap_page *page; | ||||
|   size_t i, unit_size = sizeof(uint32_t) * CHAR_BIT; | ||||
| 
 | ||||
|   page = obj2page(pic, h); | ||||
| 
 | ||||
|   i = h - page->basep; | ||||
| 
 | ||||
|   return page->bitmap[i / unit_size] & (1 << (i % unit_size)); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| mark(pic_state *pic, struct pic_object *obj) | ||||
| { | ||||
|   union header *h = ((union header *)obj) - 1; | ||||
|   struct heap_page *page; | ||||
|   size_t i, unit_size = sizeof(uint32_t) * CHAR_BIT; | ||||
| 
 | ||||
|   page = obj2page(pic, h); | ||||
| 
 | ||||
|   i = h - page->basep; | ||||
| 
 | ||||
|   page->bitmap[i / unit_size] |= (1 << (i % unit_size)); | ||||
| } | ||||
| 
 | ||||
| /* MARK */ | ||||
| 
 | ||||
| static void gc_mark_object(pic_state *, union object *); | ||||
|  | @ -272,10 +320,10 @@ gc_mark_object(pic_state *pic, union object *obj) | |||
| { | ||||
|  loop: | ||||
| 
 | ||||
|   if (obj->obj.gc_mark == PIC_GC_MARK) | ||||
|   if (is_marked(pic, &obj->obj)) | ||||
|     return; | ||||
| 
 | ||||
|   obj->obj.gc_mark = PIC_GC_MARK; | ||||
|   mark(pic, &obj->obj); | ||||
| 
 | ||||
| #define LOOP(o) obj = (union object *)(o); goto loop | ||||
| 
 | ||||
|  | @ -528,8 +576,8 @@ gc_mark_phase(pic_state *pic) | |||
|           continue; | ||||
|         key = kh_key(h, it); | ||||
|         val = kh_val(h, it); | ||||
|         if (key->gc_mark == PIC_GC_MARK) { | ||||
|           if (pic_obj_p(val) && pic_obj_ptr(val)->gc_mark == PIC_GC_UNMARK) { | ||||
|         if (is_marked(pic, key)) { | ||||
|           if (pic_obj_p(val) && ! is_marked(pic, pic_obj_ptr(val))) { | ||||
|             gc_mark(pic, val); | ||||
|             ++j; | ||||
|           } | ||||
|  | @ -624,8 +672,7 @@ gc_sweep_page(pic_state *pic, struct heap_page *page) | |||
|         goto escape; | ||||
|       } | ||||
|       obj = (union object *)(p + 1); | ||||
|       if (obj->obj.gc_mark == PIC_GC_MARK) { | ||||
|         obj->obj.gc_mark = PIC_GC_UNMARK; | ||||
|       if (is_marked(pic, &obj->obj)) { | ||||
|         alive += p->s.size; | ||||
|       } else { | ||||
|         if (head == NULL) { | ||||
|  | @ -670,7 +717,7 @@ gc_sweep_phase(pic_state *pic) | |||
|       if (! kh_exist(h, it)) | ||||
|         continue; | ||||
|       obj = kh_key(h, it); | ||||
|       if (obj->gc_mark == PIC_GC_UNMARK) { | ||||
|       if (! is_marked(pic, obj)) { | ||||
|         kh_del(reg, h, it); | ||||
|       } | ||||
|     } | ||||
|  | @ -682,7 +729,7 @@ gc_sweep_phase(pic_state *pic) | |||
|     if (! kh_exist(s, it)) | ||||
|       continue; | ||||
|     sym = kh_val(s, it); | ||||
|     if (sym->gc_mark == PIC_GC_UNMARK) { | ||||
|     if (! is_marked(pic, (struct pic_object *)sym)) { | ||||
|       kh_del(s, s, it); | ||||
|     } | ||||
|   } | ||||
|  | @ -699,6 +746,19 @@ gc_sweep_phase(pic_state *pic) | |||
|   } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| gc_init(pic_state *pic) | ||||
| { | ||||
|   struct heap_page *page; | ||||
| 
 | ||||
|   page = pic->heap->pages; | ||||
|   while (page) { | ||||
|     /* clear mark bits */ | ||||
|     memset(page->bitmap, 0, sizeof(page->bitmap)); | ||||
|     page = page->next; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pic_gc_run(pic_state *pic) | ||||
| { | ||||
|  | @ -706,6 +766,8 @@ pic_gc_run(pic_state *pic) | |||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   gc_init(pic); | ||||
| 
 | ||||
|   gc_mark_phase(pic); | ||||
|   gc_sweep_phase(pic); | ||||
| } | ||||
|  | @ -730,7 +792,6 @@ pic_obj_alloc_unsafe(pic_state *pic, size_t size, enum pic_tt tt) | |||
| 	pic_panic(pic, "GC memory exhausted"); | ||||
|     } | ||||
|   } | ||||
|   obj->gc_mark = PIC_GC_UNMARK; | ||||
|   obj->tt = tt; | ||||
| 
 | ||||
|   return obj; | ||||
|  |  | |||
|  | @ -162,8 +162,7 @@ enum pic_tt { | |||
| }; | ||||
| 
 | ||||
| #define PIC_OBJECT_HEADER			\ | ||||
|   enum pic_tt tt;                               \ | ||||
|   char gc_mark; | ||||
|   enum pic_tt tt; | ||||
| 
 | ||||
| struct pic_object { | ||||
|   PIC_OBJECT_HEADER | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Yuichi Nishiwaki
						Yuichi Nishiwaki