/* * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. * 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. * * 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. *
*/
// The markWord describes the header of an object. // // Bit-format of an object header (most significant first, big endian layout below): // // 32 bits: // -------- // hash:25 ------------>| age:4 unused_gap:1 lock:2 (normal object) // // 64 bits: // -------- // unused:25 hash:31 -->| unused_gap:1 age:4 unused_gap:1 lock:2 (normal object) // // - hash contains the identity hash value: largest value is // 31 bits, see os::random(). Also, 64-bit vm's require // a hash value no bigger than 32 bits because they will not // properly generate a mask larger than that: see library_call.cpp // // - the two lock bits are used to describe three states: locked/unlocked and monitor. // // [ptr | 00] locked ptr points to real header on stack // [header | 01] unlocked regular object header // [ptr | 10] monitor inflated lock (header is wapped out) // [ptr | 11] marked used to mark an object // [0 ............ 0| 00] inflating inflation in progress // // We assume that stack/thread pointers have the lowest two bits cleared. // // - INFLATING() is a distinguished markword value of all zeros that is // used when inflating an existing stack-lock into an ObjectMonitor. // See below for is_being_inflated() and INFLATING().
class BasicLock; class ObjectMonitor; class JavaThread; class outputStream;
// It is critical for performance that this class be trivially // destructable, copyable, and assignable.
~markWord() = default;
markWord(const markWord&) = default;
markWord& operator=(const markWord&) = default;
// Special temporary state of the markWord while being inflated. // Code that looks at mark outside a lock need to take this into account. bool is_being_inflated() const { return (value() == 0); }
// Distinguished markword value - used when inflating over // an existing stack-lock. 0 indicates the markword is "BUSY". // Lockword mutators that use a LD...CAS idiom should always // check for and avoid overwriting a 0 value installed by some // other thread. (They should spin or block instead. The 0 value // is transient and *should* be short-lived). static markWord INFLATING() { return zero(); } // inflate-in-progress
// Should this header be preserved during GC? bool must_be_preserved(const oopDesc* obj) const { return (!is_unlocked() || !has_no_hash());
}
// WARNING: The following routines are used EXCLUSIVELY by // synchronization functions. They are not really gc safe. // They must get updated if markWord layout get changed.
markWord set_unlocked() const { return markWord(value() | unlocked_value);
} bool has_locker() const { return ((value() & lock_mask_in_place) == locked_value);
}
BasicLock* locker() const {
assert(has_locker(), "check"); return (BasicLock*) value();
} bool has_monitor() const { return ((value() & lock_mask_in_place) == monitor_value);
}
ObjectMonitor* monitor() const {
assert(has_monitor(), "check"); // Use xor instead of &~ to provide one extra tag-bit check. return (ObjectMonitor*) (value() ^ monitor_value);
} bool has_displaced_mark_helper() const { return ((value() & unlocked_value) == 0);
}
markWord displaced_mark_helper() const; void set_displaced_mark_helper(markWord m) const;
markWord copy_set_hash(intptr_t hash) const {
uintptr_t tmp = value() & (~hash_mask_in_place);
tmp |= ((hash & hash_mask) << hash_shift); return markWord(tmp);
} // it is only used to be stored into BasicLock as the // indicator that the lock is using heavyweight monitor static markWord unused_mark() { return markWord(marked_value);
} // the following two functions create the markWord to be // stored into object header, it encodes monitor info static markWord encode(BasicLock* lock) { return from_pointer(lock);
} static markWord encode(ObjectMonitor* monitor) {
uintptr_t tmp = (uintptr_t) monitor; return markWord(tmp | monitor_value);
}
// used to encode pointers during GC
markWord clear_lock_bits() { return markWord(value() & ~lock_mask_in_place); }
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.