1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/vm_operations.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,413 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_RUNTIME_VM_OPERATIONS_HPP 1.29 +#define SHARE_VM_RUNTIME_VM_OPERATIONS_HPP 1.30 + 1.31 +#include "classfile/javaClasses.hpp" 1.32 +#include "memory/allocation.hpp" 1.33 +#include "oops/oop.hpp" 1.34 +#include "runtime/thread.hpp" 1.35 +#include "utilities/top.hpp" 1.36 + 1.37 +// The following classes are used for operations 1.38 +// initiated by a Java thread but that must 1.39 +// take place in the VMThread. 1.40 + 1.41 +#define VM_OP_ENUM(type) VMOp_##type, 1.42 + 1.43 +// Note: When new VM_XXX comes up, add 'XXX' to the template table. 1.44 +#define VM_OPS_DO(template) \ 1.45 + template(Dummy) \ 1.46 + template(ThreadStop) \ 1.47 + template(ThreadDump) \ 1.48 + template(PrintThreads) \ 1.49 + template(FindDeadlocks) \ 1.50 + template(ForceSafepoint) \ 1.51 + template(ForceAsyncSafepoint) \ 1.52 + template(Deoptimize) \ 1.53 + template(DeoptimizeFrame) \ 1.54 + template(DeoptimizeAll) \ 1.55 + template(ZombieAll) \ 1.56 + template(UnlinkSymbols) \ 1.57 + template(Verify) \ 1.58 + template(PrintJNI) \ 1.59 + template(HeapDumper) \ 1.60 + template(DeoptimizeTheWorld) \ 1.61 + template(CollectForMetadataAllocation) \ 1.62 + template(GC_HeapInspection) \ 1.63 + template(GenCollectFull) \ 1.64 + template(GenCollectFullConcurrent) \ 1.65 + template(GenCollectForAllocation) \ 1.66 + template(ParallelGCFailedAllocation) \ 1.67 + template(ParallelGCSystemGC) \ 1.68 + template(CGC_Operation) \ 1.69 + template(CMS_Initial_Mark) \ 1.70 + template(CMS_Final_Remark) \ 1.71 + template(G1CollectFull) \ 1.72 + template(G1CollectForAllocation) \ 1.73 + template(G1IncCollectionPause) \ 1.74 + template(EnableBiasedLocking) \ 1.75 + template(RevokeBias) \ 1.76 + template(BulkRevokeBias) \ 1.77 + template(PopulateDumpSharedSpace) \ 1.78 + template(JNIFunctionTableCopier) \ 1.79 + template(RedefineClasses) \ 1.80 + template(GetOwnedMonitorInfo) \ 1.81 + template(GetObjectMonitorUsage) \ 1.82 + template(GetCurrentContendedMonitor) \ 1.83 + template(GetStackTrace) \ 1.84 + template(GetMultipleStackTraces) \ 1.85 + template(GetAllStackTraces) \ 1.86 + template(GetThreadListStackTraces) \ 1.87 + template(GetFrameCount) \ 1.88 + template(GetFrameLocation) \ 1.89 + template(ChangeBreakpoints) \ 1.90 + template(GetOrSetLocal) \ 1.91 + template(GetCurrentLocation) \ 1.92 + template(EnterInterpOnlyMode) \ 1.93 + template(ChangeSingleStep) \ 1.94 + template(HeapWalkOperation) \ 1.95 + template(HeapIterateOperation) \ 1.96 + template(ReportJavaOutOfMemory) \ 1.97 + template(JFRCheckpoint) \ 1.98 + template(Exit) \ 1.99 + template(LinuxDllLoad) \ 1.100 + template(RotateGCLog) \ 1.101 + template(WhiteBoxOperation) \ 1.102 + 1.103 +class VM_Operation: public CHeapObj<mtInternal> { 1.104 + public: 1.105 + enum Mode { 1.106 + _safepoint, // blocking, safepoint, vm_op C-heap allocated 1.107 + _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated 1.108 + _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated 1.109 + _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated 1.110 + }; 1.111 + 1.112 + enum VMOp_Type { 1.113 + VM_OPS_DO(VM_OP_ENUM) 1.114 + VMOp_Terminating 1.115 + }; 1.116 + 1.117 + private: 1.118 + Thread* _calling_thread; 1.119 + ThreadPriority _priority; 1.120 + long _timestamp; 1.121 + VM_Operation* _next; 1.122 + VM_Operation* _prev; 1.123 + 1.124 + // The VM operation name array 1.125 + static const char* _names[]; 1.126 + 1.127 + public: 1.128 + VM_Operation() { _calling_thread = NULL; _next = NULL; _prev = NULL; } 1.129 + virtual ~VM_Operation() {} 1.130 + 1.131 + // VM operation support (used by VM thread) 1.132 + Thread* calling_thread() const { return _calling_thread; } 1.133 + ThreadPriority priority() { return _priority; } 1.134 + void set_calling_thread(Thread* thread, ThreadPriority priority); 1.135 + 1.136 + long timestamp() const { return _timestamp; } 1.137 + void set_timestamp(long timestamp) { _timestamp = timestamp; } 1.138 + 1.139 + // Called by VM thread - does in turn invoke doit(). Do not override this 1.140 + void evaluate(); 1.141 + 1.142 + // evaluate() is called by the VMThread and in turn calls doit(). 1.143 + // If the thread invoking VMThread::execute((VM_Operation*) is a JavaThread, 1.144 + // doit_prologue() is called in that thread before transferring control to 1.145 + // the VMThread. 1.146 + // If doit_prologue() returns true the VM operation will proceed, and 1.147 + // doit_epilogue() will be called by the JavaThread once the VM operation 1.148 + // completes. If doit_prologue() returns false the VM operation is cancelled. 1.149 + virtual void doit() = 0; 1.150 + virtual bool doit_prologue() { return true; }; 1.151 + virtual void doit_epilogue() {}; // Note: Not called if mode is: _concurrent 1.152 + 1.153 + // Type test 1.154 + virtual bool is_methodCompiler() const { return false; } 1.155 + 1.156 + // Linking 1.157 + VM_Operation *next() const { return _next; } 1.158 + VM_Operation *prev() const { return _prev; } 1.159 + void set_next(VM_Operation *next) { _next = next; } 1.160 + void set_prev(VM_Operation *prev) { _prev = prev; } 1.161 + 1.162 + // Configuration. Override these appropriatly in subclasses. 1.163 + virtual VMOp_Type type() const = 0; 1.164 + virtual Mode evaluation_mode() const { return _safepoint; } 1.165 + virtual bool allow_nested_vm_operations() const { return false; } 1.166 + virtual bool is_cheap_allocated() const { return false; } 1.167 + virtual void oops_do(OopClosure* f) { /* do nothing */ }; 1.168 + 1.169 + // CAUTION: <don't hang yourself with following rope> 1.170 + // If you override these methods, make sure that the evaluation 1.171 + // of these methods is race-free and non-blocking, since these 1.172 + // methods may be evaluated either by the mutators or by the 1.173 + // vm thread, either concurrently with mutators or with the mutators 1.174 + // stopped. In other words, taking locks is verboten, and if there 1.175 + // are any races in evaluating the conditions, they'd better be benign. 1.176 + virtual bool evaluate_at_safepoint() const { 1.177 + return evaluation_mode() == _safepoint || 1.178 + evaluation_mode() == _async_safepoint; 1.179 + } 1.180 + virtual bool evaluate_concurrently() const { 1.181 + return evaluation_mode() == _concurrent || 1.182 + evaluation_mode() == _async_safepoint; 1.183 + } 1.184 + 1.185 + static const char* mode_to_string(Mode mode); 1.186 + 1.187 + // Debugging 1.188 + void print_on_error(outputStream* st) const; 1.189 + const char* name() const { return _names[type()]; } 1.190 + static const char* name(int type) { 1.191 + assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type"); 1.192 + return _names[type]; 1.193 + } 1.194 +#ifndef PRODUCT 1.195 + void print_on(outputStream* st) const { print_on_error(st); } 1.196 +#endif 1.197 +}; 1.198 + 1.199 +class VM_ThreadStop: public VM_Operation { 1.200 + private: 1.201 + oop _thread; // The Thread that the Throwable is thrown against 1.202 + oop _throwable; // The Throwable thrown at the target Thread 1.203 + public: 1.204 + // All oops are passed as JNI handles, since there is no guarantee that a GC might happen before the 1.205 + // VM operation is executed. 1.206 + VM_ThreadStop(oop thread, oop throwable) { 1.207 + _thread = thread; 1.208 + _throwable = throwable; 1.209 + } 1.210 + VMOp_Type type() const { return VMOp_ThreadStop; } 1.211 + oop target_thread() const { return _thread; } 1.212 + oop throwable() const { return _throwable;} 1.213 + void doit(); 1.214 + // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated 1.215 + bool allow_nested_vm_operations() const { return true; } 1.216 + Mode evaluation_mode() const { return _async_safepoint; } 1.217 + bool is_cheap_allocated() const { return true; } 1.218 + 1.219 + // GC support 1.220 + void oops_do(OopClosure* f) { 1.221 + f->do_oop(&_thread); f->do_oop(&_throwable); 1.222 + } 1.223 +}; 1.224 + 1.225 +// dummy vm op, evaluated just to force a safepoint 1.226 +class VM_ForceSafepoint: public VM_Operation { 1.227 + public: 1.228 + VM_ForceSafepoint() {} 1.229 + void doit() {} 1.230 + VMOp_Type type() const { return VMOp_ForceSafepoint; } 1.231 +}; 1.232 + 1.233 +// dummy vm op, evaluated just to force a safepoint 1.234 +class VM_ForceAsyncSafepoint: public VM_Operation { 1.235 + public: 1.236 + VM_ForceAsyncSafepoint() {} 1.237 + void doit() {} 1.238 + VMOp_Type type() const { return VMOp_ForceAsyncSafepoint; } 1.239 + Mode evaluation_mode() const { return _async_safepoint; } 1.240 + bool is_cheap_allocated() const { return true; } 1.241 +}; 1.242 + 1.243 +class VM_Deoptimize: public VM_Operation { 1.244 + public: 1.245 + VM_Deoptimize() {} 1.246 + VMOp_Type type() const { return VMOp_Deoptimize; } 1.247 + void doit(); 1.248 + bool allow_nested_vm_operations() const { return true; } 1.249 +}; 1.250 + 1.251 + 1.252 +// Deopt helper that can deoptimize frames in threads other than the 1.253 +// current thread. Only used through Deoptimization::deoptimize_frame. 1.254 +class VM_DeoptimizeFrame: public VM_Operation { 1.255 + friend class Deoptimization; 1.256 + 1.257 + private: 1.258 + JavaThread* _thread; 1.259 + intptr_t* _id; 1.260 + VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id); 1.261 + 1.262 + public: 1.263 + VMOp_Type type() const { return VMOp_DeoptimizeFrame; } 1.264 + void doit(); 1.265 + bool allow_nested_vm_operations() const { return true; } 1.266 +}; 1.267 + 1.268 +#ifndef PRODUCT 1.269 +class VM_DeoptimizeAll: public VM_Operation { 1.270 + private: 1.271 + KlassHandle _dependee; 1.272 + public: 1.273 + VM_DeoptimizeAll() {} 1.274 + VMOp_Type type() const { return VMOp_DeoptimizeAll; } 1.275 + void doit(); 1.276 + bool allow_nested_vm_operations() const { return true; } 1.277 +}; 1.278 + 1.279 + 1.280 +class VM_ZombieAll: public VM_Operation { 1.281 + public: 1.282 + VM_ZombieAll() {} 1.283 + VMOp_Type type() const { return VMOp_ZombieAll; } 1.284 + void doit(); 1.285 + bool allow_nested_vm_operations() const { return true; } 1.286 +}; 1.287 +#endif // PRODUCT 1.288 + 1.289 +class VM_UnlinkSymbols: public VM_Operation { 1.290 + public: 1.291 + VM_UnlinkSymbols() {} 1.292 + VMOp_Type type() const { return VMOp_UnlinkSymbols; } 1.293 + void doit(); 1.294 + bool allow_nested_vm_operations() const { return true; } 1.295 +}; 1.296 + 1.297 +class VM_Verify: public VM_Operation { 1.298 + private: 1.299 + bool _silent; 1.300 + public: 1.301 + VM_Verify(bool silent = VerifySilently) : _silent(silent) {} 1.302 + VMOp_Type type() const { return VMOp_Verify; } 1.303 + void doit(); 1.304 +}; 1.305 + 1.306 + 1.307 +class VM_PrintThreads: public VM_Operation { 1.308 + private: 1.309 + outputStream* _out; 1.310 + bool _print_concurrent_locks; 1.311 + public: 1.312 + VM_PrintThreads() { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; } 1.313 + VM_PrintThreads(outputStream* out, bool print_concurrent_locks) { _out = out; _print_concurrent_locks = print_concurrent_locks; } 1.314 + VMOp_Type type() const { return VMOp_PrintThreads; } 1.315 + void doit(); 1.316 + bool doit_prologue(); 1.317 + void doit_epilogue(); 1.318 +}; 1.319 + 1.320 +class VM_PrintJNI: public VM_Operation { 1.321 + private: 1.322 + outputStream* _out; 1.323 + public: 1.324 + VM_PrintJNI() { _out = tty; } 1.325 + VM_PrintJNI(outputStream* out) { _out = out; } 1.326 + VMOp_Type type() const { return VMOp_PrintJNI; } 1.327 + void doit(); 1.328 +}; 1.329 + 1.330 +class DeadlockCycle; 1.331 +class VM_FindDeadlocks: public VM_Operation { 1.332 + private: 1.333 + bool _concurrent_locks; 1.334 + DeadlockCycle* _deadlocks; 1.335 + outputStream* _out; 1.336 + 1.337 + public: 1.338 + VM_FindDeadlocks(bool concurrent_locks) : _concurrent_locks(concurrent_locks), _out(NULL), _deadlocks(NULL) {}; 1.339 + VM_FindDeadlocks(outputStream* st) : _concurrent_locks(true), _out(st), _deadlocks(NULL) {}; 1.340 + ~VM_FindDeadlocks(); 1.341 + 1.342 + DeadlockCycle* result() { return _deadlocks; }; 1.343 + VMOp_Type type() const { return VMOp_FindDeadlocks; } 1.344 + void doit(); 1.345 + bool doit_prologue(); 1.346 +}; 1.347 + 1.348 +class ThreadDumpResult; 1.349 +class ThreadSnapshot; 1.350 +class ThreadConcurrentLocks; 1.351 + 1.352 +class VM_ThreadDump : public VM_Operation { 1.353 + private: 1.354 + ThreadDumpResult* _result; 1.355 + int _num_threads; 1.356 + GrowableArray<instanceHandle>* _threads; 1.357 + int _max_depth; 1.358 + bool _with_locked_monitors; 1.359 + bool _with_locked_synchronizers; 1.360 + 1.361 + ThreadSnapshot* snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl); 1.362 + 1.363 + public: 1.364 + VM_ThreadDump(ThreadDumpResult* result, 1.365 + int max_depth, // -1 indicates entire stack 1.366 + bool with_locked_monitors, 1.367 + bool with_locked_synchronizers); 1.368 + 1.369 + VM_ThreadDump(ThreadDumpResult* result, 1.370 + GrowableArray<instanceHandle>* threads, 1.371 + int num_threads, // -1 indicates entire stack 1.372 + int max_depth, 1.373 + bool with_locked_monitors, 1.374 + bool with_locked_synchronizers); 1.375 + 1.376 + VMOp_Type type() const { return VMOp_ThreadDump; } 1.377 + void doit(); 1.378 + bool doit_prologue(); 1.379 + void doit_epilogue(); 1.380 +}; 1.381 + 1.382 + 1.383 +class VM_Exit: public VM_Operation { 1.384 + private: 1.385 + int _exit_code; 1.386 + static volatile bool _vm_exited; 1.387 + static Thread * _shutdown_thread; 1.388 + static void wait_if_vm_exited(); 1.389 + public: 1.390 + VM_Exit(int exit_code) { 1.391 + _exit_code = exit_code; 1.392 + } 1.393 + static int wait_for_threads_in_native_to_block(); 1.394 + static int set_vm_exited(); 1.395 + static bool vm_exited() { return _vm_exited; } 1.396 + static void block_if_vm_exited() { 1.397 + if (_vm_exited) { 1.398 + wait_if_vm_exited(); 1.399 + } 1.400 + } 1.401 + VMOp_Type type() const { return VMOp_Exit; } 1.402 + void doit(); 1.403 +}; 1.404 + 1.405 + 1.406 +class VM_RotateGCLog: public VM_Operation { 1.407 + private: 1.408 + outputStream* _out; 1.409 + 1.410 + public: 1.411 + VM_RotateGCLog(outputStream* st) : _out(st) {} 1.412 + VMOp_Type type() const { return VMOp_RotateGCLog; } 1.413 + void doit() { gclog_or_tty->rotate_log(true, _out); } 1.414 +}; 1.415 + 1.416 +#endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP