instanceRefKlass.cpp 25.4 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/preserveException.hpp"
#ifndef SERIALGC
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#endif
D
duke 已提交
46

47
template <class T>
48
void specialized_oop_follow_contents(instanceRefKlass* ref, oop obj) {
49
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
50
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
D
duke 已提交
51 52
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
53
      gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
D
duke 已提交
54 55
    }
  )
56 57
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
D
duke 已提交
58
    if (!referent->is_gc_marked() &&
59 60
        MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
      // reference was discovered, referent will be traversed later
61
      ref->InstanceKlass::oop_follow_contents(obj);
D
duke 已提交
62 63
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
64
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
D
duke 已提交
65 66 67 68 69 70 71
        }
      )
      return;
    } else {
      // treat referent as normal oop
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
72
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, obj);
D
duke 已提交
73 74 75 76 77
        }
      )
      MarkSweep::mark_and_push(referent_addr);
    }
  }
78
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    // Treat discovered as normal oop, if ref is not "active",
    // i.e. if next is non-NULL.
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      MarkSweep::mark_and_push(discovered_addr);
    }
  } else {
#ifdef ASSERT
    // In the case of older JDKs which do not use the discovered
    // field for the pending list, an inactive ref (next != NULL)
    // must always have a NULL discovered field.
    oop next = oopDesc::load_decode_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
102
                   (oopDesc*)obj));
103 104 105
#endif
  }
  // treat next as normal oop.  next is a link in the reference queue.
D
duke 已提交
106 107 108 109 110 111
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    }
  )
  MarkSweep::mark_and_push(next_addr);
112
  ref->InstanceKlass::oop_follow_contents(obj);
113 114 115 116 117 118 119 120
}

void instanceRefKlass::oop_follow_contents(oop obj) {
  if (UseCompressedOops) {
    specialized_oop_follow_contents<narrowOop>(this, obj);
  } else {
    specialized_oop_follow_contents<oop>(this, obj);
  }
D
duke 已提交
121 122 123
}

#ifndef SERIALGC
124
template <class T>
125 126 127
void specialized_oop_follow_contents(instanceRefKlass* ref,
                                     ParCompactionManager* cm,
                                     oop obj) {
128
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
129
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
D
duke 已提交
130 131
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
132
      gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
D
duke 已提交
133 134
    }
  )
135 136
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
D
duke 已提交
137 138
    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
        PSParallelCompact::ref_processor()->
139
          discover_reference(obj, ref->reference_type())) {
D
duke 已提交
140
      // reference already enqueued, referent will be traversed later
141
      ref->InstanceKlass::oop_follow_contents(cm, obj);
D
duke 已提交
142 143
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
144
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
D
duke 已提交
145 146 147 148 149 150 151
        }
      )
      return;
    } else {
      // treat referent as normal oop
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
152
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, obj);
D
duke 已提交
153 154 155 156 157
        }
      )
      PSParallelCompact::mark_and_push(cm, referent_addr);
    }
  }
158
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
159 160 161 162 163 164 165 166 167 168 169 170 171
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    // Treat discovered as normal oop, if ref is not "active",
    // i.e. if next is non-NULL.
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      PSParallelCompact::mark_and_push(cm, discovered_addr);
D
duke 已提交
172
    }
173 174 175 176 177 178 179 180 181
  } else {
#ifdef ASSERT
    // In the case of older JDKs which do not use the discovered
    // field for the pending list, an inactive ref (next != NULL)
    // must always have a NULL discovered field.
    T next = oopDesc::load_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
182
                   (oopDesc*)obj));
183 184
#endif
  }
D
duke 已提交
185
  PSParallelCompact::mark_and_push(cm, next_addr);
186
  ref->InstanceKlass::oop_follow_contents(cm, obj);
D
duke 已提交
187 188
}

189 190 191 192 193 194 195 196 197
void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
                                           oop obj) {
  if (UseCompressedOops) {
    specialized_oop_follow_contents<narrowOop>(this, cm, obj);
  } else {
    specialized_oop_follow_contents<oop>(this, cm, obj);
  }
}
#endif // SERIALGC
D
duke 已提交
198 199

