68 // of an oop (the field is currently initialized to NULL for |
66 // of an oop (the field is currently initialized to NULL for |
69 // all collectors but the CMS collector). |
67 // all collectors but the CMS collector). |
70 BoolObjectClosure* _is_alive_non_header; |
68 BoolObjectClosure* _is_alive_non_header; |
71 |
69 |
72 // The discovered ref lists themselves |
70 // The discovered ref lists themselves |
73 int _num_q; // the MT'ness degree of the queues below |
71 |
74 DiscoveredList* _discoveredSoftRefs; // pointer to array of oops |
72 // The MT'ness degree of the queues below |
|
73 int _num_q; |
|
74 // Arrays of lists of oops, one per thread |
|
75 DiscoveredList* _discoveredSoftRefs; |
75 DiscoveredList* _discoveredWeakRefs; |
76 DiscoveredList* _discoveredWeakRefs; |
76 DiscoveredList* _discoveredFinalRefs; |
77 DiscoveredList* _discoveredFinalRefs; |
77 DiscoveredList* _discoveredPhantomRefs; |
78 DiscoveredList* _discoveredPhantomRefs; |
78 |
79 |
79 public: |
80 public: |
80 int num_q() { return _num_q; } |
81 int num_q() { return _num_q; } |
81 DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; } |
82 DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; } |
82 static oop* sentinel_ref() { return &_sentinelRef; } |
83 static oop sentinel_ref() { return _sentinelRef; } |
|
84 static oop* adr_sentinel_ref() { return &_sentinelRef; } |
83 |
85 |
84 public: |
86 public: |
85 // Process references with a certain reachability level. |
87 // Process references with a certain reachability level. |
86 void process_discovered_reflist(DiscoveredList refs_lists[], |
88 void process_discovered_reflist(DiscoveredList refs_lists[], |
87 ReferencePolicy* policy, |
89 ReferencePolicy* policy, |
96 VoidClosure* complete_gc); |
98 VoidClosure* complete_gc); |
97 |
99 |
98 // Work methods used by the method process_discovered_reflist |
100 // Work methods used by the method process_discovered_reflist |
99 // Phase1: keep alive all those referents that are otherwise |
101 // Phase1: keep alive all those referents that are otherwise |
100 // dead but which must be kept alive by policy (and their closure). |
102 // dead but which must be kept alive by policy (and their closure). |
101 void process_phase1(DiscoveredList& refs_list_addr, |
103 void process_phase1(DiscoveredList& refs_list, |
102 ReferencePolicy* policy, |
104 ReferencePolicy* policy, |
103 BoolObjectClosure* is_alive, |
105 BoolObjectClosure* is_alive, |
104 OopClosure* keep_alive, |
106 OopClosure* keep_alive, |
105 VoidClosure* complete_gc); |
107 VoidClosure* complete_gc); |
106 // Phase2: remove all those references whose referents are |
108 // Phase2: remove all those references whose referents are |
107 // reachable. |
109 // reachable. |
108 inline void process_phase2(DiscoveredList& refs_list_addr, |
110 inline void process_phase2(DiscoveredList& refs_list, |
109 BoolObjectClosure* is_alive, |
111 BoolObjectClosure* is_alive, |
110 OopClosure* keep_alive, |
112 OopClosure* keep_alive, |
111 VoidClosure* complete_gc) { |
113 VoidClosure* complete_gc) { |
112 if (discovery_is_atomic()) { |
114 if (discovery_is_atomic()) { |
113 // complete_gc is ignored in this case for this phase |
115 // complete_gc is ignored in this case for this phase |
114 pp2_work(refs_list_addr, is_alive, keep_alive); |
116 pp2_work(refs_list, is_alive, keep_alive); |
115 } else { |
117 } else { |
116 assert(complete_gc != NULL, "Error"); |
118 assert(complete_gc != NULL, "Error"); |
117 pp2_work_concurrent_discovery(refs_list_addr, is_alive, |
119 pp2_work_concurrent_discovery(refs_list, is_alive, |
118 keep_alive, complete_gc); |
120 keep_alive, complete_gc); |
119 } |
121 } |
120 } |
122 } |
121 // Work methods in support of process_phase2 |
123 // Work methods in support of process_phase2 |
122 void pp2_work(DiscoveredList& refs_list_addr, |
124 void pp2_work(DiscoveredList& refs_list, |
123 BoolObjectClosure* is_alive, |
125 BoolObjectClosure* is_alive, |
124 OopClosure* keep_alive); |
126 OopClosure* keep_alive); |
125 void pp2_work_concurrent_discovery( |
127 void pp2_work_concurrent_discovery( |
126 DiscoveredList& refs_list_addr, |
128 DiscoveredList& refs_list, |
127 BoolObjectClosure* is_alive, |
129 BoolObjectClosure* is_alive, |
128 OopClosure* keep_alive, |
130 OopClosure* keep_alive, |
129 VoidClosure* complete_gc); |
131 VoidClosure* complete_gc); |
130 // Phase3: process the referents by either clearing them |
132 // Phase3: process the referents by either clearing them |
131 // or keeping them alive (and their closure) |
133 // or keeping them alive (and their closure) |
132 void process_phase3(DiscoveredList& refs_list_addr, |
134 void process_phase3(DiscoveredList& refs_list, |
133 bool clear_referent, |
135 bool clear_referent, |
134 BoolObjectClosure* is_alive, |
136 BoolObjectClosure* is_alive, |
135 OopClosure* keep_alive, |
137 OopClosure* keep_alive, |
136 VoidClosure* complete_gc); |
138 VoidClosure* complete_gc); |
137 |
139 |
138 // Enqueue references with a certain reachability level |
140 // Enqueue references with a certain reachability level |
139 void enqueue_discovered_reflist(DiscoveredList& refs_list, oop* pending_list_addr); |
141 void enqueue_discovered_reflist(DiscoveredList& refs_list, HeapWord* pending_list_addr); |
140 |
142 |
141 // "Preclean" all the discovered reference lists |
143 // "Preclean" all the discovered reference lists |
142 // by removing references with strongly reachable referents. |
144 // by removing references with strongly reachable referents. |
143 // The first argument is a predicate on an oop that indicates |
145 // The first argument is a predicate on an oop that indicates |
144 // its (strong) reachability and the second is a closure that |
146 // its (strong) reachability and the second is a closure that |
167 |
169 |
168 // Returns the name of the discovered reference list |
170 // Returns the name of the discovered reference list |
169 // occupying the i / _num_q slot. |
171 // occupying the i / _num_q slot. |
170 const char* list_name(int i); |
172 const char* list_name(int i); |
171 |
173 |
|
174 void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor); |
|
175 |
172 protected: |
176 protected: |
173 // "Preclean" the given discovered reference list |
177 // "Preclean" the given discovered reference list |
174 // by removing references with strongly reachable referents. |
178 // by removing references with strongly reachable referents. |
175 // Currently used in support of CMS only. |
179 // Currently used in support of CMS only. |
176 void preclean_discovered_reflist(DiscoveredList& refs_list, |
180 void preclean_discovered_reflist(DiscoveredList& refs_list, |
177 BoolObjectClosure* is_alive, |
181 BoolObjectClosure* is_alive, |
178 OopClosure* keep_alive, |
182 OopClosure* keep_alive, |
179 VoidClosure* complete_gc, |
183 VoidClosure* complete_gc, |
180 YieldClosure* yield); |
184 YieldClosure* yield); |
181 |
185 |
182 void enqueue_discovered_reflists(oop* pending_list_addr, AbstractRefProcTaskExecutor* task_executor); |
|
183 int next_id() { |
186 int next_id() { |
184 int id = _next_id; |
187 int id = _next_id; |
185 if (++_next_id == _num_q) { |
188 if (++_next_id == _num_q) { |
186 _next_id = 0; |
189 _next_id = 0; |
187 } |
190 } |
188 return id; |
191 return id; |
189 } |
192 } |
190 DiscoveredList* get_discovered_list(ReferenceType rt); |
193 DiscoveredList* get_discovered_list(ReferenceType rt); |
191 inline void add_to_discovered_list_mt(DiscoveredList& refs_list, oop obj, |
194 inline void add_to_discovered_list_mt(DiscoveredList& refs_list, oop obj, |
192 oop* discovered_addr); |
195 HeapWord* discovered_addr); |
193 void verify_ok_to_handle_reflists() PRODUCT_RETURN; |
196 void verify_ok_to_handle_reflists() PRODUCT_RETURN; |
194 |
197 |
195 void abandon_partial_discovered_list(DiscoveredList& refs_list); |
198 void abandon_partial_discovered_list(DiscoveredList& refs_list); |
196 void abandon_partial_discovered_list_arr(DiscoveredList refs_lists[]); |
199 void abandon_partial_discovered_list_arr(DiscoveredList refs_lists[]); |
197 |
200 |
475 // Abstract reference processing task to execute. |
478 // Abstract reference processing task to execute. |
476 class AbstractRefProcTaskExecutor::EnqueueTask { |
479 class AbstractRefProcTaskExecutor::EnqueueTask { |
477 protected: |
480 protected: |
478 EnqueueTask(ReferenceProcessor& ref_processor, |
481 EnqueueTask(ReferenceProcessor& ref_processor, |
479 DiscoveredList refs_lists[], |
482 DiscoveredList refs_lists[], |
480 oop* pending_list_addr, |
483 HeapWord* pending_list_addr, |
481 oop sentinel_ref, |
484 oop sentinel_ref, |
482 int n_queues) |
485 int n_queues) |
483 : _ref_processor(ref_processor), |
486 : _ref_processor(ref_processor), |
484 _refs_lists(refs_lists), |
487 _refs_lists(refs_lists), |
485 _pending_list_addr(pending_list_addr), |
488 _pending_list_addr(pending_list_addr), |