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/atomic.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 if (LockingMode == LM_MONITOR) { 53 // With heavy monitors, we do not use the mark word. Printing the oop only shows "monitor" regardless of the 54 // locking state. 55 assert_test_pattern(object, "monitor"); 56 } else { 57 assert_test_pattern(object, pattern); 58 } 59 } 60 61 class LockerThread : public JavaTestThread { 62 oop _obj; 63 public: 64 LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {} 65 virtual ~LockerThread() {} 66 67 void main_run() { 68 JavaThread* THREAD = JavaThread::current(); 69 HandleMark hm(THREAD); 70 Handle h_obj(THREAD, _obj); 71 ResourceMark rm(THREAD); 72 73 // Wait gets the lock inflated. 74 // The object will stay locked for the context of 'ol' so the lock will 75 // still be inflated after the notify_all() call. Deflation can't happen 76 // while an ObjectMonitor is "busy" and being locked is the most "busy" 77 // state we have... 78 ObjectLocker ol(h_obj, THREAD); 79 ol.notify_all(THREAD); 80 assert_test_pattern(h_obj, "monitor"); 81 } 82 }; 83 84 85 TEST_VM(markWord, printing) { 86 JavaThread* THREAD = JavaThread::current(); 87 ThreadInVMfromNative invm(THREAD); 88 ResourceMark rm(THREAD); 89 90 oop obj = vmClasses::Byte_klass()->allocate_instance(THREAD); 91 92 FlagSetting fs(WizardMode, true); 93 94 HandleMark hm(THREAD); 95 Handle h_obj(THREAD, obj); 96 97 // Thread tries to lock it. 98 { 99 ObjectLocker ol(h_obj, THREAD); 100 assert_mark_word_print_pattern(h_obj, "locked"); 101 } 102 assert_mark_word_print_pattern(h_obj, "is_unlocked no_hash"); 103 104 // Hash the object then print it. 105 intx hash = h_obj->identity_hash(); 106 assert_mark_word_print_pattern(h_obj, "is_unlocked hash=0x"); 107 108 // Wait gets the lock inflated. 109 { 110 ObjectLocker ol(h_obj, THREAD); 111 112 Semaphore done(0); 113 LockerThread* st; 114 st = new LockerThread(&done, h_obj()); 115 st->doit(); 116 117 ol.wait(THREAD); 118 assert_test_pattern(h_obj, "monitor"); 119 done.wait_with_safepoint_check(THREAD); // wait till the thread is done. 120 } 121 } 122 123 static void assert_unlocked_state(markWord mark) { 124 EXPECT_FALSE(mark.has_displaced_mark_helper()); 125 if (LockingMode == LM_LEGACY) { 126 EXPECT_FALSE(mark.has_locker()); 127 } else if (LockingMode == LM_LIGHTWEIGHT) { 128 EXPECT_FALSE(mark.is_fast_locked()); 129 } 130 EXPECT_FALSE(mark.has_monitor()); 131 EXPECT_FALSE(mark.is_being_inflated()); 132 EXPECT_FALSE(mark.is_locked()); 133 EXPECT_TRUE(mark.is_unlocked()); 134 } 135 136 static void assert_copy_set_hash(markWord mark) { 137 const intptr_t hash = 4711; 138 EXPECT_TRUE(mark.has_no_hash()); 139 markWord copy = mark.copy_set_hash(hash); 140 EXPECT_EQ(hash, copy.hash()); 141 EXPECT_FALSE(copy.has_no_hash()); 142 } 143 144 static void assert_type(markWord mark) { 145 EXPECT_FALSE(mark.is_flat_array()); 146 EXPECT_FALSE(mark.is_inline_type()); 147 EXPECT_FALSE(mark.is_larval_state()); 148 EXPECT_FALSE(mark.is_null_free_array()); 149 } 150 151 TEST_VM(markWord, prototype) { 152 markWord mark = markWord::prototype(); 153 assert_unlocked_state(mark); 154 EXPECT_TRUE(mark.is_neutral()); 155 156 assert_type(mark); 157 158 EXPECT_TRUE(mark.has_no_hash()); 159 EXPECT_FALSE(mark.is_marked()); 160 EXPECT_TRUE(mark.decode_pointer() == nullptr); 161 162 assert_copy_set_hash(mark); 163 assert_type(mark); 164 } 165 166 static void assert_inline_type(markWord mark) { 167 EXPECT_FALSE(mark.is_flat_array()); 168 EXPECT_TRUE(mark.is_inline_type()); 169 EXPECT_FALSE(mark.is_null_free_array()); 170 } 171 172 TEST_VM(markWord, inline_type_prototype) { 173 markWord mark = markWord::inline_type_prototype(); 174 assert_unlocked_state(mark); 175 EXPECT_FALSE(mark.is_neutral()); 176 assert_test_pattern(&mark, " inline_type"); 177 178 assert_inline_type(mark); 179 EXPECT_FALSE(mark.is_larval_state()); 180 181 EXPECT_TRUE(mark.has_no_hash()); 182 EXPECT_FALSE(mark.is_marked()); 183 EXPECT_TRUE(mark.decode_pointer() == nullptr); 184 185 markWord larval = mark.enter_larval_state(); 186 EXPECT_TRUE(larval.is_larval_state()); 187 assert_inline_type(larval); 188 assert_test_pattern(&larval, " inline_type=larval"); 189 190 mark = larval.exit_larval_state(); 191 EXPECT_FALSE(mark.is_larval_state()); 192 assert_inline_type(mark); 193 194 EXPECT_TRUE(mark.has_no_hash()); 195 EXPECT_FALSE(mark.is_marked()); 196 EXPECT_TRUE(mark.decode_pointer() == nullptr); 197 } 198 199 #if _LP64 200 201 static void assert_flat_array_type(markWord mark) { 202 EXPECT_TRUE(mark.is_flat_array()); 203 EXPECT_FALSE(mark.is_inline_type()); 204 EXPECT_FALSE(mark.is_larval_state()); 205 } 206 207 TEST_VM(markWord, null_free_flat_array_prototype) { 208 markWord mark = markWord::flat_array_prototype(LayoutKind::NON_ATOMIC_FLAT); 209 assert_unlocked_state(mark); 210 EXPECT_TRUE(mark.is_neutral()); 211 212 assert_flat_array_type(mark); 213 EXPECT_TRUE(mark.is_null_free_array()); 214 215 EXPECT_TRUE(mark.has_no_hash()); 216 EXPECT_FALSE(mark.is_marked()); 217 EXPECT_TRUE(mark.decode_pointer() == nullptr); 218 219 assert_copy_set_hash(mark); 220 assert_flat_array_type(mark); 221 EXPECT_TRUE(mark.is_null_free_array()); 222 223 assert_test_pattern(&mark, " flat_null_free_array"); 224 } 225 226 TEST_VM(markWord, nullable_flat_array_prototype) { 227 markWord mark = markWord::flat_array_prototype(LayoutKind::NULLABLE_ATOMIC_FLAT); 228 assert_unlocked_state(mark); 229 EXPECT_TRUE(mark.is_neutral()); 230 231 assert_flat_array_type(mark); 232 EXPECT_FALSE(mark.is_null_free_array()); 233 234 EXPECT_TRUE(mark.has_no_hash()); 235 EXPECT_FALSE(mark.is_marked()); 236 EXPECT_TRUE(mark.decode_pointer() == nullptr); 237 238 assert_copy_set_hash(mark); 239 assert_flat_array_type(mark); 240 EXPECT_FALSE(mark.is_null_free_array()); 241 242 assert_test_pattern(&mark, " flat_array"); 243 } 244 245 static void assert_null_free_array_type(markWord mark) { 246 EXPECT_FALSE(mark.is_flat_array()); 247 EXPECT_FALSE(mark.is_inline_type()); 248 EXPECT_FALSE(mark.is_larval_state()); 249 EXPECT_TRUE(mark.is_null_free_array()); 250 } 251 252 TEST_VM(markWord, null_free_array_prototype) { 253 markWord mark = markWord::null_free_array_prototype(); 254 assert_unlocked_state(mark); 255 EXPECT_TRUE(mark.is_neutral()); 256 257 assert_null_free_array_type(mark); 258 259 EXPECT_TRUE(mark.has_no_hash()); 260 EXPECT_FALSE(mark.is_marked()); 261 EXPECT_TRUE(mark.decode_pointer() == nullptr); 262 263 assert_copy_set_hash(mark); 264 assert_null_free_array_type(mark); 265 266 assert_test_pattern(&mark, " null_free_array"); 267 } 268 #endif // _LP64 269 270 #endif // PRODUCT