#ifdef ASSERT
200 201 202 203
template <class T> void trace_reference_gc(const char *s, oop obj,
                                           T* referent_addr,
                                           T* next_addr,
                                           T* discovered_addr) {
D
duke 已提交
204
  if(TraceReferenceGC && PrintGCDetails) {
205
    gclog_or_tty->print_cr("%s obj " INTPTR_FORMAT, s, (address)obj);
D
duke 已提交
206
    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
207 208 209
         INTPTR_FORMAT, referent_addr,
         referent_addr ?
           (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL);
D
duke 已提交
210
    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
211 212
         INTPTR_FORMAT, next_addr,
         next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL);
D
duke 已提交
213
    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
214 215 216
         INTPTR_FORMAT, discovered_addr,
         discovered_addr ?
           (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL);
D
duke 已提交
217
  }
218
}
D
duke 已提交
219 220
#endif

221 222 223 224 225 226 227 228 229 230 231 232 233
template <class T> void specialized_oop_adjust_pointers(instanceRefKlass *ref, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  MarkSweep::adjust_pointer(referent_addr);
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  MarkSweep::adjust_pointer(next_addr);
  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
  MarkSweep::adjust_pointer(discovered_addr);
  debug_only(trace_reference_gc("instanceRefKlass::oop_adjust_pointers", obj,
                                referent_addr, next_addr, discovered_addr);)
}

int instanceRefKlass::oop_adjust_pointers(oop obj) {
  int size = size_helper();
234
  InstanceKlass::oop_adjust_pointers(obj);
235 236 237 238 239 240

  if (UseCompressedOops) {
    specialized_oop_adjust_pointers<narrowOop>(this, obj);
  } else {
    specialized_oop_adjust_pointers<oop>(this, obj);
  }
D
duke 已提交
241 242 243
  return size;
}

244
#define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
245
  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);             \
246 247 248 249
  if (closure->apply_to_weak_ref_discovered_field()) {                          \
    closure->do_oop##nv_suffix(disc_addr);                                      \
  }                                                                             \
                                                                                \
250
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
251
  T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
252 253
  ReferenceProcessor* rp = closure->_ref_processor;                             \
  if (!oopDesc::is_null(heap_oop)) {                                            \
254
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
D
duke 已提交
255
    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
256
        rp->discover_reference(obj, reference_type())) {                        \
D
duke 已提交
257
      return size;                                                              \
258
    } else if (contains(referent_addr)) {                                       \
D
duke 已提交
259 260 261 262 263
      /* treat referent as normal oop */                                        \
      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
      closure->do_oop##nv_suffix(referent_addr);                                \
    }                                                                           \
  }                                                                             \
264
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {               \
    T next_oop  = oopDesc::load_heap_oop(next_addr);                            \
    /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\
    if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {                   \
        /* i.e. ref is not "active" */                                          \
      debug_only(                                                               \
        if(TraceReferenceGC && PrintGCDetails) {                                \
          gclog_or_tty->print_cr("   Process discovered as normal "             \
                                 INTPTR_FORMAT, disc_addr);                     \
        }                                                                       \
      )                                                                         \
      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
      closure->do_oop##nv_suffix(disc_addr);                                    \
    }                                                                           \
  } else {                                                                      \
    /* In the case of older JDKs which do not use the discovered field for  */  \
    /* the pending list, an inactive ref (next != NULL) must always have a  */  \
    /* NULL discovered field. */                                                \
    debug_only(                                                                 \
      T next_oop = oopDesc::load_heap_oop(next_addr);                           \
      T disc_oop = oopDesc::load_heap_oop(disc_addr);                           \
      assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),          \
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \
288
                   "discovered field", (oopDesc*)obj));                                   \
289 290 291
    )                                                                           \
  }                                                                             \
  /* treat next as normal oop */                                                \
292 293 294 295
  if (contains(next_addr)) {                                                    \
    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
    closure->do_oop##nv_suffix(next_addr);                                      \
  }                                                                             \
D
duke 已提交
296
  return size;                                                                  \
297 298 299 300 301 302 303 304 305 306 307 308 309 310


template <class T> bool contains(T *t) { return true; }

// Macro to define instanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
// all closures.  Macros calling macros above for each oop size.

#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
                                                                                \
