src/share/vm/oops/instanceRefKlass.cpp

changeset 435
a61af66fc99e
child 548
ba764ed4b6f2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/oops/instanceRefKlass.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,417 @@
     1.4 +/*
     1.5 + * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +# include "incls/_precompiled.incl"
    1.29 +# include "incls/_instanceRefKlass.cpp.incl"
    1.30 +
    1.31 +void instanceRefKlass::oop_follow_contents(oop obj) {
    1.32 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
    1.33 +  oop referent = *referent_addr;
    1.34 +  debug_only(
    1.35 +    if(TraceReferenceGC && PrintGCDetails) {
    1.36 +      gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (address)obj);
    1.37 +    }
    1.38 +  )
    1.39 +  if (referent != NULL) {
    1.40 +    if (!referent->is_gc_marked() &&
    1.41 +        MarkSweep::ref_processor()->
    1.42 +          discover_reference(obj, reference_type())) {
    1.43 +      // reference already enqueued, referent will be traversed later
    1.44 +      instanceKlass::oop_follow_contents(obj);
    1.45 +      debug_only(
    1.46 +        if(TraceReferenceGC && PrintGCDetails) {
    1.47 +          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (address)obj);
    1.48 +        }
    1.49 +      )
    1.50 +      return;
    1.51 +    } else {
    1.52 +      // treat referent as normal oop
    1.53 +      debug_only(
    1.54 +        if(TraceReferenceGC && PrintGCDetails) {
    1.55 +          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (address)obj);
    1.56 +        }
    1.57 +      )
    1.58 +      MarkSweep::mark_and_push(referent_addr);
    1.59 +    }
    1.60 +  }
    1.61 +  // treat next as normal oop.  next is a link in the pending list.
    1.62 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
    1.63 +  debug_only(
    1.64 +    if(TraceReferenceGC && PrintGCDetails) {
    1.65 +      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    1.66 +    }
    1.67 +  )
    1.68 +  MarkSweep::mark_and_push(next_addr);
    1.69 +  instanceKlass::oop_follow_contents(obj);
    1.70 +}
    1.71 +
    1.72 +#ifndef SERIALGC
    1.73 +void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
    1.74 +                                           oop obj) {
    1.75 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
    1.76 +  oop referent = *referent_addr;
    1.77 +  debug_only(
    1.78 +    if(TraceReferenceGC && PrintGCDetails) {
    1.79 +      gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (address)obj);
    1.80 +    }
    1.81 +  )
    1.82 +  if (referent != NULL) {
    1.83 +    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
    1.84 +        PSParallelCompact::ref_processor()->
    1.85 +          discover_reference(obj, reference_type())) {
    1.86 +      // reference already enqueued, referent will be traversed later
    1.87 +      instanceKlass::oop_follow_contents(cm, obj);
    1.88 +      debug_only(
    1.89 +        if(TraceReferenceGC && PrintGCDetails) {
    1.90 +          gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, (address)obj);
    1.91 +        }
    1.92 +      )
    1.93 +      return;
    1.94 +    } else {
    1.95 +      // treat referent as normal oop
    1.96 +      debug_only(
    1.97 +        if(TraceReferenceGC && PrintGCDetails) {
    1.98 +          gclog_or_tty->print_cr("       Non NULL normal " INTPTR_FORMAT, (address)obj);
    1.99 +        }
   1.100 +      )
   1.101 +      PSParallelCompact::mark_and_push(cm, referent_addr);
   1.102 +    }
   1.103 +  }
   1.104 +  // treat next as normal oop.  next is a link in the pending list.
   1.105 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
   1.106 +  debug_only(
   1.107 +    if(TraceReferenceGC && PrintGCDetails) {
   1.108 +      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
   1.109 +    }
   1.110 +  )
   1.111 +  PSParallelCompact::mark_and_push(cm, next_addr);
   1.112 +  instanceKlass::oop_follow_contents(cm, obj);
   1.113 +}
   1.114 +#endif // SERIALGC
   1.115 +
   1.116 +
   1.117 +int instanceRefKlass::oop_adjust_pointers(oop obj) {
   1.118 +  int size = size_helper();
   1.119 +  instanceKlass::oop_adjust_pointers(obj);
   1.120 +
   1.121 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
   1.122 +  MarkSweep::adjust_pointer(referent_addr);
   1.123 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
   1.124 +  MarkSweep::adjust_pointer(next_addr);
   1.125 +  oop* discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
   1.126 +  MarkSweep::adjust_pointer(discovered_addr);
   1.127 +
   1.128 +#ifdef ASSERT
   1.129 +  if(TraceReferenceGC && PrintGCDetails) {
   1.130 +    gclog_or_tty->print_cr("instanceRefKlass::oop_adjust_pointers obj "
   1.131 +                           INTPTR_FORMAT, (address)obj);
   1.132 +    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
   1.133 +                           INTPTR_FORMAT, referent_addr,
   1.134 +                           referent_addr ? (address)*referent_addr : NULL);
   1.135 +    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
   1.136 +                           INTPTR_FORMAT, next_addr,
   1.137 +                           next_addr ? (address)*next_addr : NULL);
   1.138 +    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
   1.139 +                           INTPTR_FORMAT, discovered_addr,
   1.140 +                           discovered_addr ? (address)*discovered_addr : NULL);
   1.141 +  }
   1.142 +#endif
   1.143 +
   1.144 +  return size;
   1.145 +}
   1.146 +
   1.147 +#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
   1.148 +                                                                                \
   1.149 +int instanceRefKlass::                                                          \
   1.150 +oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
   1.151 +  /* Get size before changing pointers */                                       \
   1.152 +  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
   1.153 +                                                                                \
   1.154 +  int size = instanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
   1.155 +                                                                                \
   1.156 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);             \
   1.157 +  oop referent = *referent_addr;                                                \
   1.158 +  if (referent != NULL) {                                                       \
   1.159 +    ReferenceProcessor* rp = closure->_ref_processor;                           \
   1.160 +    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
   1.161 +        rp->discover_reference(obj, reference_type())) {              \
   1.162 +      return size;                                                              \
   1.163 +    } else {                                                                    \
   1.164 +      /* treat referent as normal oop */                                        \
   1.165 +      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
   1.166 +      closure->do_oop##nv_suffix(referent_addr);                                \
   1.167 +    }                                                                           \
   1.168 +  }                                                                             \
   1.169 +                                                                                \
   1.170 +  /* treat next as normal oop */                                                \
   1.171 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);                     \
   1.172 +  SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
   1.173 +  closure->do_oop##nv_suffix(next_addr);                                        \
   1.174 +  return size;                                                                  \
   1.175 +}
   1.176 +
   1.177 +#define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)      \
   1.178 +                                                                                \
   1.179 +int instanceRefKlass::                                                          \
   1.180 +oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
   1.181 +                               OopClosureType* closure,                         \
   1.182 +                               MemRegion mr) {                                  \
   1.183 +  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
   1.184 +                                                                                \
   1.185 +  int size = instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
   1.186 +                                                                                \
   1.187 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);             \
   1.188 +  oop referent = *referent_addr;                                                \
   1.189 +  if (referent != NULL && mr.contains(referent_addr)) {                         \
   1.190 +    ReferenceProcessor* rp = closure->_ref_processor;                           \
   1.191 +    if (!referent->is_gc_marked() && (rp != NULL) &&                            \
   1.192 +        rp->discover_reference(obj, reference_type())) {              \
   1.193 +      return size;                                                              \
   1.194 +    } else {                                                                    \
   1.195 +      /* treat referent as normal oop */                                        \
   1.196 +      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
   1.197 +      closure->do_oop##nv_suffix(referent_addr);                                \
   1.198 +    }                                                                           \
   1.199 +  }                                                                             \
   1.200 +                                                                                \
   1.201 +  /* treat next as normal oop */                                                \
   1.202 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);                     \
   1.203 +  if (mr.contains(next_addr)) {                                                 \
   1.204 +    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
   1.205 +    closure->do_oop##nv_suffix(next_addr);                                      \
   1.206 +  }                                                                             \
   1.207 +  return size;                                                                  \
   1.208 +}
   1.209 +
   1.210 +ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
   1.211 +ALL_OOP_OOP_ITERATE_CLOSURES_3(InstanceRefKlass_OOP_OOP_ITERATE_DEFN)
   1.212 +ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
   1.213 +ALL_OOP_OOP_ITERATE_CLOSURES_3(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m)
   1.214 +
   1.215 +
   1.216 +#ifndef SERIALGC
   1.217 +void instanceRefKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
   1.218 +  assert(!pm->depth_first(), "invariant");
   1.219 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
   1.220 +  if (PSScavenge::should_scavenge(*referent_addr)) {
   1.221 +    ReferenceProcessor* rp = PSScavenge::reference_processor();
   1.222 +    if (rp->discover_reference(obj, reference_type())) {
   1.223 +      // reference already enqueued, referent and next will be traversed later
   1.224 +      instanceKlass::oop_copy_contents(pm, obj);
   1.225 +      return;
   1.226 +    } else {
   1.227 +      // treat referent as normal oop
   1.228 +      pm->claim_or_forward_breadth(referent_addr);
   1.229 +    }
   1.230 +  }
   1.231 +  // treat next as normal oop
   1.232 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
   1.233 +  if (PSScavenge::should_scavenge(*next_addr)) {
   1.234 +    pm->claim_or_forward_breadth(next_addr);
   1.235 +  }
   1.236 +  instanceKlass::oop_copy_contents(pm, obj);
   1.237 +}
   1.238 +
   1.239 +void instanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   1.240 +  assert(pm->depth_first(), "invariant");
   1.241 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
   1.242 +  if (PSScavenge::should_scavenge(*referent_addr)) {
   1.243 +    ReferenceProcessor* rp = PSScavenge::reference_processor();
   1.244 +    if (rp->discover_reference(obj, reference_type())) {
   1.245 +      // reference already enqueued, referent and next will be traversed later
   1.246 +      instanceKlass::oop_push_contents(pm, obj);
   1.247 +      return;
   1.248 +    } else {
   1.249 +      // treat referent as normal oop
   1.250 +      pm->claim_or_forward_depth(referent_addr);
   1.251 +    }
   1.252 +  }
   1.253 +  // treat next as normal oop
   1.254 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
   1.255 +  if (PSScavenge::should_scavenge(*next_addr)) {
   1.256 +    pm->claim_or_forward_depth(next_addr);
   1.257 +  }
   1.258 +  instanceKlass::oop_push_contents(pm, obj);
   1.259 +}
   1.260 +
   1.261 +int instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   1.262 +  instanceKlass::oop_update_pointers(cm, obj);
   1.263 +
   1.264 +  oop* referent_addr = java_lang_ref_Reference::referent_addr(obj);
   1.265 +  PSParallelCompact::adjust_pointer(referent_addr);
   1.266 +  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
   1.267 +  PSParallelCompact::adjust_pointer(next_addr);
   1.268 +  oop* discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
   1.269 +  PSParallelCompact::adjust_pointer(discovered_addr);
   1.270 +
   1.271 +#ifdef ASSERT
   1.272 +  if(TraceReferenceGC && PrintGCDetails) {
   1.273 +    gclog_or_tty->print_cr("instanceRefKlass::oop_update_pointers obj "
   1.274 +                           INTPTR_FORMAT, (oopDesc*) obj);
   1.275 +    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
   1.276 +                           INTPTR_FORMAT, referent_addr,
   1.277 +                           referent_addr ? (oopDesc*) *referent_addr : NULL);
   1.278 +    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
   1.279 +                           INTPTR_FORMAT, next_addr,
   1.280 +                           next_addr ? (oopDesc*) *next_addr : NULL);
   1.281 +    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
   1.282 +                   INTPTR_FORMAT, discovered_addr,
   1.283 +                   discovered_addr ? (oopDesc*) *discovered_addr : NULL);
   1.284 +  }
   1.285 +#endif
   1.286 +
   1.287 +  return size_helper();
   1.288 +}
   1.289 +
   1.290 +int
   1.291 +instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
   1.292 +                                      HeapWord* beg_addr, HeapWord* end_addr) {
   1.293 +  instanceKlass::oop_update_pointers(cm, obj, beg_addr, end_addr);
   1.294 +
   1.295 +  oop* p;
   1.296 +  oop* referent_addr = p = java_lang_ref_Reference::referent_addr(obj);
   1.297 +  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
   1.298 +  oop* next_addr = p = java_lang_ref_Reference::next_addr(obj);
   1.299 +  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
   1.300 +  oop* discovered_addr = p = java_lang_ref_Reference::discovered_addr(obj);
   1.301 +  PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
   1.302 +
   1.303 +#ifdef ASSERT
   1.304 +  if(TraceReferenceGC && PrintGCDetails) {
   1.305 +    gclog_or_tty->print_cr("instanceRefKlass::oop_update_pointers obj "
   1.306 +                           INTPTR_FORMAT, (oopDesc*) obj);
   1.307 +    gclog_or_tty->print_cr("     referent_addr/* " INTPTR_FORMAT " / "
   1.308 +                           INTPTR_FORMAT, referent_addr,
   1.309 +                           referent_addr ? (oopDesc*) *referent_addr : NULL);
   1.310 +    gclog_or_tty->print_cr("     next_addr/* " INTPTR_FORMAT " / "
   1.311 +                           INTPTR_FORMAT, next_addr,
   1.312 +                           next_addr ? (oopDesc*) *next_addr : NULL);
   1.313 +    gclog_or_tty->print_cr("     discovered_addr/* " INTPTR_FORMAT " / "
   1.314 +                   INTPTR_FORMAT, discovered_addr,
   1.315 +                   discovered_addr ? (oopDesc*) *discovered_addr : NULL);
   1.316 +  }
   1.317 +#endif
   1.318 +
   1.319 +  return size_helper();
   1.320 +}
   1.321 +#endif // SERIALGC
   1.322 +
   1.323 +void instanceRefKlass::update_nonstatic_oop_maps(klassOop k) {
   1.324 +  // Clear the nonstatic oop-map entries corresponding to referent
   1.325 +  // and nextPending field.  They are treated specially by the
   1.326 +  // garbage collector.
   1.327 +  // The discovered field is used only by the garbage collector
   1.328 +  // and is also treated specially.
   1.329 +  instanceKlass* ik = instanceKlass::cast(k);
   1.330 +
   1.331 +  // Check that we have the right class
   1.332 +  debug_only(static bool first_time = true);
   1.333 +  assert(k == SystemDictionary::reference_klass() && first_time,
   1.334 +         "Invalid update of maps");
   1.335 +  debug_only(first_time = false);
   1.336 +  assert(ik->nonstatic_oop_map_size() == 1, "just checking");
   1.337 +
   1.338 +  OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
   1.339 +
   1.340 +  // Check that the current map is (2,4) - currently points at field with
   1.341 +  // offset 2 (words) and has 4 map entries.
   1.342 +  debug_only(int offset = java_lang_ref_Reference::referent_offset);
   1.343 +  debug_only(int length = ((java_lang_ref_Reference::discovered_offset -
   1.344 +    java_lang_ref_Reference::referent_offset)/wordSize) + 1);
   1.345 +
   1.346 +  if (UseSharedSpaces) {
   1.347 +    assert(map->offset() == java_lang_ref_Reference::queue_offset &&
   1.348 +           map->length() == 1, "just checking");
   1.349 +  } else {
   1.350 +    assert(map->offset() == offset && map->length() == length,
   1.351 +           "just checking");
   1.352 +
   1.353 +    // Update map to (3,1) - point to offset of 3 (words) with 1 map entry.
   1.354 +    map->set_offset(java_lang_ref_Reference::queue_offset);
   1.355 +    map->set_length(1);
   1.356 +  }
   1.357 +}
   1.358 +
   1.359 +
   1.360 +// Verification
   1.361 +
   1.362 +void instanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
   1.363 +  instanceKlass::oop_verify_on(obj, st);
   1.364 +  // Verify referent field
   1.365 +  oop referent = java_lang_ref_Reference::referent(obj);
   1.366 +
   1.367 +  // We should make this general to all heaps
   1.368 +  GenCollectedHeap* gch = NULL;
   1.369 +  if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap)
   1.370 +    gch = GenCollectedHeap::heap();
   1.371 +
   1.372 +  if (referent != NULL) {
   1.373 +    guarantee(referent->is_oop(), "referent field heap failed");
   1.374 +    if (gch != NULL && !gch->is_in_youngest(obj))
   1.375 +      // We do a specific remembered set check here since the referent
   1.376 +      // field is not part of the oop mask and therefore skipped by the
   1.377 +      // regular verify code.
   1.378 +      obj->verify_old_oop(java_lang_ref_Reference::referent_addr(obj), true);
   1.379 +  }
   1.380 +  // Verify next field
   1.381 +  oop next = java_lang_ref_Reference::next(obj);
   1.382 +  if (next != NULL) {
   1.383 +    guarantee(next->is_oop(), "next field verify failed");
   1.384 +    guarantee(next->is_instanceRef(), "next field verify failed");
   1.385 +    if (gch != NULL && !gch->is_in_youngest(obj)) {
   1.386 +      // We do a specific remembered set check here since the next field is
   1.387 +      // not part of the oop mask and therefore skipped by the regular
   1.388 +      // verify code.
   1.389 +      obj->verify_old_oop(java_lang_ref_Reference::next_addr(obj), true);
   1.390 +    }
   1.391 +  }
   1.392 +}
   1.393 +
   1.394 +void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
   1.395 +  // we may enter this with pending exception set
   1.396 +  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
   1.397 +  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
   1.398 +  ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD);
   1.399 +  assert(ObjectSynchronizer::current_thread_holds_lock(
   1.400 +           JavaThread::current(), h_lock),
   1.401 +         "Locking should have succeeded");
   1.402 +  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
   1.403 +}
   1.404 +
   1.405 +void instanceRefKlass::release_and_notify_pending_list_lock(
   1.406 +  BasicLock *pending_list_basic_lock) {
   1.407 +  // we may enter this with pending exception set
   1.408 +  PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
   1.409 +  //
   1.410 +  Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
   1.411 +  assert(ObjectSynchronizer::current_thread_holds_lock(
   1.412 +           JavaThread::current(), h_lock),
   1.413 +         "Lock should be held");
   1.414 +  // Notify waiters on pending lists lock if there is any reference.
   1.415 +  if (java_lang_ref_Reference::pending_list() != NULL) {
   1.416 +    ObjectSynchronizer::notifyall(h_lock, THREAD);
   1.417 +  }
   1.418 +  ObjectSynchronizer::fast_exit(h_lock(), pending_list_basic_lock, THREAD);
   1.419 +  if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
   1.420 +}

mercurial