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 #include "precompiled.hpp"
26 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
27 #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
28 #include "oops/markOop.inline.hpp"
29 #include "oops/oop.inline.hpp"
30
31 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
32
33 /////////////////////////////////////////////////////////////////////////
34 //// PromotionInfo
35 /////////////////////////////////////////////////////////////////////////
36
37
38 //////////////////////////////////////////////////////////////////////////////
39 // We go over the list of promoted objects, removing each from the list,
40 // and applying the closure (this may, in turn, add more elements to
41 // the tail of the promoted list, and these newly added objects will
42 // also be processed) until the list is empty.
43 // To aid verification and debugging, in the non-product builds
44 // we actually forward _promoHead each time we process a promoted oop.
45 // Note that this is not necessary in general (i.e. when we don't need to
46 // call PromotionInfo::verify()) because oop_iterate can only add to the
47 // end of _promoTail, and never needs to look at _promoHead.
48
49 #define PROMOTED_OOPS_ITERATE_DEFN(OopClosureType, nv_suffix) \
50 \
51 void PromotionInfo::promoted_oops_iterate##nv_suffix(OopClosureType* cl) { \
52 NOT_PRODUCT(verify()); \
53 PromotedObject *curObj, *nextObj; \
54 for (curObj = _promoHead; curObj != NULL; curObj = nextObj) { \
55 if ((nextObj = curObj->next()) == NULL) { \
56 /* protect ourselves against additions due to closure application \
57 below by resetting the list. */ \
58 assert(_promoTail == curObj, "Should have been the tail"); \
59 _promoHead = _promoTail = NULL; \
60 } \
61 if (curObj->hasDisplacedMark()) { \
62 /* restore displaced header */ \
63 oop(curObj)->set_mark(nextDisplacedHeader()); \
64 } else { \
65 /* restore prototypical header */ \
66 oop(curObj)->init_mark(); \
67 } \
68 /* The "promoted_mark" should now not be set */ \
69 assert(!curObj->hasPromotedMark(), \
70 "Should have been cleared by restoring displaced mark-word"); \
71 NOT_PRODUCT(_promoHead = nextObj); \
72 if (cl != NULL) oop(curObj)->oop_iterate(cl); \
73 if (nextObj == NULL) { /* start at head of list reset above */ \
74 nextObj = _promoHead; \
75 } \
76 } \
77 assert(noPromotions(), "post-condition violation"); \
78 assert(_promoHead == NULL && _promoTail == NULL, "emptied promoted list");\
79 assert(_spoolHead == _spoolTail, "emptied spooling buffers"); \
80 assert(_firstIndex == _nextIndex, "empty buffer"); \
81 }
82
83 // This should have been ALL_SINCE_...() just like the others,
84 // but, because the body of the method above is somehwat longer,
85 // the MSVC compiler cannot cope; as a workaround, we split the
86 // macro into its 3 constituent parts below (see original macro
87 // definition in specializedOopClosures.hpp).
88 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(PROMOTED_OOPS_ITERATE_DEFN)
89 PROMOTED_OOPS_ITERATE_DEFN(OopsInGenClosure,_v)
90
91
92 // Return the next displaced header, incrementing the pointer and
93 // recycling spool area as necessary.
94 markOop PromotionInfo::nextDisplacedHeader() {
95 assert(_spoolHead != NULL, "promotionInfo inconsistency");
96 assert(_spoolHead != _spoolTail || _firstIndex < _nextIndex,
97 "Empty spool space: no displaced header can be fetched");
98 assert(_spoolHead->bufferSize > _firstIndex, "Off by one error at head?");
99 markOop hdr = _spoolHead->displacedHdr[_firstIndex];
100 // Spool forward
101 if (++_firstIndex == _spoolHead->bufferSize) { // last location in this block
102 // forward to next block, recycling this block into spare spool buffer
103 SpoolBlock* tmp = _spoolHead->nextSpoolBlock;
104 assert(_spoolHead != _spoolTail, "Spooling storage mix-up");
105 _spoolHead->nextSpoolBlock = _spareSpool;
106 _spareSpool = _spoolHead;
107 _spoolHead = tmp;
108 _firstIndex = 1;
109 NOT_PRODUCT(
110 if (_spoolHead == NULL) { // all buffers fully consumed
111 assert(_spoolTail == NULL && _nextIndex == 1,
112 "spool buffers processing inconsistency");
113 }
114 )
115 }
116 return hdr;
117 }
118
119 void PromotionInfo::track(PromotedObject* trackOop) {
120 track(trackOop, oop(trackOop)->klass());
121 }
122
123 void PromotionInfo::track(PromotedObject* trackOop, Klass* klassOfOop) {
124 // make a copy of header as it may need to be spooled
125 markOop mark = oop(trackOop)->mark();
126 trackOop->clear_next();
127 if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) {
128 // save non-prototypical header, and mark oop
129 saveDisplacedHeader(mark);
130 trackOop->setDisplacedMark();
131 } else {
132 // we'd like to assert something like the following:
133 // assert(mark == markOopDesc::prototype(), "consistency check");
134 // ... but the above won't work because the age bits have not (yet) been
135 // cleared. The remainder of the check would be identical to the
136 // condition checked in must_be_preserved() above, so we don't really
137 // have anything useful to check here!
138 }
|
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 #include "precompiled.hpp"
26 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
27 #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
28 #include "oops/markOop.inline.hpp"
29 #include "oops/oop.inline.hpp"
30
31 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
32
33 /////////////////////////////////////////////////////////////////////////
34 //// PromotionInfo
35 /////////////////////////////////////////////////////////////////////////
36
37 void PromotionInfo::track(PromotedObject* trackOop) {
38 track(trackOop, oop(trackOop)->klass());
39 }
40
41 void PromotionInfo::track(PromotedObject* trackOop, Klass* klassOfOop) {
42 // make a copy of header as it may need to be spooled
43 markOop mark = oop(trackOop)->mark();
44 trackOop->clear_next();
45 if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) {
46 // save non-prototypical header, and mark oop
47 saveDisplacedHeader(mark);
48 trackOop->setDisplacedMark();
49 } else {
50 // we'd like to assert something like the following:
51 // assert(mark == markOopDesc::prototype(), "consistency check");
52 // ... but the above won't work because the age bits have not (yet) been
53 // cleared. The remainder of the check would be identical to the
54 // condition checked in must_be_preserved() above, so we don't really
55 // have anything useful to check here!
56 }
|