272 size_t _count;
273 public:
274 CountHandleClosure(): _count(0) {}
275 void do_oop(oop* unused) { _count++; }
276 void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
277 size_t count() { return _count; }
278 };
279 CountHandleClosure global_handle_count;
280 JNIHandles::weak_oops_do(&global_handle_count);
281 return global_handle_count.count();
282 }
283 #endif
284
285 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
286 OopClosure* keep_alive,
287 VoidClosure* complete_gc) {
288 JNIHandles::weak_oops_do(is_alive, keep_alive);
289 complete_gc->do_void();
290 }
291
292
293 template <class T>
294 bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
295 AbstractRefProcTaskExecutor* task_executor) {
296
297 // Remember old value of pending references list
298 T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
299 T old_pending_list_value = *pending_list_addr;
300
301 // Enqueue references that are not made active again, and
302 // clear the decks for the next collection (cycle).
303 ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
304 // Do the post-barrier on pending_list_addr missed in
305 // enqueue_discovered_reflist.
306 oopDesc::bs()->write_ref_field(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
307
308 // Stop treating discovered references specially.
309 ref->disable_discovery();
310
311 // Return true if new pending references were added
312 return old_pending_list_value != *pending_list_addr;
313 }
314
315 bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
316 if (UseCompressedOops) {
317 return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
318 } else {
319 return enqueue_discovered_ref_helper<oop>(this, task_executor);
320 }
321 }
322
323 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
324 HeapWord* pending_list_addr) {
325 // Given a list of refs linked through the "discovered" field
326 // (java.lang.ref.Reference.discovered), self-loop their "next" field
327 // thus distinguishing them from active References, then
328 // prepend them to the pending list.
329 //
330 // The Java threads will see the Reference objects linked together through
331 // the discovered field. Instead of trying to do the write barrier updates
332 // in all places in the reference processor where we manipulate the discovered
333 // field we make sure to do the barrier here where we anyway iterate through
334 // all linked Reference objects. Note that it is important to not dirty any
335 // cards during reference processing since this will cause card table
336 // verification to fail for G1.
337 log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(&refs_list));
338
339 oop obj = NULL;
340 oop next_d = refs_list.head();
341 // Walk down the list, self-looping the next field
342 // so that the References are not considered active.
343 while (obj != next_d) {
344 obj = next_d;
345 assert(obj->is_instance(), "should be an instance object");
346 assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
347 next_d = java_lang_ref_Reference::discovered(obj);
348 log_develop_trace(gc, ref)(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
349 assert(java_lang_ref_Reference::next(obj) == NULL,
350 "Reference not active; should not be discovered");
351 // Self-loop next, so as to make Ref not active.
352 java_lang_ref_Reference::set_next_raw(obj, obj);
353 if (next_d != obj) {
354 oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
355 } else {
356 // This is the last object.
357 // Swap refs_list into pending_list_addr and
358 // set obj's discovered to what we read from pending_list_addr.
359 oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
360 // Need post-barrier on pending_list_addr. See enqueue_discovered_ref_helper() above.
361 java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
362 oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
363 }
364 }
365 }
366
367 // Parallel enqueue task
368 class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
369 public:
370 RefProcEnqueueTask(ReferenceProcessor& ref_processor,
371 DiscoveredList discovered_refs[],
372 HeapWord* pending_list_addr,
373 int n_queues)
374 : EnqueueTask(ref_processor, discovered_refs,
375 pending_list_addr, n_queues)
376 { }
377
378 virtual void work(unsigned int work_id) {
379 assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
380 // Simplest first cut: static partitioning.
381 int index = work_id;
382 // The increment on "index" must correspond to the maximum number of queues
383 // (n_queues) with which that ReferenceProcessor was created. That
384 // is because of the "clever" way the discovered references lists were
385 // allocated and are indexed into.
386 assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
387 for (int j = 0;
388 j < ReferenceProcessor::number_of_subclasses_of_ref();
389 j++, index += _n_queues) {
390 _ref_processor.enqueue_discovered_reflist(
391 _refs_lists[index], _pending_list_addr);
392 _refs_lists[index].set_head(NULL);
393 _refs_lists[index].set_length(0);
394 }
395 }
396 };
397
398 // Enqueue references that are not made active again
399 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
400 AbstractRefProcTaskExecutor* task_executor) {
401 if (_processing_is_mt && task_executor != NULL) {
402 // Parallel code
403 RefProcEnqueueTask tsk(*this, _discovered_refs,
404 pending_list_addr, _max_num_q);
405 task_executor->execute(tsk);
406 } else {
407 // Serial code: call the parent class's implementation
408 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
409 enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
410 _discovered_refs[i].set_head(NULL);
411 _discovered_refs[i].set_length(0);
412 }
413 }
414 }
415
416 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
417 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
418 oop discovered = java_lang_ref_Reference::discovered(_ref);
419 assert(_discovered_addr && discovered->is_oop_or_null(),
420 "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
421 _next = discovered;
422 _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
423 _referent = java_lang_ref_Reference::referent(_ref);
424 assert(Universe::heap()->is_in_reserved_or_null(_referent),
425 "Wrong oop found in java.lang.Reference object");
426 assert(allow_null_referent ?
427 _referent->is_oop_or_null()
428 : _referent->is_oop(),
429 "Expected an oop%s for referent field at " PTR_FORMAT,
|
272 size_t _count;
273 public:
274 CountHandleClosure(): _count(0) {}
275 void do_oop(oop* unused) { _count++; }
276 void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
277 size_t count() { return _count; }
278 };
279 CountHandleClosure global_handle_count;
280 JNIHandles::weak_oops_do(&global_handle_count);
281 return global_handle_count.count();
282 }
283 #endif
284
285 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
286 OopClosure* keep_alive,
287 VoidClosure* complete_gc) {
288 JNIHandles::weak_oops_do(is_alive, keep_alive);
289 complete_gc->do_void();
290 }
291
292 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
293 // Enqueue references that are not made active again, and
294 // clear the decks for the next collection (cycle).
295 enqueue_discovered_reflists(task_executor);
296
297 // Stop treating discovered references specially.
298 disable_discovery();
299 }
300
301 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
302 // Given a list of refs linked through the "discovered" field
303 // (java.lang.ref.Reference.discovered), self-loop their "next" field
304 // thus distinguishing them from active References, then
305 // prepend them to the pending list.
306 //
307 // The Java threads will see the Reference objects linked together through
308 // the discovered field. Instead of trying to do the write barrier updates
309 // in all places in the reference processor where we manipulate the discovered
310 // field we make sure to do the barrier here where we anyway iterate through
311 // all linked Reference objects. Note that it is important to not dirty any
312 // cards during reference processing since this will cause card table
313 // verification to fail for G1.
314 log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(&refs_list));
315
316 oop obj = NULL;
317 oop next_d = refs_list.head();
318 // Walk down the list, self-looping the next field
319 // so that the References are not considered active.
320 while (obj != next_d) {
321 obj = next_d;
322 assert(obj->is_instance(), "should be an instance object");
323 assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
324 next_d = java_lang_ref_Reference::discovered(obj);
325 log_develop_trace(gc, ref)(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
326 assert(java_lang_ref_Reference::next(obj) == NULL,
327 "Reference not active; should not be discovered");
328 // Self-loop next, so as to make Ref not active.
329 java_lang_ref_Reference::set_next_raw(obj, obj);
330 if (next_d != obj) {
331 oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
332 } else {
333 // This is the last object.
334 // Swap refs_list into pending list and set obj's
335 // discovered to what we read from the pending list.
336 oop old = Universe::swap_reference_pending_list(refs_list.head());
337 java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
338 oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
339 }
340 }
341 }
342
343 // Parallel enqueue task
344 class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
345 public:
346 RefProcEnqueueTask(ReferenceProcessor& ref_processor,
347 DiscoveredList discovered_refs[],
348 int n_queues)
349 : EnqueueTask(ref_processor, discovered_refs, n_queues)
350 { }
351
352 virtual void work(unsigned int work_id) {
353 assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
354 // Simplest first cut: static partitioning.
355 int index = work_id;
356 // The increment on "index" must correspond to the maximum number of queues
357 // (n_queues) with which that ReferenceProcessor was created. That
358 // is because of the "clever" way the discovered references lists were
359 // allocated and are indexed into.
360 assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
361 for (int j = 0;
362 j < ReferenceProcessor::number_of_subclasses_of_ref();
363 j++, index += _n_queues) {
364 _ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
365 _refs_lists[index].set_head(NULL);
366 _refs_lists[index].set_length(0);
367 }
368 }
369 };
370
371 // Enqueue references that are not made active again
372 void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) {
373 if (_processing_is_mt && task_executor != NULL) {
374 // Parallel code
375 RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q);
376 task_executor->execute(tsk);
377 } else {
378 // Serial code: call the parent class's implementation
379 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
380 enqueue_discovered_reflist(_discovered_refs[i]);
381 _discovered_refs[i].set_head(NULL);
382 _discovered_refs[i].set_length(0);
383 }
384 }
385 }
386
387 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
388 _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
389 oop discovered = java_lang_ref_Reference::discovered(_ref);
390 assert(_discovered_addr && discovered->is_oop_or_null(),
391 "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
392 _next = discovered;
393 _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
394 _referent = java_lang_ref_Reference::referent(_ref);
395 assert(Universe::heap()->is_in_reserved_or_null(_referent),
396 "Wrong oop found in java.lang.Reference object");
397 assert(allow_null_referent ?
398 _referent->is_oop_or_null()
399 : _referent->is_oop(),
400 "Expected an oop%s for referent field at " PTR_FORMAT,
|