ysr@777: /* stefank@2314: * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. ysr@777: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ysr@777: * ysr@777: * This code is free software; you can redistribute it and/or modify it ysr@777: * under the terms of the GNU General Public License version 2 only, as ysr@777: * published by the Free Software Foundation. ysr@777: * ysr@777: * This code is distributed in the hope that it will be useful, but WITHOUT ysr@777: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ysr@777: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ysr@777: * version 2 for more details (a copy is included in the LICENSE file that ysr@777: * accompanied this code). ysr@777: * ysr@777: * You should have received a copy of the GNU General Public License version ysr@777: * 2 along with this work; if not, write to the Free Software Foundation, ysr@777: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ysr@777: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. ysr@777: * ysr@777: */ ysr@777: stefank@2314: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP stefank@2314: #define SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP stefank@2314: stefank@2314: #include "gc_implementation/g1/heapRegion.hpp" stefank@2314: #include "utilities/growableArray.hpp" stefank@2314: ysr@777: // We need to sort heap regions by collection desirability. ysr@777: apetrusenko@984: class CSetChooserCache VALUE_OBJ_CLASS_SPEC { ysr@777: private: ysr@777: enum { ysr@777: CacheLength = 16 ysr@777: } PrivateConstants; ysr@777: ysr@777: HeapRegion* _cache[CacheLength]; ysr@777: int _occupancy; // number of region in cache ysr@777: int _first; // "first" region in the cache ysr@777: ysr@777: // adding CacheLength to deal with negative values ysr@777: inline int trim_index(int index) { ysr@777: return (index + CacheLength) % CacheLength; ysr@777: } ysr@777: ysr@777: inline int get_sort_index(int index) { ysr@777: return -index-2; ysr@777: } ysr@777: inline int get_index(int sort_index) { ysr@777: return -sort_index-2; ysr@777: } ysr@777: ysr@777: public: ysr@777: CSetChooserCache(void); ysr@777: ysr@777: inline int occupancy(void) { return _occupancy; } ysr@777: inline bool is_full() { return _occupancy == CacheLength; } ysr@777: inline bool is_empty() { return _occupancy == 0; } ysr@777: ysr@777: void clear(void); ysr@777: void insert(HeapRegion *hr); ysr@777: HeapRegion *remove_first(void); ysr@777: void remove (HeapRegion *hr); ysr@777: inline HeapRegion *get_first(void) { ysr@777: return _cache[_first]; ysr@777: } ysr@777: ysr@777: #ifndef PRODUCT ysr@777: bool verify (void); ysr@777: bool region_in_cache(HeapRegion *hr) { ysr@777: int sort_index = hr->sort_index(); ysr@777: if (sort_index < -1) { ysr@777: int index = get_index(sort_index); ysr@777: guarantee(index < CacheLength, "should be within bounds"); ysr@777: return _cache[index] == hr; ysr@777: } else ysr@777: return 0; ysr@777: } ysr@777: #endif // PRODUCT ysr@777: }; ysr@777: ysr@777: class CollectionSetChooser: public CHeapObj { ysr@777: ysr@777: GrowableArray _markedRegions; ysr@777: int _curMarkedIndex; ysr@777: int _numMarkedRegions; ysr@777: CSetChooserCache _cache; ysr@777: ysr@777: // True iff last collection pause ran of out new "age 0" regions, and ysr@777: // returned an "age 1" region. ysr@777: bool _unmarked_age_1_returned_as_new; ysr@777: ysr@777: jint _first_par_unreserved_idx; ysr@777: ysr@777: public: ysr@777: ysr@777: HeapRegion* getNextMarkedRegion(double time_so_far, double avg_prediction); ysr@777: ysr@777: CollectionSetChooser(); ysr@777: ysr@777: void printSortedHeapRegions(); ysr@777: ysr@777: void sortMarkedHeapRegions(); ysr@777: void fillCache(); ysr@777: bool addRegionToCache(void); ysr@777: void addMarkedHeapRegion(HeapRegion *hr); ysr@777: ysr@777: // Must be called before calls to getParMarkedHeapRegionChunk. ysr@777: // "n_regions" is the number of regions, "chunkSize" the chunk size. ysr@777: void prepareForAddMarkedHeapRegionsPar(size_t n_regions, size_t chunkSize); ysr@777: // Returns the first index in a contiguous chunk of "n_regions" indexes ysr@777: // that the calling thread has reserved. These must be set by the ysr@777: // calling thread using "setMarkedHeapRegion" (to NULL if necessary). ysr@777: jint getParMarkedHeapRegionChunk(jint n_regions); ysr@777: // Set the marked array entry at index to hr. Careful to claim the index ysr@777: // first if in parallel. ysr@777: void setMarkedHeapRegion(jint index, HeapRegion* hr); ysr@777: // Atomically increment the number of claimed regions by "inc_by". ysr@777: void incNumMarkedHeapRegions(jint inc_by); ysr@777: ysr@777: void clearMarkedHeapRegions(); ysr@777: ysr@777: void updateAfterFullCollection(); ysr@777: ysr@777: // Ensure that "hr" is not a member of the marked region array or the cache ysr@777: void removeRegion(HeapRegion* hr); ysr@777: ysr@777: bool unmarked_age_1_returned_as_new() { return _unmarked_age_1_returned_as_new; } ysr@777: ysr@777: // Returns true if the used portion of "_markedRegions" is properly ysr@777: // sorted, otherwise asserts false. ysr@777: #ifndef PRODUCT ysr@777: bool verify(void); ysr@777: bool regionProperlyOrdered(HeapRegion* r) { ysr@777: int si = r->sort_index(); ysr@777: return (si == -1) || ysr@777: (si > -1 && _markedRegions.at(si) == r) || ysr@777: (si < -1 && _cache.region_in_cache(r)); ysr@777: } ysr@777: #endif ysr@777: ysr@777: }; stefank@2314: stefank@2314: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP