1 /* 2 * Copyright (c) 1998, 2020, 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 25 #ifndef SHARE_RUNTIME_SYNCHRONIZER_HPP 26 #define SHARE_RUNTIME_SYNCHRONIZER_HPP 27 28 #include "memory/padded.hpp" 29 #include "oops/markWord.hpp" 30 #include "runtime/basicLock.hpp" 31 #include "runtime/handles.hpp" 32 #include "runtime/os.hpp" 33 #include "runtime/perfData.hpp" 34 35 class LogStream; 36 class ObjectMonitor; 37 class ThreadsList; 38 39 class ObjectSynchronizer : AllStatic { 40 friend class VMStructs; 41 42 public: 43 typedef enum { 44 owner_self, 45 owner_none, 46 owner_other 47 } LockOwnership; 48 49 typedef enum { 50 inflate_cause_vm_internal = 0, 51 inflate_cause_monitor_enter = 1, 52 inflate_cause_wait = 2, 53 inflate_cause_notify = 3, 54 inflate_cause_hash_code = 4, 55 inflate_cause_jni_enter = 5, 56 inflate_cause_jni_exit = 6, 57 inflate_cause_nof = 7 // Number of causes 58 } InflateCause; 59 60 typedef enum { 61 NOT_ENABLED = 0, 62 FATAL_EXIT = 1, 63 LOG_WARNING = 2 64 } SyncDiagnosticOption; 65 66 // exit must be implemented non-blocking, since the compiler cannot easily handle 67 // deoptimization at monitor exit. Hence, it does not take a Handle argument. 68 69 // This is the "slow path" version of monitor enter and exit. 70 static void enter(Handle obj, BasicLock* lock, TRAPS); 71 static void exit(oop obj, BasicLock* lock, Thread* THREAD); 72 73 // Used only to handle jni locks or other unmatched monitor enter/exit 74 // Internally they will use heavy weight monitor. 75 static void jni_enter(Handle obj, TRAPS); 76 static void jni_exit(oop obj, Thread* THREAD); 77 78 // Handle all interpreter, compiler and jni cases 79 static int wait(Handle obj, jlong millis, TRAPS); 80 static void notify(Handle obj, TRAPS); 81 static void notifyall(Handle obj, TRAPS); 82 83 static bool quick_notify(oopDesc* obj, Thread* self, bool All); 84 static bool quick_enter(oop obj, Thread* self, BasicLock* Lock); 85 86 // Special internal-use-only method for use by JVM infrastructure 87 // that needs to wait() on a java-level object but that can't risk 88 // throwing unexpected InterruptedExecutionExceptions. 89 static void wait_uninterruptibly(Handle obj, jlong Millis, Thread* THREAD); 90 91 // used by classloading to free classloader object lock, 92 // wait on an internal lock, and reclaim original lock 93 // with original recursion count 94 static intx complete_exit(Handle obj, TRAPS); 95 static void reenter (Handle obj, intx recursions, TRAPS); 96 97 // Inflate light weight monitor to heavy weight monitor 98 static ObjectMonitor* inflate(Thread* self, oop obj, const InflateCause cause); 99 // This version is only for internal use 100 static void inflate_helper(oop obj); 101 static const char* inflate_cause_name(const InflateCause cause); 102 103 // Returns the identity hash value for an oop 104 // NOTE: It may cause monitor inflation 105 static intptr_t identity_hash_value_for(Handle obj); 106 static intptr_t FastHashCode(Thread* self, oop obj); 107 108 // java.lang.Thread support 109 static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj); 110 static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj); 111 112 static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj); 113 114 // JNI detach support 115 static void release_monitors_owned_by_thread(TRAPS); 116 static void monitors_iterate(MonitorClosure* m); 117 118 // Initialize the gInflationLocks 119 static void initialize(); 120 121 // GC: we current use aggressive monitor deflation policy 122 // Basically we try to deflate all monitors that are not busy. 123 static size_t deflate_idle_monitors(); 124 125 // Deflate idle monitors: 126 static void chk_for_block_req(JavaThread* self, const char* op_name, 127 const char* cnt_name, size_t cnt, LogStream* ls, 128 elapsedTimer* timer_p); 129 static size_t deflate_monitor_list(Thread* self, LogStream* ls, 130 elapsedTimer* timer_p); 131 static size_t in_use_list_ceiling(); 132 static void dec_in_use_list_ceiling(); 133 static void inc_in_use_list_ceiling(); 134 static bool is_async_deflation_needed(); is_async_deflation_requested()135 static bool is_async_deflation_requested() { return _is_async_deflation_requested; } is_final_audit()136 static bool is_final_audit() { return _is_final_audit; } set_is_final_audit()137 static void set_is_final_audit() { _is_final_audit = true; } last_async_deflation_time_ns()138 static jlong last_async_deflation_time_ns() { return _last_async_deflation_time_ns; } 139 static bool request_deflate_idle_monitors(); // for whitebox test support set_is_async_deflation_requested(bool new_value)140 static void set_is_async_deflation_requested(bool new_value) { _is_async_deflation_requested = new_value; } 141 static jlong time_since_last_async_deflation_ms(); 142 143 // debugging 144 static void audit_and_print_stats(bool on_exit); 145 static void chk_in_use_list(outputStream* out, int* error_cnt_p); 146 static void chk_in_use_entry(ObjectMonitor* n, outputStream* out, 147 int* error_cnt_p); 148 static void do_final_audit_and_print_stats(); 149 static void log_in_use_monitor_details(outputStream* out); 150 151 private: 152 friend class SynchronizerTest; 153 154 static volatile bool _is_async_deflation_requested; 155 static volatile bool _is_final_audit; 156 static jlong _last_async_deflation_time_ns; 157 158 // Support for SynchronizerTest access to GVars fields: 159 static u_char* get_gvars_addr(); 160 static u_char* get_gvars_hc_sequence_addr(); 161 static size_t get_gvars_size(); 162 static u_char* get_gvars_stw_random_addr(); 163 164 static void handle_sync_on_value_based_class(Handle obj, Thread* current); 165 }; 166 167 // ObjectLocker enforces balanced locking and can never throw an 168 // IllegalMonitorStateException. However, a pending exception may 169 // have to pass through, and we must also be able to deal with 170 // asynchronous exceptions. The caller is responsible for checking 171 // the thread's pending exception if needed. 172 class ObjectLocker : public StackObj { 173 private: 174 Thread* _thread; 175 Handle _obj; 176 BasicLock _lock; 177 bool _dolock; // default true 178 public: 179 ObjectLocker(Handle obj, Thread* thread, bool do_lock = true); 180 ~ObjectLocker(); 181 182 // Monitor behavior wait(TRAPS)183 void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever notify_all(TRAPS)184 void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); } wait_uninterruptibly(TRAPS)185 void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); } 186 // complete_exit gives up lock completely, returning recursion count 187 // reenter reclaims lock with original recursion count complete_exit(TRAPS)188 intx complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); } reenter(intx recursions,TRAPS)189 void reenter(intx recursions, TRAPS) { ObjectSynchronizer::reenter(_obj, recursions, CHECK); } 190 }; 191 192 #endif // SHARE_RUNTIME_SYNCHRONIZER_HPP 193