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