duke@435: /* trims@1907: * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: duke@435: # include "incls/_precompiled.incl" duke@435: # include "incls/_instanceRefKlass.cpp.incl" duke@435: coleenp@548: template coleenp@548: static void specialized_oop_follow_contents(instanceRefKlass* ref, oop obj) { coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); ysr@1280: T heap_oop = oopDesc::load_heap_oop(referent_addr); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); duke@435: } duke@435: ) ysr@1280: if (!oopDesc::is_null(heap_oop)) { ysr@1280: oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); duke@435: if (!referent->is_gc_marked() && duke@435: MarkSweep::ref_processor()-> coleenp@548: discover_reference(obj, ref->reference_type())) { duke@435: // reference already enqueued, referent will be traversed later coleenp@548: ref->instanceKlass::oop_follow_contents(obj); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); duke@435: } duke@435: ) duke@435: return; duke@435: } else { duke@435: // treat referent as normal oop duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj); duke@435: } duke@435: ) duke@435: MarkSweep::mark_and_push(referent_addr); duke@435: } duke@435: } duke@435: // treat next as normal oop. next is a link in the pending list. coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { duke@435: gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); duke@435: } duke@435: ) duke@435: MarkSweep::mark_and_push(next_addr); coleenp@548: ref->instanceKlass::oop_follow_contents(obj); coleenp@548: } coleenp@548: coleenp@548: void instanceRefKlass::oop_follow_contents(oop obj) { coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_follow_contents(this, obj); coleenp@548: } else { coleenp@548: specialized_oop_follow_contents(this, obj); coleenp@548: } duke@435: } duke@435: duke@435: #ifndef SERIALGC coleenp@548: template phh@1558: void specialized_oop_follow_contents(instanceRefKlass* ref, phh@1558: ParCompactionManager* cm, phh@1558: oop obj) { coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); ysr@1280: T heap_oop = oopDesc::load_heap_oop(referent_addr); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr("instanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); duke@435: } duke@435: ) ysr@1280: if (!oopDesc::is_null(heap_oop)) { ysr@1280: oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); duke@435: if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) && duke@435: PSParallelCompact::ref_processor()-> coleenp@548: discover_reference(obj, ref->reference_type())) { duke@435: // reference already enqueued, referent will be traversed later coleenp@548: ref->instanceKlass::oop_follow_contents(cm, obj); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); duke@435: } duke@435: ) duke@435: return; duke@435: } else { duke@435: // treat referent as normal oop duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj); duke@435: } duke@435: ) duke@435: PSParallelCompact::mark_and_push(cm, referent_addr); duke@435: } duke@435: } duke@435: // treat next as normal oop. next is a link in the pending list. coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); duke@435: debug_only( duke@435: if(TraceReferenceGC && PrintGCDetails) { duke@435: gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr); duke@435: } duke@435: ) duke@435: PSParallelCompact::mark_and_push(cm, next_addr); coleenp@548: ref->instanceKlass::oop_follow_contents(cm, obj); coleenp@548: } coleenp@548: coleenp@548: void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm, coleenp@548: oop obj) { coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_follow_contents(this, cm, obj); coleenp@548: } else { coleenp@548: specialized_oop_follow_contents(this, cm, obj); coleenp@548: } duke@435: } duke@435: #endif // SERIALGC duke@435: coleenp@548: #ifdef ASSERT coleenp@548: template void trace_reference_gc(const char *s, oop obj, coleenp@548: T* referent_addr, coleenp@548: T* next_addr, coleenp@548: T* discovered_addr) { coleenp@548: if(TraceReferenceGC && PrintGCDetails) { coleenp@548: gclog_or_tty->print_cr("%s obj " INTPTR_FORMAT, s, (address)obj); coleenp@548: gclog_or_tty->print_cr(" referent_addr/* " INTPTR_FORMAT " / " coleenp@548: INTPTR_FORMAT, referent_addr, coleenp@548: referent_addr ? coleenp@548: (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL); coleenp@548: gclog_or_tty->print_cr(" next_addr/* " INTPTR_FORMAT " / " coleenp@548: INTPTR_FORMAT, next_addr, coleenp@548: next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL); coleenp@548: gclog_or_tty->print_cr(" discovered_addr/* " INTPTR_FORMAT " / " coleenp@548: INTPTR_FORMAT, discovered_addr, coleenp@548: discovered_addr ? coleenp@548: (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL); coleenp@548: } coleenp@548: } coleenp@548: #endif coleenp@548: coleenp@548: template void specialized_oop_adjust_pointers(instanceRefKlass *ref, oop obj) { coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: MarkSweep::adjust_pointer(referent_addr); coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); coleenp@548: MarkSweep::adjust_pointer(next_addr); coleenp@548: T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); coleenp@548: MarkSweep::adjust_pointer(discovered_addr); coleenp@548: debug_only(trace_reference_gc("instanceRefKlass::oop_adjust_pointers", obj, coleenp@548: referent_addr, next_addr, discovered_addr);) coleenp@548: } duke@435: duke@435: int instanceRefKlass::oop_adjust_pointers(oop obj) { duke@435: int size = size_helper(); duke@435: instanceKlass::oop_adjust_pointers(obj); duke@435: coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_adjust_pointers(this, obj); coleenp@548: } else { coleenp@548: specialized_oop_adjust_pointers(this, obj); duke@435: } duke@435: return size; duke@435: } duke@435: coleenp@548: #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains) \ ysr@777: if (closure->apply_to_weak_ref_discovered_field()) { \ ysr@777: T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); \ ysr@777: closure->do_oop##nv_suffix(disc_addr); \ ysr@777: } \ ysr@777: \ coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); \ ysr@1280: T heap_oop = oopDesc::load_heap_oop(referent_addr); \ ysr@1280: if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) { \ coleenp@548: ReferenceProcessor* rp = closure->_ref_processor; \ ysr@1280: oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); \ coleenp@548: if (!referent->is_gc_marked() && (rp != NULL) && \ coleenp@548: rp->discover_reference(obj, reference_type())) { \ coleenp@548: return size; \ coleenp@548: } else { \ coleenp@548: /* treat referent as normal oop */ \ coleenp@548: SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\ coleenp@548: closure->do_oop##nv_suffix(referent_addr); \ coleenp@548: } \ coleenp@548: } \ coleenp@548: /* treat next as normal oop */ \ coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); \ coleenp@548: if (contains(next_addr)) { \ coleenp@548: SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \ coleenp@548: closure->do_oop##nv_suffix(next_addr); \ coleenp@548: } \ coleenp@548: return size; \ coleenp@548: coleenp@548: coleenp@548: template bool contains(T *t) { return true; } coleenp@548: coleenp@548: // Macro to define instanceRefKlass::oop_oop_iterate for virtual/nonvirtual for coleenp@548: // all closures. Macros calling macros above for each oop size. coleenp@548: duke@435: #define InstanceRefKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ duke@435: \ duke@435: int instanceRefKlass:: \ duke@435: oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ duke@435: /* Get size before changing pointers */ \ duke@435: SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ duke@435: \ duke@435: int size = instanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ duke@435: \ coleenp@548: if (UseCompressedOops) { \ coleenp@548: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains); \ coleenp@548: } else { \ coleenp@548: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains); \ duke@435: } \ duke@435: } duke@435: ysr@777: #ifndef SERIALGC ysr@777: #define InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ ysr@777: \ ysr@777: int instanceRefKlass:: \ ysr@777: oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ ysr@777: /* Get size before changing pointers */ \ ysr@777: SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ ysr@777: \ ysr@777: int size = instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ ysr@777: \ ysr@777: if (UseCompressedOops) { \ ysr@777: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, contains); \ ysr@777: } else { \ ysr@777: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, contains); \ ysr@777: } \ ysr@777: } ysr@777: #endif // !SERIALGC ysr@777: ysr@777: duke@435: #define InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ duke@435: \ duke@435: int instanceRefKlass:: \ duke@435: oop_oop_iterate##nv_suffix##_m(oop obj, \ duke@435: OopClosureType* closure, \ duke@435: MemRegion mr) { \ duke@435: SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\ duke@435: \ duke@435: int size = instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \ coleenp@548: if (UseCompressedOops) { \ coleenp@548: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \ coleenp@548: } else { \ coleenp@548: InstanceRefKlass_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr.contains); \ duke@435: } \ duke@435: } duke@435: duke@435: ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN) ysr@777: ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN) ysr@777: #ifndef SERIALGC ysr@777: ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ysr@777: ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) ysr@777: #endif // SERIALGC duke@435: ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) ysr@777: ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceRefKlass_OOP_OOP_ITERATE_DEFN_m) duke@435: duke@435: #ifndef SERIALGC coleenp@548: template coleenp@548: void specialized_oop_copy_contents(instanceRefKlass *ref, coleenp@548: PSPromotionManager* pm, oop obj) { duke@435: assert(!pm->depth_first(), "invariant"); coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: if (PSScavenge::should_scavenge(referent_addr)) { duke@435: ReferenceProcessor* rp = PSScavenge::reference_processor(); coleenp@548: if (rp->discover_reference(obj, ref->reference_type())) { duke@435: // reference already enqueued, referent and next will be traversed later coleenp@548: ref->instanceKlass::oop_copy_contents(pm, obj); duke@435: return; duke@435: } else { duke@435: // treat referent as normal oop duke@435: pm->claim_or_forward_breadth(referent_addr); duke@435: } duke@435: } duke@435: // treat next as normal oop coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); coleenp@548: if (PSScavenge::should_scavenge(next_addr)) { duke@435: pm->claim_or_forward_breadth(next_addr); duke@435: } coleenp@548: ref->instanceKlass::oop_copy_contents(pm, obj); duke@435: } duke@435: coleenp@548: void instanceRefKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_copy_contents(this, pm, obj); coleenp@548: } else { coleenp@548: specialized_oop_copy_contents(this, pm, obj); coleenp@548: } coleenp@548: } coleenp@548: coleenp@548: template coleenp@548: void specialized_oop_push_contents(instanceRefKlass *ref, coleenp@548: PSPromotionManager* pm, oop obj) { duke@435: assert(pm->depth_first(), "invariant"); coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: if (PSScavenge::should_scavenge(referent_addr)) { duke@435: ReferenceProcessor* rp = PSScavenge::reference_processor(); coleenp@548: if (rp->discover_reference(obj, ref->reference_type())) { duke@435: // reference already enqueued, referent and next will be traversed later coleenp@548: ref->instanceKlass::oop_push_contents(pm, obj); duke@435: return; duke@435: } else { duke@435: // treat referent as normal oop duke@435: pm->claim_or_forward_depth(referent_addr); duke@435: } duke@435: } duke@435: // treat next as normal oop coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); coleenp@548: if (PSScavenge::should_scavenge(next_addr)) { duke@435: pm->claim_or_forward_depth(next_addr); duke@435: } coleenp@548: ref->instanceKlass::oop_push_contents(pm, obj); coleenp@548: } coleenp@548: coleenp@548: void instanceRefKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_push_contents(this, pm, obj); coleenp@548: } else { coleenp@548: specialized_oop_push_contents(this, pm, obj); coleenp@548: } coleenp@548: } coleenp@548: coleenp@548: template coleenp@548: void specialized_oop_update_pointers(instanceRefKlass *ref, coleenp@548: ParCompactionManager* cm, oop obj) { coleenp@548: T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(referent_addr); coleenp@548: T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(next_addr); coleenp@548: T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(discovered_addr); coleenp@548: debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj, coleenp@548: referent_addr, next_addr, discovered_addr);) duke@435: } duke@435: duke@435: int instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { duke@435: instanceKlass::oop_update_pointers(cm, obj); coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_update_pointers(this, cm, obj); coleenp@548: } else { coleenp@548: specialized_oop_update_pointers(this, cm, obj); coleenp@548: } coleenp@548: return size_helper(); coleenp@548: } duke@435: duke@435: coleenp@548: template void coleenp@548: specialized_oop_update_pointers(ParCompactionManager* cm, oop obj, coleenp@548: HeapWord* beg_addr, HeapWord* end_addr) { coleenp@548: T* p; coleenp@548: T* referent_addr = p = (T*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); coleenp@548: T* next_addr = p = (T*)java_lang_ref_Reference::next_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); coleenp@548: T* discovered_addr = p = (T*)java_lang_ref_Reference::discovered_addr(obj); coleenp@548: PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); coleenp@548: debug_only(trace_reference_gc("instanceRefKlass::oop_update_ptrs", obj, coleenp@548: referent_addr, next_addr, discovered_addr);) duke@435: } duke@435: duke@435: int duke@435: instanceRefKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, duke@435: HeapWord* beg_addr, HeapWord* end_addr) { duke@435: instanceKlass::oop_update_pointers(cm, obj, beg_addr, end_addr); coleenp@548: if (UseCompressedOops) { coleenp@548: specialized_oop_update_pointers(cm, obj, beg_addr, end_addr); coleenp@548: } else { coleenp@548: specialized_oop_update_pointers(cm, obj, beg_addr, end_addr); duke@435: } duke@435: return size_helper(); duke@435: } duke@435: #endif // SERIALGC duke@435: duke@435: void instanceRefKlass::update_nonstatic_oop_maps(klassOop k) { duke@435: // Clear the nonstatic oop-map entries corresponding to referent duke@435: // and nextPending field. They are treated specially by the duke@435: // garbage collector. duke@435: // The discovered field is used only by the garbage collector duke@435: // and is also treated specially. duke@435: instanceKlass* ik = instanceKlass::cast(k); duke@435: duke@435: // Check that we have the right class duke@435: debug_only(static bool first_time = true); never@1577: assert(k == SystemDictionary::Reference_klass() && first_time, duke@435: "Invalid update of maps"); duke@435: debug_only(first_time = false); jcoomes@1373: assert(ik->nonstatic_oop_map_count() == 1, "just checking"); duke@435: duke@435: OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); duke@435: duke@435: // Check that the current map is (2,4) - currently points at field with duke@435: // offset 2 (words) and has 4 map entries. duke@435: debug_only(int offset = java_lang_ref_Reference::referent_offset); jcoomes@1374: debug_only(unsigned int count = ((java_lang_ref_Reference::discovered_offset - coleenp@548: java_lang_ref_Reference::referent_offset)/heapOopSize) + 1); duke@435: duke@435: if (UseSharedSpaces) { duke@435: assert(map->offset() == java_lang_ref_Reference::queue_offset && jcoomes@1373: map->count() == 1, "just checking"); duke@435: } else { jcoomes@1373: assert(map->offset() == offset && map->count() == count, duke@435: "just checking"); duke@435: duke@435: // Update map to (3,1) - point to offset of 3 (words) with 1 map entry. duke@435: map->set_offset(java_lang_ref_Reference::queue_offset); jcoomes@1373: map->set_count(1); duke@435: } duke@435: } duke@435: duke@435: duke@435: // Verification duke@435: duke@435: void instanceRefKlass::oop_verify_on(oop obj, outputStream* st) { duke@435: instanceKlass::oop_verify_on(obj, st); duke@435: // Verify referent field duke@435: oop referent = java_lang_ref_Reference::referent(obj); duke@435: duke@435: // We should make this general to all heaps duke@435: GenCollectedHeap* gch = NULL; duke@435: if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap) duke@435: gch = GenCollectedHeap::heap(); duke@435: duke@435: if (referent != NULL) { duke@435: guarantee(referent->is_oop(), "referent field heap failed"); coleenp@548: if (gch != NULL && !gch->is_in_youngest(obj)) { duke@435: // We do a specific remembered set check here since the referent duke@435: // field is not part of the oop mask and therefore skipped by the duke@435: // regular verify code. coleenp@548: if (UseCompressedOops) { coleenp@548: narrowOop* referent_addr = (narrowOop*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: obj->verify_old_oop(referent_addr, true); coleenp@548: } else { coleenp@548: oop* referent_addr = (oop*)java_lang_ref_Reference::referent_addr(obj); coleenp@548: obj->verify_old_oop(referent_addr, true); coleenp@548: } coleenp@548: } duke@435: } duke@435: // Verify next field duke@435: oop next = java_lang_ref_Reference::next(obj); duke@435: if (next != NULL) { ysr@777: guarantee(next->is_oop(), "next field verify failed"); duke@435: guarantee(next->is_instanceRef(), "next field verify failed"); duke@435: if (gch != NULL && !gch->is_in_youngest(obj)) { duke@435: // We do a specific remembered set check here since the next field is duke@435: // not part of the oop mask and therefore skipped by the regular duke@435: // verify code. coleenp@548: if (UseCompressedOops) { coleenp@548: narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj); coleenp@548: obj->verify_old_oop(next_addr, true); coleenp@548: } else { coleenp@548: oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj); coleenp@548: obj->verify_old_oop(next_addr, true); coleenp@548: } duke@435: } duke@435: } duke@435: } duke@435: duke@435: void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) { duke@435: // we may enter this with pending exception set duke@435: PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument duke@435: Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock()); duke@435: ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD); duke@435: assert(ObjectSynchronizer::current_thread_holds_lock( duke@435: JavaThread::current(), h_lock), duke@435: "Locking should have succeeded"); duke@435: if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; duke@435: } duke@435: duke@435: void instanceRefKlass::release_and_notify_pending_list_lock( duke@435: BasicLock *pending_list_basic_lock) { duke@435: // we may enter this with pending exception set duke@435: PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument duke@435: // duke@435: Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock()); duke@435: assert(ObjectSynchronizer::current_thread_holds_lock( duke@435: JavaThread::current(), h_lock), duke@435: "Lock should be held"); duke@435: // Notify waiters on pending lists lock if there is any reference. duke@435: if (java_lang_ref_Reference::pending_list() != NULL) { duke@435: ObjectSynchronizer::notifyall(h_lock, THREAD); duke@435: } duke@435: ObjectSynchronizer::fast_exit(h_lock(), pending_list_basic_lock, THREAD); duke@435: if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; duke@435: }