hotspot/src/share/vm/memory/referenceProcessor.cpp
author johnc
Thu, 22 Sep 2011 10:57:37 -0700
changeset 10670 4ea0e7d2ffbc
parent 10526 3e92f211533f
child 10683 4b5a5a507864
permissions -rw-r--r--
6484982: G1: process references during evacuation pauses Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate. Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
     2
 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4738
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4738
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4738
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    26
#include "classfile/javaClasses.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    27
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    28
#include "gc_interface/collectedHeap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    29
#include "gc_interface/collectedHeap.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    30
#include "memory/referencePolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    31
#include "memory/referenceProcessor.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    32
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    33
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6759
diff changeset
    34
#include "runtime/jniHandles.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    36
ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    37
ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
    38
bool             ReferenceProcessor::_pending_list_uses_discovered_field = false;
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    39
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
void referenceProcessor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  ReferenceProcessor::init_statics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
void ReferenceProcessor::init_statics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  // Initialize the master soft ref clock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  java_lang_ref_SoftReference::set_clock(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    48
  _always_clear_soft_ref_policy = new AlwaysClearPolicy();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    49
  _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    50
                                      NOT_COMPILER2(LRUCurrentHeapPolicy());
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    51
  if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    52
    vm_exit_during_initialization("Could not allocate reference policy object");
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
    53
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
            RefDiscoveryPolicy == ReferentBasedDiscovery,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
            "Unrecongnized RefDiscoveryPolicy");
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
    57
  _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
