instanceRefKlass.cpp 21.5 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1997, 2010, 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 48 49
template <class T>
static void specialized_oop_follow_contents(instanceRefKlass* ref, oop obj) {
  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 59
    if (!referent->is_gc_marked() &&
        MarkSweep::ref_processor()->
60
          discover_reference(obj, ref->reference_type())) {
D
duke 已提交
61
      // reference already enqueued, referent will be traversed later
62
      ref->instanceKlass::oop_follow_contents(obj);
D
duke 已提交
63 64
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
65
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
D
duke 已提交
66 67 68 69 70 71 72
        }
      )
      return;
    } else {
      // treat referent as normal oop
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
73
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, obj);
D
duke 已提交
74 75 76 77 78 79
        }
      )
      MarkSweep::mark_and_push(referent_addr);
    }
  }
  // treat next as normal oop.  next is a link in the pending list.
80
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
D
duke 已提交
81 82 83 84 85 86
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    }
  )
  MarkSweep::mark_and_push(next_addr);
87 88 89 90 91 92 93 94 95
  ref->instanceKlass::oop_follow_contents(obj);
}

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 已提交
96 97 98
}

#ifndef SERIALGC
99
template <class T>
100 101 102
void specialized_oop_follow_contents(instanceRefKlass* ref,
                                     ParCompactionManager* cm,
                                     oop obj) {
103
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
104
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
D
duke 已提交
105 106
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
107
      gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj);
D
duke 已提交
108 109
    }
  )
110 111
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
D
duke 已提交
112 113
    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
        PSParallelCompact::ref_processor()->
114
          discover_reference(obj, ref->reference_type())) {
D
duke 已提交
115
      // reference already enqueued, referent will be traversed later
116
      ref->instanceKlass::oop_follow_contents(cm, obj);
D
duke 已提交
117 118
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
119
          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
D
duke 已提交
120 121 122 123 124 125 126
        }
      )
      return;
    } else {
      // treat referent as normal oop
      debug_only(
        if(TraceReferenceGC && PrintGCDetails) {
127
          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, obj);
D
duke 已提交
128 129 130 131 132 133
        }
      )
      PSParallelCompact::mark_and_push(cm, referent_addr);
    }
  }
  // treat next as normal oop.  next is a link in the pending list.
134
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
D
duke 已提交
135 136 137 138 139 140
  debug_only(
    if(TraceReferenceGC && PrintGCDetails) {
      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    }
  )
  PSParallelCompact::mark_and_push(cm, next_addr);
141
  ref->instanceKlass::oop_follow_contents(cm, obj);
D
duke 已提交
142 143
}

144 145 146 147 148 149 150 151 152
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 已提交
153 154

#ifdef ASSERT
155 156 157 158
template <class T> void trace_reference_gc(const char *s, oop obj,
                                           T* referent_addr,
                                           T* next_addr,
                                           T* discovered_addr) {
D
duke 已提交
159
  if(TraceReferenceGC && PrintGCDetails) {
160
    gclog_or_tty->print_cr("%s obj " INTPTR_FORMAT, s, (address)obj);
D
duke 已提交
161
    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
162 163 164
         INTPTR_FORMAT, referent_addr,
         referent_addr ?
           (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL);
D
duke 已提交
165
    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
166 167
         INTPTR_FORMAT, next_addr,
         next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL);
D
duke 已提交
168
    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
169 170 171
         INTPTR_FORMAT, discovered_addr,
         discovered_addr ?
           (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL);
D
duke 已提交
172
  }
173
}
D
duke 已提交
174 175
#endif

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
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();
  instanceKlass::oop_adjust_pointers(obj);

  if (UseCompressedOops) {
    specialized_oop_adjust_pointers<narrowOop>(this, obj);
  } else {
    specialized_oop_adjust_pointers<oop>(this, obj);
  }
D
duke 已提交
196 197 198
  return size;
}

199
#define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
200 201 202 203 204
  if (closure->apply_to_weak_ref_discovered_field()) {                          \
    T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);           \
    closure->do_oop##nv_suffix(disc_addr);                                      \
  }                                                                             \
                                                                                \
205
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
206 207
  T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
  if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) {                 \
D
duke 已提交
208
    ReferenceProcessor* rp = closure->_ref_processor;                           \
209
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
D
duke 已提交
210
    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
211
        rp->discover_reference(obj, reference_type())) {                        \
D
duke 已提交
212 213 214 215 216 217 218 219
      return size;                                                              \
    } else {                                                                    \
      /* treat referent as normal oop */                                        \
      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
      closure->do_oop##nv_suffix(referent_addr);                                \
    }                                                                           \
  }                                                                             \
  /* treat next as normal oop */                                                \
220 221 222 223 224
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
  if (contains(next_addr)) {                                                    \
    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
    closure->do_oop##nv_suffix(next_addr);                                      \
  }                                                                             \
D
duke 已提交
225
  return size;                                                                  \
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246


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);\
                                                                                \
  int size = instanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
D
duke 已提交
247 248
}

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
#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);\
                                                                                \
  int size = instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
                                                                                \
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains);   \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains);         \
  }                                                                             \
}
#endif // !SERIALGC


D
duke 已提交
268 269 270 271 272 273 274 275 276
#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);\
                                                                                \
  int size = instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
277 278 279 280
  if (UseCompressedOops) {                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \
  } else {                                                                      \
    InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr.contains);      \
D
duke 已提交
281 282 283 284
  }                                                                             \
}

ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
285 286 287 288 289
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 已提交
290
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
291
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
D
duke 已提交
292 293

