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/biasedLocking.hpp"
32 #include "runtime/interfaceSupport.inline.hpp"
33 #include "runtime/orderAccess.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/synchronizer.hpp"
36 #include "runtime/semaphore.inline.hpp"
37 #include "threadHelper.inline.hpp"
38 #include "unittest.hpp"
39 #include "utilities/globalDefinitions.hpp"
40 #include "utilities/ostream.hpp"
41 
42 // The test doesn't work for PRODUCT because it needs WizardMode
43 #ifndef PRODUCT
test_pattern(stringStream * st,const char * pattern)44 static bool test_pattern(stringStream* st, const char* pattern) {
45   return (strstr(st->as_string(), pattern) != NULL);
46 }
47 
assert_test_pattern(Handle object,const char * pattern)48 static void assert_test_pattern(Handle object, const char* pattern) {
49   stringStream st;
50   object->print_on(&st);
51   ASSERT_TRUE(test_pattern(&st, pattern)) << pattern << " not in " << st.as_string();
52 }
53 
assert_not_test_pattern(Handle object,const char * pattern)54 static void assert_not_test_pattern(Handle object, const char* pattern) {
55   stringStream st;
56   object->print_on(&st);
57   ASSERT_FALSE(test_pattern(&st, pattern)) << pattern << " found in " << st.as_string();
58 }
59 
60 class LockerThread : public JavaTestThread {
61   oop _obj;
62   public:
LockerThread(Semaphore * post,oop obj)63   LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {}
~LockerThread()64   virtual ~LockerThread() {}
65 
main_run()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 
TEST_VM(markWord,printing)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   if (UseBiasedLocking && BiasedLocking::enabled()) {
97     // Can't test this with biased locking disabled.
98     // Biased locking is initially enabled for this java.lang.Byte object.
99     assert_test_pattern(h_obj, "is_biased");
100 
101     // Lock using biased locking.
102     BasicObjectLock lock;
103     lock.set_obj(obj);
104     markWord prototype_header = obj->klass()->prototype_header();
105     markWord mark = obj->mark();
106     markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
107     obj->set_mark(biased_mark);
108     // Look for the biased_locker in markWord, not prototype_header.
109 #ifdef _LP64
110     assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
111 #else
112     assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x00000000");
113 #endif
114   }
115 
116   // Same thread tries to lock it again.
117   {
118     ObjectLocker ol(h_obj, THREAD);
119     assert_test_pattern(h_obj, "locked");
120   }
121 
122   // This is no longer biased, because ObjectLocker revokes the bias.
123   assert_test_pattern(h_obj, "is_neutral no_hash");
124 
125   // Hash the object then print it.
126   intx hash = h_obj->identity_hash();
127   assert_test_pattern(h_obj, "is_neutral hash=0x");
128 
129   // Wait gets the lock inflated.
130   {
131     ObjectLocker ol(h_obj, THREAD);
132 
133     Semaphore done(0);
134     LockerThread* st;
135     st = new LockerThread(&done, h_obj());
136     st->doit();
137 
138     ol.wait(THREAD);
139     assert_test_pattern(h_obj, "monitor");
140     done.wait_with_safepoint_check(THREAD);  // wait till the thread is done.
141   }
142 }
143 #endif // PRODUCT
144