Top


定義場所(file name)

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

説明(description)

引数として処理途中の配列が渡される (forwarding pointer は埋まっているが中身が全部処理済みではないという状態).

なお, 処理途中の配列は set_partial_array_mask() されたポインタ (= G1_PARTIAL_ARRAY_MASK と OR 取ったポインタ) になっているので, それ以外のものと区別は付く.

また, 配列の本来の長さは forwarding 先の length フィールドに, 現在処理済みの長さは forwarding 元の length フィールドに入っている模様.

名前(function name)

template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) {

本体部(body)

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(has_partial_array_mask(p), "invariant");

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

      oop old = clear_partial_array_mask(p);
      assert(old->is_objArray(), "must be obj array");
      assert(old->is_forwarded(), "must be forwarded");
      assert(Universe::heap()->is_in_reserved(old), "must be in heap.");

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

      objArrayOop obj = objArrayOop(old->forwardee());
      assert((void*)old != (void*)old->forwardee(), "self forwarding here?");
      // Process ParGCArrayScanChunk elements now
      // and push the remainder back onto queue
      int start     = arrayOop(old)->length();
      int end       = obj->length();
      int remainder = end - start;
      assert(start <= end, "just checking");

  {- -------------------------------------------
  (1) 残りの未処理数が 2*ParGCArrayScanChunk 未満であれば全て処理してしまう.
      そうでなければ ParGCArrayScanChunk 個分だけ処理し, 残りは未処理として後回しにする.
      ---------------------------------------- -}

      if (remainder > 2 * ParGCArrayScanChunk) {
        // Test above combines last partial chunk with a full chunk
        end = start + ParGCArrayScanChunk;
        arrayOop(old)->set_length(end);
        // Push remainder.
        oop* old_p = set_partial_array_mask(old);
        assert(arrayOop(old)->length() < obj->length(), "Empty push?");
        _par_scan_state->push_on_queue(old_p);
      } else {
        // Restore length so that the heap remains parsable in
        // case of evacuation failure.
        arrayOop(old)->set_length(end);
      }
      _scanner.set_region(_g1->heap_region_containing_raw(obj));
      // process our set of indices (include header in first chunk)
      obj->oop_iterate_range(&_scanner, start, end);
    }

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