int instanceRefKlass::                                                          \
oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
  /* Get size before changing pointers */                                       \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
311
  int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
312 313 314 315 316 317
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
D
duke 已提交
318 319
}

320 321 322 323 324 325 326 327
#ifndef SERIALGC
#define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
                                                                                \
int instanceRefKlass::                                                          \
oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
  /* Get size before changing pointers */                                       \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
328
  int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
329 330 331 332 333 334 335 336 337 338
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
}
#endif // !SERIALGC


D
duke 已提交
339 340 341 342 343 344 345 346
#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
                                                                                \
int instanceRefKlass::                                                          \
oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
                               OopClosureType* closure,                         \
                               MemRegion mr) {                                  \
  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
                                                                                \
347
  int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
348 349 350 351
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr.contains);      \
D
duke 已提交
352 353 354 355
  }                                                                             \
}

ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
356 357 358 359 360
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
#ifndef SERIALGC
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
#endif // SERIALGC
D
duke 已提交
361
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
362
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
D
duke 已提交
363 364

#ifndef SERIALGC
365 366 367 368 369
template <class T>
void specialized_oop_push_contents(instanceRefKlass *ref,
                                   PSPromotionManager* pm, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  if (PSScavenge::should_scavenge(referent_addr)) {
D
duke 已提交
370
    ReferenceProcessor* rp = PSScavenge::reference_processor();
371
    if (rp->discover_reference(obj, ref->reference_type())) {
D
duke 已提交
372
      // reference already enqueued, referent and next will be traversed later
373
      ref->InstanceKlass::oop_push_contents(pm, obj);
D
duke 已提交
374 375 376 377 378 379
      return;
    } else {
      // treat referent as normal oop
      pm->claim_or_forward_depth(referent_addr);
    }
  }
380 381
  // Treat discovered as normal oop, if ref is not "active",
  // i.e. if next is non-NULL.
382
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
    T  next_oop = oopDesc::load_heap_oop(next_addr);
    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
          gclog_or_tty->print_cr("   Process discovered as normal "
                                 INTPTR_FORMAT, discovered_addr);
        }
      )
      if (PSScavenge::should_scavenge(discovered_addr)) {
        pm->claim_or_forward_depth(discovered_addr);
      }
    }
  } else {
#ifdef ASSERT
    // In the case of older JDKs which do not use the discovered
    // field for the pending list, an inactive ref (next != NULL)
    // must always have a NULL discovered field.
    oop next = oopDesc::load_decode_heap_oop(next_addr);
    oop discovered = java_lang_ref_Reference::discovered(obj);
    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
406
                   (oopDesc*)obj));
407 408 409 410
#endif
  }

  // Treat next as normal oop;  next is a link in the reference queue.
411
  if (PSScavenge::should_scavenge(next_addr)) {
D
duke 已提交
412 413
    pm->claim_or_forward_depth(next_addr);
  }
414
  ref->InstanceKlass::oop_push_contents(pm, obj);
D
duke 已提交
415 416
}

417 418 419 420 421 422 423
void instanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
  if (UseCompressedOops) {
    specialized_oop_push_contents<narrowOop>(this, pm, obj);
  } else {
    specialized_oop_push_contents<oop>(this, pm, obj);
  }
}
D
duke 已提交
424

425 426 427 428
template <class T>
void specialized_oop_update_pointers(instanceRefKlass *ref,
                                    ParCompactionManager* cm, oop obj) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
D
duke 已提交
429
  PSParallelCompact::adjust_pointer(referent_addr);
430
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
D
duke 已提交
431
  PSParallelCompact::adjust_pointer(next_addr);
432
  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
D
duke 已提交
433
  PSParallelCompact::adjust_pointer(discovered_addr);
434 435 436
  debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj,
                                referent_addr, next_addr, discovered_addr);)
}
D
duke 已提交
437

438
int instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
439
  InstanceKlass::oop_update_pointers(cm, obj);
440 441 442 443
  if (UseCompressedOops) {
    specialized_oop_update_pointers<narrowOop>(this, cm, obj);
  } else {
    specialized_oop_update_pointers<oop>(this, cm, obj);
D
duke 已提交
444 445 446 447 448
  }
  return size_helper();
}
#endif // SERIALGC

