src/share/vm/gc_implementation/g1/collectionSetChooser.hpp

Tue, 10 Jan 2012 18:58:13 -0500

author
tonyp
date
Tue, 10 Jan 2012 18:58:13 -0500
changeset 3416
2ace1c4ee8da
parent 3185
b9390528617c
child 3539
a9647476d1a4
permissions
-rw-r--r--

6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
Summary: This change simplifies the interaction between GC and concurrent marking. By disabling survivor spaces during the initial-mark pause we don't need to propagate marks of objects we copy during each GC (since we never need to copy an explicitly marked object).
Reviewed-by: johnc, brutisso

ysr@777 1 /*
ysr@3185 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
stefank@2314 27
stefank@2314 28 #include "gc_implementation/g1/heapRegion.hpp"
stefank@2314 29 #include "utilities/growableArray.hpp"
stefank@2314 30
ysr@777 31 // We need to sort heap regions by collection desirability.
ysr@3185 32 // This sorting is currently done in two "stages". An initial sort is
ysr@3185 33 // done following a cleanup pause as soon as all of the marked but
ysr@3185 34 // non-empty regions have been identified and the completely empty
ysr@3185 35 // ones reclaimed.
ysr@3185 36 // This gives us a global sort on a GC efficiency metric
ysr@3185 37 // based on predictive data available at that time. However,
ysr@3185 38 // any of these regions that are collected will only be collected
ysr@3185 39 // during a future GC pause, by which time it is possible that newer
ysr@3185 40 // data might allow us to revise and/or refine the earlier
ysr@3185 41 // pause predictions, leading to changes in expected gc efficiency
ysr@3185 42 // order. To somewhat mitigate this obsolescence, more so in the
ysr@3185 43 // case of regions towards the end of the list, which will be
ysr@3185 44 // picked later, these pre-sorted regions from the _markedRegions
ysr@3185 45 // array are not used as is, but a small prefix thereof is
ysr@3185 46 // insertion-sorted again into a small cache, based on more
ysr@3185 47 // recent remembered set information. Regions are then drawn
ysr@3185 48 // from this cache to construct the collection set at each
ysr@3185 49 // incremental GC.
ysr@3185 50 // This scheme and/or its implementation may be subject to
ysr@3185 51 // revision in the future.
ysr@777 52
apetrusenko@984 53 class CSetChooserCache VALUE_OBJ_CLASS_SPEC {
ysr@777 54 private:
ysr@777 55 enum {
ysr@777 56 CacheLength = 16
ysr@777 57 } PrivateConstants;
ysr@777 58
ysr@777 59 HeapRegion* _cache[CacheLength];
ysr@3185 60 int _occupancy; // number of regions in cache
ysr@3185 61 int _first; // (index of) "first" region in the cache
ysr@777 62
ysr@777 63 // adding CacheLength to deal with negative values
ysr@777 64 inline int trim_index(int index) {
ysr@777 65 return (index + CacheLength) % CacheLength;
ysr@777 66 }
ysr@777 67
ysr@777 68 inline int get_sort_index(int index) {
ysr@777 69 return -index-2;
ysr@777 70 }
ysr@777 71 inline int get_index(int sort_index) {
ysr@777 72 return -sort_index-2;
ysr@777 73 }
ysr@777 74
ysr@777 75 public:
ysr@777 76 CSetChooserCache(void);
ysr@777 77
ysr@777 78 inline int occupancy(void) { return _occupancy; }
ysr@777 79 inline bool is_full() { return _occupancy == CacheLength; }
ysr@777 80 inline bool is_empty() { return _occupancy == 0; }
ysr@777 81
ysr@777 82 void clear(void);
ysr@777 83 void insert(HeapRegion *hr);
ysr@777 84 HeapRegion *remove_first(void);
ysr@777 85 inline HeapRegion *get_first(void) {
ysr@777 86 return _cache[_first];
ysr@777 87 }
ysr@777 88
ysr@777 89 #ifndef PRODUCT
ysr@777 90 bool verify (void);
ysr@777 91 bool region_in_cache(HeapRegion *hr) {
ysr@777 92 int sort_index = hr->sort_index();
ysr@777 93 if (sort_index < -1) {
ysr@777 94 int index = get_index(sort_index);
ysr@777 95 guarantee(index < CacheLength, "should be within bounds");
ysr@777 96 return _cache[index] == hr;
ysr@777 97 } else
ysr@777 98 return 0;
ysr@777 99 }
ysr@777 100 #endif // PRODUCT
ysr@777 101 };
ysr@777 102
ysr@777 103 class CollectionSetChooser: public CHeapObj {
ysr@777 104
ysr@777 105 GrowableArray<HeapRegion*> _markedRegions;
ysr@777 106 int _curMarkedIndex;
ysr@777 107 int _numMarkedRegions;
ysr@777 108 CSetChooserCache _cache;
ysr@777 109
ysr@777 110 // True iff last collection pause ran of out new "age 0" regions, and
ysr@777 111 // returned an "age 1" region.
ysr@777 112 bool _unmarked_age_1_returned_as_new;
ysr@777 113
ysr@777 114 jint _first_par_unreserved_idx;
ysr@777 115
ysr@777 116 public:
ysr@777 117
ysr@777 118 HeapRegion* getNextMarkedRegion(double time_so_far, double avg_prediction);
ysr@777 119
ysr@777 120 CollectionSetChooser();
ysr@777 121
ysr@777 122 void sortMarkedHeapRegions();
ysr@777 123 void fillCache();
ysr@777 124 void addMarkedHeapRegion(HeapRegion *hr);
ysr@777 125
ysr@777 126 // Must be called before calls to getParMarkedHeapRegionChunk.
ysr@777 127 // "n_regions" is the number of regions, "chunkSize" the chunk size.
ysr@777 128 void prepareForAddMarkedHeapRegionsPar(size_t n_regions, size_t chunkSize);
ysr@777 129 // Returns the first index in a contiguous chunk of "n_regions" indexes
ysr@777 130 // that the calling thread has reserved. These must be set by the
ysr@777 131 // calling thread using "setMarkedHeapRegion" (to NULL if necessary).
ysr@777 132 jint getParMarkedHeapRegionChunk(jint n_regions);
ysr@777 133 // Set the marked array entry at index to hr. Careful to claim the index
ysr@777 134 // first if in parallel.
ysr@777 135 void setMarkedHeapRegion(jint index, HeapRegion* hr);
ysr@777 136 // Atomically increment the number of claimed regions by "inc_by".
ysr@777 137 void incNumMarkedHeapRegions(jint inc_by);
ysr@777 138
ysr@777 139 void clearMarkedHeapRegions();
ysr@777 140
ysr@777 141 void updateAfterFullCollection();
ysr@777 142
ysr@777 143 bool unmarked_age_1_returned_as_new() { return _unmarked_age_1_returned_as_new; }
ysr@777 144
ysr@777 145 // Returns true if the used portion of "_markedRegions" is properly
ysr@777 146 // sorted, otherwise asserts false.
ysr@777 147 #ifndef PRODUCT
ysr@777 148 bool verify(void);
ysr@777 149 bool regionProperlyOrdered(HeapRegion* r) {
ysr@777 150 int si = r->sort_index();
ysr@777 151 return (si == -1) ||
ysr@777 152 (si > -1 && _markedRegions.at(si) == r) ||
ysr@777 153 (si < -1 && _cache.region_in_cache(r));
ysr@777 154 }
ysr@777 155 #endif
ysr@777 156
ysr@777 157 };
stefank@2314 158
stefank@2314 159 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP

mercurial