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(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_being_inflated());
122 EXPECT_FALSE(mark.is_locked());
123 EXPECT_TRUE(mark.is_unlocked());
124 }
125
126 static void assert_copy_set_hash(markWord mark) {
127 const intptr_t hash = 4711;
128 EXPECT_TRUE(mark.has_no_hash());
129 markWord copy = mark.copy_set_hash(hash);
130 EXPECT_EQ(hash, copy.hash());
131 EXPECT_FALSE(copy.has_no_hash());
132 }
133
134 static void assert_type(markWord mark) {
135 EXPECT_FALSE(mark.is_flat_array());
136 EXPECT_FALSE(mark.is_inline_type());
137 EXPECT_FALSE(mark.is_larval_state());
138 EXPECT_FALSE(mark.is_null_free_array());
139 }
140
141 TEST_VM(markWord, prototype) {
142 markWord mark = markWord::prototype();
143 assert_unlocked_state(mark);
144 EXPECT_TRUE(mark.is_neutral());
145
146 assert_type(mark);
147
148 EXPECT_TRUE(mark.has_no_hash());
149 EXPECT_FALSE(mark.is_marked());
150
151 assert_copy_set_hash(mark);
152 assert_type(mark);
153 }
154
155 static void assert_inline_type(markWord mark) {
156 EXPECT_FALSE(mark.is_flat_array());
157 EXPECT_TRUE(mark.is_inline_type());
158 EXPECT_FALSE(mark.is_null_free_array());
159 }
160
161 TEST_VM(markWord, inline_type_prototype) {
162 markWord mark = markWord::inline_type_prototype();
163 assert_unlocked_state(mark);
164 EXPECT_FALSE(mark.is_neutral());
165 assert_test_pattern(&mark, " inline_type");
166
167 assert_inline_type(mark);
168 EXPECT_FALSE(mark.is_larval_state());
169
170 EXPECT_TRUE(mark.has_no_hash());
171 EXPECT_FALSE(mark.is_marked());
172
173 markWord larval = mark.enter_larval_state();
174 EXPECT_TRUE(larval.is_larval_state());
175 assert_inline_type(larval);
176 assert_test_pattern(&larval, " inline_type=larval");
177
178 mark = larval.exit_larval_state();
179 EXPECT_FALSE(mark.is_larval_state());
180 assert_inline_type(mark);
181
182 EXPECT_TRUE(mark.has_no_hash());
183 EXPECT_FALSE(mark.is_marked());
184 }
185
186 #if _LP64
187
188 static void assert_flat_array_type(markWord mark) {
189 EXPECT_TRUE(mark.is_flat_array());
190 EXPECT_FALSE(mark.is_inline_type());
191 EXPECT_FALSE(mark.is_larval_state());
192 }
193
194 TEST_VM(markWord, null_free_flat_array_prototype) {
195 markWord mark = markWord::flat_array_prototype(LayoutKind::NON_ATOMIC_FLAT);
196 assert_unlocked_state(mark);
197 EXPECT_TRUE(mark.is_neutral());
198
199 assert_flat_array_type(mark);
200 EXPECT_TRUE(mark.is_null_free_array());
201
202 EXPECT_TRUE(mark.has_no_hash());
203 EXPECT_FALSE(mark.is_marked());
204
205 assert_copy_set_hash(mark);
206 assert_flat_array_type(mark);
207 EXPECT_TRUE(mark.is_null_free_array());
208
209 assert_test_pattern(&mark, " flat_null_free_array");
210 }
211
212 TEST_VM(markWord, nullable_flat_array_prototype) {
213 markWord mark = markWord::flat_array_prototype(LayoutKind::NULLABLE_ATOMIC_FLAT);
214 assert_unlocked_state(mark);
215 EXPECT_TRUE(mark.is_neutral());
216
217 assert_flat_array_type(mark);
218 EXPECT_FALSE(mark.is_null_free_array());
219
220 EXPECT_TRUE(mark.has_no_hash());
221 EXPECT_FALSE(mark.is_marked());
222
223 assert_copy_set_hash(mark);
224 assert_flat_array_type(mark);
225 EXPECT_FALSE(mark.is_null_free_array());
226
227 assert_test_pattern(&mark, " flat_array");
228 }
229
230 static void assert_null_free_array_type(markWord mark) {
231 EXPECT_FALSE(mark.is_flat_array());
232 EXPECT_FALSE(mark.is_inline_type());
233 EXPECT_FALSE(mark.is_larval_state());
234 EXPECT_TRUE(mark.is_null_free_array());
235 }
236
237 TEST_VM(markWord, null_free_array_prototype) {
238 markWord mark = markWord::null_free_array_prototype();
239 assert_unlocked_state(mark);
240 EXPECT_TRUE(mark.is_neutral());
241
242 assert_null_free_array_type(mark);
243
244 EXPECT_TRUE(mark.has_no_hash());
245 EXPECT_FALSE(mark.is_marked());
246
247 assert_copy_set_hash(mark);
248 assert_null_free_array_type(mark);
249
250 assert_test_pattern(&mark, " null_free_array");
251 }
252 #endif // _LP64
253
254 #endif // PRODUCT