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