449
void instanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
D
duke 已提交
450 451 452 453 454
  // Clear the nonstatic oop-map entries corresponding to referent
  // and nextPending field.  They are treated specially by the
  // garbage collector.
  // The discovered field is used only by the garbage collector
  // and is also treated specially.
455
  InstanceKlass* ik = InstanceKlass::cast(k);
D
duke 已提交
456 457 458

  // Check that we have the right class
  debug_only(static bool first_time = true);
459
  assert(k == SystemDictionary::Reference_klass() && first_time,
D
duke 已提交
460 461
         "Invalid update of maps");
  debug_only(first_time = false);
462
  assert(ik->nonstatic_oop_map_count() == 1, "just checking");
D
duke 已提交
463 464 465 466 467 468

  OopMapBlock* map = ik->start_of_nonstatic_oop_maps();

  // Check that the current map is (2,4) - currently points at field with
  // offset 2 (words) and has 4 map entries.
  debug_only(int offset = java_lang_ref_Reference::referent_offset);
469
  debug_only(unsigned int count = ((java_lang_ref_Reference::discovered_offset -
470
    java_lang_ref_Reference::referent_offset)/heapOopSize) + 1);
D
duke 已提交
471 472 473

  if (UseSharedSpaces) {
    assert(map->offset() == java_lang_ref_Reference::queue_offset &&
474
           map->count() == 1, "just checking");
D
duke 已提交
475
  } else {
476
    assert(map->offset() == offset && map->count() == count,
D
duke 已提交
477 478 479 480
           "just checking");

    // Update map to (3,1) - point to offset of 3 (words) with 1 map entry.
    map->set_offset(java_lang_ref_Reference::queue_offset);
481
    map->set_count(1);
D
duke 已提交
482 483 484 485 486 487 488
  }
}


// Verification

void instanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
489
  InstanceKlass::oop_verify_on(obj, st);
D
duke 已提交
490 491 492 493 494 495 496 497 498 499 500 501 502 503
  // Verify referent field
  oop referent = java_lang_ref_Reference::referent(obj);

  // We should make this general to all heaps
  GenCollectedHeap* gch = NULL;
  if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap)
    gch = GenCollectedHeap::heap();

  if (referent != NULL) {
    guarantee(referent->is_oop(), "referent field heap failed");
  }
  // Verify next field
  oop next = java_lang_ref_Reference::next(obj);
  if (next != NULL) {
504
    guarantee(next->is_oop(), "next field verify failed");
D
duke 已提交
505 506 507 508
    guarantee(next->is_instanceRef(), "next field verify failed");
  }
}

509
bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) {
510
  if (java_lang_ref_Reference::pending_list_lock() == NULL) return false;
511 512 513 514
  Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock());
  return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock);
}

D
duke 已提交
515 516 517
void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
  // we may enter this with pending exception set
  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
518 519 520 521 522 523

  // Create a HandleMark in case we retry a GC multiple times.
  // Each time we attempt the GC, we allocate the handle below
  // to hold the pending list lock. We want to free this handle.
  HandleMark hm;

D
duke 已提交
524 525 526 527 528 529 530 531 532 533 534 535
  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
  ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD);
  assert(ObjectSynchronizer::current_thread_holds_lock(
           JavaThread::current(), h_lock),
         "Locking should have succeeded");
  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
}

void instanceRefKlass::release_and_notify_pending_list_lock(
  BasicLock *pending_list_basic_lock) {
  // we may enter this with pending exception set
  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
536 537 538 539 540 541

  // Create a HandleMark in case we retry a GC multiple times.
  // Each time we attempt the GC, we allocate the handle below
  // to hold the pending list lock. We want to free this handle.
  HandleMark hm;

D
duke 已提交
542 543 544 545 546 547 548 549 550 551 552
  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
  assert(ObjectSynchronizer::current_thread_holds_lock(
           JavaThread::current(), h_lock),
         "Lock should be held");
  // Notify waiters on pending lists lock if there is any reference.
  if (java_lang_ref_Reference::pending_list() != NULL) {
    ObjectSynchronizer::notifyall(h_lock, THREAD);
  }
  ObjectSynchronizer::fast_exit(h_lock(), pending_list_basic_lock, THREAD);
  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
}