1 /*
  2  * Copyright (c) 2006, 2019, Oracle and/or its affiliates. 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_OOPS_MARKWORD_INLINE_HPP
 26 #define SHARE_OOPS_MARKWORD_INLINE_HPP
 27 
 28 #include "oops/markWord.hpp"
 29 
 30 #include "oops/klass.hpp"
 31 #include "oops/oop.inline.hpp"
 32 #include "runtime/globals.hpp"
 33 #include "runtime/safepoint.hpp"
 34 
 35 // Should this header be preserved during GC?
 36 inline bool markWord::must_be_preserved(const oopDesc* obj) const {
 37   if (UseBiasedLocking) {
 38     if (has_bias_pattern()) {
 39       // Will reset bias at end of collection
 40       // Mark words of biased and currently locked objects are preserved separately
 41       return false;
 42     }
 43     markWord prototype_header = prototype_for_klass(obj->klass());
 44     if (prototype_header.has_bias_pattern()) {
 45       // Individual instance which has its bias revoked; must return
 46       // true for correctness
 47       return true;
 48     }
 49   }
 50   return (!is_unlocked() || !has_no_hash());
 51 }
 52 
 53 // Should this header be preserved in the case of a promotion failure during scavenge?
 54 inline bool markWord::must_be_preserved_for_promotion_failure(const oopDesc* obj) const {
 55   if (UseBiasedLocking) {
 56     // We don't explicitly save off the mark words of biased and
 57     // currently-locked objects during scavenges, so if during a
 58     // promotion failure we encounter either a biased mark word or a
 59     // klass which still has a biasable prototype header, we have to
 60     // preserve the mark word. This results in oversaving, but promotion
 61     // failures are rare, and this avoids adding more complex logic to
 62     // the scavengers to call new variants of
 63     // BiasedLocking::preserve_marks() / restore_marks() in the middle
 64     // of a scavenge when a promotion failure has first been detected.
 65     if (has_bias_pattern() || prototype_for_klass(obj->klass()).has_bias_pattern()) {
 66       return true;
 67     }
 68   }
 69   return (!is_unlocked() || !has_no_hash());
 70 }
 71 
 72 inline markWord markWord::prototype_for_klass(const Klass* klass) {
 73   markWord prototype_header = klass->prototype_header();
 74   assert(UseCompactObjectHeaders || prototype_header == prototype() || prototype_header.has_bias_pattern(), "corrupt prototype header");
 75 
 76   return prototype_header;
 77 }
 78 
 79 #ifdef _LP64
 80 markWord markWord::actual_mark() const {
 81   assert(UseCompactObjectHeaders, "only safe when using compact headers");
 82   if (has_displaced_mark_helper()) {
 83     return displaced_mark_helper();
 84   } else {
 85     return *this;
 86   }
 87 }
 88 
 89 narrowKlass markWord::narrow_klass() const {
 90   assert(UseCompactObjectHeaders, "only used with compact object headers");
 91   return narrowKlass(value() >> klass_shift);
 92 }
 93 
 94 Klass* markWord::klass() const {
 95   assert(UseCompactObjectHeaders, "only used with compact object headers");
 96   assert(!CompressedKlassPointers::is_null(narrow_klass()), "narrow klass must not be null: " INTPTR_FORMAT, value());
 97   return CompressedKlassPointers::decode_not_null(narrow_klass());
 98 }
 99 
100 Klass* markWord::klass_or_null() const {
101   assert(UseCompactObjectHeaders, "only used with compact object headers");
102   return CompressedKlassPointers::decode(narrow_klass());
103 }
104 
105 markWord markWord::set_narrow_klass(const narrowKlass nklass) const {
106   assert(UseCompactObjectHeaders, "only used with compact object headers");
107   return markWord((value() & ~klass_mask_in_place) | ((uintptr_t) nklass << klass_shift));
108 }
109 
110 Klass* markWord::safe_klass() const {
111   assert(UseCompactObjectHeaders, "only used with compact object headers");
112   assert(SafepointSynchronize::is_at_safepoint(), "only call at safepoint");
113   markWord m = *this;
114   if (m.has_displaced_mark_helper()) {
115     m = m.displaced_mark_helper();
116   }
117   return CompressedKlassPointers::decode_not_null(m.narrow_klass());
118 }
119 
120 markWord markWord::set_klass(const Klass* klass) const {
121   assert(UseCompactObjectHeaders, "only used with compact object headers");
122   assert(UseCompressedClassPointers, "expect compressed klass pointers");
123   // TODO: Don't cast to non-const, change CKP::encode() to accept const Klass* instead.
124   narrowKlass nklass = CompressedKlassPointers::encode(const_cast<Klass*>(klass));
125   return set_narrow_klass(nklass);
126 }
127 #endif
128 
129 #endif // SHARE_OOPS_MARKWORD_INLINE_HPP