1 /*
 2  * Copyright (c) 2022, Red Hat, Inc. All rights reserved.
 3  * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
 4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 5  *
 6  * This code is free software; you can redistribute it and/or modify it
 7  * under the terms of the GNU General Public License version 2 only, as
 8  * published by the Free Software Foundation.
 9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  *
24  */
25 
26 #ifndef SHARE_RUNTIME_LOCKSTACK_HPP
27 #define SHARE_RUNTIME_LOCKSTACK_HPP
28 
29 #include "oops/oopsHierarchy.hpp"
30 #include "utilities/globalDefinitions.hpp"
31 #include "utilities/sizes.hpp"
32 
33 class JavaThread;
34 class OopClosure;
35 class outputStream;
36 
37 class LockStack {
38   friend class VMStructs;
39 private:
40   static const int CAPACITY = 8;
41 
42   // TODO: It would be very useful if JavaThread::lock_stack_offset() and friends were constexpr,
43   // but this is currently not the case because we're using offset_of() which is non-constexpr,
44   // GCC would warn about non-standard-layout types if we were using offsetof() (which *is* constexpr).
45   static const int lock_stack_offset;
46   static const int lock_stack_top_offset;
47   static const int lock_stack_base_offset;
48 
49   // The offset of the next element, in bytes, relative to the JavaThread structure.
50   // We do this instead of a simple index into the array because this allows for
51   // efficient addressing in generated code.
52   uint32_t _top;
53   oop _base[CAPACITY];
54 
55   // Get the owning thread of this lock-stack.
56   inline JavaThread* get_thread() const;
57 
58   // Tests if the calling thread is the thread that owns this lock-stack.
59   bool is_owning_thread() const;
60 
61   // Verifies consistency of the lock-stack.
62   void verify(const char* msg) const PRODUCT_RETURN;
63 
64   // Given an offset (in bytes) calculate the index into the lock-stack.
65   static inline int to_index(uint32_t offset);
66 
67 public:
68   static ByteSize top_offset()  { return byte_offset_of(LockStack, _top); }
69   static ByteSize base_offset() { return byte_offset_of(LockStack, _base); }
70 
71   LockStack(JavaThread* jt);
72 
73   // The boundary indicies of the lock-stack.
74   static uint32_t start_offset();
75   static uint32_t end_offset();
76 
77   // Return true if we have room to push onto this lock-stack, false otherwise.
78   inline bool can_push() const;
79 
80   // Pushes an oop on this lock-stack.
81   inline void push(oop o);
82 
83   // Pops an oop from this lock-stack.
84   inline oop pop();
85 
86   // Removes an oop from an arbitrary location of this lock-stack.
87   inline void remove(oop o);
88 
89   // Tests whether the oop is on this lock-stack.
90   inline bool contains(oop o) const;
91 
92   // GC support
93   inline void oops_do(OopClosure* cl);
94 
95   // Printing
96   void print_on(outputStream* st);
97 };
98 
99 #endif // SHARE_RUNTIME_LOCKSTACK_HPP