1 /*
2 * Copyright (c) 2019, 2025, 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 #include "classfile/vmClasses.hpp"
25 #include "memory/resourceArea.hpp"
26 #include "memory/universe.hpp"
27 #include "oops/instanceKlass.hpp"
28 #include "oops/oop.inline.hpp"
29 #include "runtime/atomicAccess.hpp"
30 #include "runtime/interfaceSupport.inline.hpp"
31 #include "runtime/orderAccess.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/semaphore.inline.hpp"
34 #include "runtime/synchronizer.hpp"
35 #include "threadHelper.inline.hpp"
36 #include "unittest.hpp"
37 #include "utilities/globalDefinitions.hpp"
38 #include "utilities/ostream.hpp"
39
40 // The test doesn't work for PRODUCT because it needs WizardMode
41 #ifndef PRODUCT
42
43 template<typename Printable>
44 static void assert_test_pattern(Printable object, const char* pattern) {
45 stringStream st;
46 object->print_on(&st);
47 ASSERT_THAT(st.base(), testing::HasSubstr(pattern));
48 }
49
50 template<typename Printable>
51 static void assert_mark_word_print_pattern(Printable object, const char* pattern) {
52 assert_test_pattern(object, pattern);
53 }
54
55 class LockerThread : public JavaTestThread {
56 oop _obj;
57 public:
58 LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {}
59 virtual ~LockerThread() {}
60
61 void main_run() {
62 JavaThread* THREAD = JavaThread::current();
63 HandleMark hm(THREAD);
64 Handle h_obj(THREAD, _obj);
65 ResourceMark rm(THREAD);
66
67 // Wait gets the lock inflated.
68 // The object will stay locked for the context of 'ol' so the lock will
69 // still be inflated after the notify_all() call. Deflation can't happen
70 // while an ObjectMonitor is "busy" and being locked is the most "busy"
71 // state we have...
72 ObjectLocker ol(h_obj, THREAD);
73 ol.notify_all(THREAD);
74 assert_test_pattern(h_obj, "monitor");
75 }
76 };
77
78
79 TEST_VM(markWord, printing) {
80 JavaThread* THREAD = JavaThread::current();
81 ThreadInVMfromNative invm(THREAD);
82 ResourceMark rm(THREAD);
83
84 oop obj = vmClasses::Byte_klass()->allocate_instance(THREAD);
85
86 FlagSetting fs(WizardMode, true);
87
88 HandleMark hm(THREAD);
89 Handle h_obj(THREAD, obj);
90
91 // Thread tries to lock it.
92 {
93 ObjectLocker ol(h_obj, THREAD);
94 assert_mark_word_print_pattern(h_obj, "locked");
95 }
96 assert_mark_word_print_pattern(h_obj, "is_unlocked no_hash");
97
98 // Hash the object then print it.
99 intx hash = h_obj->identity_hash();
100 assert_mark_word_print_pattern(h_obj, "is_unlocked hash=0x");
101
102 // Wait gets the lock inflated.
103 {
104 ObjectLocker ol(h_obj, THREAD);
105
106 Semaphore done(0);
107 LockerThread* st;
108 st = new LockerThread(&done, h_obj());
109 st->doit();
110
111 ol.wait_uninterruptibly(THREAD);
112 assert_test_pattern(h_obj, "monitor");
113 done.wait_with_safepoint_check(THREAD); // wait till the thread is done.
114 }
115 }
116
117 static void assert_unlocked_state(markWord mark) {
118 EXPECT_FALSE(mark.has_displaced_mark_helper());
119 EXPECT_FALSE(mark.is_fast_locked());
120 EXPECT_FALSE(mark.has_monitor());
121 EXPECT_FALSE(mark.is_locked());
122 EXPECT_TRUE(mark.is_unlocked());
123 }
124
125 static void assert_copy_set_hash(markWord mark) {
126 const intptr_t hash = 4711;
127 EXPECT_TRUE(mark.has_no_hash());
128 markWord copy = mark.copy_set_hash(hash);
129 EXPECT_EQ(hash, copy.hash());
130 EXPECT_FALSE(copy.has_no_hash());
131 }
132
133 static void assert_type(markWord mark) {
134 EXPECT_FALSE(mark.is_flat_array());
135 EXPECT_FALSE(mark.is_inline_type());
136 EXPECT_FALSE(mark.is_larval_state());
137 EXPECT_FALSE(mark.is_null_free_array());
138 }
139
140 TEST_VM(markWord, prototype) {
141 markWord mark = markWord::prototype();
142 assert_unlocked_state(mark);
143 EXPECT_TRUE(mark.is_neutral());
144
145 assert_type(mark);
146
147 EXPECT_TRUE(mark.has_no_hash());
148 EXPECT_FALSE(mark.is_marked());
149
150 assert_copy_set_hash(mark);
151 assert_type(mark);
152 }
153
154 static void assert_inline_type(markWord mark) {
155 EXPECT_FALSE(mark.is_flat_array());
156 EXPECT_TRUE(mark.is_inline_type());
157 EXPECT_FALSE(mark.is_null_free_array());
158 }
159
160 TEST_VM(markWord, inline_type_prototype) {
161 markWord mark = markWord::inline_type_prototype();
162 assert_unlocked_state(mark);
163 EXPECT_FALSE(mark.is_neutral());
164 assert_test_pattern(&mark, " inline_type");
165
166 assert_inline_type(mark);
167 EXPECT_FALSE(mark.is_larval_state());
168
169 EXPECT_TRUE(mark.has_no_hash());
170 EXPECT_FALSE(mark.is_marked());
171
172 markWord larval = mark.enter_larval_state();
173 EXPECT_TRUE(larval.is_larval_state());
174 assert_inline_type(larval);
175 assert_test_pattern(&larval, " inline_type=larval");
176
177 mark = larval.exit_larval_state();
178 EXPECT_FALSE(mark.is_larval_state());
179 assert_inline_type(mark);
180
181 EXPECT_TRUE(mark.has_no_hash());
182 EXPECT_FALSE(mark.is_marked());
183 }
184
185 #if _LP64
186
187 static void assert_flat_array_type(markWord mark) {
188 EXPECT_TRUE(mark.is_flat_array());
189 EXPECT_FALSE(mark.is_inline_type());
190 EXPECT_FALSE(mark.is_larval_state());
191 }
192
193 TEST_VM(markWord, null_free_flat_array_prototype) {
194 markWord mark = markWord::flat_array_prototype(LayoutKind::NULL_FREE_NON_ATOMIC_FLAT);
195 assert_unlocked_state(mark);
196 EXPECT_TRUE(mark.is_neutral());
197
198 assert_flat_array_type(mark);
199 EXPECT_TRUE(mark.is_null_free_array());
200
201 EXPECT_TRUE(mark.has_no_hash());
202 EXPECT_FALSE(mark.is_marked());
203
204 assert_copy_set_hash(mark);
205 assert_flat_array_type(mark);
206 EXPECT_TRUE(mark.is_null_free_array());
207
208 assert_test_pattern(&mark, " flat_null_free_array");
209 }
210
211 TEST_VM(markWord, nullable_flat_array_prototype) {
212 markWord mark = markWord::flat_array_prototype(LayoutKind::NULLABLE_ATOMIC_FLAT);
213 assert_unlocked_state(mark);
214 EXPECT_TRUE(mark.is_neutral());
215
216 assert_flat_array_type(mark);
217 EXPECT_FALSE(mark.is_null_free_array());
218
219 EXPECT_TRUE(mark.has_no_hash());
220 EXPECT_FALSE(mark.is_marked());
221
222 assert_copy_set_hash(mark);
223 assert_flat_array_type(mark);
224 EXPECT_FALSE(mark.is_null_free_array());
225
226 assert_test_pattern(&mark, " flat_array");
227 }
228
229 static void assert_null_free_array_type(markWord mark) {
230 EXPECT_FALSE(mark.is_flat_array());
231 EXPECT_FALSE(mark.is_inline_type());
232 EXPECT_FALSE(mark.is_larval_state());
233 EXPECT_TRUE(mark.is_null_free_array());
234 }
235
236 TEST_VM(markWord, null_free_array_prototype) {
237 markWord mark = markWord::null_free_array_prototype();
238 assert_unlocked_state(mark);
239 EXPECT_TRUE(mark.is_neutral());
240
241 assert_null_free_array_type(mark);
242
243 EXPECT_TRUE(mark.has_no_hash());
244 EXPECT_FALSE(mark.is_marked());
245
246 assert_copy_set_hash(mark);
247 assert_null_free_array_type(mark);
248
249 assert_test_pattern(&mark, " null_free_array");
250 }
251 #endif // _LP64
252
253 #endif // PRODUCT