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 Thread;
34 class OopClosure;
35 
36 class LockStack {
37   friend class VMStructs;
38 private:
39   static const int CAPACITY = 8;
40 
41   // TODO: It would be very useful if JavaThread::lock_stack_offset() and friends were constexpr,
42   // but this is currently not the case because we're using offset_of() which is non-constexpr,
43   // GCC would warn about non-standard-layout types if we were using offsetof() (which *is* constexpr).
44   static const int lock_stack_offset;
45   static const int lock_stack_top_offset;
46   static const int lock_stack_base_offset;
47 
48   // The offset of the next element, in bytes, relative to the JavaThread structure.
49   // We do this instead of a simple index into the array because this allows for
50   // efficient addressing in generated code.
51   uint32_t _top;
52   oop _base[CAPACITY];
53 
54   // Get the owning thread of this lock-stack.
55   inline JavaThread* get_thread() const;
56 
57   // Tests if the calling thread is the thread that owns this lock-stack.
58   bool is_owning_thread() const;
59 
60   // Verifies consistency of the lock-stack.
61   void verify(const char* msg) const PRODUCT_RETURN;
62 
63   // Given an offset (in bytes) calculate the index into the lock-stack.
64   static inline int to_index(uint32_t offset);
65 
66 public:
67   static ByteSize top_offset()  { return byte_offset_of(LockStack, _top); }
68   static ByteSize base_offset() { return byte_offset_of(LockStack, _base); }
69 
70   LockStack(JavaThread* jt);
71 
72   // The boundary indicies of the lock-stack.
73   static uint32_t start_offset();
74   static uint32_t end_offset();
75 
76   // Return true if we have room to push onto this lock-stack, false otherwise.
77   inline bool can_push() const;
78 
79   // Pushes an oop on this lock-stack.
80   inline void push(oop o);
81 
82   // Pops an oop from this lock-stack.
83   inline oop pop();
84 
85   // Removes an oop from an arbitrary location of this lock-stack.
86   inline void remove(oop o);
87 
88   // Tests whether the oop is on this lock-stack.
89   inline bool contains(oop o) const;
90 
91   // GC support
92   inline void oops_do(OopClosure* cl);
93 
94 };
95 
96 #endif // SHARE_RUNTIME_LOCKSTACK_HPP