Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp

名前(function name)

  HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

        HeapWord* obj = NULL;
        size_t gclab_word_size = _g1h->desired_plab_sz(purpose);

  {- -------------------------------------------
  (1) (以下の処理はバッファの残り量が十分かどうかに応じて 2通り.
       ここに来ていると言うことは, fast path の確保処理は失敗したと言うこと.
       失敗した理由としては, バッファの残り量が少な過ぎるケースと, 確保要求量が大き過ぎるケースが考えられる.

       バッファの残り量が少な過ぎる場合は, 新しいバッファを確保する.
       確保要求量が大き過ぎる場合は, (現在のバッファはまだ破棄するにはもったいないので) 
       G1CollectedHeap 中から直接メモリ領域を確保する.)
      ---------------------------------------- -}

  {- -------------------------------------------
  (1) (以下は, 確保要求量は大きくなかった場合 (= バッファの残り量が少な過ぎる場合).
       より具体的に言うと, 確保要求量(word_sz)が
       デフォルトの plab サイズ (= G1CollectedHeap::desired_plab_sz() の返値) の
       ParallelGCBufferWastePct% 未満の場合.
       なお, word_sz を 100倍しているのは ParallelGCBufferWastePct の単位が % であるため.)
      ---------------------------------------- -}

        if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {

    {- -------------------------------------------
  (1.1) まず G1ParGCAllocBuffer::retire() を呼んで, 
        purpose 引数に対応する G1ParGCAllocBuffer オブジェクトのバッファを無効にする.

        次に G1CollectedHeap::par_allocate_during_gc() を呼んで新しいバッファを確保し, 
        G1ParGCAllocBuffer::set_buf() でその G1ParGCAllocBuffer にセットする.

        最後に, ParGCAllocBuffer::allocate() を呼んで
        word_sz 引数で指定された量のメモリ領域を
        新しいバッファから確保する.

        (なお, G1ParGCAllocBuffer のバッファを無効にする直前に
         G1ParScanThreadState::add_to_alloc_buffer_waste() を呼び出し, 
         無駄になる領域量の記録も行っている)
        ---------------------------------------- -}

          G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
          assert(gclab_word_size == alloc_buf->word_sz(),
                 "dynamic resizing is not supported");
          add_to_alloc_buffer_waste(alloc_buf->words_remaining());
          alloc_buf->retire(false, false);

          HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
          if (buf == NULL) return NULL; // Let caller handle allocation failure.
          // Otherwise.
          alloc_buf->set_buf(buf);

          obj = alloc_buf->allocate(word_sz);
          assert(obj != NULL, "buffer was definitely big enough...");

  {- -------------------------------------------
  (1) (以下は, 確保要求量が大き過ぎる場合)
      ---------------------------------------- -}

        } else {

    {- -------------------------------------------
  (1.1) G1CollectedHeap::par_allocate_during_gc() を呼んで, 
        word_sz 引数で指定された量のメモリ領域を確保する.
        ---------------------------------------- -}

          obj = _g1h->par_allocate_during_gc(purpose, word_sz);
        }

  {- -------------------------------------------
  (1) 確保したメモリ領域をリターン
      ---------------------------------------- -}

        return obj;
      }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.