39
40 template <class T>
41 inline void PSPromotionManager::claim_or_forward_internal_depth(T* p) {
42 if (p != NULL) { // XXX: error if p != NULL here
43 oop o = oopDesc::load_decode_heap_oop_not_null(p);
44 if (o->is_forwarded()) {
45 o = o->forwardee();
46 // Card mark
47 if (PSScavenge::is_obj_in_young(o)) {
48 PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
49 }
50 oopDesc::encode_store_heap_oop_not_null(p, o);
51 } else {
52 push_depth(p);
53 }
54 }
55 }
56
57 template <class T>
58 inline void PSPromotionManager::claim_or_forward_depth(T* p) {
59 assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
60 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap,
61 "Sanity");
62 assert(Universe::heap()->is_in(p), "pointer outside heap");
63
64 claim_or_forward_internal_depth(p);
65 }
66
67 inline void PSPromotionManager::promotion_trace_event(oop new_obj, oop old_obj,
68 size_t obj_size,
69 uint age, bool tenured,
70 const PSPromotionLAB* lab) {
71 // Skip if memory allocation failed
72 if (new_obj != NULL) {
73 const ParallelScavengeTracer* gc_tracer = PSScavenge::gc_tracer();
74
75 if (lab != NULL) {
76 // Promotion of object through newly allocated PLAB
77 if (gc_tracer->should_report_promotion_in_new_plab_event()) {
78 size_t obj_bytes = obj_size * HeapWordSize;
79 size_t lab_size = lab->capacity();
81 age, tenured, lab_size);
82 }
83 } else {
84 // Promotion of object directly to heap
85 if (gc_tracer->should_report_promotion_outside_plab_event()) {
86 size_t obj_bytes = obj_size * HeapWordSize;
87 gc_tracer->report_promotion_outside_plab_event(old_obj->klass(), obj_bytes,
88 age, tenured);
89 }
90 }
91 }
92 }
93
94 //
95 // This method is pretty bulky. It would be nice to split it up
96 // into smaller submethods, but we need to be careful not to hurt
97 // performance.
98 //
99 template<bool promote_immediately>
100 oop PSPromotionManager::copy_to_survivor_space(oop o) {
101 assert(PSScavenge::should_scavenge(&o), "Sanity");
102
103 oop new_obj = NULL;
104
105 // NOTE! We must be very careful with any methods that access the mark
106 // in o. There may be multiple threads racing on it, and it may be forwarded
107 // at any time. Do not use oop methods for accessing the mark!
108 markOop test_mark = o->mark();
109
110 // The same test as "o->is_forwarded()"
111 if (!test_mark->is_marked()) {
112 bool new_obj_is_tenured = false;
113 size_t new_obj_size = o->size();
114
115 // Find the objects age, MT safe.
116 uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
117 test_mark->displaced_mark_helper()->age() : test_mark->age();
118
119 if (!promote_immediately) {
120 // Try allocating obj in to-space (unless too old)
121 if (age < PSScavenge::tenuring_threshold()) {
240 if (!_old_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
241 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
242 }
243 } else if (!_young_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
244 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
245 }
246
247 // don't update this before the unallocation!
248 new_obj = o->forwardee();
249 }
250 } else {
251 assert(o->is_forwarded(), "Sanity");
252 new_obj = o->forwardee();
253 }
254
255 #ifndef PRODUCT
256 // This code must come after the CAS test, or it will print incorrect
257 // information.
258 if (TraceScavenge) {
259 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
260 PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
261 new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
262 }
263 #endif
264
265 return new_obj;
266 }
267
268
269 inline void PSPromotionManager::process_popped_location_depth(StarTask p) {
270 if (is_oop_masked(p)) {
271 assert(PSChunkLargeArrays, "invariant");
272 oop const old = unmask_chunked_array_oop(p);
273 process_array_chunk(old);
274 } else {
275 if (p.is_narrow()) {
276 assert(UseCompressedOops, "Error");
277 PSScavenge::copy_and_push_safe_barrier<narrowOop, /*promote_immediately=*/false>(this, p);
278 } else {
279 PSScavenge::copy_and_push_safe_barrier<oop, /*promote_immediately=*/false>(this, p);
280 }
281 }
282 }
283
284 #if TASKQUEUE_STATS
285 void PSPromotionManager::record_steal(StarTask& p) {
286 if (is_oop_masked(p)) {
287 ++_masked_steals;
288 }
289 }
290 #endif // TASKQUEUE_STATS
291
292 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
|
39
40 template <class T>
41 inline void PSPromotionManager::claim_or_forward_internal_depth(T* p) {
42 if (p != NULL) { // XXX: error if p != NULL here
43 oop o = oopDesc::load_decode_heap_oop_not_null(p);
44 if (o->is_forwarded()) {
45 o = o->forwardee();
46 // Card mark
47 if (PSScavenge::is_obj_in_young(o)) {
48 PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
49 }
50 oopDesc::encode_store_heap_oop_not_null(p, o);
51 } else {
52 push_depth(p);
53 }
54 }
55 }
56
57 template <class T>
58 inline void PSPromotionManager::claim_or_forward_depth(T* p) {
59 assert(should_scavenge(p, true), "revisiting object?");
60 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap,
61 "Sanity");
62 assert(Universe::heap()->is_in(p), "pointer outside heap");
63
64 claim_or_forward_internal_depth(p);
65 }
66
67 inline void PSPromotionManager::promotion_trace_event(oop new_obj, oop old_obj,
68 size_t obj_size,
69 uint age, bool tenured,
70 const PSPromotionLAB* lab) {
71 // Skip if memory allocation failed
72 if (new_obj != NULL) {
73 const ParallelScavengeTracer* gc_tracer = PSScavenge::gc_tracer();
74
75 if (lab != NULL) {
76 // Promotion of object through newly allocated PLAB
77 if (gc_tracer->should_report_promotion_in_new_plab_event()) {
78 size_t obj_bytes = obj_size * HeapWordSize;
79 size_t lab_size = lab->capacity();
81 age, tenured, lab_size);
82 }
83 } else {
84 // Promotion of object directly to heap
85 if (gc_tracer->should_report_promotion_outside_plab_event()) {
86 size_t obj_bytes = obj_size * HeapWordSize;
87 gc_tracer->report_promotion_outside_plab_event(old_obj->klass(), obj_bytes,
88 age, tenured);
89 }
90 }
91 }
92 }
93
94 //
95 // This method is pretty bulky. It would be nice to split it up
96 // into smaller submethods, but we need to be careful not to hurt
97 // performance.
98 //
99 template<bool promote_immediately>
100 oop PSPromotionManager::copy_to_survivor_space(oop o) {
101 assert(should_scavenge(&o), "Sanity");
102
103 oop new_obj = NULL;
104
105 // NOTE! We must be very careful with any methods that access the mark
106 // in o. There may be multiple threads racing on it, and it may be forwarded
107 // at any time. Do not use oop methods for accessing the mark!
108 markOop test_mark = o->mark();
109
110 // The same test as "o->is_forwarded()"
111 if (!test_mark->is_marked()) {
112 bool new_obj_is_tenured = false;
113 size_t new_obj_size = o->size();
114
115 // Find the objects age, MT safe.
116 uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
117 test_mark->displaced_mark_helper()->age() : test_mark->age();
118
119 if (!promote_immediately) {
120 // Try allocating obj in to-space (unless too old)
121 if (age < PSScavenge::tenuring_threshold()) {
240 if (!_old_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
241 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
242 }
243 } else if (!_young_lab.unallocate_object((HeapWord*) new_obj, new_obj_size)) {
244 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
245 }
246
247 // don't update this before the unallocation!
248 new_obj = o->forwardee();
249 }
250 } else {
251 assert(o->is_forwarded(), "Sanity");
252 new_obj = o->forwardee();
253 }
254
255 #ifndef PRODUCT
256 // This code must come after the CAS test, or it will print incorrect
257 // information.
258 if (TraceScavenge) {
259 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
260 should_scavenge(&new_obj) ? "copying" : "tenuring",
261 new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
262 }
263 #endif
264
265 return new_obj;
266 }
267
268 // Attempt to "claim" oop at p via CAS, push the new obj if successful
269 // This version tests the oop* to make sure it is within the heap before
270 // attempting marking.
271 template <class T, bool promote_immediately>
272 inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) {
273 assert(should_scavenge(p, true), "revisiting object?");
274
275 oop o = oopDesc::load_decode_heap_oop_not_null(p);
276 oop new_obj = o->is_forwarded()
277 ? o->forwardee()
278 : copy_to_survivor_space<promote_immediately>(o);
279
280 #ifndef PRODUCT
281 // This code must come after the CAS test, or it will print incorrect
282 // information.
283 if (TraceScavenge && o->is_forwarded()) {
284 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
285 "forwarding",
286 new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
287 }
288 #endif
289
290 oopDesc::encode_store_heap_oop_not_null(p, new_obj);
291
292 // We cannot mark without test, as some code passes us pointers
293 // that are outside the heap. These pointers are either from roots
294 // or from metadata.
295 if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
296 Universe::heap()->is_in_reserved(p)) {
297 if (PSScavenge::is_obj_in_young(new_obj)) {
298 PSScavenge::card_table()->inline_write_ref_field_gc(p, new_obj);
299 }
300 }
301 }
302
303 inline void PSPromotionManager::process_popped_location_depth(StarTask p) {
304 if (is_oop_masked(p)) {
305 assert(PSChunkLargeArrays, "invariant");
306 oop const old = unmask_chunked_array_oop(p);
307 process_array_chunk(old);
308 } else {
309 if (p.is_narrow()) {
310 assert(UseCompressedOops, "Error");
311 copy_and_push_safe_barrier<narrowOop, /*promote_immediately=*/false>(p);
312 } else {
313 copy_and_push_safe_barrier<oop, /*promote_immediately=*/false>(p);
314 }
315 }
316 }
317
318 #if TASKQUEUE_STATS
319 void PSPromotionManager::record_steal(StarTask& p) {
320 if (is_oop_masked(p)) {
321 ++_masked_steals;
322 }
323 }
324 #endif // TASKQUEUE_STATS
325
326 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
|