OpenJDK / loom / loom
changeset 53055:9e041366c764
8214850: Rename vm_operations.?pp files to vmOperations.?pp files
Reviewed-by: dholmes, coleenp
line wrap: on
line diff
--- a/src/hotspot/share/aot/aotCodeHeap.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/aot/aotCodeHeap.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -40,7 +40,7 @@ #include "runtime/os.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/sharedRuntime.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" bool AOTLib::_narrow_oop_shift_initialized = false; int AOTLib::_narrow_oop_shift = 0;
--- a/src/hotspot/share/classfile/classLoaderStats.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/classfile/classLoaderStats.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -30,7 +30,7 @@ #include "oops/klass.hpp" #include "oops/oop.hpp" #include "oops/oopsHierarchy.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/diagnosticCommand.hpp" #include "utilities/resourceHash.hpp"
--- a/src/hotspot/share/gc/cms/cmsVMOperations.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/gc/cms/cmsVMOperations.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -29,7 +29,7 @@ #include "gc/shared/gcCause.hpp" #include "gc/shared/gcId.hpp" #include "gc/shared/gcVMOperations.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // The VM_CMS_Operation is slightly different from // a VM_GC_Operation -- and would not have subclassed easily
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -57,7 +57,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/threadCritical.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/memoryService.hpp" #include "utilities/stack.inline.hpp"
--- a/src/hotspot/share/gc/shared/gcVMOperations.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/gc/shared/gcVMOperations.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -32,7 +32,7 @@ #include "runtime/handles.hpp" #include "runtime/jniHandles.hpp" #include "runtime/synchronizer.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // The following class hierarchy represents // a set of operations (VM_Operation) related to GC.
--- a/src/hotspot/share/gc/z/zDriver.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/gc/z/zDriver.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -34,7 +34,7 @@ #include "gc/z/zStat.hpp" #include "logging/log.hpp" #include "memory/universe.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" static const ZStatPhaseCycle ZPhaseCycle("Garbage Collection Cycle");
--- a/src/hotspot/share/jfr/leakprofiler/emitEventOperation.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/emitEventOperation.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -25,7 +25,7 @@ #ifndef SHARE_VM_LEAKPROFILER_EMITEVENTOPERATION_HPP #define SHARE_VM_LEAKPROFILER_EMITEVENTOPERATION_HPP -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" class BFSClosure; class EdgeStore;
--- a/src/hotspot/share/jfr/leakprofiler/startOperation.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/startOperation.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -30,7 +30,7 @@ #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "logging/log.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // Safepoint operation for starting leak profiler object sampler class StartOperation : public VM_Operation {
--- a/src/hotspot/share/jfr/leakprofiler/stopOperation.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/stopOperation.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -29,7 +29,7 @@ #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "logging/log.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // Safepoint operation for stopping leak profiler object sampler class StopOperation : public VM_Operation {
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -49,7 +49,7 @@ #include "runtime/safepoint.hpp" #include "runtime/synchronizer.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #ifdef COMPILER2 #include "opto/compile.hpp"
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -50,7 +50,7 @@ #include "runtime/os.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" // set data iff *dest == NULL
--- a/src/hotspot/share/memory/metaspaceShared.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/memory/metaspaceShared.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -61,7 +61,7 @@ #include "runtime/signature.hpp" #include "runtime/timerTrace.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/align.hpp" #include "utilities/bitMap.hpp" #include "utilities/defaultStream.hpp"
--- a/src/hotspot/share/memory/universe.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/memory/universe.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -72,7 +72,7 @@ #include "runtime/synchronizer.hpp" #include "runtime/thread.inline.hpp" #include "runtime/timerTrace.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/memoryService.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp"
--- a/src/hotspot/share/prims/jni.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jni.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -79,7 +79,7 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "utilities/defaultStream.hpp"
--- a/src/hotspot/share/prims/jvm.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvm.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -72,7 +72,7 @@ #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vframe.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" #include "services/management.hpp"
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -52,7 +52,7 @@ #include "runtime/vframe.hpp" #include "runtime/vframe_hp.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" /////////////////////////////////////////////////////////////// //
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -33,7 +33,7 @@ #include "runtime/fieldDescriptor.hpp" #include "runtime/frame.hpp" #include "runtime/thread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/growableArray.hpp" #include "utilities/macros.hpp"
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -37,7 +37,7 @@ #include "runtime/signature.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vframe.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" ///////////////////////////////////////////////////////////////
--- a/src/hotspot/share/prims/jvmtiEventController.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiEventController.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -38,7 +38,7 @@ #include "runtime/vframe.hpp" #include "runtime/vframe_hp.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #ifdef JVMTI_TRACE #define EC_TRACE(out) do { \
--- a/src/hotspot/share/prims/jvmtiImpl.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiImpl.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -50,7 +50,7 @@ #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vframe_hp.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/exceptions.hpp" //
--- a/src/hotspot/share/prims/jvmtiImpl.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiImpl.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -33,7 +33,7 @@ #include "prims/jvmtiTrace.hpp" #include "prims/jvmtiUtil.hpp" #include "runtime/stackValueCollection.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/ostream.hpp" //
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -30,7 +30,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // Introduction: //
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -58,7 +58,7 @@ #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/macros.hpp" #if INCLUDE_ZGC #include "gc/z/zGlobals.hpp"
--- a/src/hotspot/share/prims/jvmtiTrace.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiTrace.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -32,7 +32,7 @@ #include "prims/jvmtiEventController.hpp" #include "prims/jvmtiUtil.hpp" #include "runtime/stackValueCollection.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" /////////////////////////////////////////////////////////////// //
--- a/src/hotspot/share/prims/jvmtiUtil.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/prims/jvmtiUtil.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -27,7 +27,7 @@ #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/exceptions.hpp" //
--- a/src/hotspot/share/runtime/biasedLocking.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/biasedLocking.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -39,7 +39,7 @@ #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" static bool _biased_locking_enabled = false;
--- a/src/hotspot/share/runtime/compilationPolicy.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/compilationPolicy.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -42,7 +42,7 @@ #include "runtime/tieredThresholdPolicy.hpp" #include "runtime/timer.hpp" #include "runtime/vframe.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/events.hpp" #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/runtime/compilationPolicy.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/compilationPolicy.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -28,7 +28,7 @@ #include "code/nmethod.hpp" #include "compiler/compileBroker.hpp" #include "memory/allocation.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/growableArray.hpp" // The CompilationPolicy selects which method (if any) should be compiled.
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -32,7 +32,7 @@ #include "runtime/safepointMechanism.inline.hpp" #include "runtime/safepointVerifiers.hpp" #include "runtime/thread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/preserveException.hpp"
--- a/src/hotspot/share/runtime/java.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/java.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -68,7 +68,7 @@ #include "runtime/task.hpp" #include "runtime/thread.inline.hpp" #include "runtime/timer.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/memTracker.hpp" #include "utilities/dtrace.hpp" #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/runtime/sweeper.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/sweeper.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -46,7 +46,7 @@ #include "runtime/os.hpp" #include "runtime/sweeper.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" #include "utilities/events.hpp" #include "utilities/xmlstream.hpp"
--- a/src/hotspot/share/runtime/thread.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/thread.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -100,7 +100,7 @@ #include "runtime/vframeArray.hpp" #include "runtime/vframe_hp.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" #include "services/management.hpp"
--- a/src/hotspot/share/runtime/threadSMR.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/threadSMR.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -28,7 +28,7 @@ #include "runtime/jniHandles.inline.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/threadService.hpp" #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/runtime/vmOperations.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -0,0 +1,508 @@ +/* + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "classfile/symbolTable.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" +#include "compiler/compileBroker.hpp" +#include "gc/shared/isGCActiveMark.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" +#include "memory/heapInspection.hpp" +#include "memory/resourceArea.hpp" +#include "oops/symbol.hpp" +#include "runtime/arguments.hpp" +#include "runtime/deoptimization.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/sweeper.hpp" +#include "runtime/thread.inline.hpp" +#include "runtime/threadSMR.inline.hpp" +#include "runtime/vmOperations.hpp" +#include "services/threadService.hpp" + +#define VM_OP_NAME_INITIALIZE(name) #name, + +const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ + { VM_OPS_DO(VM_OP_NAME_INITIALIZE) }; + +void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) { + _calling_thread = thread; + assert(MinPriority <= priority && priority <= MaxPriority, "sanity check"); + _priority = priority; +} + + +void VM_Operation::evaluate() { + ResourceMark rm; + LogTarget(Debug, vmoperation) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print("begin "); + print_on_error(&ls); + ls.cr(); + } + doit(); + if (lt.is_enabled()) { + LogStream ls(lt); + ls.print("end "); + print_on_error(&ls); + ls.cr(); + } +} + +const char* VM_Operation::mode_to_string(Mode mode) { + switch(mode) { + case _safepoint : return "safepoint"; + case _no_safepoint : return "no safepoint"; + case _concurrent : return "concurrent"; + case _async_safepoint: return "async safepoint"; + default : return "unknown"; + } +} +// Called by fatal error handler. +void VM_Operation::print_on_error(outputStream* st) const { + st->print("VM_Operation (" PTR_FORMAT "): ", p2i(this)); + st->print("%s", name()); + + const char* mode = mode_to_string(evaluation_mode()); + st->print(", mode: %s", mode); + + if (calling_thread()) { + st->print(", requested by thread " PTR_FORMAT, p2i(calling_thread())); + } +} + +void VM_ThreadStop::doit() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); + ThreadsListHandle tlh; + JavaThread* target = java_lang_Thread::thread(target_thread()); + // Note that this now allows multiple ThreadDeath exceptions to be + // thrown at a thread. + if (target != NULL && (!EnableThreadSMRExtraValidityChecks || tlh.includes(target))) { + // The target thread has run and has not exited yet. + target->send_thread_stop(throwable()); + } +} + +void VM_ClearICs::doit() { + if (_preserve_static_stubs) { + CodeCache::cleanup_inline_caches(); + } else { + CodeCache::clear_inline_caches(); + } +} + +void VM_Deoptimize::doit() { + // We do not want any GCs to happen while we are in the middle of this VM operation + ResourceMark rm; + DeoptimizationMarker dm; + + // Deoptimize all activations depending on marked nmethods + Deoptimization::deoptimize_dependents(); + + // Make the dependent methods not entrant + CodeCache::make_marked_nmethods_not_entrant(); +} + +void VM_MarkActiveNMethods::doit() { + NMethodSweeper::mark_active_nmethods(); +} + +VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) { + _thread = thread; + _id = id; + _reason = reason; +} + + +void VM_DeoptimizeFrame::doit() { + assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::Reason_LIMIT, "invalid deopt reason"); + Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason); +} + + +#ifndef PRODUCT + +void VM_DeoptimizeAll::doit() { + DeoptimizationMarker dm; + JavaThreadIteratorWithHandle jtiwh; + // deoptimize all java threads in the system + if (DeoptimizeALot) { + for (; JavaThread *thread = jtiwh.next(); ) { + if (thread->has_last_Java_frame()) { + thread->deoptimize(); + } + } + } else if (DeoptimizeRandom) { + + // Deoptimize some selected threads and frames + int tnum = os::random() & 0x3; + int fnum = os::random() & 0x3; + int tcount = 0; + for (; JavaThread *thread = jtiwh.next(); ) { + if (thread->has_last_Java_frame()) { + if (tcount++ == tnum) { + tcount = 0; + int fcount = 0; + // Deoptimize some selected frames. + // Biased llocking wants a updated register map + for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) { + if (fst.current()->can_be_deoptimized()) { + if (fcount++ == fnum) { + fcount = 0; + Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); + } + } + } + } + } + } + } +} + + +void VM_ZombieAll::doit() { + JavaThread *thread = (JavaThread *)calling_thread(); + assert(thread->is_Java_thread(), "must be a Java thread"); + thread->make_zombies(); +} + +#endif // !PRODUCT + +void VM_Verify::doit() { + Universe::heap()->prepare_for_verify(); + Universe::verify(); +} + +bool VM_PrintThreads::doit_prologue() { + // Get Heap_lock if concurrent locks will be dumped + if (_print_concurrent_locks) { + Heap_lock->lock(); + } + return true; +} + +void VM_PrintThreads::doit() { + Threads::print_on(_out, true, false, _print_concurrent_locks, _print_extended_info); +} + +void VM_PrintThreads::doit_epilogue() { + if (_print_concurrent_locks) { + // Release Heap_lock + Heap_lock->unlock(); + } +} + +void VM_PrintJNI::doit() { + JNIHandles::print_on(_out); +} + +void VM_PrintMetadata::doit() { + MetaspaceUtils::print_report(_out, _scale, _flags); +} + +VM_FindDeadlocks::~VM_FindDeadlocks() { + if (_deadlocks != NULL) { + DeadlockCycle* cycle = _deadlocks; + while (cycle != NULL) { + DeadlockCycle* d = cycle; + cycle = cycle->next(); + delete d; + } + } +} + +void VM_FindDeadlocks::doit() { + // Update the hazard ptr in the originating thread to the current + // list of threads. This VM operation needs the current list of + // threads for proper deadlock detection and those are the + // JavaThreads we need to be protected when we return info to the + // originating thread. + _setter.set(); + + _deadlocks = ThreadService::find_deadlocks_at_safepoint(_setter.list(), _concurrent_locks); + if (_out != NULL) { + int num_deadlocks = 0; + for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) { + num_deadlocks++; + cycle->print_on_with(_setter.list(), _out); + } + + if (num_deadlocks == 1) { + _out->print_cr("\nFound 1 deadlock.\n"); + _out->flush(); + } else if (num_deadlocks > 1) { + _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks); + _out->flush(); + } + } +} + +VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, + int max_depth, + bool with_locked_monitors, + bool with_locked_synchronizers) { + _result = result; + _num_threads = 0; // 0 indicates all threads + _threads = NULL; + _result = result; + _max_depth = max_depth; + _with_locked_monitors = with_locked_monitors; + _with_locked_synchronizers = with_locked_synchronizers; +} + +VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, + GrowableArray<instanceHandle>* threads, + int num_threads, + int max_depth, + bool with_locked_monitors, + bool with_locked_synchronizers) { + _result = result; + _num_threads = num_threads; + _threads = threads; + _result = result; + _max_depth = max_depth; + _with_locked_monitors = with_locked_monitors; + _with_locked_synchronizers = with_locked_synchronizers; +} + +bool VM_ThreadDump::doit_prologue() { + if (_with_locked_synchronizers) { + // Acquire Heap_lock to dump concurrent locks + Heap_lock->lock(); + } + + return true; +} + +void VM_ThreadDump::doit_epilogue() { + if (_with_locked_synchronizers) { + // Release Heap_lock + Heap_lock->unlock(); + } +} + +void VM_ThreadDump::doit() { + ResourceMark rm; + + // Set the hazard ptr in the originating thread to protect the + // current list of threads. This VM operation needs the current list + // of threads for a proper dump and those are the JavaThreads we need + // to be protected when we return info to the originating thread. + _result->set_t_list(); + + ConcurrentLocksDump concurrent_locks(true); + if (_with_locked_synchronizers) { + concurrent_locks.dump_at_safepoint(); + } + + if (_num_threads == 0) { + // Snapshot all live threads + + for (uint i = 0; i < _result->t_list()->length(); i++) { + JavaThread* jt = _result->t_list()->thread_at(i); + if (jt->is_exiting() || + jt->is_hidden_from_external_view()) { + // skip terminating threads and hidden threads + continue; + } + ThreadConcurrentLocks* tcl = NULL; + if (_with_locked_synchronizers) { + tcl = concurrent_locks.thread_concurrent_locks(jt); + } + ThreadSnapshot* ts = snapshot_thread(jt, tcl); + _result->add_thread_snapshot(ts); + } + } else { + // Snapshot threads in the given _threads array + // A dummy snapshot is created if a thread doesn't exist + + for (int i = 0; i < _num_threads; i++) { + instanceHandle th = _threads->at(i); + if (th() == NULL) { + // skip if the thread doesn't exist + // Add a dummy snapshot + _result->add_thread_snapshot(new ThreadSnapshot()); + continue; + } + + // Dump thread stack only if the thread is alive and not exiting + // and not VM internal thread. + JavaThread* jt = java_lang_Thread::thread(th()); + if (jt != NULL && !_result->t_list()->includes(jt)) { + // _threads[i] doesn't refer to a valid JavaThread; this check + // is primarily for JVM_DumpThreads() which doesn't have a good + // way to validate the _threads array. + jt = NULL; + } + if (jt == NULL || /* thread not alive */ + jt->is_exiting() || + jt->is_hidden_from_external_view()) { + // add a NULL snapshot if skipped + _result->add_thread_snapshot(new ThreadSnapshot()); + continue; + } + ThreadConcurrentLocks* tcl = NULL; + if (_with_locked_synchronizers) { + tcl = concurrent_locks.thread_concurrent_locks(jt); + } + ThreadSnapshot* ts = snapshot_thread(jt, tcl); + _result->add_thread_snapshot(ts); + } + } +} + +ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { + ThreadSnapshot* snapshot = new ThreadSnapshot(_result->t_list(), java_thread); + snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); + snapshot->set_concurrent_locks(tcl); + return snapshot; +} + +volatile bool VM_Exit::_vm_exited = false; +Thread * volatile VM_Exit::_shutdown_thread = NULL; + +int VM_Exit::set_vm_exited() { + + Thread * thr_cur = Thread::current(); + + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); + + int num_active = 0; + + _shutdown_thread = thr_cur; + _vm_exited = true; // global flag + for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { + if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { + ++num_active; + thr->set_terminated(JavaThread::_vm_exited); // per-thread flag + } + } + + return num_active; +} + +int VM_Exit::wait_for_threads_in_native_to_block() { + // VM exits at safepoint. This function must be called at the final safepoint + // to wait for threads in _thread_in_native state to be quiescent. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); + + Thread * thr_cur = Thread::current(); + Monitor timer(Mutex::leaf, "VM_Exit timer", true, + Monitor::_safepoint_check_never); + + // Compiler threads need longer wait because they can access VM data directly + // while in native. If they are active and some structures being used are + // deleted by the shutdown sequence, they will crash. On the other hand, user + // threads must go through native=>Java/VM transitions first to access VM + // data, and they will be stopped during state transition. In theory, we + // don't have to wait for user threads to be quiescent, but it's always + // better to terminate VM when current thread is the only active thread, so + // wait for user threads too. Numbers are in 10 milliseconds. + int max_wait_user_thread = 30; // at least 300 milliseconds + int max_wait_compiler_thread = 1000; // at least 10 seconds + + int max_wait = max_wait_compiler_thread; + + int attempts = 0; + JavaThreadIteratorWithHandle jtiwh; + while (true) { + int num_active = 0; + int num_active_compiler_thread = 0; + + jtiwh.rewind(); + for (; JavaThread *thr = jtiwh.next(); ) { + if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { + num_active++; + if (thr->is_Compiler_thread()) { + num_active_compiler_thread++; + } + } + } + + if (num_active == 0) { + return 0; + } else if (attempts > max_wait) { + return num_active; + } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { + return num_active; + } + + attempts++; + + MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); + timer.wait(Mutex::_no_safepoint_check_flag, 10); + } +} + +void VM_Exit::doit() { + CompileBroker::set_should_block(); + + // Wait for a short period for threads in native to block. Any thread + // still executing native code after the wait will be stopped at + // native==>Java/VM barriers. + // Among 16276 JCK tests, 94% of them come here without any threads still + // running in native; the other 6% are quiescent within 250ms (Ultra 80). + wait_for_threads_in_native_to_block(); + + set_vm_exited(); + + // cleanup globals resources before exiting. exit_globals() currently + // cleans up outputStream resources and PerfMemory resources. + exit_globals(); + + // Check for exit hook + exit_hook_t exit_hook = Arguments::exit_hook(); + if (exit_hook != NULL) { + // exit hook should exit. + exit_hook(_exit_code); + // ... but if it didn't, we must do it here + vm_direct_exit(_exit_code); + } else { + vm_direct_exit(_exit_code); + } +} + + +void VM_Exit::wait_if_vm_exited() { + if (_vm_exited && + Thread::current_or_null() != _shutdown_thread) { + // _vm_exited is set at safepoint, and the Threads_lock is never released + // we will block here until the process dies + Threads_lock->lock_without_safepoint_check(); + ShouldNotReachHere(); + } +} + +void VM_PrintCompileQueue::doit() { + CompileBroker::print_compile_queues(_out); +} + +#if INCLUDE_SERVICES +void VM_PrintClassHierarchy::doit() { + KlassHierarchy::print_class_hierarchy(_out, _print_interfaces, _print_subclasses, _classname); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/runtime/vmOperations.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -0,0 +1,512 @@ +/* + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_RUNTIME_VMOPERATIONS_HPP +#define SHARE_VM_RUNTIME_VMOPERATIONS_HPP + +#include "classfile/javaClasses.hpp" +#include "memory/allocation.hpp" +#include "oops/oop.hpp" +#include "runtime/thread.hpp" +#include "runtime/threadSMR.hpp" +#include "code/codeCache.hpp" + +// The following classes are used for operations +// initiated by a Java thread but that must +// take place in the VMThread. + +#define VM_OP_ENUM(type) VMOp_##type, + +// Note: When new VM_XXX comes up, add 'XXX' to the template table. +#define VM_OPS_DO(template) \ + template(None) \ + template(ThreadStop) \ + template(ThreadDump) \ + template(PrintThreads) \ + template(FindDeadlocks) \ + template(ClearICs) \ + template(ForceSafepoint) \ + template(ForceAsyncSafepoint) \ + template(Deoptimize) \ + template(DeoptimizeFrame) \ + template(DeoptimizeAll) \ + template(ZombieAll) \ + template(Verify) \ + template(PrintJNI) \ + template(HeapDumper) \ + template(DeoptimizeTheWorld) \ + template(CollectForMetadataAllocation) \ + template(GC_HeapInspection) \ + template(GenCollectFull) \ + template(GenCollectFullConcurrent) \ + template(GenCollectForAllocation) \ + template(ParallelGCFailedAllocation) \ + template(ParallelGCSystemGC) \ + template(CMS_Initial_Mark) \ + template(CMS_Final_Remark) \ + template(G1CollectForAllocation) \ + template(G1CollectFull) \ + template(G1Concurrent) \ + template(ZOperation) \ + template(HandshakeOneThread) \ + template(HandshakeAllThreads) \ + template(HandshakeFallback) \ + template(EnableBiasedLocking) \ + template(RevokeBias) \ + template(BulkRevokeBias) \ + template(PopulateDumpSharedSpace) \ + template(JNIFunctionTableCopier) \ + template(RedefineClasses) \ + template(UpdateForPopTopFrame) \ + template(SetFramePop) \ + template(GetOwnedMonitorInfo) \ + template(GetObjectMonitorUsage) \ + template(GetCurrentContendedMonitor) \ + template(GetStackTrace) \ + template(GetMultipleStackTraces) \ + template(GetAllStackTraces) \ + template(GetThreadListStackTraces) \ + template(GetFrameCount) \ + template(GetFrameLocation) \ + template(ChangeBreakpoints) \ + template(GetOrSetLocal) \ + template(GetCurrentLocation) \ + template(EnterInterpOnlyMode) \ + template(ChangeSingleStep) \ + template(HeapWalkOperation) \ + template(HeapIterateOperation) \ + template(ReportJavaOutOfMemory) \ + template(JFRCheckpoint) \ + template(Exit) \ + template(LinuxDllLoad) \ + template(RotateGCLog) \ + template(WhiteBoxOperation) \ + template(ClassLoaderStatsOperation) \ + template(ClassLoaderHierarchyOperation) \ + template(DumpHashtable) \ + template(DumpTouchedMethods) \ + template(MarkActiveNMethods) \ + template(PrintCompileQueue) \ + template(PrintClassHierarchy) \ + template(ThreadSuspend) \ + template(CTWThreshold) \ + template(ThreadsSuspendJVMTI) \ + template(ICBufferFull) \ + template(ScavengeMonitors) \ + template(PrintMetadata) \ + template(GTestExecuteAtSafepoint) \ + +class VM_Operation: public CHeapObj<mtInternal> { + public: + enum Mode { + _safepoint, // blocking, safepoint, vm_op C-heap allocated + _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated + _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated + _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated + }; + + enum VMOp_Type { + VM_OPS_DO(VM_OP_ENUM) + VMOp_Terminating + }; + + private: + Thread* _calling_thread; + ThreadPriority _priority; + long _timestamp; + VM_Operation* _next; + VM_Operation* _prev; + + // The VM operation name array + static const char* _names[]; + + public: + VM_Operation() { _calling_thread = NULL; _next = NULL; _prev = NULL; } + virtual ~VM_Operation() {} + + // VM operation support (used by VM thread) + Thread* calling_thread() const { return _calling_thread; } + ThreadPriority priority() { return _priority; } + void set_calling_thread(Thread* thread, ThreadPriority priority); + + long timestamp() const { return _timestamp; } + void set_timestamp(long timestamp) { _timestamp = timestamp; } + + // Called by VM thread - does in turn invoke doit(). Do not override this + void evaluate(); + + // evaluate() is called by the VMThread and in turn calls doit(). + // If the thread invoking VMThread::execute((VM_Operation*) is a JavaThread, + // doit_prologue() is called in that thread before transferring control to + // the VMThread. + // If doit_prologue() returns true the VM operation will proceed, and + // doit_epilogue() will be called by the JavaThread once the VM operation + // completes. If doit_prologue() returns false the VM operation is cancelled. + virtual void doit() = 0; + virtual bool doit_prologue() { return true; }; + virtual void doit_epilogue() {}; // Note: Not called if mode is: _concurrent + + // Type test + virtual bool is_methodCompiler() const { return false; } + + // Linking + VM_Operation *next() const { return _next; } + VM_Operation *prev() const { return _prev; } + void set_next(VM_Operation *next) { _next = next; } + void set_prev(VM_Operation *prev) { _prev = prev; } + + // Configuration. Override these appropriately in subclasses. + virtual VMOp_Type type() const = 0; + virtual Mode evaluation_mode() const { return _safepoint; } + virtual bool allow_nested_vm_operations() const { return false; } + virtual bool is_cheap_allocated() const { return false; } + virtual void oops_do(OopClosure* f) { /* do nothing */ }; + + // CAUTION: <don't hang yourself with following rope> + // If you override these methods, make sure that the evaluation + // of these methods is race-free and non-blocking, since these + // methods may be evaluated either by the mutators or by the + // vm thread, either concurrently with mutators or with the mutators + // stopped. In other words, taking locks is verboten, and if there + // are any races in evaluating the conditions, they'd better be benign. + virtual bool evaluate_at_safepoint() const { + return evaluation_mode() == _safepoint || + evaluation_mode() == _async_safepoint; + } + virtual bool evaluate_concurrently() const { + return evaluation_mode() == _concurrent || + evaluation_mode() == _async_safepoint; + } + + static const char* mode_to_string(Mode mode); + + // Debugging + virtual void print_on_error(outputStream* st) const; + const char* name() const { return _names[type()]; } + static const char* name(int type) { + assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type"); + return _names[type]; + } +#ifndef PRODUCT + void print_on(outputStream* st) const { print_on_error(st); } +#endif +}; + +class VM_ThreadStop: public VM_Operation { + private: + oop _thread; // The Thread that the Throwable is thrown against + oop _throwable; // The Throwable thrown at the target Thread + public: + // All oops are passed as JNI handles, since there is no guarantee that a GC might happen before the + // VM operation is executed. + VM_ThreadStop(oop thread, oop throwable) { + _thread = thread; + _throwable = throwable; + } + VMOp_Type type() const { return VMOp_ThreadStop; } + oop target_thread() const { return _thread; } + oop throwable() const { return _throwable;} + void doit(); + // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated + bool allow_nested_vm_operations() const { return true; } + Mode evaluation_mode() const { return _async_safepoint; } + bool is_cheap_allocated() const { return true; } + + // GC support + void oops_do(OopClosure* f) { + f->do_oop(&_thread); f->do_oop(&_throwable); + } +}; + +class VM_ClearICs: public VM_Operation { + private: + bool _preserve_static_stubs; + public: + VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } + void doit(); + VMOp_Type type() const { return VMOp_ClearICs; } +}; + +// empty vm op, evaluated just to force a safepoint +class VM_ForceSafepoint: public VM_Operation { + public: + void doit() {} + VMOp_Type type() const { return VMOp_ForceSafepoint; } +}; + +// empty vm op, when forcing a safepoint to suspend a thread +class VM_ThreadSuspend: public VM_ForceSafepoint { + public: + VMOp_Type type() const { return VMOp_ThreadSuspend; } +}; + +// empty vm op, when forcing a safepoint due to ctw threshold is reached for the sweeper +class VM_CTWThreshold: public VM_ForceSafepoint { + public: + VMOp_Type type() const { return VMOp_CTWThreshold; } +}; + +// empty vm op, when forcing a safepoint to suspend threads from jvmti +class VM_ThreadsSuspendJVMTI: public VM_ForceSafepoint { + public: + VMOp_Type type() const { return VMOp_ThreadsSuspendJVMTI; } +}; + +// empty vm op, when forcing a safepoint due to inline cache buffers being full +class VM_ICBufferFull: public VM_ForceSafepoint { + public: + VMOp_Type type() const { return VMOp_ICBufferFull; } +}; + +// empty asynchronous vm op, when forcing a safepoint to scavenge monitors +class VM_ScavengeMonitors: public VM_ForceSafepoint { + public: + VMOp_Type type() const { return VMOp_ScavengeMonitors; } + Mode evaluation_mode() const { return _async_safepoint; } + bool is_cheap_allocated() const { return true; } +}; + +// Base class for invoking parts of a gtest in a safepoint. +// Derived classes provide the doit method. +// Typically also need to transition the gtest thread from native to VM. +class VM_GTestExecuteAtSafepoint: public VM_Operation { + public: + VMOp_Type type() const { return VMOp_GTestExecuteAtSafepoint; } + + protected: + VM_GTestExecuteAtSafepoint() {} +}; + +class VM_Deoptimize: public VM_Operation { + public: + VM_Deoptimize() {} + VMOp_Type type() const { return VMOp_Deoptimize; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; + +class VM_MarkActiveNMethods: public VM_Operation { + public: + VM_MarkActiveNMethods() {} + VMOp_Type type() const { return VMOp_MarkActiveNMethods; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; + +// Deopt helper that can deoptimize frames in threads other than the +// current thread. Only used through Deoptimization::deoptimize_frame. +class VM_DeoptimizeFrame: public VM_Operation { + friend class Deoptimization; + + private: + JavaThread* _thread; + intptr_t* _id; + int _reason; + VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason); + + public: + VMOp_Type type() const { return VMOp_DeoptimizeFrame; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; + +#ifndef PRODUCT +class VM_DeoptimizeAll: public VM_Operation { + private: + Klass* _dependee; + public: + VM_DeoptimizeAll() {} + VMOp_Type type() const { return VMOp_DeoptimizeAll; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; + + +class VM_ZombieAll: public VM_Operation { + public: + VM_ZombieAll() {} + VMOp_Type type() const { return VMOp_ZombieAll; } + void doit(); + bool allow_nested_vm_operations() const { return true; } +}; +#endif // PRODUCT + +class VM_Verify: public VM_Operation { + public: + VMOp_Type type() const { return VMOp_Verify; } + void doit(); +}; + + +class VM_PrintThreads: public VM_Operation { + private: + outputStream* _out; + bool _print_concurrent_locks; + bool _print_extended_info; + public: + VM_PrintThreads() + : _out(tty), _print_concurrent_locks(PrintConcurrentLocks), _print_extended_info(false) + {} + VM_PrintThreads(outputStream* out, bool print_concurrent_locks, bool print_extended_info) + : _out(out), _print_concurrent_locks(print_concurrent_locks), _print_extended_info(print_extended_info) + {} + VMOp_Type type() const { + return VMOp_PrintThreads; + } + void doit(); + bool doit_prologue(); + void doit_epilogue(); +}; + +class VM_PrintJNI: public VM_Operation { + private: + outputStream* _out; + public: + VM_PrintJNI() { _out = tty; } + VM_PrintJNI(outputStream* out) { _out = out; } + VMOp_Type type() const { return VMOp_PrintJNI; } + void doit(); +}; + +class VM_PrintMetadata : public VM_Operation { + private: + outputStream* const _out; + const size_t _scale; + const int _flags; + + public: + VM_PrintMetadata(outputStream* out, size_t scale, int flags) + : _out(out), _scale(scale), _flags(flags) + {}; + + VMOp_Type type() const { return VMOp_PrintMetadata; } + void doit(); +}; + +class DeadlockCycle; +class VM_FindDeadlocks: public VM_Operation { + private: + bool _concurrent_locks; + DeadlockCycle* _deadlocks; + outputStream* _out; + ThreadsListSetter _setter; // Helper to set hazard ptr in the originating thread + // which protects the JavaThreads in _deadlocks. + + public: + VM_FindDeadlocks(bool concurrent_locks) : _concurrent_locks(concurrent_locks), _deadlocks(NULL), _out(NULL), _setter() {}; + VM_FindDeadlocks(outputStream* st) : _concurrent_locks(true), _deadlocks(NULL), _out(st) {}; + ~VM_FindDeadlocks(); + + DeadlockCycle* result() { return _deadlocks; }; + VMOp_Type type() const { return VMOp_FindDeadlocks; } + void doit(); +}; + +class ThreadDumpResult; +class ThreadSnapshot; +class ThreadConcurrentLocks; + +class VM_ThreadDump : public VM_Operation { + private: + ThreadDumpResult* _result; + int _num_threads; + GrowableArray<instanceHandle>* _threads; + int _max_depth; + bool _with_locked_monitors; + bool _with_locked_synchronizers; + + ThreadSnapshot* snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl); + + public: + VM_ThreadDump(ThreadDumpResult* result, + int max_depth, // -1 indicates entire stack + bool with_locked_monitors, + bool with_locked_synchronizers); + + VM_ThreadDump(ThreadDumpResult* result, + GrowableArray<instanceHandle>* threads, + int num_threads, // -1 indicates entire stack + int max_depth, + bool with_locked_monitors, + bool with_locked_synchronizers); + + VMOp_Type type() const { return VMOp_ThreadDump; } + void doit(); + bool doit_prologue(); + void doit_epilogue(); +}; + + +class VM_Exit: public VM_Operation { + private: + int _exit_code; + static volatile bool _vm_exited; + static Thread * volatile _shutdown_thread; + static void wait_if_vm_exited(); + public: + VM_Exit(int exit_code) { + _exit_code = exit_code; + } + static int wait_for_threads_in_native_to_block(); + static int set_vm_exited(); + static bool vm_exited() { return _vm_exited; } + static Thread * shutdown_thread() { return _shutdown_thread; } + static void block_if_vm_exited() { + if (_vm_exited) { + wait_if_vm_exited(); + } + } + VMOp_Type type() const { return VMOp_Exit; } + void doit(); +}; + +class VM_PrintCompileQueue: public VM_Operation { + private: + outputStream* _out; + + public: + VM_PrintCompileQueue(outputStream* st) : _out(st) {} + VMOp_Type type() const { return VMOp_PrintCompileQueue; } + Mode evaluation_mode() const { return _safepoint; } + void doit(); +}; + +#if INCLUDE_SERVICES +class VM_PrintClassHierarchy: public VM_Operation { + private: + outputStream* _out; + bool _print_interfaces; + bool _print_subclasses; + char* _classname; + + public: + VM_PrintClassHierarchy(outputStream* st, bool print_interfaces, bool print_subclasses, char* classname) : + _out(st), _print_interfaces(print_interfaces), _print_subclasses(print_subclasses), + _classname(classname) {} + VMOp_Type type() const { return VMOp_PrintClassHierarchy; } + void doit(); +}; +#endif // INCLUDE_SERVICES + +#endif // SHARE_VM_RUNTIME_VMOPERATIONS_HPP
--- a/src/hotspot/share/runtime/vmThread.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/vmThread.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -39,7 +39,7 @@ #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/runtimeService.hpp" #include "utilities/dtrace.hpp" #include "utilities/events.hpp"
--- a/src/hotspot/share/runtime/vmThread.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/runtime/vmThread.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -27,7 +27,7 @@ #include "runtime/perfData.hpp" #include "runtime/thread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" // // Prioritized queue of VM operations.
--- a/src/hotspot/share/runtime/vm_operations.cpp Thu Dec 06 15:44:13 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,508 +0,0 @@ -/* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/symbolTable.hpp" -#include "classfile/vmSymbols.hpp" -#include "code/codeCache.hpp" -#include "compiler/compileBroker.hpp" -#include "gc/shared/isGCActiveMark.hpp" -#include "logging/log.hpp" -#include "logging/logStream.hpp" -#include "memory/heapInspection.hpp" -#include "memory/resourceArea.hpp" -#include "oops/symbol.hpp" -#include "runtime/arguments.hpp" -#include "runtime/deoptimization.hpp" -#include "runtime/frame.inline.hpp" -#include "runtime/interfaceSupport.inline.hpp" -#include "runtime/sweeper.hpp" -#include "runtime/thread.inline.hpp" -#include "runtime/threadSMR.inline.hpp" -#include "runtime/vm_operations.hpp" -#include "services/threadService.hpp" - -#define VM_OP_NAME_INITIALIZE(name) #name, - -const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ - { VM_OPS_DO(VM_OP_NAME_INITIALIZE) }; - -void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) { - _calling_thread = thread; - assert(MinPriority <= priority && priority <= MaxPriority, "sanity check"); - _priority = priority; -} - - -void VM_Operation::evaluate() { - ResourceMark rm; - LogTarget(Debug, vmoperation) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("begin "); - print_on_error(&ls); - ls.cr(); - } - doit(); - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("end "); - print_on_error(&ls); - ls.cr(); - } -} - -const char* VM_Operation::mode_to_string(Mode mode) { - switch(mode) { - case _safepoint : return "safepoint"; - case _no_safepoint : return "no safepoint"; - case _concurrent : return "concurrent"; - case _async_safepoint: return "async safepoint"; - default : return "unknown"; - } -} -// Called by fatal error handler. -void VM_Operation::print_on_error(outputStream* st) const { - st->print("VM_Operation (" PTR_FORMAT "): ", p2i(this)); - st->print("%s", name()); - - const char* mode = mode_to_string(evaluation_mode()); - st->print(", mode: %s", mode); - - if (calling_thread()) { - st->print(", requested by thread " PTR_FORMAT, p2i(calling_thread())); - } -} - -void VM_ThreadStop::doit() { - assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); - ThreadsListHandle tlh; - JavaThread* target = java_lang_Thread::thread(target_thread()); - // Note that this now allows multiple ThreadDeath exceptions to be - // thrown at a thread. - if (target != NULL && (!EnableThreadSMRExtraValidityChecks || tlh.includes(target))) { - // The target thread has run and has not exited yet. - target->send_thread_stop(throwable()); - } -} - -void VM_ClearICs::doit() { - if (_preserve_static_stubs) { - CodeCache::cleanup_inline_caches(); - } else { - CodeCache::clear_inline_caches(); - } -} - -void VM_Deoptimize::doit() { - // We do not want any GCs to happen while we are in the middle of this VM operation - ResourceMark rm; - DeoptimizationMarker dm; - - // Deoptimize all activations depending on marked nmethods - Deoptimization::deoptimize_dependents(); - - // Make the dependent methods not entrant - CodeCache::make_marked_nmethods_not_entrant(); -} - -void VM_MarkActiveNMethods::doit() { - NMethodSweeper::mark_active_nmethods(); -} - -VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) { - _thread = thread; - _id = id; - _reason = reason; -} - - -void VM_DeoptimizeFrame::doit() { - assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::Reason_LIMIT, "invalid deopt reason"); - Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason); -} - - -#ifndef PRODUCT - -void VM_DeoptimizeAll::doit() { - DeoptimizationMarker dm; - JavaThreadIteratorWithHandle jtiwh; - // deoptimize all java threads in the system - if (DeoptimizeALot) { - for (; JavaThread *thread = jtiwh.next(); ) { - if (thread->has_last_Java_frame()) { - thread->deoptimize(); - } - } - } else if (DeoptimizeRandom) { - - // Deoptimize some selected threads and frames - int tnum = os::random() & 0x3; - int fnum = os::random() & 0x3; - int tcount = 0; - for (; JavaThread *thread = jtiwh.next(); ) { - if (thread->has_last_Java_frame()) { - if (tcount++ == tnum) { - tcount = 0; - int fcount = 0; - // Deoptimize some selected frames. - // Biased llocking wants a updated register map - for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) { - if (fst.current()->can_be_deoptimized()) { - if (fcount++ == fnum) { - fcount = 0; - Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); - } - } - } - } - } - } - } -} - - -void VM_ZombieAll::doit() { - JavaThread *thread = (JavaThread *)calling_thread(); - assert(thread->is_Java_thread(), "must be a Java thread"); - thread->make_zombies(); -} - -#endif // !PRODUCT - -void VM_Verify::doit() { - Universe::heap()->prepare_for_verify(); - Universe::verify(); -} - -bool VM_PrintThreads::doit_prologue() { - // Get Heap_lock if concurrent locks will be dumped - if (_print_concurrent_locks) { - Heap_lock->lock(); - } - return true; -} - -void VM_PrintThreads::doit() { - Threads::print_on(_out, true, false, _print_concurrent_locks, _print_extended_info); -} - -void VM_PrintThreads::doit_epilogue() { - if (_print_concurrent_locks) { - // Release Heap_lock - Heap_lock->unlock(); - } -} - -void VM_PrintJNI::doit() { - JNIHandles::print_on(_out); -} - -void VM_PrintMetadata::doit() { - MetaspaceUtils::print_report(_out, _scale, _flags); -} - -VM_FindDeadlocks::~VM_FindDeadlocks() { - if (_deadlocks != NULL) { - DeadlockCycle* cycle = _deadlocks; - while (cycle != NULL) { - DeadlockCycle* d = cycle; - cycle = cycle->next(); - delete d; - } - } -} - -void VM_FindDeadlocks::doit() { - // Update the hazard ptr in the originating thread to the current - // list of threads. This VM operation needs the current list of - // threads for proper deadlock detection and those are the - // JavaThreads we need to be protected when we return info to the - // originating thread. - _setter.set(); - - _deadlocks = ThreadService::find_deadlocks_at_safepoint(_setter.list(), _concurrent_locks); - if (_out != NULL) { - int num_deadlocks = 0; - for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) { - num_deadlocks++; - cycle->print_on_with(_setter.list(), _out); - } - - if (num_deadlocks == 1) { - _out->print_cr("\nFound 1 deadlock.\n"); - _out->flush(); - } else if (num_deadlocks > 1) { - _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks); - _out->flush(); - } - } -} - -VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, - int max_depth, - bool with_locked_monitors, - bool with_locked_synchronizers) { - _result = result; - _num_threads = 0; // 0 indicates all threads - _threads = NULL; - _result = result; - _max_depth = max_depth; - _with_locked_monitors = with_locked_monitors; - _with_locked_synchronizers = with_locked_synchronizers; -} - -VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, - GrowableArray<instanceHandle>* threads, - int num_threads, - int max_depth, - bool with_locked_monitors, - bool with_locked_synchronizers) { - _result = result; - _num_threads = num_threads; - _threads = threads; - _result = result; - _max_depth = max_depth; - _with_locked_monitors = with_locked_monitors; - _with_locked_synchronizers = with_locked_synchronizers; -} - -bool VM_ThreadDump::doit_prologue() { - if (_with_locked_synchronizers) { - // Acquire Heap_lock to dump concurrent locks - Heap_lock->lock(); - } - - return true; -} - -void VM_ThreadDump::doit_epilogue() { - if (_with_locked_synchronizers) { - // Release Heap_lock - Heap_lock->unlock(); - } -} - -void VM_ThreadDump::doit() { - ResourceMark rm; - - // Set the hazard ptr in the originating thread to protect the - // current list of threads. This VM operation needs the current list - // of threads for a proper dump and those are the JavaThreads we need - // to be protected when we return info to the originating thread. - _result->set_t_list(); - - ConcurrentLocksDump concurrent_locks(true); - if (_with_locked_synchronizers) { - concurrent_locks.dump_at_safepoint(); - } - - if (_num_threads == 0) { - // Snapshot all live threads - - for (uint i = 0; i < _result->t_list()->length(); i++) { - JavaThread* jt = _result->t_list()->thread_at(i); - if (jt->is_exiting() || - jt->is_hidden_from_external_view()) { - // skip terminating threads and hidden threads - continue; - } - ThreadConcurrentLocks* tcl = NULL; - if (_with_locked_synchronizers) { - tcl = concurrent_locks.thread_concurrent_locks(jt); - } - ThreadSnapshot* ts = snapshot_thread(jt, tcl); - _result->add_thread_snapshot(ts); - } - } else { - // Snapshot threads in the given _threads array - // A dummy snapshot is created if a thread doesn't exist - - for (int i = 0; i < _num_threads; i++) { - instanceHandle th = _threads->at(i); - if (th() == NULL) { - // skip if the thread doesn't exist - // Add a dummy snapshot - _result->add_thread_snapshot(new ThreadSnapshot()); - continue; - } - - // Dump thread stack only if the thread is alive and not exiting - // and not VM internal thread. - JavaThread* jt = java_lang_Thread::thread(th()); - if (jt != NULL && !_result->t_list()->includes(jt)) { - // _threads[i] doesn't refer to a valid JavaThread; this check - // is primarily for JVM_DumpThreads() which doesn't have a good - // way to validate the _threads array. - jt = NULL; - } - if (jt == NULL || /* thread not alive */ - jt->is_exiting() || - jt->is_hidden_from_external_view()) { - // add a NULL snapshot if skipped - _result->add_thread_snapshot(new ThreadSnapshot()); - continue; - } - ThreadConcurrentLocks* tcl = NULL; - if (_with_locked_synchronizers) { - tcl = concurrent_locks.thread_concurrent_locks(jt); - } - ThreadSnapshot* ts = snapshot_thread(jt, tcl); - _result->add_thread_snapshot(ts); - } - } -} - -ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { - ThreadSnapshot* snapshot = new ThreadSnapshot(_result->t_list(), java_thread); - snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); - snapshot->set_concurrent_locks(tcl); - return snapshot; -} - -volatile bool VM_Exit::_vm_exited = false; -Thread * volatile VM_Exit::_shutdown_thread = NULL; - -int VM_Exit::set_vm_exited() { - - Thread * thr_cur = Thread::current(); - - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); - - int num_active = 0; - - _shutdown_thread = thr_cur; - _vm_exited = true; // global flag - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { - if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { - ++num_active; - thr->set_terminated(JavaThread::_vm_exited); // per-thread flag - } - } - - return num_active; -} - -int VM_Exit::wait_for_threads_in_native_to_block() { - // VM exits at safepoint. This function must be called at the final safepoint - // to wait for threads in _thread_in_native state to be quiescent. - assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); - - Thread * thr_cur = Thread::current(); - Monitor timer(Mutex::leaf, "VM_Exit timer", true, - Monitor::_safepoint_check_never); - - // Compiler threads need longer wait because they can access VM data directly - // while in native. If they are active and some structures being used are - // deleted by the shutdown sequence, they will crash. On the other hand, user - // threads must go through native=>Java/VM transitions first to access VM - // data, and they will be stopped during state transition. In theory, we - // don't have to wait for user threads to be quiescent, but it's always - // better to terminate VM when current thread is the only active thread, so - // wait for user threads too. Numbers are in 10 milliseconds. - int max_wait_user_thread = 30; // at least 300 milliseconds - int max_wait_compiler_thread = 1000; // at least 10 seconds - - int max_wait = max_wait_compiler_thread; - - int attempts = 0; - JavaThreadIteratorWithHandle jtiwh; - while (true) { - int num_active = 0; - int num_active_compiler_thread = 0; - - jtiwh.rewind(); - for (; JavaThread *thr = jtiwh.next(); ) { - if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { - num_active++; - if (thr->is_Compiler_thread()) { - num_active_compiler_thread++; - } - } - } - - if (num_active == 0) { - return 0; - } else if (attempts > max_wait) { - return num_active; - } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { - return num_active; - } - - attempts++; - - MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); - timer.wait(Mutex::_no_safepoint_check_flag, 10); - } -} - -void VM_Exit::doit() { - CompileBroker::set_should_block(); - - // Wait for a short period for threads in native to block. Any thread - // still executing native code after the wait will be stopped at - // native==>Java/VM barriers. - // Among 16276 JCK tests, 94% of them come here without any threads still - // running in native; the other 6% are quiescent within 250ms (Ultra 80). - wait_for_threads_in_native_to_block(); - - set_vm_exited(); - - // cleanup globals resources before exiting. exit_globals() currently - // cleans up outputStream resources and PerfMemory resources. - exit_globals(); - - // Check for exit hook - exit_hook_t exit_hook = Arguments::exit_hook(); - if (exit_hook != NULL) { - // exit hook should exit. - exit_hook(_exit_code); - // ... but if it didn't, we must do it here - vm_direct_exit(_exit_code); - } else { - vm_direct_exit(_exit_code); - } -} - - -void VM_Exit::wait_if_vm_exited() { - if (_vm_exited && - Thread::current_or_null() != _shutdown_thread) { - // _vm_exited is set at safepoint, and the Threads_lock is never released - // we will block here until the process dies - Threads_lock->lock_without_safepoint_check(); - ShouldNotReachHere(); - } -} - -void VM_PrintCompileQueue::doit() { - CompileBroker::print_compile_queues(_out); -} - -#if INCLUDE_SERVICES -void VM_PrintClassHierarchy::doit() { - KlassHierarchy::print_class_hierarchy(_out, _print_interfaces, _print_subclasses, _classname); -} -#endif
--- a/src/hotspot/share/runtime/vm_operations.hpp Thu Dec 06 15:44:13 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,512 +0,0 @@ -/* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_RUNTIME_VM_OPERATIONS_HPP -#define SHARE_VM_RUNTIME_VM_OPERATIONS_HPP - -#include "classfile/javaClasses.hpp" -#include "memory/allocation.hpp" -#include "oops/oop.hpp" -#include "runtime/thread.hpp" -#include "runtime/threadSMR.hpp" -#include "code/codeCache.hpp" - -// The following classes are used for operations -// initiated by a Java thread but that must -// take place in the VMThread. - -#define VM_OP_ENUM(type) VMOp_##type, - -// Note: When new VM_XXX comes up, add 'XXX' to the template table. -#define VM_OPS_DO(template) \ - template(None) \ - template(ThreadStop) \ - template(ThreadDump) \ - template(PrintThreads) \ - template(FindDeadlocks) \ - template(ClearICs) \ - template(ForceSafepoint) \ - template(ForceAsyncSafepoint) \ - template(Deoptimize) \ - template(DeoptimizeFrame) \ - template(DeoptimizeAll) \ - template(ZombieAll) \ - template(Verify) \ - template(PrintJNI) \ - template(HeapDumper) \ - template(DeoptimizeTheWorld) \ - template(CollectForMetadataAllocation) \ - template(GC_HeapInspection) \ - template(GenCollectFull) \ - template(GenCollectFullConcurrent) \ - template(GenCollectForAllocation) \ - template(ParallelGCFailedAllocation) \ - template(ParallelGCSystemGC) \ - template(CMS_Initial_Mark) \ - template(CMS_Final_Remark) \ - template(G1CollectForAllocation) \ - template(G1CollectFull) \ - template(G1Concurrent) \ - template(ZOperation) \ - template(HandshakeOneThread) \ - template(HandshakeAllThreads) \ - template(HandshakeFallback) \ - template(EnableBiasedLocking) \ - template(RevokeBias) \ - template(BulkRevokeBias) \ - template(PopulateDumpSharedSpace) \ - template(JNIFunctionTableCopier) \ - template(RedefineClasses) \ - template(UpdateForPopTopFrame) \ - template(SetFramePop) \ - template(GetOwnedMonitorInfo) \ - template(GetObjectMonitorUsage) \ - template(GetCurrentContendedMonitor) \ - template(GetStackTrace) \ - template(GetMultipleStackTraces) \ - template(GetAllStackTraces) \ - template(GetThreadListStackTraces) \ - template(GetFrameCount) \ - template(GetFrameLocation) \ - template(ChangeBreakpoints) \ - template(GetOrSetLocal) \ - template(GetCurrentLocation) \ - template(EnterInterpOnlyMode) \ - template(ChangeSingleStep) \ - template(HeapWalkOperation) \ - template(HeapIterateOperation) \ - template(ReportJavaOutOfMemory) \ - template(JFRCheckpoint) \ - template(Exit) \ - template(LinuxDllLoad) \ - template(RotateGCLog) \ - template(WhiteBoxOperation) \ - template(ClassLoaderStatsOperation) \ - template(ClassLoaderHierarchyOperation) \ - template(DumpHashtable) \ - template(DumpTouchedMethods) \ - template(MarkActiveNMethods) \ - template(PrintCompileQueue) \ - template(PrintClassHierarchy) \ - template(ThreadSuspend) \ - template(CTWThreshold) \ - template(ThreadsSuspendJVMTI) \ - template(ICBufferFull) \ - template(ScavengeMonitors) \ - template(PrintMetadata) \ - template(GTestExecuteAtSafepoint) \ - -class VM_Operation: public CHeapObj<mtInternal> { - public: - enum Mode { - _safepoint, // blocking, safepoint, vm_op C-heap allocated - _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated - _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated - _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated - }; - - enum VMOp_Type { - VM_OPS_DO(VM_OP_ENUM) - VMOp_Terminating - }; - - private: - Thread* _calling_thread; - ThreadPriority _priority; - long _timestamp; - VM_Operation* _next; - VM_Operation* _prev; - - // The VM operation name array - static const char* _names[]; - - public: - VM_Operation() { _calling_thread = NULL; _next = NULL; _prev = NULL; } - virtual ~VM_Operation() {} - - // VM operation support (used by VM thread) - Thread* calling_thread() const { return _calling_thread; } - ThreadPriority priority() { return _priority; } - void set_calling_thread(Thread* thread, ThreadPriority priority); - - long timestamp() const { return _timestamp; } - void set_timestamp(long timestamp) { _timestamp = timestamp; } - - // Called by VM thread - does in turn invoke doit(). Do not override this - void evaluate(); - - // evaluate() is called by the VMThread and in turn calls doit(). - // If the thread invoking VMThread::execute((VM_Operation*) is a JavaThread, - // doit_prologue() is called in that thread before transferring control to - // the VMThread. - // If doit_prologue() returns true the VM operation will proceed, and - // doit_epilogue() will be called by the JavaThread once the VM operation - // completes. If doit_prologue() returns false the VM operation is cancelled. - virtual void doit() = 0; - virtual bool doit_prologue() { return true; }; - virtual void doit_epilogue() {}; // Note: Not called if mode is: _concurrent - - // Type test - virtual bool is_methodCompiler() const { return false; } - - // Linking - VM_Operation *next() const { return _next; } - VM_Operation *prev() const { return _prev; } - void set_next(VM_Operation *next) { _next = next; } - void set_prev(VM_Operation *prev) { _prev = prev; } - - // Configuration. Override these appropriately in subclasses. - virtual VMOp_Type type() const = 0; - virtual Mode evaluation_mode() const { return _safepoint; } - virtual bool allow_nested_vm_operations() const { return false; } - virtual bool is_cheap_allocated() const { return false; } - virtual void oops_do(OopClosure* f) { /* do nothing */ }; - - // CAUTION: <don't hang yourself with following rope> - // If you override these methods, make sure that the evaluation - // of these methods is race-free and non-blocking, since these - // methods may be evaluated either by the mutators or by the - // vm thread, either concurrently with mutators or with the mutators - // stopped. In other words, taking locks is verboten, and if there - // are any races in evaluating the conditions, they'd better be benign. - virtual bool evaluate_at_safepoint() const { - return evaluation_mode() == _safepoint || - evaluation_mode() == _async_safepoint; - } - virtual bool evaluate_concurrently() const { - return evaluation_mode() == _concurrent || - evaluation_mode() == _async_safepoint; - } - - static const char* mode_to_string(Mode mode); - - // Debugging - virtual void print_on_error(outputStream* st) const; - const char* name() const { return _names[type()]; } - static const char* name(int type) { - assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type"); - return _names[type]; - } -#ifndef PRODUCT - void print_on(outputStream* st) const { print_on_error(st); } -#endif -}; - -class VM_ThreadStop: public VM_Operation { - private: - oop _thread; // The Thread that the Throwable is thrown against - oop _throwable; // The Throwable thrown at the target Thread - public: - // All oops are passed as JNI handles, since there is no guarantee that a GC might happen before the - // VM operation is executed. - VM_ThreadStop(oop thread, oop throwable) { - _thread = thread; - _throwable = throwable; - } - VMOp_Type type() const { return VMOp_ThreadStop; } - oop target_thread() const { return _thread; } - oop throwable() const { return _throwable;} - void doit(); - // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated - bool allow_nested_vm_operations() const { return true; } - Mode evaluation_mode() const { return _async_safepoint; } - bool is_cheap_allocated() const { return true; } - - // GC support - void oops_do(OopClosure* f) { - f->do_oop(&_thread); f->do_oop(&_throwable); - } -}; - -class VM_ClearICs: public VM_Operation { - private: - bool _preserve_static_stubs; - public: - VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } - void doit(); - VMOp_Type type() const { return VMOp_ClearICs; } -}; - -// empty vm op, evaluated just to force a safepoint -class VM_ForceSafepoint: public VM_Operation { - public: - void doit() {} - VMOp_Type type() const { return VMOp_ForceSafepoint; } -}; - -// empty vm op, when forcing a safepoint to suspend a thread -class VM_ThreadSuspend: public VM_ForceSafepoint { - public: - VMOp_Type type() const { return VMOp_ThreadSuspend; } -}; - -// empty vm op, when forcing a safepoint due to ctw threshold is reached for the sweeper -class VM_CTWThreshold: public VM_ForceSafepoint { - public: - VMOp_Type type() const { return VMOp_CTWThreshold; } -}; - -// empty vm op, when forcing a safepoint to suspend threads from jvmti -class VM_ThreadsSuspendJVMTI: public VM_ForceSafepoint { - public: - VMOp_Type type() const { return VMOp_ThreadsSuspendJVMTI; } -}; - -// empty vm op, when forcing a safepoint due to inline cache buffers being full -class VM_ICBufferFull: public VM_ForceSafepoint { - public: - VMOp_Type type() const { return VMOp_ICBufferFull; } -}; - -// empty asynchronous vm op, when forcing a safepoint to scavenge monitors -class VM_ScavengeMonitors: public VM_ForceSafepoint { - public: - VMOp_Type type() const { return VMOp_ScavengeMonitors; } - Mode evaluation_mode() const { return _async_safepoint; } - bool is_cheap_allocated() const { return true; } -}; - -// Base class for invoking parts of a gtest in a safepoint. -// Derived classes provide the doit method. -// Typically also need to transition the gtest thread from native to VM. -class VM_GTestExecuteAtSafepoint: public VM_Operation { - public: - VMOp_Type type() const { return VMOp_GTestExecuteAtSafepoint; } - - protected: - VM_GTestExecuteAtSafepoint() {} -}; - -class VM_Deoptimize: public VM_Operation { - public: - VM_Deoptimize() {} - VMOp_Type type() const { return VMOp_Deoptimize; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; - -class VM_MarkActiveNMethods: public VM_Operation { - public: - VM_MarkActiveNMethods() {} - VMOp_Type type() const { return VMOp_MarkActiveNMethods; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; - -// Deopt helper that can deoptimize frames in threads other than the -// current thread. Only used through Deoptimization::deoptimize_frame. -class VM_DeoptimizeFrame: public VM_Operation { - friend class Deoptimization; - - private: - JavaThread* _thread; - intptr_t* _id; - int _reason; - VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason); - - public: - VMOp_Type type() const { return VMOp_DeoptimizeFrame; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; - -#ifndef PRODUCT -class VM_DeoptimizeAll: public VM_Operation { - private: - Klass* _dependee; - public: - VM_DeoptimizeAll() {} - VMOp_Type type() const { return VMOp_DeoptimizeAll; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; - - -class VM_ZombieAll: public VM_Operation { - public: - VM_ZombieAll() {} - VMOp_Type type() const { return VMOp_ZombieAll; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; -#endif // PRODUCT - -class VM_Verify: public VM_Operation { - public: - VMOp_Type type() const { return VMOp_Verify; } - void doit(); -}; - - -class VM_PrintThreads: public VM_Operation { - private: - outputStream* _out; - bool _print_concurrent_locks; - bool _print_extended_info; - public: - VM_PrintThreads() - : _out(tty), _print_concurrent_locks(PrintConcurrentLocks), _print_extended_info(false) - {} - VM_PrintThreads(outputStream* out, bool print_concurrent_locks, bool print_extended_info) - : _out(out), _print_concurrent_locks(print_concurrent_locks), _print_extended_info(print_extended_info) - {} - VMOp_Type type() const { - return VMOp_PrintThreads; - } - void doit(); - bool doit_prologue(); - void doit_epilogue(); -}; - -class VM_PrintJNI: public VM_Operation { - private: - outputStream* _out; - public: - VM_PrintJNI() { _out = tty; } - VM_PrintJNI(outputStream* out) { _out = out; } - VMOp_Type type() const { return VMOp_PrintJNI; } - void doit(); -}; - -class VM_PrintMetadata : public VM_Operation { - private: - outputStream* const _out; - const size_t _scale; - const int _flags; - - public: - VM_PrintMetadata(outputStream* out, size_t scale, int flags) - : _out(out), _scale(scale), _flags(flags) - {}; - - VMOp_Type type() const { return VMOp_PrintMetadata; } - void doit(); -}; - -class DeadlockCycle; -class VM_FindDeadlocks: public VM_Operation { - private: - bool _concurrent_locks; - DeadlockCycle* _deadlocks; - outputStream* _out; - ThreadsListSetter _setter; // Helper to set hazard ptr in the originating thread - // which protects the JavaThreads in _deadlocks. - - public: - VM_FindDeadlocks(bool concurrent_locks) : _concurrent_locks(concurrent_locks), _deadlocks(NULL), _out(NULL), _setter() {}; - VM_FindDeadlocks(outputStream* st) : _concurrent_locks(true), _deadlocks(NULL), _out(st) {}; - ~VM_FindDeadlocks(); - - DeadlockCycle* result() { return _deadlocks; }; - VMOp_Type type() const { return VMOp_FindDeadlocks; } - void doit(); -}; - -class ThreadDumpResult; -class ThreadSnapshot; -class ThreadConcurrentLocks; - -class VM_ThreadDump : public VM_Operation { - private: - ThreadDumpResult* _result; - int _num_threads; - GrowableArray<instanceHandle>* _threads; - int _max_depth; - bool _with_locked_monitors; - bool _with_locked_synchronizers; - - ThreadSnapshot* snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl); - - public: - VM_ThreadDump(ThreadDumpResult* result, - int max_depth, // -1 indicates entire stack - bool with_locked_monitors, - bool with_locked_synchronizers); - - VM_ThreadDump(ThreadDumpResult* result, - GrowableArray<instanceHandle>* threads, - int num_threads, // -1 indicates entire stack - int max_depth, - bool with_locked_monitors, - bool with_locked_synchronizers); - - VMOp_Type type() const { return VMOp_ThreadDump; } - void doit(); - bool doit_prologue(); - void doit_epilogue(); -}; - - -class VM_Exit: public VM_Operation { - private: - int _exit_code; - static volatile bool _vm_exited; - static Thread * volatile _shutdown_thread; - static void wait_if_vm_exited(); - public: - VM_Exit(int exit_code) { - _exit_code = exit_code; - } - static int wait_for_threads_in_native_to_block(); - static int set_vm_exited(); - static bool vm_exited() { return _vm_exited; } - static Thread * shutdown_thread() { return _shutdown_thread; } - static void block_if_vm_exited() { - if (_vm_exited) { - wait_if_vm_exited(); - } - } - VMOp_Type type() const { return VMOp_Exit; } - void doit(); -}; - -class VM_PrintCompileQueue: public VM_Operation { - private: - outputStream* _out; - - public: - VM_PrintCompileQueue(outputStream* st) : _out(st) {} - VMOp_Type type() const { return VMOp_PrintCompileQueue; } - Mode evaluation_mode() const { return _safepoint; } - void doit(); -}; - -#if INCLUDE_SERVICES -class VM_PrintClassHierarchy: public VM_Operation { - private: - outputStream* _out; - bool _print_interfaces; - bool _print_subclasses; - char* _classname; - - public: - VM_PrintClassHierarchy(outputStream* st, bool print_interfaces, bool print_subclasses, char* classname) : - _out(st), _print_interfaces(print_interfaces), _print_subclasses(print_subclasses), - _classname(classname) {} - VMOp_Type type() const { return VMOp_PrintClassHierarchy; } - void doit(); -}; -#endif // INCLUDE_SERVICES - -#endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
--- a/src/hotspot/share/services/dtraceAttacher.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/services/dtraceAttacher.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -28,7 +28,7 @@ #include "runtime/deoptimization.hpp" #include "runtime/flags/jvmFlag.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/dtraceAttacher.hpp" #ifdef SOLARIS
--- a/src/hotspot/share/services/heapDumper.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/services/heapDumper.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -48,7 +48,7 @@ #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/heapDumper.hpp" #include "services/threadService.hpp" #include "utilities/macros.hpp"
--- a/src/hotspot/share/services/memTracker.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/services/memTracker.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -26,7 +26,7 @@ #include "runtime/orderAccess.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/memBaseline.hpp" #include "services/memReporter.hpp" #include "services/mallocTracker.inline.hpp"
--- a/src/hotspot/share/services/nmtDCmd.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/services/nmtDCmd.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -25,7 +25,7 @@ #include "memory/resourceArea.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/nmtDCmd.hpp" #include "services/memReporter.hpp" #include "services/memTracker.hpp"
--- a/src/hotspot/share/services/threadService.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/services/threadService.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -39,7 +39,7 @@ #include "runtime/threadSMR.inline.hpp" #include "runtime/vframe.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "services/threadService.hpp" // TODO: we need to define a naming convention for perf counters
--- a/src/hotspot/share/utilities/vmError.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/src/hotspot/share/utilities/vmError.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -40,7 +40,7 @@ #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vm_version.hpp" #include "runtime/flags/jvmFlag.hpp" #include "services/memTracker.hpp"
--- a/test/hotspot/gtest/gc/g1/test_heapRegion.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/test/hotspot/gtest/gc/g1/test_heapRegion.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -28,7 +28,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/shared/referenceProcessor.hpp" #include "runtime/interfaceSupport.inline.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" #include "unittest.hpp"
--- a/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/test/hotspot/gtest/gc/shared/test_oopStorage.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -34,7 +34,7 @@ #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/thread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" #include "utilities/align.hpp" #include "utilities/ostream.hpp"
--- a/test/hotspot/gtest/gc/shared/test_oopStorage_parperf.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/test/hotspot/gtest/gc/shared/test_oopStorage_parperf.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -32,7 +32,7 @@ #include "runtime/interfaceSupport.inline.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "runtime/vmThread.hpp" #include "utilities/debug.hpp" #include "utilities/ostream.hpp"
--- a/test/hotspot/gtest/threadHelper.inline.hpp Thu Dec 06 15:44:13 2018 +0100 +++ b/test/hotspot/gtest/threadHelper.inline.hpp Thu Dec 06 15:44:40 2018 +0100 @@ -28,7 +28,7 @@ #include "runtime/semaphore.hpp" #include "runtime/thread.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "unittest.hpp" class VM_StopSafepoint : public VM_Operation {
--- a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp Thu Dec 06 15:44:13 2018 +0100 +++ b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp Thu Dec 06 15:44:40 2018 +0100 @@ -26,7 +26,7 @@ #include "runtime/semaphore.hpp" #include "runtime/thread.hpp" #include "runtime/vmThread.hpp" -#include "runtime/vm_operations.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/concurrentHashTable.inline.hpp" #include "utilities/concurrentHashTableTasks.inline.hpp" #include "threadHelper.inline.hpp"