src/share/vm/runtime/vm_operations.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     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

mercurial