1 /* 2 * Copyright (c) 2015, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_INLINE_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_INLINE_HPP 26 27 #include "gc/shared/cmBitMap.inline.hpp" 28 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 29 #include "gc/shenandoah/shenandoahHeap.hpp" 30 #include "runtime/atomic.inline.hpp" 31 32 /* 33 * Marks the object. Returns true if the object has not been marked before and has 34 * been marked by this thread. Returns false if the object has already been marked, 35 * or if a competing thread succeeded in marking this object. 36 */ 37 inline bool ShenandoahHeap::mark_current(oop obj) const { 38 #ifdef ASSERT 39 if (obj != oopDesc::bs()->read_barrier(obj)) { 40 tty->print_cr("heap region containing obj:"); 41 ShenandoahHeapRegion* obj_region = heap_region_containing(obj); 42 obj_region->print(); 43 tty->print_cr("heap region containing forwardee:"); 44 ShenandoahHeapRegion* forward_region = heap_region_containing(oopDesc::bs()->read_barrier(obj)); 45 forward_region->print(); 46 } 47 #endif 48 49 assert(obj == oopDesc::bs()->read_barrier(obj), "only mark forwarded copy of objects"); 50 return mark_current_no_checks(obj); 51 } 52 53 inline bool ShenandoahHeap::mark_current_no_checks(oop obj) const { 54 return _next_mark_bit_map->parMark((HeapWord*) obj); 55 } 56 57 inline bool ShenandoahHeap::is_marked_current(oop obj) const { 58 return _next_mark_bit_map->isMarked((HeapWord*) obj); 59 } 60 61 inline bool ShenandoahHeap::need_update_refs() const { 62 return _need_update_refs; 63 } 64 65 inline uint ShenandoahHeap::heap_region_index_containing(const void* addr) const { 66 uintptr_t region_start = ((uintptr_t) addr); // & ~(ShenandoahHeapRegion::RegionSizeBytes - 1); 67 uintptr_t index = (region_start - (uintptr_t) _first_region_bottom) >> ShenandoahHeapRegion::RegionSizeShift; 68 #ifdef ASSERT 69 if (!(index < _num_regions)) { 70 tty->print_cr("heap region does not contain address, first_region_bottom: "PTR_FORMAT", real bottom of first region: "PTR_FORMAT", num_regions: "SIZE_FORMAT", region_size: "SIZE_FORMAT, p2i(_first_region_bottom), p2i(_ordered_regions[0]->bottom()), _num_regions, ShenandoahHeapRegion::RegionSizeBytes); 71 } 72 #endif 73 assert(index < _num_regions, "heap region index must be in range"); 74 return index; 75 } 76 77 oop ShenandoahHeap::maybe_update_oop_ref(oop* p) { 78 79 assert((! is_in(p)) || (! heap_region_containing(p)->is_in_collection_set()), 80 "never update refs in from-space, unless evacuation has been cancelled"); 81 82 oop heap_oop = oopDesc::load_heap_oop(p); // read p 83 if (! oopDesc::is_null(heap_oop)) { 84 85 #ifdef ASSERT 86 if (! is_in(heap_oop)) { 87 print_heap_regions(); 88 tty->print_cr("object not in heap: "PTR_FORMAT", referenced by: "PTR_FORMAT, p2i((HeapWord*) heap_oop), p2i(p)); 89 assert(is_in(heap_oop), "object must be in heap"); 90 } 91 #endif 92 assert(is_in(heap_oop), "only ever call this on objects in the heap"); 93 assert((! (is_in(p) && heap_region_containing(p)->is_in_collection_set())), "we don't want to update references in from-space"); 94 oop forwarded_oop = ShenandoahBarrierSet::resolve_oop_static_not_null(heap_oop); // read brooks ptr 95 if (forwarded_oop != heap_oop) { 96 // tty->print_cr("updating old ref: "PTR_FORMAT" pointing to "PTR_FORMAT" to new ref: "PTR_FORMAT, p2i(p), p2i(heap_oop), p2i(forwarded_oop)); 97 assert(forwarded_oop->is_oop(), "oop required"); 98 assert(is_in(forwarded_oop), "forwardee must be in heap"); 99 assert(! heap_region_containing(forwarded_oop)->is_in_collection_set(), "forwardee must not be in collection set"); 100 // If this fails, another thread wrote to p before us, it will be logged in SATB and the 101 // reference be updated later. 102 oop result = (oop) Atomic::cmpxchg_ptr(forwarded_oop, p, heap_oop); 103 104 if (result == heap_oop) { // CAS successful. 105 return forwarded_oop; 106 } else { 107 return result; 108 } 109 } else { 110 return forwarded_oop; 111 } 112 /* 113 else { 114 tty->print_cr("not updating ref: "PTR_FORMAT, p2i(heap_oop)); 115 } 116 */ 117 } 118 return NULL; 119 } 120 121 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAP_INLINE_HPP