1 /* 2 * Copyright (c) 2022, Red Hat, Inc. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHOBJECTUTILS_INLINE_HPP 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHOBJECTUTILS_INLINE_HPP 27 28 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 29 #include "gc/shenandoah/shenandoahObjectUtils.hpp" 30 #include "oops/klass.hpp" 31 #include "oops/markWord.inline.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "runtime/objectMonitor.inline.hpp" 34 #include "runtime/thread.hpp" 35 36 // This is a variant of oopDesc::actual_mark(), which does the same thing, but also 37 // handles forwarded objects. This is intended to be used by concurrent evacuation only. No other 38 // code is supposed to observe from-space objects. 39 #ifdef _LP64 40 markWord ShenandoahObjectUtils::stable_mark(oop obj) { 41 assert(UseCompactObjectHeaders, "only used with compact object headers"); 42 ShenandoahHeap* heap = ShenandoahHeap::heap(); 43 assert(heap->is_in(obj), "object not in heap: " PTR_FORMAT, p2i(obj)); 44 markWord mark = obj->mark_acquire(); 45 46 assert(!mark.is_being_inflated(), "can not be inflating"); 47 assert(!mark.has_locker(), "can not be stack-locked"); 48 49 // The mark can be in one of the following states: 50 // * Marked - object is forwarded, try again on forwardee 51 // * Inflated - just return mark from inflated monitor 52 // * Fast-locked - return mark 53 // * Neutral - return mark 54 55 // Most common cases first. 56 if (mark.is_neutral() || mark.is_fast_locked()) { 57 return mark; 58 } 59 60 // If object is already forwarded, then resolve it, and try again. 61 if (mark.is_marked()) { 62 if (heap->is_full_gc_move_in_progress()) { 63 // In these cases, we want to return the header as-is: the Klass* would not be overloaded. 64 return mark; 65 } 66 obj = cast_to_oop(mark.decode_pointer()); 67 return stable_mark(obj); 68 } 69 70 // CASE: inflated 71 assert(mark.has_monitor(), "must be monitor-locked at this point"); 72 // It is safe to access the object monitor because all Java and GC worker threads 73 // participate in the monitor deflation protocol (i.e, they react to handshakes and STS requests). 74 ObjectMonitor* inf = mark.monitor(); 75 markWord dmw = inf->header(); 76 assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT ", original mark: " INTPTR_FORMAT, dmw.value(), mark.value()); 77 return dmw; 78 } 79 #endif 80 81 Klass* ShenandoahObjectUtils::klass(oop obj) { 82 if (!UseCompactObjectHeaders) { 83 return obj->klass(); 84 } 85 #ifdef _LP64 86 markWord header = stable_mark(obj); 87 assert(header.narrow_klass() != 0, "klass must not be NULL: " INTPTR_FORMAT, header.value()); 88 return header.klass(); 89 #else 90 return obj->klass(); 91 #endif 92 } 93 94 size_t ShenandoahObjectUtils::size(oop obj) { 95 if (!UseCompactObjectHeaders) { 96 return obj->size(); 97 } 98 Klass* kls = klass(obj); 99 return obj->size_given_klass(kls); 100 } 101 102 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHOBJECTUTILS_HPP