23 * questions.
24 *
25 */
26
27 #include "precompiled.hpp"
28 #include "memory/allocation.hpp"
29 #include "oops/markWord.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/globals.hpp"
32 #include "runtime/lockStack.inline.hpp"
33 #include "runtime/objectMonitor.inline.hpp"
34 #include "runtime/safepoint.hpp"
35 #include "runtime/stackWatermark.hpp"
36 #include "runtime/stackWatermarkSet.inline.hpp"
37 #include "runtime/thread.hpp"
38 #include "utilities/copy.hpp"
39 #include "utilities/debug.hpp"
40 #include "utilities/globalDefinitions.hpp"
41 #include "utilities/growableArray.hpp"
42 #include "utilities/ostream.hpp"
43
44 #include <type_traits>
45
46 const int LockStack::lock_stack_offset = in_bytes(JavaThread::lock_stack_offset());
47 const int LockStack::lock_stack_top_offset = in_bytes(JavaThread::lock_stack_top_offset());
48 const int LockStack::lock_stack_base_offset = in_bytes(JavaThread::lock_stack_base_offset());
49
50 LockStack::LockStack(JavaThread* jt) :
51 _top(lock_stack_base_offset), _base() {
52 // Make sure the layout of the object is compatible with the emitted code's assumptions.
53 STATIC_ASSERT(sizeof(_bad_oop_sentinel) == oopSize);
54 STATIC_ASSERT(sizeof(_base[0]) == oopSize);
55 STATIC_ASSERT(std::is_standard_layout<LockStack>::value);
56 STATIC_ASSERT(offsetof(LockStack, _bad_oop_sentinel) == offsetof(LockStack, _base) - oopSize);
57 #ifdef ASSERT
58 for (int i = 0; i < CAPACITY; i++) {
59 _base[i] = nullptr;
60 }
61 #endif
62 }
121 top_index = index + 1;
122 break;
123 }
124 }
125
126 if (VM_Version::supports_recursive_lightweight_locking()) {
127 // With recursive looks there may be more of the same object
128 while (lock_index-- > 0 && lock_order.at(lock_index) == obj) {
129 top_index++;
130 }
131 assert(top_index <= to_index(_top), "too many obj in lock_order");
132 }
133
134 break;
135 }
136 }
137
138 lock_index = lock_order.length();
139 }
140
141 while (lock_index-- > 0) {
142 const oop obj = lock_order.at(lock_index);
143 const markWord mark = obj->mark_acquire();
144 assert(obj->is_locked(), "must be locked");
145 if (top_index > 0 && obj == _base[top_index - 1]) {
146 assert(mark.is_fast_locked() || mark.monitor()->is_owner_anonymous(),
147 "must be fast_locked or inflated by other thread");
148 top_index--;
149 } else {
150 assert(!mark.is_fast_locked(), "must be inflated");
151 assert(mark.monitor()->owner_raw() == get_thread() ||
152 (!leaf_frame && get_thread()->current_waiting_monitor() == mark.monitor()),
153 "must be owned by (or waited on by) thread");
154 assert(!contains(obj), "must not be on lock_stack");
155 }
156 }
157 }
158 #endif
159
160 void LockStack::print_on(outputStream* st) {
161 for (int i = to_index(_top); (--i) >= 0;) {
162 st->print("LockStack[%d]: ", i);
163 oop o = _base[i];
164 if (oopDesc::is_oop(o)) {
165 o->print_on(st);
166 } else {
167 st->print_cr("not an oop: " PTR_FORMAT, p2i(o));
168 }
169 }
170 }
|
23 * questions.
24 *
25 */
26
27 #include "precompiled.hpp"
28 #include "memory/allocation.hpp"
29 #include "oops/markWord.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/globals.hpp"
32 #include "runtime/lockStack.inline.hpp"
33 #include "runtime/objectMonitor.inline.hpp"
34 #include "runtime/safepoint.hpp"
35 #include "runtime/stackWatermark.hpp"
36 #include "runtime/stackWatermarkSet.inline.hpp"
37 #include "runtime/thread.hpp"
38 #include "utilities/copy.hpp"
39 #include "utilities/debug.hpp"
40 #include "utilities/globalDefinitions.hpp"
41 #include "utilities/growableArray.hpp"
42 #include "utilities/ostream.hpp"
43 #include "utilities/sizes.hpp"
44
45 #include <type_traits>
46
47 const int LockStack::lock_stack_offset = in_bytes(JavaThread::lock_stack_offset());
48 const int LockStack::lock_stack_top_offset = in_bytes(JavaThread::lock_stack_top_offset());
49 const int LockStack::lock_stack_base_offset = in_bytes(JavaThread::lock_stack_base_offset());
50
51 LockStack::LockStack(JavaThread* jt) :
52 _top(lock_stack_base_offset), _base() {
53 // Make sure the layout of the object is compatible with the emitted code's assumptions.
54 STATIC_ASSERT(sizeof(_bad_oop_sentinel) == oopSize);
55 STATIC_ASSERT(sizeof(_base[0]) == oopSize);
56 STATIC_ASSERT(std::is_standard_layout<LockStack>::value);
57 STATIC_ASSERT(offsetof(LockStack, _bad_oop_sentinel) == offsetof(LockStack, _base) - oopSize);
58 #ifdef ASSERT
59 for (int i = 0; i < CAPACITY; i++) {
60 _base[i] = nullptr;
61 }
62 #endif
63 }
122 top_index = index + 1;
123 break;
124 }
125 }
126
127 if (VM_Version::supports_recursive_lightweight_locking()) {
128 // With recursive looks there may be more of the same object
129 while (lock_index-- > 0 && lock_order.at(lock_index) == obj) {
130 top_index++;
131 }
132 assert(top_index <= to_index(_top), "too many obj in lock_order");
133 }
134
135 break;
136 }
137 }
138
139 lock_index = lock_order.length();
140 }
141
142 JavaThread* thread = get_thread();
143 Thread* current = Thread::current();
144 while (lock_index-- > 0) {
145 const oop obj = lock_order.at(lock_index);
146 const markWord mark = obj->mark_acquire();
147 assert(obj->is_locked(), "must be locked");
148 ObjectMonitor* monitor = nullptr;
149 if (mark.has_monitor()) {
150 monitor = LightweightSynchronizer::read_monitor(current, obj);
151 }
152 if (top_index > 0 && obj == _base[top_index - 1]) {
153 assert(mark.is_fast_locked() || monitor->is_owner_anonymous(),
154 "must be fast_locked or inflated by other thread");
155 top_index--;
156 } else {
157 assert(!mark.is_fast_locked(), "must be inflated");
158 assert(monitor->owner_raw() == thread ||
159 (!leaf_frame && thread->current_waiting_monitor() == monitor),
160 "must be owned by (or waited on by) thread");
161 assert(!contains(obj), "must not be on lock_stack");
162 }
163 }
164 }
165 #endif
166
167 void LockStack::print_on(outputStream* st) {
168 for (int i = to_index(_top); (--i) >= 0;) {
169 st->print("LockStack[%d]: ", i);
170 oop o = _base[i];
171 if (oopDesc::is_oop(o)) {
172 o->print_on(st);
173 } else {
174 st->print_cr("not an oop: " PTR_FORMAT, p2i(o));
175 }
176 }
177 }
178
179 OMCache::OMCache(JavaThread* jt) : _entries() {
180 STATIC_ASSERT(std::is_standard_layout<OMCache>::value);
181 STATIC_ASSERT(std::is_standard_layout<OMCache::OMCacheEntry>::value);
182 STATIC_ASSERT(offsetof(OMCache, _null_sentinel) == offsetof(OMCache, _entries) +
183 offsetof(OMCache::OMCacheEntry, _oop) +
184 OMCache::CAPACITY * in_bytes(oop_to_oop_difference()));
185 }
|