#ifndef SERIALGC
294 295 296 297 298
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 已提交
299
    ReferenceProcessor* rp = PSScavenge::reference_processor();
300
    if (rp->discover_reference(obj, ref->reference_type())) {
D
duke 已提交
301
      // reference already enqueued, referent and next will be traversed later
302
      ref->instanceKlass::oop_push_contents(pm, obj);
D
duke 已提交
303 304 305 306 307 308 309
      return;
    } else {
      // treat referent as normal oop
      pm->claim_or_forward_depth(referent_addr);
    }
  }
  // treat next as normal oop
310 311
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  if (PSScavenge::should_scavenge(next_addr)) {
D
duke 已提交
312 313
    pm->claim_or_forward_depth(next_addr);
  }
314
  ref->instanceKlass::oop_push_contents(pm, obj);
D
duke 已提交
315 316
}

317 318 319 320 321 322 323
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 已提交
324

325 326 327 328
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 已提交
329
  PSParallelCompact::adjust_pointer(referent_addr);
330
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
D
duke 已提交
331
  PSParallelCompact::adjust_pointer(next_addr);
332
  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
D
duke 已提交
333
  PSParallelCompact::adjust_pointer(discovered_addr);
334 335 336
  debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj,
                                referent_addr, next_addr, discovered_addr);)
}
D
duke 已提交
337

338 339 340 341 342 343
int instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  instanceKlass::oop_update_pointers(cm, obj);
  if (UseCompressedOops) {
    specialized_oop_update_pointers<narrowOop>(this, cm, obj);
  } else {
    specialized_oop_update_pointers<oop>(this, cm, obj);
D
duke 已提交
344 345 346 347 348
  }
  return size_helper();
}


349 350 351 352 353
template <class T> void
specialized_oop_update_pointers(ParCompactionManager* cm, oop obj,
                                HeapWord* beg_addr, HeapWord* end_addr) {
  T* p;
  T* referent_addr = p = (T*)java_lang_ref_Reference::referent_addr(obj);
D
duke 已提交
354
  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
355
  T* next_addr = p = (T*)java_lang_ref_Reference::next_addr(obj);
D
duke 已提交
356
  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
357
  T* discovered_addr = p = (T*)java_lang_ref_Reference::discovered_addr(obj);
D
duke 已提交
358
  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
359 360 361
  debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj,
                                referent_addr, next_addr, discovered_addr);)
}
D
duke 已提交
362

363 364 365 366 367 368 369 370
int
instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
                                      HeapWord* beg_addr, HeapWord* end_addr) {
  instanceKlass::oop_update_pointers(cm, obj, beg_addr, end_addr);
  if (UseCompressedOops) {
    specialized_oop_update_pointers<narrowOop>(cm, obj, beg_addr, end_addr);
  } else {
    specialized_oop_update_pointers<oop>(cm, obj, beg_addr, end_addr);
D
duke 已提交
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
  }
  return size_helper();
}
#endif // SERIALGC

void instanceRefKlass::update_nonstatic_oop_maps(klassOop k) {
  // 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.
  instanceKlass* ik = instanceKlass::cast(k);

  // Check that we have the right class
  debug_only(static bool first_time = true);
386
  assert(k == SystemDictionary::Reference_klass() && first_time,
D
duke 已提交
387 388
         "Invalid update of maps");
  debug_only(first_time = false);
389
  assert(ik->nonstatic_oop_map_count() == 1, "just checking");
D
duke 已提交
390 391 392 393 394 395

  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);
396
  debug_only(unsigned int count = ((java_lang_ref_Reference::discovered_offset -
397
    java_lang_ref_Reference::referent_offset)/heapOopSize) + 1);
D
duke 已提交
398 399 400

  if (UseSharedSpaces) {
    assert(map->offset() == java_lang_ref_Reference::queue_offset &&
401
           map->count() == 1, "just checking");
D
duke 已提交
402
  } else {
403
    assert(map->offset() == offset && map->count() == count,
D
duke 已提交
404 405 406 407
           "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);
408
    map->set_count(1);
D
duke 已提交
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
  }
}


// Verification

void instanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
  instanceKlass::oop_verify_on(obj, st);
  // 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");
427
    if (gch != NULL && !gch->is_in_youngest(obj)) {
D
duke 已提交
428 429 430
      // We do a specific remembered set check here since the referent
      // field is not part of the oop mask and therefore skipped by the
      // regular verify code.
431 432 433 434 435 436 437 438
      if (UseCompressedOops) {
        narrowOop* referent_addr = (narrowOop*)java_lang_ref_Reference::referent_addr(obj);
        obj->verify_old_oop(referent_addr, true);
      } else {
        oop* referent_addr = (oop*)java_lang_ref_Reference::referent_addr(obj);
        obj->verify_old_oop(referent_addr, true);
      }
    }
D
duke 已提交
439 440 441 442
  }
  // Verify next field
  oop next = java_lang_ref_Reference::next(obj);
  if (next != NULL) {
443
    guarantee(next->is_oop(), "next field verify failed");
D
duke 已提交
444 445 446 447 448
    guarantee(next->is_instanceRef(), "next field verify failed");
    if (gch != NULL && !gch->is_in_youngest(obj)) {
      // We do a specific remembered set check here since the next field is
      // not part of the oop mask and therefore skipped by the regular
      // verify code.
449 450 451 452 453 454 455
      if (UseCompressedOops) {
        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
        obj->verify_old_oop(next_addr, true);
      } else {
        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
        obj->verify_old_oop(next_addr, true);
      }
D
duke 已提交
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
    }
  }
}

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
  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
  //
  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;
}