1 /*
  2  * Copyright (c) 1998, 2024, 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_RUNTIME_BASICLOCK_HPP
 26 #define SHARE_RUNTIME_BASICLOCK_HPP
 27 
 28 #include "oops/markWord.hpp"
 29 #include "runtime/atomic.hpp"
 30 #include "runtime/handles.hpp"
 31 #include "utilities/globalDefinitions.hpp"
 32 #include "utilities/sizes.hpp"
 33 
 34 class BasicLock {
 35   friend class VMStructs;
 36   friend class JVMCIVMStructs;
 37  private:
 38   // * For LM_MONITOR
 39   // Unused.
 40   // * For LM_LEGACY
 41   // This is either the actual displaced header from a locked object, or
 42   // a sentinel zero value indicating a recursive stack-lock.
 43   // * For LM_LIGHTWEIGHT
 44   // Used as a cache the ObjectMonitor* used when locking. Must either
 45   // be nullptr or the ObjectMonitor* used when locking.
 46   volatile uintptr_t _metadata;
 47 
 48   uintptr_t get_metadata() const { return Atomic::load(&_metadata); }
 49   void set_metadata(uintptr_t value) { Atomic::store(&_metadata, value); }
 50   static int metadata_offset_in_bytes() { return (int)offset_of(BasicLock, _metadata); }
 51 
 52  public:
 53   // LM_MONITOR
 54   void set_bad_metadata_deopt() { set_metadata(badDispHeaderDeopt); }
 55 
 56   // LM_LEGACY
 57   inline markWord displaced_header() const;
 58   inline void set_displaced_header(markWord header);
 59   static int displaced_header_offset_in_bytes() { return metadata_offset_in_bytes(); }
 60 
 61   // LM_LIGHTWEIGHT
 62   inline ObjectMonitor* object_monitor_cache() const;
 63   inline void clear_object_monitor_cache();
 64   inline void set_object_monitor_cache(ObjectMonitor* mon);
 65   static int object_monitor_cache_offset_in_bytes() { return metadata_offset_in_bytes(); }
 66 
 67   void print_on(outputStream* st, oop owner) const;
 68 
 69   // move a basic lock (used during deoptimization)
 70   void move_to(oop obj, BasicLock* dest);
 71 };
 72 
 73 // A BasicObjectLock associates a specific Java object with a BasicLock.
 74 // It is currently embedded in an interpreter frame.
 75 
 76 // Because some machines have alignment restrictions on the control stack,
 77 // the actual space allocated by the interpreter may include padding words
 78 // after the end of the BasicObjectLock.  Also, in order to guarantee
 79 // alignment of the embedded BasicLock objects on such machines, we
 80 // put the embedded BasicLock at the beginning of the struct.
 81 
 82 class BasicObjectLock {
 83   friend class VMStructs;
 84  private:
 85   BasicLock _lock;                                    // the lock, must be double word aligned
 86   oop       _obj;                                     // object holds the lock;
 87 
 88  public:
 89   // Manipulation
 90   oop      obj() const                                { return _obj;  }
 91   void set_obj(oop obj)                               { _obj = obj; }
 92   BasicLock* lock()                                   { return &_lock; }
 93 
 94   // Note: Use frame::interpreter_frame_monitor_size() for the size of BasicObjectLocks
 95   //       in interpreter activation frames since it includes machine-specific padding.
 96   static int size()                                   { return sizeof(BasicObjectLock)/wordSize; }
 97 
 98   // GC support
 99   void oops_do(OopClosure* f) { f->do_oop(&_obj); }
100 
101   static ByteSize obj_offset()                { return byte_offset_of(BasicObjectLock, _obj);  }
102   static ByteSize lock_offset()               { return byte_offset_of(BasicObjectLock, _lock); }
103 };
104 
105 
106 #endif // SHARE_RUNTIME_BASICLOCK_HPP