1 /*
2 * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_RUNTIME_VMOPERATION_HPP
26 #define SHARE_RUNTIME_VMOPERATION_HPP
27
28 #include "memory/allocation.hpp"
29
30 // The following classes are used for operations
31 // initiated by a Java thread but that must
32 // take place in the VMThread.
33
34 #define VM_OP_ENUM(type) VMOp_##type,
35
36 // Note: When new VM_XXX comes up, add 'XXX' to the template table.
37 #define VM_OPS_DO(template) \
38 template(Halt) \
39 template(SafepointALot) \
40 template(ThreadDump) \
41 template(PrintThreads) \
42 template(FindDeadlocks) \
43 template(ClearICs) \
44 template(ForceSafepoint) \
45 template(DeoptimizeFrame) \
46 template(DeoptimizeAll) \
47 template(ZombieAll) \
48 template(Verify) \
49 template(HeapDumper) \
50 template(CollectForMetadataAllocation) \
51 template(GC_HeapInspection) \
52 template(SerialCollectForAllocation) \
53 template(SerialGCCollect) \
54 template(ParallelCollectForAllocation) \
55 template(ParallelGCCollect) \
56 template(G1CollectForAllocation) \
57 template(G1CollectFull) \
58 template(G1PauseRemark) \
59 template(G1PauseCleanup) \
60 template(G1TryInitiateConcMark) \
61 template(G1RendezvousGCThreads) \
62 template(G1StopMarking) \
63 template(ZMarkEndOld) \
64 template(ZMarkEndYoung) \
65 template(ZMarkFlushOperation) \
66 template(ZMarkStartYoung) \
67 template(ZMarkStartYoungAndOld) \
68 template(ZRelocateStartOld) \
69 template(ZRelocateStartYoung) \
70 template(ZRendezvousGCThreads) \
71 template(ZVerifyOld) \
72 template(HandshakeAllThreads) \
73 template(PopulateDumpSharedSpace) \
74 template(JNIFunctionTableCopier) \
75 template(RedefineClasses) \
76 template(GetObjectMonitorUsage) \
77 template(GetAllStackTraces) \
78 template(GetThreadListStackTraces) \
79 template(ChangeBreakpoints) \
80 template(GetOrSetLocal) \
81 template(VirtualThreadGetOrSetLocal) \
82 template(ChangeSingleStep) \
83 template(SetNotifyJvmtiEventsMode) \
84 template(HeapWalkOperation) \
85 template(HeapIterateOperation) \
86 template(ReportJavaOutOfMemory) \
87 template(JFRSafepointClear) \
88 template(JFRSafepointWrite) \
89 template(ShenandoahFullGC) \
90 template(ShenandoahInitMark) \
91 template(ShenandoahFinalMarkStartEvac) \
92 template(ShenandoahInitUpdateRefs) \
93 template(ShenandoahFinalUpdateRefs) \
94 template(ShenandoahFinalVerify) \
95 template(ShenandoahDegeneratedGC) \
96 template(Exit) \
97 template(LinuxDllLoad) \
98 template(WhiteBoxOperation) \
99 template(ClassLoaderStatsOperation) \
100 template(ClassLoaderHierarchyOperation) \
101 template(DumpHashtable) \
102 template(CleanClassLoaderDataMetaspaces) \
103 template(RehashStringTable) \
104 template(RehashSymbolTable) \
105 template(PrintCompileQueue) \
106 template(PrintClassHierarchy) \
107 template(PrintClasses) \
108 template(PrintMetadata) \
109 template(GTestExecuteAtSafepoint) \
110 template(GTestStopSafepoint) \
111 template(JFROldObject) \
112 template(RendezvousGCThreads) \
113 template(JFRInitializeCPUTimeSampler) \
114 template(JFRTerminateCPUTimeSampler) \
115
116 class Thread;
117 class outputStream;
118
119 class VM_Operation : public StackObj {
120 public:
121 enum VMOp_Type {
122 VM_OPS_DO(VM_OP_ENUM)
123 VMOp_Terminating
124 };
125
126 private:
127 Thread* _calling_thread;
128
129 // The VM operation name array
130 static const char* _names[];
131
132 public:
133 VM_Operation() : _calling_thread(nullptr) {}
134
135 // VM operation support (used by VM thread)
136 Thread* calling_thread() const { return _calling_thread; }
137 void set_calling_thread(Thread* thread);
138
139 // Called by VM thread - does in turn invoke doit(). Do not override this
140 void evaluate();
141
142 // evaluate() is called by the VMThread and in turn calls doit().
143 // If the thread invoking VMThread::execute((VM_Operation*) is a JavaThread,
144 // doit_prologue() is called in that thread before transferring control to
145 // the VMThread.
146 // If doit_prologue() returns true the VM operation will proceed, and
147 // doit_epilogue() will be called by the JavaThread once the VM operation
148 // completes. If doit_prologue() returns false the VM operation is cancelled.
149 virtual void doit() = 0;
150 virtual bool doit_prologue() { return true; };
151 virtual void doit_epilogue() {};
152
153 // Configuration. Override these appropriately in subclasses.
154 virtual VMOp_Type type() const = 0;
155 virtual bool allow_nested_vm_operations() const { return false; }
156
157 // VMOp_Type may belong to a category of the operation.
158 // Override is_XX_operation() appropriately in subclasses.
159 virtual bool is_gc_operation() const { return false; }
160
161 // You may override skip_thread_oop_barriers to return true if the operation
162 // does not access thread-private oops (including frames).
163 virtual bool skip_thread_oop_barriers() const { return false; }
164
165 // An operation can either be done inside a safepoint
166 // or concurrently with Java threads running.
167 virtual bool evaluate_at_safepoint() const { return true; }
168
169 // Debugging
170 virtual void print_on_error(outputStream* st) const;
171 virtual const char* name() const { return _names[type()]; }
172 static const char* name(int type) {
173 assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type");
174 return _names[type];
175 }
176 // Extra information about what triggered this operation.
177 virtual const char* cause() const { return nullptr; }
178 #ifndef PRODUCT
179 void print_on(outputStream* st) const { print_on_error(st); }
180 #endif
181 };
182
183 #endif // SHARE_RUNTIME_VMOPERATION_HPP