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