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 --- EOF ---