hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
changeset 1374 4c24294029a9
child 1425 ec7818f129f8
equal deleted inserted replaced
615:570062d730b2 1374:4c24294029a9
       
     1 /*
       
     2  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "incls/_precompiled.incl"
       
    26 #include "incls/_heapRegionSeq.cpp.incl"
       
    27 
       
    28 // Local to this file.
       
    29 
       
    30 static int orderRegions(HeapRegion** hr1p, HeapRegion** hr2p) {
       
    31   if ((*hr1p)->end() <= (*hr2p)->bottom()) return -1;
       
    32   else if ((*hr2p)->end() <= (*hr1p)->bottom()) return 1;
       
    33   else if (*hr1p == *hr2p) return 0;
       
    34   else {
       
    35     assert(false, "We should never compare distinct overlapping regions.");
       
    36   }
       
    37   return 0;
       
    38 }
       
    39 
       
    40 HeapRegionSeq::HeapRegionSeq() :
       
    41   _alloc_search_start(0),
       
    42   // The line below is the worst bit of C++ hackery I've ever written
       
    43   // (Detlefs, 11/23).  You should think of it as equivalent to
       
    44   // "_regions(100, true)": initialize the growable array and inform it
       
    45   // that it should allocate its elem array(s) on the C heap.  The first
       
    46   // argument, however, is actually a comma expression (new-expr, 100).
       
    47   // The purpose of the new_expr is to inform the growable array that it
       
    48   // is *already* allocated on the C heap: it uses the placement syntax to
       
    49   // keep it from actually doing any allocation.
       
    50   _regions((ResourceObj::operator new (sizeof(GrowableArray<HeapRegion*>),
       
    51                                        (void*)&_regions,
       
    52                                        ResourceObj::C_HEAP),
       
    53             100),
       
    54            true),
       
    55   _next_rr_candidate(0),
       
    56   _seq_bottom(NULL)
       
    57 {}
       
    58 
       
    59 // Private methods.
       
    60 
       
    61 HeapWord*
       
    62 HeapRegionSeq::alloc_obj_from_region_index(int ind, size_t word_size) {
       
    63   assert(G1CollectedHeap::isHumongous(word_size),
       
    64          "Allocation size should be humongous");
       
    65   int cur = ind;
       
    66   int first = cur;
       
    67   size_t sumSizes = 0;
       
    68   while (cur < _regions.length() && sumSizes < word_size) {
       
    69     // Loop invariant:
       
    70     //  For all i in [first, cur):
       
    71     //       _regions.at(i)->is_empty()
       
    72     //    && _regions.at(i) is contiguous with its predecessor, if any
       
    73     //  && sumSizes is the sum of the sizes of the regions in the interval
       
    74     //       [first, cur)
       
    75     HeapRegion* curhr = _regions.at(cur);
       
    76     if (curhr->is_empty()
       
    77         && !curhr->is_reserved()
       
    78         && (first == cur
       
    79             || (_regions.at(cur-1)->end() ==
       
    80                 curhr->bottom()))) {
       
    81       sumSizes += curhr->capacity() / HeapWordSize;
       
    82     } else {
       
    83       first = cur + 1;
       
    84       sumSizes = 0;
       
    85     }
       
    86     cur++;
       
    87   }
       
    88   if (sumSizes >= word_size) {
       
    89     _alloc_search_start = cur;
       
    90     // Mark the allocated regions as allocated.
       
    91     bool zf = G1CollectedHeap::heap()->allocs_are_zero_filled();
       
    92     HeapRegion* first_hr = _regions.at(first);
       
    93     for (int i = first; i < cur; i++) {
       
    94       HeapRegion* hr = _regions.at(i);
       
    95       if (zf)
       
    96         hr->ensure_zero_filled();
       
    97       {
       
    98         MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag);
       
    99         hr->set_zero_fill_allocated();
       
   100       }
       
   101       size_t sz = hr->capacity() / HeapWordSize;
       
   102       HeapWord* tmp = hr->allocate(sz);
       
   103       assert(tmp != NULL, "Humongous allocation failure");
       
   104       MemRegion mr = MemRegion(tmp, sz);
       
   105       SharedHeap::fill_region_with_object(mr);
       
   106       hr->declare_filled_region_to_BOT(mr);
       
   107       if (i == first) {
       
   108         first_hr->set_startsHumongous();
       
   109       } else {
       
   110         assert(i > first, "sanity");
       
   111         hr->set_continuesHumongous(first_hr);
       
   112       }
       
   113     }
       
   114     HeapWord* first_hr_bot = first_hr->bottom();
       
   115     HeapWord* obj_end = first_hr_bot + word_size;
       
   116     first_hr->set_top(obj_end);
       
   117     return first_hr_bot;
       
   118   } else {
       
   119     // If we started from the beginning, we want to know why we can't alloc.
       
   120     return NULL;
       
   121   }
       
   122 }
       
   123 
       
   124 void HeapRegionSeq::print_empty_runs(bool reserved_are_empty) {
       
   125   int empty_run = 0;
       
   126   int n_empty = 0;
       
   127   bool at_least_one_reserved = false;
       
   128   int empty_run_start;
       
   129   for (int i = 0; i < _regions.length(); i++) {
       
   130     HeapRegion* r = _regions.at(i);
       
   131     if (r->continuesHumongous()) continue;
       
   132     if (r->is_empty() && (reserved_are_empty || !r->is_reserved())) {
       
   133       assert(!r->isHumongous(), "H regions should not be empty.");
       
   134       if (empty_run == 0) empty_run_start = i;
       
   135       empty_run++;
       
   136       n_empty++;
       
   137       if (r->is_reserved()) {
       
   138         at_least_one_reserved = true;
       
   139       }
       
   140     } else {
       
   141       if (empty_run > 0) {
       
   142         gclog_or_tty->print("  %d:%d", empty_run_start, empty_run);
       
   143         if (reserved_are_empty && at_least_one_reserved)
       
   144           gclog_or_tty->print("(R)");
       
   145         empty_run = 0;
       
   146         at_least_one_reserved = false;
       
   147       }
       
   148     }
       
   149   }
       
   150   if (empty_run > 0) {
       
   151     gclog_or_tty->print(" %d:%d", empty_run_start, empty_run);
       
   152     if (reserved_are_empty && at_least_one_reserved) gclog_or_tty->print("(R)");
       
   153   }
       
   154   gclog_or_tty->print_cr(" [tot = %d]", n_empty);
       
   155 }
       
   156 
       
   157 int HeapRegionSeq::find(HeapRegion* hr) {
       
   158   // FIXME: optimized for adjacent regions of fixed size.
       
   159   int ind = hr->hrs_index();
       
   160   if (ind != -1) {
       
   161     assert(_regions.at(ind) == hr, "Mismatch");
       
   162   }
       
   163   return ind;
       
   164 }
       
   165 
       
   166 
       
   167 // Public methods.
       
   168 
       
   169 void HeapRegionSeq::insert(HeapRegion* hr) {
       
   170   if (_regions.length() == 0
       
   171       || _regions.top()->end() <= hr->bottom()) {
       
   172     hr->set_hrs_index(_regions.length());
       
   173     _regions.append(hr);
       
   174   } else {
       
   175     _regions.append(hr);
       
   176     _regions.sort(orderRegions);
       
   177     for (int i = 0; i < _regions.length(); i++) {
       
   178       _regions.at(i)->set_hrs_index(i);
       
   179     }
       
   180   }
       
   181   char* bot = (char*)_regions.at(0)->bottom();
       
   182   if (_seq_bottom == NULL || bot < _seq_bottom) _seq_bottom = bot;
       
   183 }
       
   184 
       
   185 size_t HeapRegionSeq::length() {
       
   186   return _regions.length();
       
   187 }
       
   188 
       
   189 size_t HeapRegionSeq::free_suffix() {
       
   190   size_t res = 0;
       
   191   int first = _regions.length() - 1;
       
   192   int cur = first;
       
   193   while (cur >= 0 &&
       
   194          (_regions.at(cur)->is_empty()
       
   195           && !_regions.at(cur)->is_reserved()
       
   196           && (first == cur
       
   197               || (_regions.at(cur+1)->bottom() ==
       
   198                   _regions.at(cur)->end())))) {
       
   199       res++;
       
   200       cur--;
       
   201   }
       
   202   return res;
       
   203 }
       
   204 
       
   205 HeapWord* HeapRegionSeq::obj_allocate(size_t word_size) {
       
   206   int cur = _alloc_search_start;
       
   207   // Make sure "cur" is a valid index.
       
   208   assert(cur >= 0, "Invariant.");
       
   209   HeapWord* res = alloc_obj_from_region_index(cur, word_size);
       
   210   if (res == NULL)
       
   211     res = alloc_obj_from_region_index(0, word_size);
       
   212   return res;
       
   213 }
       
   214 
       
   215 void HeapRegionSeq::iterate(HeapRegionClosure* blk) {
       
   216   iterate_from((HeapRegion*)NULL, blk);
       
   217 }
       
   218 
       
   219 // The first argument r is the heap region at which iteration begins.
       
   220 // This operation runs fastest when r is NULL, or the heap region for
       
   221 // which a HeapRegionClosure most recently returned true, or the
       
   222 // heap region immediately to its right in the sequence.  In all
       
   223 // other cases a linear search is required to find the index of r.
       
   224 
       
   225 void HeapRegionSeq::iterate_from(HeapRegion* r, HeapRegionClosure* blk) {
       
   226 
       
   227   // :::: FIXME ::::
       
   228   // Static cache value is bad, especially when we start doing parallel
       
   229   // remembered set update. For now just don't cache anything (the
       
   230   // code in the def'd out blocks).
       
   231 
       
   232 #if 0
       
   233   static int cached_j = 0;
       
   234 #endif
       
   235   int len = _regions.length();
       
   236   int j = 0;
       
   237   // Find the index of r.
       
   238   if (r != NULL) {
       
   239 #if 0
       
   240     assert(cached_j >= 0, "Invariant.");
       
   241     if ((cached_j < len) && (r == _regions.at(cached_j))) {
       
   242       j = cached_j;
       
   243     } else if ((cached_j + 1 < len) && (r == _regions.at(cached_j + 1))) {
       
   244       j = cached_j + 1;
       
   245     } else {
       
   246       j = find(r);
       
   247 #endif
       
   248       if (j < 0) {
       
   249         j = 0;
       
   250       }
       
   251 #if 0
       
   252     }
       
   253 #endif
       
   254   }
       
   255   int i;
       
   256   for (i = j; i < len; i += 1) {
       
   257     int res = blk->doHeapRegion(_regions.at(i));
       
   258     if (res) {
       
   259 #if 0
       
   260       cached_j = i;
       
   261 #endif
       
   262       blk->incomplete();
       
   263       return;
       
   264     }
       
   265   }
       
   266   for (i = 0; i < j; i += 1) {
       
   267     int res = blk->doHeapRegion(_regions.at(i));
       
   268     if (res) {
       
   269 #if 0
       
   270       cached_j = i;
       
   271 #endif
       
   272       blk->incomplete();
       
   273       return;
       
   274     }
       
   275   }
       
   276 }
       
   277 
       
   278 void HeapRegionSeq::iterate_from(int idx, HeapRegionClosure* blk) {
       
   279   int len = _regions.length();
       
   280   int i;
       
   281   for (i = idx; i < len; i++) {
       
   282     if (blk->doHeapRegion(_regions.at(i))) {
       
   283       blk->incomplete();
       
   284       return;
       
   285     }
       
   286   }
       
   287   for (i = 0; i < idx; i++) {
       
   288     if (blk->doHeapRegion(_regions.at(i))) {
       
   289       blk->incomplete();
       
   290       return;
       
   291     }
       
   292   }
       
   293 }
       
   294 
       
   295 MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes,
       
   296                                    size_t& num_regions_deleted) {
       
   297   assert(shrink_bytes % os::vm_page_size() == 0, "unaligned");
       
   298   assert(shrink_bytes % HeapRegion::GrainBytes == 0, "unaligned");
       
   299 
       
   300   if (_regions.length() == 0) {
       
   301     num_regions_deleted = 0;
       
   302     return MemRegion();
       
   303   }
       
   304   int j = _regions.length() - 1;
       
   305   HeapWord* end = _regions.at(j)->end();
       
   306   HeapWord* last_start = end;
       
   307   while (j >= 0 && shrink_bytes > 0) {
       
   308     HeapRegion* cur = _regions.at(j);
       
   309     // We have to leave humongous regions where they are,
       
   310     // and work around them.
       
   311     if (cur->isHumongous()) {
       
   312       return MemRegion(last_start, end);
       
   313     }
       
   314     cur->reset_zero_fill();
       
   315     assert(cur == _regions.top(), "Should be top");
       
   316     if (!cur->is_empty()) break;
       
   317     shrink_bytes -= cur->capacity();
       
   318     num_regions_deleted++;
       
   319     _regions.pop();
       
   320     last_start = cur->bottom();
       
   321     // We need to delete these somehow, but can't currently do so here: if
       
   322     // we do, the ZF thread may still access the deleted region.  We'll
       
   323     // leave this here as a reminder that we have to do something about
       
   324     // this.
       
   325     // delete cur;
       
   326     j--;
       
   327   }
       
   328   return MemRegion(last_start, end);
       
   329 }
       
   330 
       
   331 
       
   332 class PrintHeapRegionClosure : public  HeapRegionClosure {
       
   333 public:
       
   334   bool doHeapRegion(HeapRegion* r) {
       
   335     gclog_or_tty->print(PTR_FORMAT ":", r);
       
   336     r->print();
       
   337     return false;
       
   338   }
       
   339 };
       
   340 
       
   341 void HeapRegionSeq::print() {
       
   342   PrintHeapRegionClosure cl;
       
   343   iterate(&cl);
       
   344 }