概要

引数

  • work:

戻り値


なし。

実装



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;
}
タグ

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

管理人/副管理人のみ編集できます