29 return 1; |
29 return 1; |
30 } |
30 } |
31 } |
31 } |
32 |
32 |
33 inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, oop* p) { |
33 inline void HRInto_G1RemSet::write_ref_nv(HeapRegion* from, oop* p) { |
34 oop obj = *p; |
34 par_write_ref(from, p, 0); |
35 assert(from != NULL && from->is_in_reserved(p), |
|
36 "p is not in a from"); |
|
37 HeapRegion* to = _g1->heap_region_containing(obj); |
|
38 if (from != to && to != NULL) { |
|
39 if (!to->popular() && !from->is_survivor()) { |
|
40 #if G1_REM_SET_LOGGING |
|
41 gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS" |
|
42 " for region [" PTR_FORMAT ", " PTR_FORMAT ")", |
|
43 p, obj, |
|
44 to->bottom(), to->end()); |
|
45 #endif |
|
46 assert(to->rem_set() != NULL, "Need per-region 'into' remsets."); |
|
47 if (to->rem_set()->add_reference(p)) { |
|
48 _g1->schedule_popular_region_evac(to); |
|
49 } |
|
50 } |
|
51 } |
|
52 } |
35 } |
53 |
36 |
54 inline void HRInto_G1RemSet::write_ref(HeapRegion* from, oop* p) { |
37 inline void HRInto_G1RemSet::write_ref(HeapRegion* from, oop* p) { |
55 write_ref_nv(from, p); |
38 write_ref_nv(from, p); |
56 } |
39 } |
80 assert(from == NULL || from->is_in_reserved(p), |
63 assert(from == NULL || from->is_in_reserved(p), |
81 "p is not in from"); |
64 "p is not in from"); |
82 HeapRegion* to = _g1->heap_region_containing(obj); |
65 HeapRegion* to = _g1->heap_region_containing(obj); |
83 // The test below could be optimized by applying a bit op to to and from. |
66 // The test below could be optimized by applying a bit op to to and from. |
84 if (to != NULL && from != NULL && from != to) { |
67 if (to != NULL && from != NULL && from != to) { |
85 if (!to->popular() && !from->is_survivor()) { |
68 bool update_delayed = false; |
|
69 // There is a tricky infinite loop if we keep pushing |
|
70 // self forwarding pointers onto our _new_refs list. |
|
71 // The _par_traversal_in_progress flag is true during the collection pause, |
|
72 // false during the evacuation failure handing. |
|
73 if (_par_traversal_in_progress && |
|
74 to->in_collection_set() && !self_forwarded(obj)) { |
|
75 _new_refs[tid]->push(p); |
|
76 // Deferred updates to the Cset are either discarded (in the normal case), |
|
77 // or processed (if an evacuation failure occurs) at the end |
|
78 // of the collection. |
|
79 // See HRInto_G1RemSet::cleanup_after_oops_into_collection_set_do(). |
|
80 update_delayed = true; |
|
81 } |
|
82 |
|
83 if (!to->popular() && !update_delayed) { |
86 #if G1_REM_SET_LOGGING |
84 #if G1_REM_SET_LOGGING |
87 gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS" |
85 gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS" |
88 " for region [" PTR_FORMAT ", " PTR_FORMAT ")", |
86 " for region [" PTR_FORMAT ", " PTR_FORMAT ")", |
89 p, obj, |
87 p, obj, |
90 to->bottom(), to->end()); |
88 to->bottom(), to->end()); |
92 assert(to->rem_set() != NULL, "Need per-region 'into' remsets."); |
90 assert(to->rem_set() != NULL, "Need per-region 'into' remsets."); |
93 if (to->rem_set()->add_reference(p, tid)) { |
91 if (to->rem_set()->add_reference(p, tid)) { |
94 _g1->schedule_popular_region_evac(to); |
92 _g1->schedule_popular_region_evac(to); |
95 } |
93 } |
96 } |
94 } |
97 // There is a tricky infinite loop if we keep pushing |
|
98 // self forwarding pointers onto our _new_refs list. |
|
99 if (_par_traversal_in_progress && |
|
100 to->in_collection_set() && !self_forwarded(obj)) { |
|
101 _new_refs[tid]->push(p); |
|
102 } |
|
103 } |
95 } |
104 } |
96 } |