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