ReferenceProcessor::ReferenceProcessor(MemRegion span,
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    61
                                       bool      mt_processing,
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    62
                                       int       mt_processing_degree,
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
    63
                                       bool      mt_discovery,
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    64
                                       int       mt_discovery_degree,
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    65
                                       bool      atomic_discovery,
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    66
                                       BoolObjectClosure* is_alive_non_header,
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    67
                                       bool      discovered_list_needs_barrier)  :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  _discovering_refs(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  _enqueuing_is_done(false),
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    70
  _is_alive_non_header(is_alive_non_header),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    71
  _discovered_list_needs_barrier(discovered_list_needs_barrier),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    72
  _bs(NULL),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  _processing_is_mt(mt_processing),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  _next_id(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  _span = span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  _discovery_is_atomic = atomic_discovery;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  _discovery_is_mt     = mt_discovery;
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    79
  _num_q               = MAX2(1, mt_processing_degree);
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    80
  _max_num_q           = MAX2(_num_q, mt_discovery_degree);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
    81
  _discoveredSoftRefs  = NEW_C_HEAP_ARRAY(DiscoveredList,
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
    82
                                          _max_num_q * number_of_subclasses_of_ref());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  if (_discoveredSoftRefs == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    vm_exit_during_initialization("Could not allocated RefProc Array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    86
  _discoveredWeakRefs    = &_discoveredSoftRefs[_max_num_q];
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    87
  _discoveredFinalRefs   = &_discoveredWeakRefs[_max_num_q];
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
    88
  _discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
    89
  // Initialized all entries to NULL
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
    90
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
    91
    _discoveredSoftRefs[i].set_head(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    _discoveredSoftRefs[i].set_length(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  }
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
    94
  // If we do barriers, cache a copy of the barrier set.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    95
  if (discovered_list_needs_barrier) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    96
    _bs = Universe::heap()->barrier_set();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
    97
  }
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
    98
  setup_policy(false /* default soft ref policy */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
void ReferenceProcessor::verify_no_references_recorded() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  guarantee(!_discovering_refs, "Discovering refs?");
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   104
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   105
    guarantee(_discoveredSoftRefs[i].is_empty(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
              "Found non-empty discovered list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
void ReferenceProcessor::weak_oops_do(OopClosure* f) {
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   112
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   113
    if (UseCompressedOops) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   114
      f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head());
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   115
    } else {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   116
      f->do_oop((oop*)_discoveredSoftRefs[i].adr_head());
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   117
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   121
void ReferenceProcessor::update_soft_ref_master_clock() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // Update (advance) the soft ref master clock field. This must be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  // after processing the soft ref list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  jlong now = os::javaTimeMillis();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  jlong clock = java_lang_ref_SoftReference::clock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  if (now < clock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    warning("time warp: %d to %d", clock, now);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // In product mode, protect ourselves from system time being adjusted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  // externally and going backward; see note in the implementation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  // GenCollectedHeap::time_since_last_gc() for the right way to fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // this uniformly throughout the VM; see bug-id 4741166. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  if (now > clock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    java_lang_ref_SoftReference::set_clock(now);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  // Else leave clock stalled at its old value until time progresses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // past clock value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   142
void ReferenceProcessor::process_discovered_references(
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  BoolObjectClosure*           is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  OopClosure*                  keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  VoidClosure*                 complete_gc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  AbstractRefProcTaskExecutor* task_executor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  NOT_PRODUCT(verify_ok_to_handle_reflists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // Stop treating discovered references specially.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  disable_discovery();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  bool trace_time = PrintGCDetails && PrintReferenceGC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  // Soft references
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
   157
    process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
                               is_alive, keep_alive, complete_gc, task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  update_soft_ref_master_clock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  // Weak references
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    TraceTime tt("WeakReference", trace_time, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    process_discovered_reflist(_discoveredWeakRefs, NULL, true,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
                               is_alive, keep_alive, complete_gc, task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  // Final references
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    TraceTime tt("FinalReference", trace_time, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    process_discovered_reflist(_discoveredFinalRefs, NULL, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
                               is_alive, keep_alive, complete_gc, task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // Phantom references
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
                               is_alive, keep_alive, complete_gc, task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // Weak global JNI references. It would make more sense (semantically) to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // traverse these simultaneously with the regular weak references above, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // that is not how the JDK1.2 specification is. See #4126360. Native code can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // thus use JNI weak references to circumvent the phantom references and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // resurrect a "post-mortem" object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    if (task_executor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      task_executor->set_single_threaded_mode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    process_phaseJNI(is_alive, keep_alive, complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
// Calculate the number of jni handles.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   200
uint ReferenceProcessor::count_jni_refs() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  class AlwaysAliveClosure: public BoolObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  public:
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   203
    virtual bool do_object_b(oop obj) { return true; }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   204
    virtual void do_object(oop obj) { assert(false, "Don't call"); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  class CountHandleClosure: public OopClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    int _count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    CountHandleClosure(): _count(0) {}
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   212
    void do_oop(oop* unused)       { _count++; }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   213
    void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    int count() { return _count; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  CountHandleClosure global_handle_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  AlwaysAliveClosure always_alive;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  JNIHandles::weak_oops_do(&always_alive, &global_handle_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  return global_handle_count.count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
                                          OopClosure*        keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
                                          VoidClosure*       complete_gc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  if (PrintGCDetails && PrintReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    unsigned int count = count_jni_refs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    gclog_or_tty->print(", %u refs", count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  JNIHandles::weak_oops_do(is_alive, keep_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  complete_gc->do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   236
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   237
template <class T>
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 3690
diff changeset
   238
bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 3690
diff changeset
   239
                                   AbstractRefProcTaskExecutor* task_executor) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   240
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  // Remember old value of pending references list
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   242
  T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   243
  T old_pending_list_value = *pending_list_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  // Enqueue references that are not made active again, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  // clear the decks for the next collection (cycle).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   247
  ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // Do the oop-check on pending_list_addr missed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  // enqueue_discovered_reflist. We should probably
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  // do a raw oop_check so that future such idempotent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  // oop_stores relying on the oop-check side-effect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // may be elided automatically and safely without
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  // affecting correctness.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   254
  oop_store(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  // Stop treating discovered references specially.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   257
  ref->disable_discovery();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  // Return true if new pending references were added
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  return old_pending_list_value != *pending_list_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   263
bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   264
  NOT_PRODUCT(verify_ok_to_handle_reflists());
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   265
  if (UseCompressedOops) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   266
    return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   267
  } else {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   268
    return enqueue_discovered_ref_helper<oop>(this, task_executor);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   269
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   270
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   271
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   273
                                                    HeapWord* pending_list_addr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  // Given a list of refs linked through the "discovered" field
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   275
  // (java.lang.ref.Reference.discovered), self-loop their "next" field
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   276
  // thus distinguishing them from active References, then
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   277
  // prepend them to the pending list.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   278
  // BKWRD COMPATIBILITY NOTE: For older JDKs (prior to the fix for 4956777),
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   279
  // the "next" field is used to chain the pending list, not the discovered
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   280
  // field.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   281
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  if (TraceReferenceGC && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
                           INTPTR_FORMAT, (address)refs_list.head());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  }
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   286
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   287
  oop obj = NULL;
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   288
  oop next_d = refs_list.head();
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   289
  if (pending_list_uses_discovered_field()) { // New behaviour
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   290
    // Walk down the list, self-looping the next field
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   291
    // so that the References are not considered active.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   292
    while (obj != next_d) {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   293
      obj = next_d;
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   294
      assert(obj->is_instanceRef(), "should be reference object");
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   295
      next_d = java_lang_ref_Reference::discovered(obj);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   296
      if (TraceReferenceGC && PrintGCDetails) {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   297
        gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   298
                               obj, next_d);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   299
      }
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   300
      assert(java_lang_ref_Reference::next(obj) == NULL,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   301
             "Reference not active; should not be discovered");
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   302
      // Self-loop next, so as to make Ref not active.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   303
      java_lang_ref_Reference::set_next(obj, obj);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   304
      if (next_d == obj) {  // obj is last
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   305
        // Swap refs_list into pendling_list_addr and
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   306
        // set obj's discovered to what we read from pending_list_addr.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   307
        oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   308
        // Need oop_check on pending_list_addr above;
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   309
        // see special oop-check code at the end of
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   310
        // enqueue_discovered_reflists() further below.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   311
        java_lang_ref_Reference::set_discovered(obj, old); // old may be NULL
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   312
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    }
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   314
  } else { // Old behaviour
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   315
    // Walk down the list, copying the discovered field into
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   316
    // the next field and clearing the discovered field.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   317
    while (obj != next_d) {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   318
      obj = next_d;
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   319
      assert(obj->is_instanceRef(), "should be reference object");
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   320
      next_d = java_lang_ref_Reference::discovered(obj);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   321
      if (TraceReferenceGC && PrintGCDetails) {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   322
        gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   323
                               obj, next_d);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   324
      }
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   325
      assert(java_lang_ref_Reference::next(obj) == NULL,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   326
             "The reference should not be enqueued");
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   327
      if (next_d == obj) {  // obj is last
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   328
        // Swap refs_list into pendling_list_addr and
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   329
        // set obj's next to what we read from pending_list_addr.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   330
        oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   331
        // Need oop_check on pending_list_addr above;
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   332
        // see special oop-check code at the end of
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   333
        // enqueue_discovered_reflists() further below.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   334
        if (old == NULL) {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   335
          // obj should be made to point to itself, since
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   336
          // pending list was empty.
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   337
          java_lang_ref_Reference::set_next(obj, obj);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   338
        } else {
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   339
          java_lang_ref_Reference::set_next(obj, old);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   340
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
      } else {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   342
        java_lang_ref_Reference::set_next(obj, next_d);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      }
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   344
      java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
// Parallel enqueue task
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  RefProcEnqueueTask(ReferenceProcessor& ref_processor,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
                     DiscoveredList      discovered_refs[],
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   354
                     HeapWord*           pending_list_addr,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
                     int                 n_queues)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    : EnqueueTask(ref_processor, discovered_refs,
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   357
                  pending_list_addr, n_queues)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   360
  virtual void work(unsigned int work_id) {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   361
    assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    // Simplest first cut: static partitioning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    int index = work_id;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   364
    // The increment on "index" must correspond to the maximum number of queues
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   365
    // (n_queues) with which that ReferenceProcessor was created.  That
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   366
    // is because of the "clever" way the discovered references lists were
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   367
    // allocated and are indexed into.
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   368
    assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   369
    for (int j = 0;
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   370
         j < ReferenceProcessor::number_of_subclasses_of_ref();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   371
         j++, index += _n_queues) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
      _ref_processor.enqueue_discovered_reflist(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
        _refs_lists[index], _pending_list_addr);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   374
      _refs_lists[index].set_head(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
      _refs_lists[index].set_length(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// Enqueue references that are not made active again
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   381
void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  AbstractRefProcTaskExecutor* task_executor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  if (_processing_is_mt && task_executor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
    // Parallel code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   386
                           pending_list_addr, _max_num_q);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
    task_executor->execute(tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    // Serial code: call the parent class's implementation
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   390
    for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
      enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   392
      _discoveredSoftRefs[i].set_head(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
      _discoveredSoftRefs[i].set_length(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   398
void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   400
  oop discovered = java_lang_ref_Reference::discovered(_ref);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   401
  assert(_discovered_addr && discovered->is_oop_or_null(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
         "discovered field is bad");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   403
  _next = discovered;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   405
  _referent = java_lang_ref_Reference::referent(_ref);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  assert(Universe::heap()->is_in_reserved_or_null(_referent),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
         "Wrong oop found in java.lang.Reference object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  assert(allow_null_referent ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
             _referent->is_oop_or_null()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
           : _referent->is_oop(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
         "bad referent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   414
void DiscoveredListIterator::remove() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  assert(_ref->is_oop(), "Dropping a bad reference");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   416
  oop_store_raw(_discovered_addr, NULL);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   417
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   418
  // First _prev_next ref actually points into DiscoveredList (gross).
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   419
  oop new_next;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   420
  if (_next == _ref) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   421
    // At the end of the list, we should make _prev point to itself.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   422
    // If _ref is the first ref, then _prev_next will be in the DiscoveredList,
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   423
    // and _prev will be NULL.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   424
    new_next = _prev;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   425
  } else {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   426
    new_next = _next;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   427
  }
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   428
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   429
  if (UseCompressedOops) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   430
    // Remove Reference object from list.
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   431
    oopDesc::encode_store_heap_oop((narrowOop*)_prev_next, new_next);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   432
  } else {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   433
    // Remove Reference object from list.
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   434
    oopDesc::store_heap_oop((oop*)_prev_next, new_next);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   435
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  NOT_PRODUCT(_removed++);
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   437
  _refs_list.dec_length(1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   440
// Make the Reference object active again.
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   441
void DiscoveredListIterator::make_active() {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   442
  // For G1 we don't want to use set_next - it
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   443
  // will dirty the card for the next field of
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   444
  // the reference object and will fail
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   445
  // CT verification.
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   446
  if (UseG1GC) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   447
    BarrierSet* bs = oopDesc::bs();
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   448
    HeapWord* next_addr = java_lang_ref_Reference::next_addr(_ref);
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   449
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   450
    if (UseCompressedOops) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   451
      bs->write_ref_field_pre((narrowOop*)next_addr, NULL);
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   452
    } else {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   453
      bs->write_ref_field_pre((oop*)next_addr, NULL);
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   454
    }
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   455
    java_lang_ref_Reference::set_next_raw(_ref, NULL);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   456
  } else {
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   457
    java_lang_ref_Reference::set_next(_ref, NULL);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   458
  }
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   459
}
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   460
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   461
void DiscoveredListIterator::clear_referent() {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   462
  oop_store_raw(_referent_addr, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
// NOTE: process_phase*() are largely similar, and at a high level
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
// merely iterate over the extant list applying a predicate to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
// each of its elements and possibly removing that element from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
// list and applying some further closures to that element.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
// We should consider the possibility of replacing these
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
// process_phase*() methods by abstracting them into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
// a single general iterator invocation that receives appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
// closures that accomplish this work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
// (SoftReferences only) Traverse the list and remove any SoftReferences whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
// referents are not alive, but that should be kept alive for policy reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
// Keep alive the transitive closure of all such referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
void
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   478
ReferenceProcessor::process_phase1(DiscoveredList&    refs_list,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
                                   ReferencePolicy*   policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
                                   BoolObjectClosure* is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
                                   OopClosure*        keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
                                   VoidClosure*       complete_gc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  assert(policy != NULL, "Must have a non-NULL policy");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   484
  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  // Decide which softly reachable refs should be kept alive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    if (referent_is_dead && !policy->should_clear_reference(iter.obj())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
      if (TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
        gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   492
                               iter.obj(), iter.obj()->blueprint()->internal_name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      }
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   494
      // Remove Reference object from list
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   495
      iter.remove();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
      // Make the Reference object active again
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
      iter.make_active();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
      // keep the referent around
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      iter.make_referent_alive();
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   500
      iter.move_to_next();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  // Close the reachable set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  complete_gc->do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
    if (PrintGCDetails && TraceReferenceGC) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   509
      gclog_or_tty->print_cr(" Dropped %d dead Refs out of %d "
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
   510
        "discovered Refs by policy, from list " INTPTR_FORMAT,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   511
        iter.removed(), iter.processed(), (address)refs_list.head());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
// Traverse the list and remove any Refs that are not active, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
// whose referents are either alive or NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
void
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   519
ReferenceProcessor::pp2_work(DiscoveredList&    refs_list,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
                             BoolObjectClosure* is_alive,
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   521
                             OopClosure*        keep_alive) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  assert(discovery_is_atomic(), "Error");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   523
  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   526
    DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   527
    assert(next == NULL, "Should not discover inactive Reference");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    if (iter.is_referent_alive()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
      if (TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   531
                               iter.obj(), iter.obj()->blueprint()->internal_name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
      // The referent is reachable after all.
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   534
      // Remove Reference object from list.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   535
      iter.remove();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
      // Update the referent pointer as necessary: Note that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      // should not entail any recursive marking because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
      // referent must already have been traversed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
      iter.make_referent_alive();
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   540
      iter.move_to_next();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  NOT_PRODUCT(
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   546
    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   547
      gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   548
        "Refs in discovered list " INTPTR_FORMAT,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   549
        iter.removed(), iter.processed(), (address)refs_list.head());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
void
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   555
ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList&    refs_list,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   556
                                                  BoolObjectClosure* is_alive,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   557
                                                  OopClosure*        keep_alive,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   558
                                                  VoidClosure*       complete_gc) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  assert(!discovery_is_atomic(), "Error");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   560
  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   563
    HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   564
    oop next = java_lang_ref_Reference::next(iter.obj());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    if ((iter.referent() == NULL || iter.is_referent_alive() ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   566
         next != NULL)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   567
      assert(next->is_oop_or_null(), "bad next field");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      // Remove Reference object from list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
      iter.remove();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
      // Trace the cohorts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
      iter.make_referent_alive();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   572
      if (UseCompressedOops) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   573
        keep_alive->do_oop((narrowOop*)next_addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   574
      } else {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   575
        keep_alive->do_oop((oop*)next_addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   576
      }
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   577
      iter.move_to_next();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
      iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // Now close the newly reachable set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  complete_gc->do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  NOT_PRODUCT(
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   585
    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   586
      gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   587
        "Refs in discovered list " INTPTR_FORMAT,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   588
        iter.removed(), iter.processed(), (address)refs_list.head());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
// Traverse the list and process the referents, by either
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   594
// clearing them or keeping them (and their reachable
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
// closure) alive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
void
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   597
ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
                                   bool               clear_referent,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
                                   BoolObjectClosure* is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
                                   OopClosure*        keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
                                   VoidClosure*       complete_gc) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   602
  ResourceMark rm;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   603
  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    iter.update_discovered();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
    if (clear_referent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      // NULL out referent pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      iter.clear_referent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
      // keep the referent around
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
      iter.make_referent_alive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    if (TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
                             clear_referent ? "cleared " : "",
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   617
                             iter.obj(), iter.obj()->blueprint()->internal_name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
    assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  }
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   622
  // Remember to update the next pointer of the last ref.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  iter.update_discovered();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  // Close the reachable set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  complete_gc->do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
void
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   629
ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   630
  oop obj = NULL;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   631
  oop next = refs_list.head();
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   632
  while (next != obj) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   633
    obj = next;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   634
    next = java_lang_ref_Reference::discovered(obj);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   635
    java_lang_ref_Reference::set_discovered_raw(obj, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  }
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   637
  refs_list.set_head(NULL);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   638
  refs_list.set_length(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   641
void
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   642
ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   643
  clear_discovered_references(refs_list);
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   644
}
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   645
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
   646
void ReferenceProcessor::abandon_partial_discovery() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
   647
  // loop over the lists
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   648
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   649
    if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   650
      gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
   651
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
   652
    abandon_partial_discovered_list(_discoveredSoftRefs[i]);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
class RefProcPhase1Task: public AbstractRefProcTaskExecutor::ProcessTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  RefProcPhase1Task(ReferenceProcessor& ref_processor,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
                    DiscoveredList      refs_lists[],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
                    ReferencePolicy*    policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
                    bool                marks_oops_alive)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    : ProcessTask(ref_processor, refs_lists, marks_oops_alive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
      _policy(policy)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  virtual void work(unsigned int i, BoolObjectClosure& is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
                    OopClosure& keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
                    VoidClosure& complete_gc)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   669
    Thread* thr = Thread::current();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   670
    int refs_list_index = ((WorkerThread*)thr)->id();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   671
    _ref_processor.process_phase1(_refs_lists[refs_list_index], _policy,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
                                  &is_alive, &keep_alive, &complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  ReferencePolicy* _policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
class RefProcPhase2Task: public AbstractRefProcTaskExecutor::ProcessTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  RefProcPhase2Task(ReferenceProcessor& ref_processor,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
                    DiscoveredList      refs_lists[],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
                    bool                marks_oops_alive)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
    : ProcessTask(ref_processor, refs_lists, marks_oops_alive)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  virtual void work(unsigned int i, BoolObjectClosure& is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
                    OopClosure& keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
                    VoidClosure& complete_gc)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
    _ref_processor.process_phase2(_refs_lists[i],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
                                  &is_alive, &keep_alive, &complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
class RefProcPhase3Task: public AbstractRefProcTaskExecutor::ProcessTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  RefProcPhase3Task(ReferenceProcessor& ref_processor,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
                    DiscoveredList      refs_lists[],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
                    bool                clear_referent,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
                    bool                marks_oops_alive)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    : ProcessTask(ref_processor, refs_lists, marks_oops_alive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
      _clear_referent(clear_referent)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  virtual void work(unsigned int i, BoolObjectClosure& is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
                    OopClosure& keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
                    VoidClosure& complete_gc)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   707
    // Don't use "refs_list_index" calculated in this way because
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   708
    // balance_queues() has moved the Ref's into the first n queues.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   709
    // Thread* thr = Thread::current();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   710
    // int refs_list_index = ((WorkerThread*)thr)->id();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   711
    // _ref_processor.process_phase3(_refs_lists[refs_list_index], _clear_referent,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    _ref_processor.process_phase3(_refs_lists[i], _clear_referent,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
                                  &is_alive, &keep_alive, &complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  bool _clear_referent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   719
void ReferenceProcessor::set_discovered(oop ref, oop value) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   720
  if (_discovered_list_needs_barrier) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   721
    java_lang_ref_Reference::set_discovered(ref, value);
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   722
  } else {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   723
    java_lang_ref_Reference::set_discovered_raw(ref, value);
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   724
  }
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   725
}
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   726
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
// Balances reference queues.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   728
// Move entries from all queues[0, 1, ..., _max_num_q-1] to
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   729
// queues[0, 1, ..., _num_q-1] because only the first _num_q
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   730
// corresponding to the active workers will be processed.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // calculate total length
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  size_t total_refs = 0;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   735
  if (TraceReferenceGC && PrintGCDetails) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   736
    gclog_or_tty->print_cr("\nBalance ref_lists ");
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   737
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   738
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   739
  for (int i = 0; i < _max_num_q; ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    total_refs += ref_lists[i].length();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   741
    if (TraceReferenceGC && PrintGCDetails) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   742
      gclog_or_tty->print("%d ", ref_lists[i].length());
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   743
    }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   744
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   745
  if (TraceReferenceGC && PrintGCDetails) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   746
    gclog_or_tty->print_cr(" = %d", total_refs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  size_t avg_refs = total_refs / _num_q + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  int to_idx = 0;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   750
  for (int from_idx = 0; from_idx < _max_num_q; from_idx++) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   751
    bool move_all = false;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   752
    if (from_idx >= _num_q) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   753
      move_all = ref_lists[from_idx].length() > 0;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   754
    }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   755
    while ((ref_lists[from_idx].length() > avg_refs) ||
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   756
           move_all) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
      assert(to_idx < _num_q, "Sanity Check!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
      if (ref_lists[to_idx].length() < avg_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
        // move superfluous refs
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   760
        size_t refs_to_move;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   761
        // Move all the Ref's if the from queue will not be processed.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   762
        if (move_all) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   763
          refs_to_move = MIN2(ref_lists[from_idx].length(),
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   764
                              avg_refs - ref_lists[to_idx].length());
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   765
        } else {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   766
          refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   767
                              avg_refs - ref_lists[to_idx].length());
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   768
        }
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   769
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   770
        assert(refs_to_move > 0, "otherwise the code below will fail");
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   771
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
        oop move_head = ref_lists[from_idx].head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
        oop move_tail = move_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
        oop new_head  = move_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
        // find an element to split the list on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
        for (size_t j = 0; j < refs_to_move; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
          move_tail = new_head;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   778
          new_head = java_lang_ref_Reference::discovered(new_head);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
        }
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   780
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   781
        // Add the chain to the to list.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   782
        if (ref_lists[to_idx].head() == NULL) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   783
          // to list is empty. Make a loop at the end.
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   784
          set_discovered(move_tail, move_tail);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   785
        } else {
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   786
          set_discovered(move_tail, ref_lists[to_idx].head());
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   787
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
        ref_lists[to_idx].set_head(move_head);
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   789
        ref_lists[to_idx].inc_length(refs_to_move);
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   790
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   791
        // Remove the chain from the from list.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   792
        if (move_tail == new_head) {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   793
          // We found the end of the from list.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   794
          ref_lists[from_idx].set_head(NULL);
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   795
        } else {
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   796
          ref_lists[from_idx].set_head(new_head);
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
   797
        }
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   798
        ref_lists[from_idx].dec_length(refs_to_move);
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   799
        if (ref_lists[from_idx].length() == 0) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   800
          break;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   801
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
      } else {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   803
        to_idx = (to_idx + 1) % _num_q;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
  }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   807
#ifdef ASSERT
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   808
  size_t balanced_total_refs = 0;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   809
  for (int i = 0; i < _max_num_q; ++i) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   810
    balanced_total_refs += ref_lists[i].length();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   811
    if (TraceReferenceGC && PrintGCDetails) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   812
      gclog_or_tty->print("%d ", ref_lists[i].length());
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   813
    }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   814
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   815
  if (TraceReferenceGC && PrintGCDetails) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   816
    gclog_or_tty->print_cr(" = %d", balanced_total_refs);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   817
    gclog_or_tty->flush();
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   818
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   819
  assert(total_refs == balanced_total_refs, "Balancing was incomplete");
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   820
#endif
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   821
}
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   822
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   823
void ReferenceProcessor::balance_all_queues() {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   824
  balance_queues(_discoveredSoftRefs);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   825
  balance_queues(_discoveredWeakRefs);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   826
  balance_queues(_discoveredFinalRefs);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   827
  balance_queues(_discoveredPhantomRefs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
ReferenceProcessor::process_discovered_reflist(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  DiscoveredList               refs_lists[],
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  ReferencePolicy*             policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  bool                         clear_referent,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  BoolObjectClosure*           is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  OopClosure*                  keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  VoidClosure*                 complete_gc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  AbstractRefProcTaskExecutor* task_executor)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
{
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   840
  bool mt_processing = task_executor != NULL && _processing_is_mt;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   841
  // If discovery used MT and a dynamic number of GC threads, then
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   842
  // the queues must be balanced for correctness if fewer than the
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   843
  // maximum number of queues were used.  The number of queue used
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   844
  // during discovery may be different than the number to be used
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   845
  // for processing so don't depend of _num_q < _max_num_q as part
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   846
  // of the test.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   847
  bool must_balance = _discovery_is_mt;
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   848
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   849
  if ((mt_processing && ParallelRefProcBalancingEnabled) ||
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   850
      must_balance) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
    balance_queues(refs_lists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  if (PrintReferenceGC && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
    size_t total = 0;
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   855
    for (int i = 0; i < _max_num_q; ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
      total += refs_lists[i].length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    gclog_or_tty->print(", %u refs", total);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  // Phase 1 (soft refs only):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  // . Traverse the list and remove any SoftReferences whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
  //   referents are not alive, but that should be kept alive for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
  //   policy reasons. Keep alive the transitive closure of all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  //   such referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
  if (policy != NULL) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   867
    if (mt_processing) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
      RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
      task_executor->execute(phase1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    } else {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   871
      for (int i = 0; i < _max_num_q; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
        process_phase1(refs_lists[i], policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
                       is_alive, keep_alive, complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  } else { // policy == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    assert(refs_lists != _discoveredSoftRefs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
           "Policy must be specified for soft references.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // Phase 2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // . Traverse the list and remove any refs whose referents are alive.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   883
  if (mt_processing) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
    RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
    task_executor->execute(phase2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  } else {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   887
    for (int i = 0; i < _max_num_q; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  // Phase 3:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  // . Traverse the list and process referents as appropriate.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   894
  if (mt_processing) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
    RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    task_executor->execute(phase3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  } else {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   898
    for (int i = 0; i < _max_num_q; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
      process_phase3(refs_lists[i], clear_referent,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
                     is_alive, keep_alive, complete_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
void ReferenceProcessor::clean_up_discovered_references() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  // loop over the lists
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
   907
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
   908
    if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
        "\nScrubbing %s discovered list of Null referents",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
        list_name(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    clean_up_discovered_reflist(_discoveredSoftRefs[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  assert(!discovery_is_atomic(), "Else why call this method?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  DiscoveredListIterator iter(refs_list, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   922
    oop next = java_lang_ref_Reference::next(iter.obj());
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   923
    assert(next->is_oop_or_null(), "bad next field");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    // If referent has been cleared or Reference is not active,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
    // drop it.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   926
    if (iter.referent() == NULL || next != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
      debug_only(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
        if (PrintGCDetails && TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
          gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
            INTPTR_FORMAT " with next field: " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
            " and referent: " INTPTR_FORMAT,
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   932
            iter.obj(), next, iter.referent());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
      )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
      // Remove Reference object from list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
      iter.remove();
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
   937
      iter.move_to_next();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
      iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
    if (PrintGCDetails && TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      gclog_or_tty->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
        " Removed %d Refs with NULL referents out of %d discovered Refs",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
        iter.removed(), iter.processed());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  int id = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  // Determine the queue index to use for this object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  if (_discovery_is_mt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
    // During a multi-threaded discovery phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    // each thread saves to its "own" list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
    Thread* thr = Thread::current();
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
   958
    id = thr->as_Worker_thread()->id();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    // single-threaded discovery, we save in round-robin
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
    // fashion to each of the lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    if (_processing_is_mt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
      id = next_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   966
  assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  // Get the discovered queue to which we will add
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  DiscoveredList* list = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  switch (rt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
    case REF_OTHER:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
      // Unknown reference type, no special treatment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
    case REF_SOFT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      list = &_discoveredSoftRefs[id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
    case REF_WEAK:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
      list = &_discoveredWeakRefs[id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
    case REF_FINAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
      list = &_discoveredFinalRefs[id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
    case REF_PHANTOM:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
      list = &_discoveredPhantomRefs[id];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
    case REF_NONE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
      // we should not reach here if we are an instanceRefKlass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   991
  if (TraceReferenceGC && PrintGCDetails) {
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
   992
    gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, id, list);
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
   993
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  return list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   997
inline void
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   998
ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
   999
                                              oop             obj,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1000
                                              HeapWord*       discovered_addr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  assert(_discovery_is_mt, "!_discovery_is_mt should have been handled by caller");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  // First we must make sure this object is only enqueued once. CAS in a non null
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // discovered_addr.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1004
  oop current_head = refs_list.head();
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1005
  // The last ref must have its discovered field pointing to itself.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1006
  oop next_discovered = (current_head != NULL) ? current_head : obj;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1007
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
  1008
  // Note: In the case of G1, this specific pre-barrier is strictly
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1009
  // not necessary because the only case we are interested in
3262
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
  1010
  // here is when *discovered_addr is NULL (see the CAS further below),
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
  1011
  // so this will expand to nothing. As a result, we have manually
30d1c247fc25 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 2105
diff changeset
  1012
  // elided this out for G1, but left in the test for some future
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1013
  // collector that might have need for a pre-barrier here, e.g.:-
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1014
  // _bs->write_ref_field_pre((oop* or narrowOop*)discovered_addr, next_discovered);
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1015
  assert(!_discovered_list_needs_barrier || UseG1GC,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1016
         "Need to check non-G1 collector: "
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1017
         "may need a pre-write-barrier for CAS from NULL below");
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1018
  oop retest = oopDesc::atomic_compare_exchange_oop(next_discovered, discovered_addr,
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1019
                                                    NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  if (retest == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    // This thread just won the right to enqueue the object.
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1022
    // We have separate lists for enqueueing, so no synchronization
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    // is necessary.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1024
    refs_list.set_head(obj);
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1025
    refs_list.inc_length(1);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1026
    if (_discovered_list_needs_barrier) {
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1027
      _bs->write_ref_field((void*)discovered_addr, next_discovered);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1028
    }
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1029
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1030
    if (TraceReferenceGC) {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1031
      gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1032
                             obj, obj->blueprint()->internal_name());
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1033
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    // If retest was non NULL, another thread beat us to it:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    // The reference has already been discovered...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
    if (TraceReferenceGC) {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1038
      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
                             obj, obj->blueprint()->internal_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
7420
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1044
#ifndef PRODUCT
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1045
// Non-atomic (i.e. concurrent) discovery might allow us
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1046
// to observe j.l.References with NULL referents, being those
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1047
// cleared concurrently by mutators during (or after) discovery.
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1048
void ReferenceProcessor::verify_referent(oop obj) {
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1049
  bool da = discovery_is_atomic();
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1050
  oop referent = java_lang_ref_Reference::referent(obj);
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1051
  assert(da ? referent->is_oop() : referent->is_oop_or_null(),
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1052
         err_msg("Bad referent " INTPTR_FORMAT " found in Reference "
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1053
                 INTPTR_FORMAT " during %satomic discovery ",
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1054
                 (intptr_t)referent, (intptr_t)obj, da ? "" : "non-"));
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1055
}
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1056
#endif
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1057
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
// We mention two of several possible choices here:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
// #0: if the reference object is not in the "originating generation"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
//     (or part of the heap being collected, indicated by our "span"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
//     we don't treat it specially (i.e. we scan it as we would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
//     a normal oop, treating its references as strong references).
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1063
//     This means that references can't be discovered unless their
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
//     referent is also in the same span. This is the simplest,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
//     most "local" and most conservative approach, albeit one
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
//     that may cause weak references to be enqueued least promptly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
//     We call this choice the "ReferenceBasedDiscovery" policy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
// #1: the reference object may be in any generation (span), but if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
//     the referent is in the generation (span) being currently collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
//     then we can discover the reference object, provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
//     the object has not already been discovered by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
//     a different concurrently running collector (as may be the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
//     case, for instance, if the reference object is in CMS and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
//     the referent in DefNewGeneration), and provided the processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
//     of this reference object by the current collector will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
//     appear atomic to every other collector in the system.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
//     (Thus, for instance, a concurrent collector may not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
//     discover references in other generations even if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
//     referent is in its own generation). This policy may,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
//     in certain cases, enqueue references somewhat sooner than
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
//     might Policy #0 above, but at marginally increased cost
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
//     and complexity in processing these references.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
//     We call this choice the "RefeferentBasedDiscovery" policy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1085
  // Make sure we are discovering refs (rather than processing discovered refs).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  if (!_discovering_refs || !RegisterReferences) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
  }
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1089
  // We only discover active references.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1090
  oop next = java_lang_ref_Reference::next(obj);
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1091
  if (next != NULL) {   // Ref is no longer active
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  HeapWord* obj_addr = (HeapWord*)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
  if (RefDiscoveryPolicy == ReferenceBasedDiscovery &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
      !_span.contains(obj_addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    // Reference is not in the originating generation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    // don't treat it specially (i.e. we want to scan it as a normal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    // object with strong references).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1104
  // We only discover references whose referents are not (yet)
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1105
  // known to be strongly reachable.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
  if (is_alive_non_header() != NULL) {
7420
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1107
    verify_referent(obj);
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1108
    if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
      return false;  // referent is reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  }
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1112
  if (rt == REF_SOFT) {
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1113
    // For soft refs we can decide now if these are not
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1114
    // current candidates for clearing, in which case we
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1115
    // can mark through them now, rather than delaying that
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1116
    // to the reference-processing phase. Since all current
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1117
    // time-stamp policies advance the soft-ref clock only
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1118
    // at a major collection cycle, this is always currently
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1119
    // accurate.
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1120
    if (!_current_soft_ref_policy->should_clear_reference(obj)) {
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1121
      return false;
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1122
    }
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1123
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1125
  ResourceMark rm;      // Needed for tracing.
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1126
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1127
  HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1128
  const oop  discovered = java_lang_ref_Reference::discovered(obj);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1129
  assert(discovered->is_oop_or_null(), "bad discovered field");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1130
  if (discovered != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
    // The reference has already been discovered...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
    if (TraceReferenceGC) {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1133
      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1134
                             obj, obj->blueprint()->internal_name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
    if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
      // assumes that an object is not processed twice;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
      // if it's been already discovered it must be on another
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
      // generation's discovered list; so we won't discover it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
      assert(RefDiscoveryPolicy == ReferenceBasedDiscovery,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
             "Unrecognized policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
      // Check assumption that an object is not potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
      // discovered twice except by concurrent collectors that potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
      // trace the same Reference object twice.
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1147
      assert(UseConcMarkSweepGC || UseG1GC,
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1148
             "Only possible with a concurrent marking collector");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
7420
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1154
    verify_referent(obj);
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1155
    // Discover if and only if EITHER:
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1156
    // .. reference is in our span, OR
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1157
    // .. we are an atomic collector and referent is in our span
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
    if (_span.contains(obj_addr) ||
7420
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1159
        (discovery_is_atomic() &&
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1160
         _span.contains(java_lang_ref_Reference::referent(obj)))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
      // should_enqueue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
    assert(RefDiscoveryPolicy == ReferenceBasedDiscovery &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
           _span.contains(obj_addr), "code inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  // Get the right type of discovered queue head.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  DiscoveredList* list = get_discovered_list(rt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  if (list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
    return false;   // nothing special needs to be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  if (_discovery_is_mt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
    add_to_discovered_list_mt(*list, obj, discovered_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  } else {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1179
    // If "_discovered_list_needs_barrier", we do write barriers when
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1180
    // updating the discovered reference list.  Otherwise, we do a raw store
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1181
    // here: the field will be visited later when processing the discovered
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1182
    // references.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1183
    oop current_head = list->head();
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1184
    // The last ref must have its discovered field pointing to itself.
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1185
    oop next_discovered = (current_head != NULL) ? current_head : obj;
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1186
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1187
    // As in the case further above, since we are over-writing a NULL
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1188
    // pre-value, we can safely elide the pre-barrier here for the case of G1.
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1189
    // e.g.:- _bs->write_ref_field_pre((oop* or narrowOop*)discovered_addr, next_discovered);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1190
    assert(discovered == NULL, "control point invariant");
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1191
    assert(!_discovered_list_needs_barrier || UseG1GC,
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1192
           "For non-G1 collector, may need a pre-write-barrier for CAS from NULL below");
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1193
    oop_store_raw(discovered_addr, next_discovered);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1194
    if (_discovered_list_needs_barrier) {
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1195
      _bs->write_ref_field((void*)discovered_addr, next_discovered);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 360
diff changeset
  1196
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    list->set_head(obj);
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1198
    list->inc_length(1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1200
    if (TraceReferenceGC) {
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1201
      gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
7399
4ecd771fa2d1 6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents: 7397
diff changeset
  1202
                                obj, obj->blueprint()->internal_name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
  }
10526
3e92f211533f 4965777: GC changes to support use of discovered field for pending references
ysr
parents: 10524
diff changeset
  1205
  assert(obj->is_oop(), "Discovered a bad reference");
7420
24071b15dde6 7005259: CMS: BubbleUpRef asserts referent(obj)->is_oop() failed: Enqueued a bad referent
ysr
parents: 7399
diff changeset
  1206
  verify_referent(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
// Preclean the discovered references by removing those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
// whose referents are alive, and by marking from those that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
// are not active. These lists can be handled here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
// in any order and, indeed, concurrently.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
void ReferenceProcessor::preclean_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
  BoolObjectClosure* is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
  OopClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  VoidClosure* complete_gc,
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4573
diff changeset
  1218
  YieldClosure* yield,
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4573
diff changeset
  1219
  bool should_unload_classes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
  NOT_PRODUCT(verify_ok_to_handle_reflists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 3262
diff changeset
  1223
#ifdef ASSERT
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 3262
diff changeset
  1224
  bool must_remember_klasses = ClassUnloading && !UseConcMarkSweepGC ||
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4573
diff changeset
  1225
                               CMSClassUnloadingEnabled && UseConcMarkSweepGC ||
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4573
diff changeset
  1226
                               ExplicitGCInvokesConcurrentAndUnloadsClasses &&
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4573
diff changeset
  1227
                                 UseConcMarkSweepGC && should_unload_classes;
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 3262
diff changeset
  1228
  RememberKlassesChecker mx(must_remember_klasses);
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 3262
diff changeset
  1229
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  // Soft references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
    TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
              false, gclog_or_tty);
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
  1234
    for (int i = 0; i < _max_num_q; i++) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1235
      if (yield->should_return()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1236
        return;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1237
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
      preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
                                  keep_alive, complete_gc, yield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
  // Weak references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
    TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
              false, gclog_or_tty);
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
  1247
    for (int i = 0; i < _max_num_q; i++) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1248
      if (yield->should_return()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1249
        return;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1250
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
      preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
                                  keep_alive, complete_gc, yield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  // Final references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
    TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
              false, gclog_or_tty);
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
  1260
    for (int i = 0; i < _max_num_q; i++) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1261
      if (yield->should_return()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1262
        return;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1263
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
      preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
                                  keep_alive, complete_gc, yield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
  // Phantom references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
    TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
              false, gclog_or_tty);
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
  1273
    for (int i = 0; i < _max_num_q; i++) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1274
      if (yield->should_return()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1275
        return;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1276
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
      preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
                                  keep_alive, complete_gc, yield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
// Walk the given discovered ref list, and remove all reference objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
// whose referents are still alive, whose referents are NULL or which
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1285
// are not active (have a non-NULL next field). NOTE: When we are
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1286
// thus precleaning the ref lists (which happens single-threaded today),
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1287
// we do not disable refs discovery to honour the correct semantics of
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1288
// java.lang.Reference. As a result, we need to be careful below
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1289
// that ref removal steps interleave safely with ref discovery steps
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1290
// (in this thread).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1291
void
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1292
ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1293
                                                BoolObjectClosure* is_alive,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1294
                                                OopClosure*        keep_alive,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1295
                                                VoidClosure*       complete_gc,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1296
                                                YieldClosure*      yield) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
  while (iter.has_next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1300
    oop obj = iter.obj();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1301
    oop next = java_lang_ref_Reference::next(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    if (iter.referent() == NULL || iter.is_referent_alive() ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1303
        next != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
      // The referent has been cleared, or is alive, or the Reference is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
      // active; we need to trace and mark its cohort.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
      if (TraceReferenceGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
        gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
                               iter.obj(), iter.obj()->blueprint()->internal_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
      // Remove Reference object from list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
      iter.remove();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
      // Keep alive its cohort.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
      iter.make_referent_alive();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1314
      if (UseCompressedOops) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1315
        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1316
        keep_alive->do_oop(next_addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1317
      } else {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1318
        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1319
        keep_alive->do_oop(next_addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 178
diff changeset
  1320
      }
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1388
diff changeset
  1321
      iter.move_to_next();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
      iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  // Close the reachable set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
  complete_gc->do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
  NOT_PRODUCT(
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 7420
diff changeset
  1330
    if (PrintGCDetails && PrintReferenceGC && (iter.processed() > 0)) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
  1331
      gclog_or_tty->print_cr(" Dropped %d Refs out of %d "
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
  1332
        "Refs in discovered list " INTPTR_FORMAT,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
  1333
        iter.removed(), iter.processed(), (address)refs_list.head());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
const char* ReferenceProcessor::list_name(int i) {
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1339
   assert(i >= 0 && i <= _max_num_q * number_of_subclasses_of_ref(),
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1340
          "Out of bounds index");
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1341
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 5547
diff changeset
  1342
   int j = i / _max_num_q;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
   switch (j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
     case 0: return "SoftRef";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
     case 1: return "WeakRef";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
     case 2: return "FinalRef";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
     case 3: return "PhantomRef";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
   ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
   return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
void ReferenceProcessor::verify_ok_to_handle_reflists() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  // empty for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
void ReferenceProcessor::clear_discovered_references() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  guarantee(!_discovering_refs, "Discovering refs?");
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10526
diff changeset
  1362
  for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1363
    clear_discovered_references(_discoveredSoftRefs[i]);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
}
10524
6594ca81279a 7085906: Replace the permgen allocated sentinelRef with a self-looped end
stefank
parents: 8688
diff changeset
  1366
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
#endif // PRODUCT