1109 oop ParNewGeneration::real_forwardee(oop obj) {
1110 oop forward_ptr = obj->forwardee();
1111 if (forward_ptr != ClaimedForwardPtr) {
1112 return forward_ptr;
1113 } else {
1114 return real_forwardee_slow(obj);
1115 }
1116 }
1117
1118 oop ParNewGeneration::real_forwardee_slow(oop obj) {
1119 // Spin-read if it is claimed but not yet written by another thread.
1120 oop forward_ptr = obj->forwardee();
1121 while (forward_ptr == ClaimedForwardPtr) {
1122 waste_some_time();
1123 assert(obj->is_forwarded(), "precondition");
1124 forward_ptr = obj->forwardee();
1125 }
1126 return forward_ptr;
1127 }
1128
1129 #ifdef ASSERT
1130 bool ParNewGeneration::is_legal_forward_ptr(oop p) {
1131 return
1132 (p == ClaimedForwardPtr)
1133 || Universe::heap()->is_in_reserved(p);
1134 }
1135 #endif
1136
1137 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
1138 if (m->must_be_preserved_for_promotion_failure(obj)) {
1139 // We should really have separate per-worker stacks, rather
1140 // than use locking of a common pair of stacks.
1141 MutexLocker ml(ParGCRareEvent_lock);
1142 preserve_mark(obj, m);
1143 }
1144 }
1145
1146 // Multiple GC threads may try to promote an object. If the object
1147 // is successfully promoted, a forwarding pointer will be installed in
1148 // the object in the young generation. This method claims the right
1149 // to install the forwarding pointer before it copies the object,
1150 // thus avoiding the need to undo the copy as in
1151 // copy_to_survivor_space_avoiding_with_undo.
1152
1153 oop ParNewGeneration::copy_to_survivor_space(
1154 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
1155 // In the sequential version, this assert also says that the object is
1156 // not forwarded. That might not be the case here. It is the case that
1191
1192 if (!_promotion_failed) {
1193 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1194 old, m, sz);
1195 }
1196
1197 if (new_obj == NULL) {
1198 // promotion failed, forward to self
1199 _promotion_failed = true;
1200 new_obj = old;
1201
1202 preserve_mark_if_necessary(old, m);
1203 par_scan_state->register_promotion_failure(sz);
1204 }
1205
1206 old->forward_to(new_obj);
1207 forward_ptr = NULL;
1208 } else {
1209 // Is in to-space; do copying ourselves.
1210 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1211 forward_ptr = old->forward_to_atomic(new_obj);
1212 // Restore the mark word copied above.
1213 new_obj->set_mark(m);
1214 // Increment age if obj still in new generation
1215 new_obj->incr_age();
1216 par_scan_state->age_table()->add(new_obj, sz);
1217 }
1218 assert(new_obj != NULL, "just checking");
1219
1220 #ifndef PRODUCT
1221 // This code must come after the CAS test, or it will print incorrect
1222 // information.
1223 if (TraceScavenge) {
1224 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
1225 is_in_reserved(new_obj) ? "copying" : "tenuring",
1226 new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
1227 }
1228 #endif
1229
1230 if (forward_ptr == NULL) {
|
1109 oop ParNewGeneration::real_forwardee(oop obj) {
1110 oop forward_ptr = obj->forwardee();
1111 if (forward_ptr != ClaimedForwardPtr) {
1112 return forward_ptr;
1113 } else {
1114 return real_forwardee_slow(obj);
1115 }
1116 }
1117
1118 oop ParNewGeneration::real_forwardee_slow(oop obj) {
1119 // Spin-read if it is claimed but not yet written by another thread.
1120 oop forward_ptr = obj->forwardee();
1121 while (forward_ptr == ClaimedForwardPtr) {
1122 waste_some_time();
1123 assert(obj->is_forwarded(), "precondition");
1124 forward_ptr = obj->forwardee();
1125 }
1126 return forward_ptr;
1127 }
1128
1129 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
1130 if (m->must_be_preserved_for_promotion_failure(obj)) {
1131 // We should really have separate per-worker stacks, rather
1132 // than use locking of a common pair of stacks.
1133 MutexLocker ml(ParGCRareEvent_lock);
1134 preserve_mark(obj, m);
1135 }
1136 }
1137
1138 // Multiple GC threads may try to promote an object. If the object
1139 // is successfully promoted, a forwarding pointer will be installed in
1140 // the object in the young generation. This method claims the right
1141 // to install the forwarding pointer before it copies the object,
1142 // thus avoiding the need to undo the copy as in
1143 // copy_to_survivor_space_avoiding_with_undo.
1144
1145 oop ParNewGeneration::copy_to_survivor_space(
1146 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
1147 // In the sequential version, this assert also says that the object is
1148 // not forwarded. That might not be the case here. It is the case that
1183
1184 if (!_promotion_failed) {
1185 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1186 old, m, sz);
1187 }
1188
1189 if (new_obj == NULL) {
1190 // promotion failed, forward to self
1191 _promotion_failed = true;
1192 new_obj = old;
1193
1194 preserve_mark_if_necessary(old, m);
1195 par_scan_state->register_promotion_failure(sz);
1196 }
1197
1198 old->forward_to(new_obj);
1199 forward_ptr = NULL;
1200 } else {
1201 // Is in to-space; do copying ourselves.
1202 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1203 assert(Universe::heap()->is_in_reserved(new_obj), "illegal forwarding pointer value.");
1204 forward_ptr = old->forward_to_atomic(new_obj);
1205 // Restore the mark word copied above.
1206 new_obj->set_mark(m);
1207 // Increment age if obj still in new generation
1208 new_obj->incr_age();
1209 par_scan_state->age_table()->add(new_obj, sz);
1210 }
1211 assert(new_obj != NULL, "just checking");
1212
1213 #ifndef PRODUCT
1214 // This code must come after the CAS test, or it will print incorrect
1215 // information.
1216 if (TraceScavenge) {
1217 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
1218 is_in_reserved(new_obj) ? "copying" : "tenuring",
1219 new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
1220 }
1221 #endif
1222
1223 if (forward_ptr == NULL) {
|