hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
author tonyp
Sat, 16 Oct 2010 17:12:19 -0400
changeset 6983 a8c50cedbce9
parent 6183 4c74cfe14f20
child 7397 5b173b4ca846
permissions -rw-r--r--
6991377: G1: race between concurrent refinement and humongous object allocation Summary: There is a race between the concurrent refinement threads and the humongous object allocation that can cause the concurrent refinement threads to corrupt the part of the BOT that it is being initialized by the humongous object allocation operation. The solution is to do the humongous object allocation in careful steps to ensure that the concurrent refinement threads always have a consistent view over the BOT, region contents, and top. The fix includes some very minor tidying up in sparsePRT. Reviewed-by: jcoomes, johnc, ysr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3807
diff changeset
     2
 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     4
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     7
 * published by the Free Software Foundation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     8
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    13
 * accompanied this code).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    14
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3807
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3807
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3807
diff changeset
    21
 * questions.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    22
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    23
 */
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    24
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    25
#include "incls/_precompiled.incl"
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    26
#include "incls/_heapRegionSeq.cpp.incl"
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    27
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    28
// Local to this file.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    29
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    30
static int orderRegions(HeapRegion** hr1p, HeapRegion** hr2p) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    31
  if ((*hr1p)->end() <= (*hr2p)->bottom()) return -1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    32
  else if ((*hr2p)->end() <= (*hr1p)->bottom()) return 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    33
  else if (*hr1p == *hr2p) return 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    34
  else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    35
    assert(false, "We should never compare distinct overlapping regions.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    36
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    37
  return 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    38
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    39
1425
ec7818f129f8 6758633: G1: SEGV with GCOld on Linux
iveresov
parents: 1374
diff changeset
    40
HeapRegionSeq::HeapRegionSeq(const size_t max_size) :
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    41
  _alloc_search_start(0),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    42
  // The line below is the worst bit of C++ hackery I've ever written
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    43
  // (Detlefs, 11/23).  You should think of it as equivalent to
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    44
  // "_regions(100, true)": initialize the growable array and inform it
6183
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    45
  // that it should allocate its elem array(s) on the C heap.
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    46
  //
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    47
  // The first argument, however, is actually a comma expression
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    48
  // (set_allocation_type(this, C_HEAP), 100). The purpose of the
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    49
  // set_allocation_type() call is to replace the default allocation
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    50
  // type for embedded objects STACK_OR_EMBEDDED with C_HEAP. It will
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    51
  // allow to pass the assert in GenericGrowableArray() which checks
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    52
  // that a growable array object must be on C heap if elements are.
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    53
  //
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    54
  // Note: containing object is allocated on C heap since it is CHeapObj.
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    55
  //
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    56
  _regions((ResourceObj::set_allocation_type((address)&_regions,
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5547
diff changeset
    57
                                             ResourceObj::C_HEAP),
1425
ec7818f129f8 6758633: G1: SEGV with GCOld on Linux
iveresov
parents: 1374
diff changeset
    58
            (int)max_size),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    59
           true),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    60
  _next_rr_candidate(0),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    61
  _seq_bottom(NULL)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    62
{}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    63
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    64
// Private methods.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    65
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    66
HeapWord*
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    67
HeapRegionSeq::alloc_obj_from_region_index(int ind, size_t word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    68
  assert(G1CollectedHeap::isHumongous(word_size),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    69
         "Allocation size should be humongous");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    70
  int cur = ind;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    71
  int first = cur;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    72
  size_t sumSizes = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    73
  while (cur < _regions.length() && sumSizes < word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    74
    // Loop invariant:
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    75
    //  For all i in [first, cur):
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    76
    //       _regions.at(i)->is_empty()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    77
    //    && _regions.at(i) is contiguous with its predecessor, if any
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    78
    //  && sumSizes is the sum of the sizes of the regions in the interval
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    79
    //       [first, cur)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    80
    HeapRegion* curhr = _regions.at(cur);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    81
    if (curhr->is_empty()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    82
        && (first == cur
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    83
            || (_regions.at(cur-1)->end() ==
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    84
                curhr->bottom()))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    85
      sumSizes += curhr->capacity() / HeapWordSize;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    86
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    87
      first = cur + 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    88
      sumSizes = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    89
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    90
    cur++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    91
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    92
  if (sumSizes >= word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    93
    _alloc_search_start = cur;
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    94
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    95
    // We need to initialize the region(s) we just discovered. This is
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    96
    // a bit tricky given that it can happen concurrently with
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    97
    // refinement threads refining cards on these regions and
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    98
    // potentially wanting to refine the BOT as they are scanning
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
    99
    // those cards (this can happen shortly after a cleanup; see CR
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   100
    // 6991377). So we have to set up the region(s) carefully and in
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   101
    // a specific order.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   102
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   103
    // Currently, allocs_are_zero_filled() returns false. The zero
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   104
    // filling infrastructure will be going away soon (see CR 6977804).
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   105
    // So no need to do anything else here.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   106
    bool zf = G1CollectedHeap::heap()->allocs_are_zero_filled();
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   107
    assert(!zf, "not supported");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   108
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   109
    // This will be the "starts humongous" region.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   110
    HeapRegion* first_hr = _regions.at(first);
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   111
    {
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   112
      MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   113
      first_hr->set_zero_fill_allocated();
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   114
    }
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   115
    // The header of the new object will be placed at the bottom of
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   116
    // the first region.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   117
    HeapWord* new_obj = first_hr->bottom();
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   118
    // This will be the new end of the first region in the series that
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   119
    // should also match the end of the last region in the seriers.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   120
    // (Note: sumSizes = "region size" x "number of regions we found").
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   121
    HeapWord* new_end = new_obj + sumSizes;
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   122
    // This will be the new top of the first region that will reflect
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   123
    // this allocation.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   124
    HeapWord* new_top = new_obj + word_size;
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   125
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   126
    // First, we need to zero the header of the space that we will be
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   127
    // allocating. When we update top further down, some refinement
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   128
    // threads might try to scan the region. By zeroing the header we
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   129
    // ensure that any thread that will try to scan the region will
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   130
    // come across the zero klass word and bail out.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   131
    //
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   132
    // NOTE: It would not have been correct to have used
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   133
    // CollectedHeap::fill_with_object() and make the space look like
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   134
    // an int array. The thread that is doing the allocation will
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   135
    // later update the object header to a potentially different array
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   136
    // type and, for a very short period of time, the klass and length
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   137
    // fields will be inconsistent. This could cause a refinement
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   138
    // thread to calculate the object size incorrectly.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   139
    Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   140
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   141
    // We will set up the first region as "starts humongous". This
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   142
    // will also update the BOT covering all the regions to reflect
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   143
    // that there is a single object that starts at the bottom of the
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   144
    // first region.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   145
    first_hr->set_startsHumongous(new_end);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   146
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   147
    // Then, if there are any, we will set up the "continues
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   148
    // humongous" regions.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   149
    HeapRegion* hr = NULL;
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   150
    for (int i = first + 1; i < cur; ++i) {
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   151
      hr = _regions.at(i);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   152
      {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   153
        MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   154
        hr->set_zero_fill_allocated();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   155
      }
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   156
      hr->set_continuesHumongous(first_hr);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   157
    }
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   158
    // If we have "continues humongous" regions (hr != NULL), then the
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   159
    // end of the last one should match new_end.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   160
    assert(hr == NULL || hr->end() == new_end, "sanity");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   161
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   162
    // Up to this point no concurrent thread would have been able to
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   163
    // do any scanning on any region in this series. All the top
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   164
    // fields still point to bottom, so the intersection between
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   165
    // [bottom,top] and [card_start,card_end] will be empty. Before we
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   166
    // update the top fields, we'll do a storestore to make sure that
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   167
    // no thread sees the update to top before the zeroing of the
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   168
    // object header and the BOT initialization.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   169
    OrderAccess::storestore();
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   170
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   171
    // Now that the BOT and the object header have been initialized,
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   172
    // we can update top of the "starts humongous" region.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   173
    assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   174
           "new_top should be in this region");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   175
    first_hr->set_top(new_top);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   176
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   177
    // Now, we will update the top fields of the "continues humongous"
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   178
    // regions. The reason we need to do this is that, otherwise,
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   179
    // these regions would look empty and this will confuse parts of
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   180
    // G1. For example, the code that looks for a consecutive number
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   181
    // of empty regions will consider them empty and try to
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   182
    // re-allocate them. We can extend is_empty() to also include
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   183
    // !continuesHumongous(), but it is easier to just update the top
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   184
    // fields here.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   185
    hr = NULL;
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   186
    for (int i = first + 1; i < cur; ++i) {
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   187
      hr = _regions.at(i);
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   188
      if ((i + 1) == cur) {
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   189
        // last continues humongous region
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   190
        assert(hr->bottom() < new_top && new_top <= hr->end(),
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   191
               "new_top should fall on this region");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   192
        hr->set_top(new_top);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   193
      } else {
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   194
        // not last one
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   195
        assert(new_top > hr->end(), "new_top should be above this region");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   196
        hr->set_top(hr->end());
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   197
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   198
    }
6983
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   199
    // If we have continues humongous regions (hr != NULL), then the
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   200
    // end of the last one should match new_end and its top should
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   201
    // match new_top.
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   202
    assert(hr == NULL ||
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   203
           (hr->end() == new_end && hr->top() == new_top), "sanity");
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   204
a8c50cedbce9 6991377: G1: race between concurrent refinement and humongous object allocation
tonyp
parents: 6183
diff changeset
   205
    return new_obj;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   206
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   207
    // If we started from the beginning, we want to know why we can't alloc.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   208
    return NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   209
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   210
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   211
2344
f2e09ba7ceab 6543938: G1: remove the concept of popularity
apetrusenko
parents: 2105
diff changeset
   212
void HeapRegionSeq::print_empty_runs() {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   213
  int empty_run = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   214
  int n_empty = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   215
  int empty_run_start;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   216
  for (int i = 0; i < _regions.length(); i++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   217
    HeapRegion* r = _regions.at(i);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   218
    if (r->continuesHumongous()) continue;
2344
f2e09ba7ceab 6543938: G1: remove the concept of popularity
apetrusenko
parents: 2105
diff changeset
   219
    if (r->is_empty()) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   220
      assert(!r->isHumongous(), "H regions should not be empty.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   221
      if (empty_run == 0) empty_run_start = i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   222
      empty_run++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   223
      n_empty++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   224
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   225
      if (empty_run > 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   226
        gclog_or_tty->print("  %d:%d", empty_run_start, empty_run);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   227
        empty_run = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   228
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   229
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   230
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   231
  if (empty_run > 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   232
    gclog_or_tty->print(" %d:%d", empty_run_start, empty_run);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   233
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   234
  gclog_or_tty->print_cr(" [tot = %d]", n_empty);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   235
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   236
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   237
int HeapRegionSeq::find(HeapRegion* hr) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   238
  // FIXME: optimized for adjacent regions of fixed size.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   239
  int ind = hr->hrs_index();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   240
  if (ind != -1) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   241
    assert(_regions.at(ind) == hr, "Mismatch");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   242
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   243
  return ind;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   244
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   245
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   246
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   247
// Public methods.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   248
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   249
void HeapRegionSeq::insert(HeapRegion* hr) {
1425
ec7818f129f8 6758633: G1: SEGV with GCOld on Linux
iveresov
parents: 1374
diff changeset
   250
  assert(!_regions.is_full(), "Too many elements in HeapRegionSeq");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   251
  if (_regions.length() == 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   252
      || _regions.top()->end() <= hr->bottom()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   253
    hr->set_hrs_index(_regions.length());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   254
    _regions.append(hr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   255
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   256
    _regions.append(hr);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   257
    _regions.sort(orderRegions);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   258
    for (int i = 0; i < _regions.length(); i++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   259
      _regions.at(i)->set_hrs_index(i);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   260
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   261
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   262
  char* bot = (char*)_regions.at(0)->bottom();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   263
  if (_seq_bottom == NULL || bot < _seq_bottom) _seq_bottom = bot;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   264
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   265
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   266
size_t HeapRegionSeq::length() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   267
  return _regions.length();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   268
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   269
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   270
size_t HeapRegionSeq::free_suffix() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   271
  size_t res = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   272
  int first = _regions.length() - 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   273
  int cur = first;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   274
  while (cur >= 0 &&
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   275
         (_regions.at(cur)->is_empty()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   276
          && (first == cur
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   277
              || (_regions.at(cur+1)->bottom() ==
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   278
                  _regions.at(cur)->end())))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   279
      res++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   280
      cur--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   281
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   282
  return res;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   283
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   284
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   285
HeapWord* HeapRegionSeq::obj_allocate(size_t word_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   286
  int cur = _alloc_search_start;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   287
  // Make sure "cur" is a valid index.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   288
  assert(cur >= 0, "Invariant.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   289
  HeapWord* res = alloc_obj_from_region_index(cur, word_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   290
  if (res == NULL)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   291
    res = alloc_obj_from_region_index(0, word_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   292
  return res;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   293
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   294
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   295
void HeapRegionSeq::iterate(HeapRegionClosure* blk) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   296
  iterate_from((HeapRegion*)NULL, blk);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   297
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   298
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   299
// The first argument r is the heap region at which iteration begins.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   300
// This operation runs fastest when r is NULL, or the heap region for
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   301
// which a HeapRegionClosure most recently returned true, or the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   302
// heap region immediately to its right in the sequence.  In all
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   303
// other cases a linear search is required to find the index of r.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   304
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   305
void HeapRegionSeq::iterate_from(HeapRegion* r, HeapRegionClosure* blk) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   306
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   307
  // :::: FIXME ::::
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   308
  // Static cache value is bad, especially when we start doing parallel
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   309
  // remembered set update. For now just don't cache anything (the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   310
  // code in the def'd out blocks).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   311
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   312
#if 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   313
  static int cached_j = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   314
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   315
  int len = _regions.length();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   316
  int j = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   317
  // Find the index of r.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   318
  if (r != NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   319
#if 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   320
    assert(cached_j >= 0, "Invariant.");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   321
    if ((cached_j < len) && (r == _regions.at(cached_j))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   322
      j = cached_j;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   323
    } else if ((cached_j + 1 < len) && (r == _regions.at(cached_j + 1))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   324
      j = cached_j + 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   325
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   326
      j = find(r);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   327
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   328
      if (j < 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   329
        j = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   330
      }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   331
#if 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   332
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   333
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   334
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   335
  int i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   336
  for (i = j; i < len; i += 1) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   337
    int res = blk->doHeapRegion(_regions.at(i));
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   338
    if (res) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   339
#if 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   340
      cached_j = i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   341
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   342
      blk->incomplete();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   343
      return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   344
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   345
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   346
  for (i = 0; i < j; i += 1) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   347
    int res = blk->doHeapRegion(_regions.at(i));
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   348
    if (res) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   349
#if 0
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   350
      cached_j = i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   351
#endif
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   352
      blk->incomplete();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   353
      return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   354
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   355
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   356
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   357
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   358
void HeapRegionSeq::iterate_from(int idx, HeapRegionClosure* blk) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   359
  int len = _regions.length();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   360
  int i;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   361
  for (i = idx; i < len; i++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   362
    if (blk->doHeapRegion(_regions.at(i))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   363
      blk->incomplete();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   364
      return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   365
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   366
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   367
  for (i = 0; i < idx; i++) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   368
    if (blk->doHeapRegion(_regions.at(i))) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   369
      blk->incomplete();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   370
      return;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   371
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   372
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   373
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   375
MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   376
                                   size_t& num_regions_deleted) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   377
  assert(shrink_bytes % os::vm_page_size() == 0, "unaligned");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   378
  assert(shrink_bytes % HeapRegion::GrainBytes == 0, "unaligned");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   379
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   380
  if (_regions.length() == 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   381
    num_regions_deleted = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   382
    return MemRegion();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   383
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   384
  int j = _regions.length() - 1;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   385
  HeapWord* end = _regions.at(j)->end();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   386
  HeapWord* last_start = end;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   387
  while (j >= 0 && shrink_bytes > 0) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   388
    HeapRegion* cur = _regions.at(j);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   389
    // We have to leave humongous regions where they are,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   390
    // and work around them.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   391
    if (cur->isHumongous()) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   392
      return MemRegion(last_start, end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   393
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   394
    assert(cur == _regions.top(), "Should be top");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   395
    if (!cur->is_empty()) break;
3807
d8368e0b3783 6861557: G1: assert(top() == bottom() || zfs == Allocated,"Region must be empty, or ...")
ysr
parents: 2344
diff changeset
   396
    cur->reset_zero_fill();
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   397
    shrink_bytes -= cur->capacity();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   398
    num_regions_deleted++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   399
    _regions.pop();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   400
    last_start = cur->bottom();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   401
    // We need to delete these somehow, but can't currently do so here: if
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   402
    // we do, the ZF thread may still access the deleted region.  We'll
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   403
    // leave this here as a reminder that we have to do something about
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   404
    // this.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   405
    // delete cur;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   406
    j--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   407
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   408
  return MemRegion(last_start, end);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   409
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   410
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   411
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   412
class PrintHeapRegionClosure : public  HeapRegionClosure {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   413
public:
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   414
  bool doHeapRegion(HeapRegion* r) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   415
    gclog_or_tty->print(PTR_FORMAT ":", r);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   416
    r->print();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   417
    return false;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   418
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   419
};
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   420
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   421
void HeapRegionSeq::print() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   422
  PrintHeapRegionClosure cl;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   423
  iterate(&cl);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   424
}