Mercurial > hg > graal-compiler
comparison src/share/vm/memory/referenceProcessor.cpp @ 10408:836a62f43af9
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 19 Jun 2013 10:45:56 +0200 |
parents | 4a7dc38ae96b f2110083203d |
children | f22cbff51c12 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | 26 #include "classfile/javaClasses.hpp" |
27 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
28 #include "gc_implementation/shared/gcTimer.hpp" | |
29 #include "gc_implementation/shared/gcTraceTime.hpp" | |
28 #include "gc_interface/collectedHeap.hpp" | 30 #include "gc_interface/collectedHeap.hpp" |
29 #include "gc_interface/collectedHeap.inline.hpp" | 31 #include "gc_interface/collectedHeap.inline.hpp" |
30 #include "memory/referencePolicy.hpp" | 32 #include "memory/referencePolicy.hpp" |
31 #include "memory/referenceProcessor.hpp" | 33 #include "memory/referenceProcessor.hpp" |
32 #include "oops/oop.inline.hpp" | 34 #include "oops/oop.inline.hpp" |
182 } | 184 } |
183 // Else leave clock stalled at its old value until time progresses | 185 // Else leave clock stalled at its old value until time progresses |
184 // past clock value. | 186 // past clock value. |
185 } | 187 } |
186 | 188 |
187 void ReferenceProcessor::process_discovered_references( | 189 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) { |
190 size_t total = 0; | |
191 for (uint i = 0; i < _max_num_q; ++i) { | |
192 total += lists[i].length(); | |
193 } | |
194 return total; | |
195 } | |
196 | |
197 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( | |
188 BoolObjectClosure* is_alive, | 198 BoolObjectClosure* is_alive, |
189 OopClosure* keep_alive, | 199 OopClosure* keep_alive, |
190 VoidClosure* complete_gc, | 200 VoidClosure* complete_gc, |
191 AbstractRefProcTaskExecutor* task_executor) { | 201 AbstractRefProcTaskExecutor* task_executor, |
202 GCTimer* gc_timer) { | |
192 NOT_PRODUCT(verify_ok_to_handle_reflists()); | 203 NOT_PRODUCT(verify_ok_to_handle_reflists()); |
193 | 204 |
194 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); | 205 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); |
195 // Stop treating discovered references specially. | 206 // Stop treating discovered references specially. |
196 disable_discovery(); | 207 disable_discovery(); |
204 // discovered soft refs. | 215 // discovered soft refs. |
205 | 216 |
206 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); | 217 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); |
207 | 218 |
208 bool trace_time = PrintGCDetails && PrintReferenceGC; | 219 bool trace_time = PrintGCDetails && PrintReferenceGC; |
220 | |
209 // Soft references | 221 // Soft references |
222 size_t soft_count = 0; | |
210 { | 223 { |
211 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); | 224 GCTraceTime tt("SoftReference", trace_time, false, gc_timer); |
212 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, | 225 soft_count = |
213 is_alive, keep_alive, complete_gc, task_executor); | 226 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, |
227 is_alive, keep_alive, complete_gc, task_executor); | |
214 } | 228 } |
215 | 229 |
216 update_soft_ref_master_clock(); | 230 update_soft_ref_master_clock(); |
217 | 231 |
218 // Weak references | 232 // Weak references |
233 size_t weak_count = 0; | |
219 { | 234 { |
220 TraceTime tt("WeakReference", trace_time, false, gclog_or_tty); | 235 GCTraceTime tt("WeakReference", trace_time, false, gc_timer); |
221 process_discovered_reflist(_discoveredWeakRefs, NULL, true, | 236 weak_count = |
222 is_alive, keep_alive, complete_gc, task_executor); | 237 process_discovered_reflist(_discoveredWeakRefs, NULL, true, |
238 is_alive, keep_alive, complete_gc, task_executor); | |
223 } | 239 } |
224 | 240 |
225 // Final references | 241 // Final references |
242 size_t final_count = 0; | |
226 { | 243 { |
227 TraceTime tt("FinalReference", trace_time, false, gclog_or_tty); | 244 GCTraceTime tt("FinalReference", trace_time, false, gc_timer); |
228 process_discovered_reflist(_discoveredFinalRefs, NULL, false, | 245 final_count = |
229 is_alive, keep_alive, complete_gc, task_executor); | 246 process_discovered_reflist(_discoveredFinalRefs, NULL, false, |
247 is_alive, keep_alive, complete_gc, task_executor); | |
230 } | 248 } |
231 | 249 |
232 // Phantom references | 250 // Phantom references |
251 size_t phantom_count = 0; | |
233 { | 252 { |
234 TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty); | 253 GCTraceTime tt("PhantomReference", trace_time, false, gc_timer); |
235 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, | 254 phantom_count = |
236 is_alive, keep_alive, complete_gc, task_executor); | 255 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, |
256 is_alive, keep_alive, complete_gc, task_executor); | |
237 } | 257 } |
238 | 258 |
239 // Weak global JNI references. It would make more sense (semantically) to | 259 // Weak global JNI references. It would make more sense (semantically) to |
240 // traverse these simultaneously with the regular weak references above, but | 260 // traverse these simultaneously with the regular weak references above, but |
241 // that is not how the JDK1.2 specification is. See #4126360. Native code can | 261 // that is not how the JDK1.2 specification is. See #4126360. Native code can |
242 // thus use JNI weak references to circumvent the phantom references and | 262 // thus use JNI weak references to circumvent the phantom references and |
243 // resurrect a "post-mortem" object. | 263 // resurrect a "post-mortem" object. |
244 { | 264 { |
245 TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty); | 265 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer); |
246 if (task_executor != NULL) { | 266 if (task_executor != NULL) { |
247 task_executor->set_single_threaded_mode(); | 267 task_executor->set_single_threaded_mode(); |
248 } | 268 } |
249 process_phaseJNI(is_alive, keep_alive, complete_gc); | 269 process_phaseJNI(is_alive, keep_alive, complete_gc); |
250 #ifdef GRAAL | 270 #ifdef GRAAL |
251 process_phaseGraalNMethods(keep_alive, complete_gc); | 271 process_phaseGraalNMethods(keep_alive, complete_gc); |
252 #endif | 272 #endif |
253 } | 273 } |
274 | |
275 return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count); | |
254 } | 276 } |
255 | 277 |
256 #ifndef PRODUCT | 278 #ifndef PRODUCT |
257 // Calculate the number of jni handles. | 279 // Calculate the number of jni handles. |
258 uint ReferenceProcessor::count_jni_refs() { | 280 uint ReferenceProcessor::count_jni_refs() { |
259 class AlwaysAliveClosure: public BoolObjectClosure { | 281 class AlwaysAliveClosure: public BoolObjectClosure { |
260 public: | 282 public: |
261 virtual bool do_object_b(oop obj) { return true; } | 283 virtual bool do_object_b(oop obj) { return true; } |
262 virtual void do_object(oop obj) { assert(false, "Don't call"); } | |
263 }; | 284 }; |
264 | 285 |
265 class CountHandleClosure: public OopClosure { | 286 class CountHandleClosure: public OopClosure { |
266 private: | 287 private: |
267 int _count; | 288 int _count; |
892 balance_queues(_discoveredWeakRefs); | 913 balance_queues(_discoveredWeakRefs); |
893 balance_queues(_discoveredFinalRefs); | 914 balance_queues(_discoveredFinalRefs); |
894 balance_queues(_discoveredPhantomRefs); | 915 balance_queues(_discoveredPhantomRefs); |
895 } | 916 } |
896 | 917 |
897 void | 918 size_t |
898 ReferenceProcessor::process_discovered_reflist( | 919 ReferenceProcessor::process_discovered_reflist( |
899 DiscoveredList refs_lists[], | 920 DiscoveredList refs_lists[], |
900 ReferencePolicy* policy, | 921 ReferencePolicy* policy, |
901 bool clear_referent, | 922 bool clear_referent, |
902 BoolObjectClosure* is_alive, | 923 BoolObjectClosure* is_alive, |
915 | 936 |
916 if ((mt_processing && ParallelRefProcBalancingEnabled) || | 937 if ((mt_processing && ParallelRefProcBalancingEnabled) || |
917 must_balance) { | 938 must_balance) { |
918 balance_queues(refs_lists); | 939 balance_queues(refs_lists); |
919 } | 940 } |
941 | |
942 size_t total_list_count = total_count(refs_lists); | |
943 | |
920 if (PrintReferenceGC && PrintGCDetails) { | 944 if (PrintReferenceGC && PrintGCDetails) { |
921 size_t total = 0; | 945 gclog_or_tty->print(", %u refs", total_list_count); |
922 for (uint i = 0; i < _max_num_q; ++i) { | |
923 total += refs_lists[i].length(); | |
924 } | |
925 gclog_or_tty->print(", %u refs", total); | |
926 } | 946 } |
927 | 947 |
928 // Phase 1 (soft refs only): | 948 // Phase 1 (soft refs only): |
929 // . Traverse the list and remove any SoftReferences whose | 949 // . Traverse the list and remove any SoftReferences whose |
930 // referents are not alive, but that should be kept alive for | 950 // referents are not alive, but that should be kept alive for |
965 for (uint i = 0; i < _max_num_q; i++) { | 985 for (uint i = 0; i < _max_num_q; i++) { |
966 process_phase3(refs_lists[i], clear_referent, | 986 process_phase3(refs_lists[i], clear_referent, |
967 is_alive, keep_alive, complete_gc); | 987 is_alive, keep_alive, complete_gc); |
968 } | 988 } |
969 } | 989 } |
990 | |
991 return total_list_count; | |
970 } | 992 } |
971 | 993 |
972 void ReferenceProcessor::clean_up_discovered_references() { | 994 void ReferenceProcessor::clean_up_discovered_references() { |
973 // loop over the lists | 995 // loop over the lists |
974 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { | 996 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { |
1280 // in any order and, indeed, concurrently. | 1302 // in any order and, indeed, concurrently. |
1281 void ReferenceProcessor::preclean_discovered_references( | 1303 void ReferenceProcessor::preclean_discovered_references( |
1282 BoolObjectClosure* is_alive, | 1304 BoolObjectClosure* is_alive, |
1283 OopClosure* keep_alive, | 1305 OopClosure* keep_alive, |
1284 VoidClosure* complete_gc, | 1306 VoidClosure* complete_gc, |
1285 YieldClosure* yield) { | 1307 YieldClosure* yield, |
1308 GCTimer* gc_timer) { | |
1286 | 1309 |
1287 NOT_PRODUCT(verify_ok_to_handle_reflists()); | 1310 NOT_PRODUCT(verify_ok_to_handle_reflists()); |
1288 | 1311 |
1289 // Soft references | 1312 // Soft references |
1290 { | 1313 { |
1291 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, | 1314 GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, |
1292 false, gclog_or_tty); | 1315 false, gc_timer); |
1293 for (uint i = 0; i < _max_num_q; i++) { | 1316 for (uint i = 0; i < _max_num_q; i++) { |
1294 if (yield->should_return()) { | 1317 if (yield->should_return()) { |
1295 return; | 1318 return; |
1296 } | 1319 } |
1297 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, | 1320 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, |
1299 } | 1322 } |
1300 } | 1323 } |
1301 | 1324 |
1302 // Weak references | 1325 // Weak references |
1303 { | 1326 { |
1304 TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, | 1327 GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, |
1305 false, gclog_or_tty); | 1328 false, gc_timer); |
1306 for (uint i = 0; i < _max_num_q; i++) { | 1329 for (uint i = 0; i < _max_num_q; i++) { |
1307 if (yield->should_return()) { | 1330 if (yield->should_return()) { |
1308 return; | 1331 return; |
1309 } | 1332 } |
1310 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, | 1333 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, |
1312 } | 1335 } |
1313 } | 1336 } |
1314 | 1337 |
1315 // Final references | 1338 // Final references |
1316 { | 1339 { |
1317 TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, | 1340 GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, |
1318 false, gclog_or_tty); | 1341 false, gc_timer); |
1319 for (uint i = 0; i < _max_num_q; i++) { | 1342 for (uint i = 0; i < _max_num_q; i++) { |
1320 if (yield->should_return()) { | 1343 if (yield->should_return()) { |
1321 return; | 1344 return; |
1322 } | 1345 } |
1323 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, | 1346 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, |
1325 } | 1348 } |
1326 } | 1349 } |
1327 | 1350 |
1328 // Phantom references | 1351 // Phantom references |
1329 { | 1352 { |
1330 TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, | 1353 GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, |
1331 false, gclog_or_tty); | 1354 false, gc_timer); |
1332 for (uint i = 0; i < _max_num_q; i++) { | 1355 for (uint i = 0; i < _max_num_q; i++) { |
1333 if (yield->should_return()) { | 1356 if (yield->should_return()) { |
1334 return; | 1357 return; |
1335 } | 1358 } |
1336 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, | 1359 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, |