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
  42 static bool test_pattern(stringStream* st, const char* pattern) {
  43   return (strstr(st->as_string(), pattern) != NULL);
  44 }
  45 
  46 static 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 
  52 static 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 
  58 class 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 
  82 TEST_VM(markWord, 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   markWord prototype_header = obj->klass()->prototype_header();
 102   markWord mark = obj->mark();
 103   markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
 104   obj->set_mark(biased_mark);
 105   // Look for the biased_locker in markWord, not prototype_header.
 106 #ifdef _LP64
 107   assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
 108 #else
 109   assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x00000000");
 110 #endif
 111 
 112   // Same thread tries to lock it again.
 113   {
 114     ObjectLocker ol(h_obj, THREAD);
 115     assert_test_pattern(h_obj, "locked");
 116   }
 117 
 118   // This is no longer biased, because ObjectLocker revokes the bias.
 119   assert_test_pattern(h_obj, "is_neutral no_hash");
 120 
 121   // Wait gets the lock inflated.
 122   {
 123     ObjectLocker ol(h_obj, THREAD);
 124 
 125     Semaphore done(0);
 126     LockerThread* st;
 127     st = new LockerThread(&done, h_obj());
 128     st->doit();
 129 
 130     ol.wait(THREAD);
 131     assert_test_pattern(h_obj, "monitor");
 132     done.wait_with_safepoint_check(THREAD);  // wait till the thread is done.
 133   }
 134 
 135   // Make the object older. Not all GCs use this field.
 136   Universe::heap()->collect(GCCause::_java_lang_system_gc);
 137   if (UseParallelGC) {
 138     assert_test_pattern(h_obj, "is_neutral no_hash age 1");
 139   }
 140 
 141   // Hash the object then print it.
 142   intx hash = h_obj->identity_hash();
 143   assert_test_pattern(h_obj, "is_neutral hash=0x");
 144 }
 145 #endif // PRODUCT