29 |
29 |
30 // This must a ifdef'ed because the counting it controls is in a |
30 // This must a ifdef'ed because the counting it controls is in a |
31 // perf-critical inner loop. |
31 // perf-critical inner loop. |
32 #define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0 |
32 #define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0 |
33 |
33 |
34 inline void FilterIntoCSClosure::do_oop_nv(oop* p) { |
34 template <class T> inline void FilterIntoCSClosure::do_oop_nv(T* p) { |
35 oop obj = *p; |
35 T heap_oop = oopDesc::load_heap_oop(p); |
36 if (obj != NULL && _g1->obj_in_cs(obj)) { |
36 if (!oopDesc::is_null(heap_oop) && |
|
37 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) { |
37 _oc->do_oop(p); |
38 _oc->do_oop(p); |
38 #if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT |
39 #if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT |
39 _dcto_cl->incr_count(); |
40 _dcto_cl->incr_count(); |
40 #endif |
41 #endif |
41 } |
42 } |
42 } |
43 } |
43 |
44 |
44 inline void FilterIntoCSClosure::do_oop(oop* p) |
|
45 { |
|
46 do_oop_nv(p); |
|
47 } |
|
48 |
|
49 #define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0 |
45 #define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0 |
50 |
46 |
51 inline void FilterOutOfRegionClosure::do_oop_nv(oop* p) { |
47 template <class T> inline void FilterOutOfRegionClosure::do_oop_nv(T* p) { |
52 oop obj = *p; |
48 T heap_oop = oopDesc::load_heap_oop(p); |
53 HeapWord* obj_hw = (HeapWord*)obj; |
49 if (!oopDesc::is_null(heap_oop)) { |
54 if (obj_hw != NULL && (obj_hw < _r_bottom || obj_hw >= _r_end)) { |
50 HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop); |
55 _oc->do_oop(p); |
51 if (obj_hw < _r_bottom || obj_hw >= _r_end) { |
|
52 _oc->do_oop(p); |
56 #if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT |
53 #if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT |
57 _out_of_region++; |
54 _out_of_region++; |
58 #endif |
55 #endif |
|
56 } |
59 } |
57 } |
60 } |
58 } |
61 |
59 |
62 inline void FilterOutOfRegionClosure::do_oop(oop* p) |
60 template <class T> inline void FilterInHeapRegionAndIntoCSClosure::do_oop_nv(T* p) { |
63 { |
61 T heap_oop = oopDesc::load_heap_oop(p); |
64 do_oop_nv(p); |
62 if (!oopDesc::is_null(heap_oop) && |
65 } |
63 _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) |
66 |
|
67 inline void FilterInHeapRegionAndIntoCSClosure::do_oop_nv(oop* p) { |
|
68 oop obj = *p; |
|
69 if (obj != NULL && _g1->obj_in_cs(obj)) |
|
70 _oc->do_oop(p); |
64 _oc->do_oop(p); |
71 } |
65 } |
72 |
66 |
73 inline void FilterInHeapRegionAndIntoCSClosure::do_oop(oop* p) |
67 template <class T> inline void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop_nv(T* p) { |
74 { |
68 T heap_oop = oopDesc::load_heap_oop(p); |
75 do_oop_nv(p); |
69 if (!oopDesc::is_null(heap_oop)) { |
76 } |
70 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
77 |
|
78 |
|
79 inline void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop_nv(oop* p) { |
|
80 oop obj = *p; |
|
81 if (obj != NULL) { |
|
82 HeapRegion* hr = _g1->heap_region_containing((HeapWord*) obj); |
71 HeapRegion* hr = _g1->heap_region_containing((HeapWord*) obj); |
83 if (hr != NULL) { |
72 if (hr != NULL) { |
84 if (hr->in_collection_set()) |
73 if (hr->in_collection_set()) |
85 _oc->do_oop(p); |
74 _oc->do_oop(p); |
86 else if (!hr->is_young()) |
75 else if (!hr->is_young()) |
87 _cm->grayRoot(obj); |
76 _cm->grayRoot(obj); |
88 } |
77 } |
89 } |
78 } |
90 } |
79 } |
91 |
80 |
92 inline void FilterAndMarkInHeapRegionAndIntoCSClosure::do_oop(oop* p) |
81 // This closure is applied to the fields of the objects that have just been copied. |
93 { |
82 template <class T> inline void G1ParScanClosure::do_oop_nv(T* p) { |
94 do_oop_nv(p); |
83 T heap_oop = oopDesc::load_heap_oop(p); |
|
84 |
|
85 if (!oopDesc::is_null(heap_oop)) { |
|
86 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
|
87 if (_g1->in_cset_fast_test(obj)) { |
|
88 // We're not going to even bother checking whether the object is |
|
89 // already forwarded or not, as this usually causes an immediate |
|
90 // stall. We'll try to prefetch the object (for write, given that |
|
91 // we might need to install the forwarding reference) and we'll |
|
92 // get back to it when pop it from the queue |
|
93 Prefetch::write(obj->mark_addr(), 0); |
|
94 Prefetch::read(obj->mark_addr(), (HeapWordSize*2)); |
|
95 |
|
96 // slightly paranoid test; I'm trying to catch potential |
|
97 // problems before we go into push_on_queue to know where the |
|
98 // problem is coming from |
|
99 assert(obj == oopDesc::load_decode_heap_oop(p), |
|
100 "p should still be pointing to obj"); |
|
101 _par_scan_state->push_on_queue(p); |
|
102 } else { |
|
103 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
|
104 } |
|
105 } |
95 } |
106 } |
96 |
|
97 inline void G1ScanAndBalanceClosure::do_oop_nv(oop* p) { |
|
98 RefToScanQueue* q; |
|
99 if (ParallelGCThreads > 0) { |
|
100 // Deal the work out equally. |
|
101 _nq = (_nq + 1) % ParallelGCThreads; |
|
102 q = _g1->task_queue(_nq); |
|
103 } else { |
|
104 q = _g1->task_queue(0); |
|
105 } |
|
106 bool nooverflow = q->push(p); |
|
107 guarantee(nooverflow, "Overflow during poplularity region processing"); |
|
108 } |
|
109 |
|
110 inline void G1ScanAndBalanceClosure::do_oop(oop* p) { |
|
111 do_oop_nv(p); |
|
112 } |
|