1/*
2 * Copyright (c) 2019, 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/systemDictionary.hpp"
26#include "memory/resourceArea.hpp"
27#include "memory/universe.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/synchronizer.hpp"
34#include "runtime/semaphore.inline.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
42static bool test_pattern(stringStream* st, const char* pattern) {
43 return (strstr(st->as_string(), pattern) != NULL);
44}
45
46static void assert_test_pattern(Handle object, const char* pattern) {
47 stringStream st;
48 object->print_on(&st);
49 ASSERT_TRUE(test_pattern(&st, pattern)) << pattern << " not in " << st.as_string();
50}
51
52static void assert_not_test_pattern(Handle object, const char* pattern) {
53 stringStream st;
54 object->print_on(&st);
55 ASSERT_FALSE(test_pattern(&st, pattern)) << pattern << " found in " << st.as_string();
56}
57
58class LockerThread : public JavaTestThread {
59 oop _obj;
60 public:
61 LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {}
62 virtual ~LockerThread() {}
63
64 void main_run() {
65 Thread* THREAD = Thread::current();
66 HandleMark hm(THREAD);
67 Handle h_obj(THREAD, _obj);
68 ResourceMark rm(THREAD);
69
70 // Wait gets the lock inflated.
71 // The object will stay locked for the context of 'ol' so the lock will
72 // still be inflated after the notify_all() call. Deflation can't happen
73 // while an ObjectMonitor is "busy" and being locked is the most "busy"
74 // state we have...
75 ObjectLocker ol(h_obj, THREAD);
76 ol.notify_all(THREAD);
77 assert_test_pattern(h_obj, "monitor");
78 }
79};
80
81
82TEST_VM(markOopDesc, printing) {
83 JavaThread* THREAD = JavaThread::current();
84 ThreadInVMfromNative invm(THREAD);
85 ResourceMark rm(THREAD);
86
87 oop obj = SystemDictionary::Byte_klass()->allocate_instance(THREAD);
88
89 FlagSetting fs(WizardMode, true);
90 FlagSetting bf(UseBiasedLocking, true);
91
92 HandleMark hm(THREAD);
93 Handle h_obj(THREAD, obj);
94
95 // Biased locking is initially enabled for this java.lang.Byte object.
96 assert_test_pattern(h_obj, "is_biased");
97
98 // Lock using biased locking.
99 BasicObjectLock lock;
100 lock.set_obj(obj);
101 markOop mark = obj->mark()->incr_bias_epoch();
102 obj->set_mark(mark);
103 ObjectSynchronizer::fast_enter(h_obj, lock.lock(), true, THREAD);
104 // Look for the biased_locker in markOop, not prototype_header.
105#ifdef _LP64
106 assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
107#else
108 assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x00000000");
109#endif
110
111 // Same thread tries to lock it again.
112 {
113 ObjectLocker ol(h_obj, THREAD);
114 assert_test_pattern(h_obj, "locked");
115 }
116
117 // This is no longer biased, because ObjectLocker revokes the bias.
118 assert_test_pattern(h_obj, "is_neutral no_hash");
119
120 // Wait gets the lock inflated.
121 {
122 ObjectLocker ol(h_obj, THREAD);
123
124 Semaphore done(0);
125 LockerThread* st;
126 st = new LockerThread(&done, h_obj());
127 st->doit();
128
129 ol.wait(THREAD);
130 assert_test_pattern(h_obj, "monitor");
131 done.wait_with_safepoint_check(THREAD); // wait till the thread is done.
132 }
133
134 // Make the object older. Not all GCs use this field.
135 Universe::heap()->collect(GCCause::_java_lang_system_gc);
136 if (UseParallelGC) {
137 assert_test_pattern(h_obj, "is_neutral no_hash age 1");
138 }
139
140 // Hash the object then print it.
141 intx hash = h_obj->identity_hash();
142 assert_test_pattern(h_obj, "is_neutral hash=0x");
143}
144#endif // PRODUCT
145