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