最終更新:ID:D7J/gPk67w 2009年02月05日(木) 22:23:44履歴
static void mark_slice (intnat work)
{ value *gray_vals_ptr; /* Local copy of gray_vals_cur */
value v, child; header_t hd;
mlsize_t size, i;
caml_gc_message (0x40, "Marking %ld words\n", work); caml_gc_message (0x40, "Subphase = %ld\n", caml_gc_subphase); gray_vals_ptr = gray_vals_cur;
while (work > 0){ if (gray_vals_ptr > gray_vals){
v = *--gray_vals_ptr; hd = Hd_val(v);
Assert (Is_gray_hd (hd)); Hd_val (v) = Blackhd_hd (hd);
size = Wosize_hd (hd);
if (Tag_hd (hd) < No_scan_tag){
for (i = 0; i < size; i++){ child = Field (v, i);
if (Is_block (child) && Is_in_heap (child)) {
hd = Hd_val (child); if (Tag_hd (hd) == Forward_tag){
value f = Forward_val (child);
if (Is_block (f) && (!Is_in_value_area(f) || Tag_val (f) == Forward_tag || Tag_val (f) == Lazy_tag || Tag_val (f) == Double_tag)){
/* Do not short-circuit the pointer. */ }else{ Field (v, i) = f; } } else if (Tag_hd(hd) == Infix_tag) {
child -= Infix_offset_val(child);
hd = Hd_val(child); } if (Is_white_hd (hd)){
Hd_val (child) = Grayhd_hd (hd);
*gray_vals_ptr++ = child; if (gray_vals_ptr >= gray_vals_end) {
gray_vals_cur = gray_vals_ptr; realloc_gray_vals ();
gray_vals_ptr = gray_vals_cur; } } } } } work -= Whsize_wosize(size);
}else if (markhp != NULL){
if (markhp == limit){
chunk = Chunk_next (chunk);
if (chunk == NULL){ markhp = NULL; }else{ markhp = chunk; limit = chunk + Chunk_size (chunk);
} }else{ if (Is_gray_val (Val_hp (markhp))){
Assert (gray_vals_ptr == gray_vals); *gray_vals_ptr++ = Val_hp (markhp); } markhp += Bhsize_hp (markhp);
} }else if (!heap_is_pure){
heap_is_pure = 1; chunk = caml_heap_start;
markhp = chunk; limit = chunk + Chunk_size (chunk); }else{ switch (caml_gc_subphase){
case Subphase_main: {
/* The main marking phase is over. Start removing weak pointers to dead values. */
主なマーキングフェーズは終了した。無効な値への弱参照ポインタを削除し始める。
caml_gc_subphase = Subphase_weak1;
weak_prev = &caml_weak_list_head;
} break; case Subphase_weak1: {
value cur, curfield; mlsize_t sz, i; header_t hd; cur = *weak_prev; if (cur != (value) NULL){ hd = Hd_val (cur); sz = Wosize_hd (hd); for (i = 1; i < sz; i++){ curfield = Field (cur, i); weak_again: if (curfield != caml_weak_none && Is_block (curfield) && Is_in_heap (curfield)){ if (Tag_val (curfield) == Forward_tag){ value f = Forward_val (curfield); if (Is_block (f)) { if (!Is_in_value_area(f) || Tag_val (f) == Forward_tag || Tag_val (f) == Lazy_tag || Tag_val (f) == Double_tag){ /* Do not short-circuit the pointer. */ }else{ Field (cur, i) = curfield = f; goto weak_again; } } } if (Is_white_val (curfield)){
Field (cur, i) = caml_weak_none;
} } } weak_prev = &Field (cur, 0); work -= Whsize_hd (hd); }else{ /* Subphase_weak1 is done. Start removing dead weak arrays. */
Subphase_weak1は終了した。無効な弱参照配列を削除する。
caml_gc_subphase = Subphase_weak2;
weak_prev = &caml_weak_list_head; } } break; case Subphase_weak2: { value cur; header_t hd; cur = *weak_prev; if (cur != (value) NULL){ hd = Hd_val (cur); if (Color_hd (hd) == Caml_white){
/* The whole array is dead, remove it from the list. */
配列全体は死んでおり、これをリストから削除する。
*weak_prev = Field (cur, 0); }else{ weak_prev = &Field (cur, 0); } work -= 1; }else{ /* Subphase_weak2 is done. Handle finalised values. */ gray_vals_cur = gray_vals_ptr; caml_final_update ();
gray_vals_ptr = gray_vals_cur; caml_gc_subphase = Subphase_final;
} } break; case Subphase_final: { /* Initialise the sweep phase. */
スイープフェーズを初期化する。
gray_vals_cur = gray_vals_ptr; caml_gc_sweep_hp = caml_heap_start;
caml_fl_init_merge ();
caml_gc_phase = Phase_sweep;
chunk = caml_heap_start;
caml_gc_sweep_hp = chunk; limit = chunk + Chunk_size (chunk); work = 0; caml_fl_size_at_phase_change = caml_fl_cur_size;
} break; default: Assert (0); } } } gray_vals_cur = gray_vals_ptr; }
タグ
コメントをかく