Mon, 10 May 2010 12:31:52 -0700
6951188: CMS: move PromotionInfo into its own file
Summary: Moved PromotionInfo and friends into new files promotionInfo.{h,c}pp from their previous compactibleFreeListSpace.{h,c}pp home.
Reviewed-by: apetrusenko
ysr@1876 | 1 | /* |
ysr@1876 | 2 | * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved. |
ysr@1876 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ysr@1876 | 4 | * |
ysr@1876 | 5 | * This code is free software; you can redistribute it and/or modify it |
ysr@1876 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ysr@1876 | 7 | * published by the Free Software Foundation. |
ysr@1876 | 8 | * |
ysr@1876 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ysr@1876 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ysr@1876 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ysr@1876 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
ysr@1876 | 13 | * accompanied this code). |
ysr@1876 | 14 | * |
ysr@1876 | 15 | * You should have received a copy of the GNU General Public License version |
ysr@1876 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
ysr@1876 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ysr@1876 | 18 | * |
ysr@1876 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
ysr@1876 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
ysr@1876 | 21 | * have any questions. |
ysr@1876 | 22 | * |
ysr@1876 | 23 | */ |
ysr@1876 | 24 | |
ysr@1876 | 25 | // Forward declarations |
ysr@1876 | 26 | class CompactibleFreeListSpace; |
ysr@1876 | 27 | |
ysr@1876 | 28 | class PromotedObject VALUE_OBJ_CLASS_SPEC { |
ysr@1876 | 29 | private: |
ysr@1876 | 30 | enum { |
ysr@1876 | 31 | promoted_mask = right_n_bits(2), // i.e. 0x3 |
ysr@1876 | 32 | displaced_mark = nth_bit(2), // i.e. 0x4 |
ysr@1876 | 33 | next_mask = ~(right_n_bits(3)) // i.e. ~(0x7) |
ysr@1876 | 34 | }; |
ysr@1876 | 35 | intptr_t _next; |
ysr@1876 | 36 | public: |
ysr@1876 | 37 | inline PromotedObject* next() const { |
ysr@1876 | 38 | return (PromotedObject*)(_next & next_mask); |
ysr@1876 | 39 | } |
ysr@1876 | 40 | inline void setNext(PromotedObject* x) { |
ysr@1876 | 41 | assert(((intptr_t)x & ~next_mask) == 0, |
ysr@1876 | 42 | "Conflict in bit usage, " |
ysr@1876 | 43 | " or insufficient alignment of objects"); |
ysr@1876 | 44 | _next |= (intptr_t)x; |
ysr@1876 | 45 | } |
ysr@1876 | 46 | inline void setPromotedMark() { |
ysr@1876 | 47 | _next |= promoted_mask; |
ysr@1876 | 48 | } |
ysr@1876 | 49 | inline bool hasPromotedMark() const { |
ysr@1876 | 50 | return (_next & promoted_mask) == promoted_mask; |
ysr@1876 | 51 | } |
ysr@1876 | 52 | inline void setDisplacedMark() { |
ysr@1876 | 53 | _next |= displaced_mark; |
ysr@1876 | 54 | } |
ysr@1876 | 55 | inline bool hasDisplacedMark() const { |
ysr@1876 | 56 | return (_next & displaced_mark) != 0; |
ysr@1876 | 57 | } |
ysr@1876 | 58 | inline void clearNext() { _next = 0; } |
ysr@1876 | 59 | debug_only(void *next_addr() { return (void *) &_next; }) |
ysr@1876 | 60 | }; |
ysr@1876 | 61 | |
ysr@1876 | 62 | class SpoolBlock: public FreeChunk { |
ysr@1876 | 63 | friend class PromotionInfo; |
ysr@1876 | 64 | protected: |
ysr@1876 | 65 | SpoolBlock* nextSpoolBlock; |
ysr@1876 | 66 | size_t bufferSize; // number of usable words in this block |
ysr@1876 | 67 | markOop* displacedHdr; // the displaced headers start here |
ysr@1876 | 68 | |
ysr@1876 | 69 | // Note about bufferSize: it denotes the number of entries available plus 1; |
ysr@1876 | 70 | // legal indices range from 1 through BufferSize - 1. See the verification |
ysr@1876 | 71 | // code verify() that counts the number of displaced headers spooled. |
ysr@1876 | 72 | size_t computeBufferSize() { |
ysr@1876 | 73 | return (size() * sizeof(HeapWord) - sizeof(*this)) / sizeof(markOop); |
ysr@1876 | 74 | } |
ysr@1876 | 75 | |
ysr@1876 | 76 | public: |
ysr@1876 | 77 | void init() { |
ysr@1876 | 78 | bufferSize = computeBufferSize(); |
ysr@1876 | 79 | displacedHdr = (markOop*)&displacedHdr; |
ysr@1876 | 80 | nextSpoolBlock = NULL; |
ysr@1876 | 81 | } |
ysr@1876 | 82 | |
ysr@1876 | 83 | void print_on(outputStream* st) const; |
ysr@1876 | 84 | void print() const { print_on(gclog_or_tty); } |
ysr@1876 | 85 | }; |
ysr@1876 | 86 | |
ysr@1876 | 87 | class PromotionInfo VALUE_OBJ_CLASS_SPEC { |
ysr@1876 | 88 | bool _tracking; // set if tracking |
ysr@1876 | 89 | CompactibleFreeListSpace* _space; // the space to which this belongs |
ysr@1876 | 90 | PromotedObject* _promoHead; // head of list of promoted objects |
ysr@1876 | 91 | PromotedObject* _promoTail; // tail of list of promoted objects |
ysr@1876 | 92 | SpoolBlock* _spoolHead; // first spooling block |
ysr@1876 | 93 | SpoolBlock* _spoolTail; // last non-full spooling block or null |
ysr@1876 | 94 | SpoolBlock* _splice_point; // when _spoolTail is null, holds list tail |
ysr@1876 | 95 | SpoolBlock* _spareSpool; // free spool buffer |
ysr@1876 | 96 | size_t _firstIndex; // first active index in |
ysr@1876 | 97 | // first spooling block (_spoolHead) |
ysr@1876 | 98 | size_t _nextIndex; // last active index + 1 in last |
ysr@1876 | 99 | // spooling block (_spoolTail) |
ysr@1876 | 100 | private: |
ysr@1876 | 101 | // ensure that spooling space exists; return true if there is spooling space |
ysr@1876 | 102 | bool ensure_spooling_space_work(); |
ysr@1876 | 103 | |
ysr@1876 | 104 | public: |
ysr@1876 | 105 | PromotionInfo() : |
ysr@1876 | 106 | _tracking(0), _space(NULL), |
ysr@1876 | 107 | _promoHead(NULL), _promoTail(NULL), |
ysr@1876 | 108 | _spoolHead(NULL), _spoolTail(NULL), |
ysr@1876 | 109 | _spareSpool(NULL), _firstIndex(1), |
ysr@1876 | 110 | _nextIndex(1) {} |
ysr@1876 | 111 | |
ysr@1876 | 112 | bool noPromotions() const { |
ysr@1876 | 113 | assert(_promoHead != NULL || _promoTail == NULL, "list inconsistency"); |
ysr@1876 | 114 | return _promoHead == NULL; |
ysr@1876 | 115 | } |
ysr@1876 | 116 | void startTrackingPromotions(); |
ysr@1876 | 117 | void stopTrackingPromotions(uint worker_id = 0); |
ysr@1876 | 118 | bool tracking() const { return _tracking; } |
ysr@1876 | 119 | void track(PromotedObject* trackOop); // keep track of a promoted oop |
ysr@1876 | 120 | // The following variant must be used when trackOop is not fully |
ysr@1876 | 121 | // initialized and has a NULL klass: |
ysr@1876 | 122 | void track(PromotedObject* trackOop, klassOop klassOfOop); // keep track of a promoted oop |
ysr@1876 | 123 | void setSpace(CompactibleFreeListSpace* sp) { _space = sp; } |
ysr@1876 | 124 | CompactibleFreeListSpace* space() const { return _space; } |
ysr@1876 | 125 | markOop nextDisplacedHeader(); // get next header & forward spool pointer |
ysr@1876 | 126 | void saveDisplacedHeader(markOop hdr); |
ysr@1876 | 127 | // save header and forward spool |
ysr@1876 | 128 | |
ysr@1876 | 129 | inline size_t refillSize() const; |
ysr@1876 | 130 | |
ysr@1876 | 131 | SpoolBlock* getSpoolBlock(); // return a free spooling block |
ysr@1876 | 132 | inline bool has_spooling_space() { |
ysr@1876 | 133 | return _spoolTail != NULL && _spoolTail->bufferSize > _nextIndex; |
ysr@1876 | 134 | } |
ysr@1876 | 135 | // ensure that spooling space exists |
ysr@1876 | 136 | bool ensure_spooling_space() { |
ysr@1876 | 137 | return has_spooling_space() || ensure_spooling_space_work(); |
ysr@1876 | 138 | } |
ysr@1876 | 139 | #define PROMOTED_OOPS_ITERATE_DECL(OopClosureType, nv_suffix) \ |
ysr@1876 | 140 | void promoted_oops_iterate##nv_suffix(OopClosureType* cl); |
ysr@1876 | 141 | ALL_SINCE_SAVE_MARKS_CLOSURES(PROMOTED_OOPS_ITERATE_DECL) |
ysr@1876 | 142 | #undef PROMOTED_OOPS_ITERATE_DECL |
ysr@1876 | 143 | void promoted_oops_iterate(OopsInGenClosure* cl) { |
ysr@1876 | 144 | promoted_oops_iterate_v(cl); |
ysr@1876 | 145 | } |
ysr@1876 | 146 | void verify() const; |
ysr@1876 | 147 | void reset() { |
ysr@1876 | 148 | _promoHead = NULL; |
ysr@1876 | 149 | _promoTail = NULL; |
ysr@1876 | 150 | _spoolHead = NULL; |
ysr@1876 | 151 | _spoolTail = NULL; |
ysr@1876 | 152 | _spareSpool = NULL; |
ysr@1876 | 153 | _firstIndex = 0; |
ysr@1876 | 154 | _nextIndex = 0; |
ysr@1876 | 155 | |
ysr@1876 | 156 | } |
ysr@1876 | 157 | |
ysr@1876 | 158 | void print_on(outputStream* st) const; |
ysr@1876 | 159 | void print_statistics(uint worker_id) const; |
ysr@1876 | 160 | }; |
ysr@1876 | 161 |