1 /*
 2  * Copyright (c) 2022, 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 #include "precompiled.hpp"
26 #include "memory/allocation.hpp"
27 #include "runtime/lockStack.hpp"
28 #include "runtime/safepoint.hpp"
29 #include "runtime/thread.hpp"
30 #include "utilities/copy.hpp"
31 #include "utilities/ostream.hpp"
32 
33 LockStack::LockStack() :
34         _base(UseHeavyMonitors ? NULL : NEW_C_HEAP_ARRAY(oop, INITIAL_CAPACITY, mtSynchronizer)),
35         _limit(_base + INITIAL_CAPACITY),
36         _current(_base) {
37 }
38 
39 LockStack::~LockStack() {
40   if (!UseHeavyMonitors) {
41     FREE_C_HEAP_ARRAY(oop, _base);
42   }
43 }
44 
45 #ifndef PRODUCT
46 void LockStack::validate(const char* msg) const {
47   assert(!UseHeavyMonitors, "never use lock-stack when fast-locking is disabled");
48   for (oop* loc1 = _base; loc1 < _current - 1; loc1++) {
49     for (oop* loc2 = loc1 + 1; loc2 < _current; loc2++) {
50       assert(*loc1 != *loc2, "entries must be unique: %s", msg);
51     }
52   }
53 }
54 #endif
55 
56 void LockStack::grow(size_t min_capacity) {
57   // Grow stack.
58   assert(_limit > _base, "invariant");
59   size_t capacity = _limit - _base;
60   size_t index = _current - _base;
61   size_t new_capacity = MAX2(min_capacity, capacity * 2);
62   oop* new_stack = NEW_C_HEAP_ARRAY(oop, new_capacity, mtSynchronizer);
63   for (size_t i = 0; i < index; i++) {
64     *(new_stack + i) = *(_base + i);
65   }
66   FREE_C_HEAP_ARRAY(oop, _base);
67   _base = new_stack;
68   _limit = _base + new_capacity;
69   _current = _base + index;
70   assert(_current < _limit, "must fit after growing");
71   assert((_limit - _base) >= (ptrdiff_t) min_capacity, "must grow enough");
72 }
73 
74 void LockStack::grow() {
75   grow((_limit - _base) + 1);
76 }
77 
78 void LockStack::grow(oop* required_limit) {
79   grow(required_limit - _base);
80 }
81 
82 void LockStack::ensure_lock_stack_size(oop* _required_limit) {
83   JavaThread* jt = JavaThread::current();
84   jt->lock_stack().grow(_required_limit);
85 }