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_INLINE_HPP 27 #define SHARE_RUNTIME_LOCKSTACK_INLINE_HPP 28 29 #include "memory/iterator.hpp" 30 #include "runtime/javaThread.hpp" 31 #include "runtime/lockStack.hpp" 32 #include "runtime/safepoint.hpp" 33 #include "runtime/stackWatermark.hpp" 34 #include "runtime/stackWatermarkSet.inline.hpp" 35 36 inline int LockStack::to_index(uint32_t offset) { 37 return (offset - lock_stack_base_offset) / oopSize; 38 } 39 40 JavaThread* LockStack::get_thread() const { 41 char* addr = reinterpret_cast<char*>(const_cast<LockStack*>(this)); 42 return reinterpret_cast<JavaThread*>(addr - lock_stack_offset); 43 } 44 45 inline bool LockStack::can_push() const { 46 return to_index(_top) < CAPACITY; 47 } 48 49 inline bool LockStack::is_owning_thread() const { 50 Thread* current = Thread::current(); 51 if (current->is_Java_thread()) { 52 JavaThread* thread = JavaThread::cast(current); 53 bool is_owning = &thread->lock_stack() == this; 54 assert(is_owning == (get_thread() == thread), "is_owning sanity"); 55 return is_owning; 56 } 57 return false; 58 } 59 60 inline void LockStack::push(oop o) { 61 verify("pre-push"); 62 assert(oopDesc::is_oop(o), "must be"); 63 assert(!contains(o), "entries must be unique"); 64 assert(can_push(), "must have room"); 65 assert(_base[to_index(_top)] == nullptr, "expect zapped entry"); 66 _base[to_index(_top)] = o; 67 _top += oopSize; 68 verify("post-push"); 69 } 70 71 inline oop LockStack::pop() { 72 verify("pre-pop"); 73 assert(to_index(_top) > 0, "underflow, probably unbalanced push/pop"); 74 _top -= oopSize; 75 oop o = _base[to_index(_top)]; 76 #ifdef ASSERT 77 _base[to_index(_top)] = nullptr; 78 #endif 79 assert(!contains(o), "entries must be unique: " PTR_FORMAT, p2i(o)); 80 verify("post-pop"); 81 return o; 82 } 83 84 inline void LockStack::remove(oop o) { 85 verify("pre-remove"); 86 assert(contains(o), "entry must be present: " PTR_FORMAT, p2i(o)); 87 int end = to_index(_top); 88 for (int i = 0; i < end; i++) { 89 if (_base[i] == o) { 90 int last = end - 1; 91 for (; i < last; i++) { 92 _base[i] = _base[i + 1]; 93 } 94 _top -= oopSize; 95 #ifdef ASSERT 96 _base[to_index(_top)] = nullptr; 97 #endif 98 break; 99 } 100 } 101 assert(!contains(o), "entries must be unique: " PTR_FORMAT, p2i(o)); 102 verify("post-remove"); 103 } 104 105 inline bool LockStack::contains(oop o) const { 106 verify("pre-contains"); 107 108 // Can't poke around in thread oops without having started stack watermark processing. 109 assert(StackWatermarkSet::processing_started(get_thread()), "Processing must have started!"); 110 111 int end = to_index(_top); 112 for (int i = end - 1; i >= 0; i--) { 113 if (_base[i] == o) { 114 verify("post-contains"); 115 return true; 116 } 117 } 118 verify("post-contains"); 119 return false; 120 } 121 122 inline void LockStack::oops_do(OopClosure* cl) { 123 verify("pre-oops-do"); 124 int end = to_index(_top); 125 for (int i = 0; i < end; i++) { 126 cl->do_oop(&_base[i]); 127 } 128 verify("post-oops-do"); 129 } 130 131 #endif // SHARE_RUNTIME_LOCKSTACK_INLINE_HPP