1 /* 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP 27 28 #include "gc_implementation/g1/heapRegion.hpp" 29 #include "utilities/growableArray.hpp" 30 31 // We need to sort heap regions by collection desirability. 32 33 class CSetChooserCache VALUE_OBJ_CLASS_SPEC { 34 private: 35 enum { 36 CacheLength = 16 37 } PrivateConstants; 38 39 HeapRegion* _cache[CacheLength]; 40 int _occupancy; // number of region in cache 41 int _first; // "first" region in the cache 42 43 // adding CacheLength to deal with negative values 44 inline int trim_index(int index) { 45 return (index + CacheLength) % CacheLength; 46 } 47 48 inline int get_sort_index(int index) { 49 return -index-2; 50 } 51 inline int get_index(int sort_index) { 52 return -sort_index-2; 53 } 54 55 public: 56 CSetChooserCache(void); 57 58 inline int occupancy(void) { return _occupancy; } 59 inline bool is_full() { return _occupancy == CacheLength; } 60 inline bool is_empty() { return _occupancy == 0; } 61 62 void clear(void); 63 void insert(HeapRegion *hr); 64 HeapRegion *remove_first(void); 65 void remove (HeapRegion *hr); 66 inline HeapRegion *get_first(void) { 67 return _cache[_first]; 68 } 69 70 #ifndef PRODUCT 71 bool verify (void); 72 bool region_in_cache(HeapRegion *hr) { 73 int sort_index = hr->sort_index(); 74 if (sort_index < -1) { 75 int index = get_index(sort_index); 76 guarantee(index < CacheLength, "should be within bounds"); 77 return _cache[index] == hr; 78 } else 79 return 0; 80 } 81 #endif // PRODUCT 82 }; 83 84 class CollectionSetChooser: public CHeapObj { 85 86 GrowableArray<HeapRegion*> _markedRegions; 87 int _curMarkedIndex; 88 int _numMarkedRegions; 89 CSetChooserCache _cache; 90 91 // True iff last collection pause ran of out new "age 0" regions, and 92 // returned an "age 1" region. 93 bool _unmarked_age_1_returned_as_new; 94 95 jint _first_par_unreserved_idx; 96 97 public: 98 99 HeapRegion* getNextMarkedRegion(double time_so_far, double avg_prediction); 100 101 CollectionSetChooser(); 102 103 void printSortedHeapRegions(); 104 105 void sortMarkedHeapRegions(); 106 void fillCache(); 107 bool addRegionToCache(void); 108 void addMarkedHeapRegion(HeapRegion *hr); 109 110 // Must be called before calls to getParMarkedHeapRegionChunk. 111 // "n_regions" is the number of regions, "chunkSize" the chunk size. 112 void prepareForAddMarkedHeapRegionsPar(size_t n_regions, size_t chunkSize); 113 // Returns the first index in a contiguous chunk of "n_regions" indexes 114 // that the calling thread has reserved. These must be set by the 115 // calling thread using "setMarkedHeapRegion" (to NULL if necessary). 116 jint getParMarkedHeapRegionChunk(jint n_regions); 117 // Set the marked array entry at index to hr. Careful to claim the index 118 // first if in parallel. 119 void setMarkedHeapRegion(jint index, HeapRegion* hr); 120 // Atomically increment the number of claimed regions by "inc_by". 121 void incNumMarkedHeapRegions(jint inc_by); 122 123 void clearMarkedHeapRegions(); 124 125 void updateAfterFullCollection(); 126 127 // Ensure that "hr" is not a member of the marked region array or the cache 128 void removeRegion(HeapRegion* hr); 129 130 bool unmarked_age_1_returned_as_new() { return _unmarked_age_1_returned_as_new; } 131 132 // Returns true if the used portion of "_markedRegions" is properly 133 // sorted, otherwise asserts false. 134 #ifndef PRODUCT 135 bool verify(void); 136 bool regionProperlyOrdered(HeapRegion* r) { 137 int si = r->sort_index(); 138 return (si == -1) || 139 (si > -1 && _markedRegions.at(si) == r) || 140 (si < -1 && _cache.region_in_cache(r)); 141 } 142 #endif 143 144 }; 145 146 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP