126 template(ScavengeMonitors) \ |
126 template(ScavengeMonitors) \ |
127 template(PrintMetadata) \ |
127 template(PrintMetadata) \ |
128 template(GTestExecuteAtSafepoint) \ |
128 template(GTestExecuteAtSafepoint) \ |
129 template(JFROldObject) \ |
129 template(JFROldObject) \ |
130 |
130 |
131 class VM_Operation: public CHeapObj<mtInternal> { |
131 class VM_Operation : public StackObj { |
132 public: |
132 public: |
133 enum Mode { |
|
134 _safepoint, // blocking, safepoint, vm_op C-heap allocated |
|
135 _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated |
|
136 _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated |
|
137 _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated |
|
138 }; |
|
139 |
|
140 enum VMOp_Type { |
133 enum VMOp_Type { |
141 VM_OPS_DO(VM_OP_ENUM) |
134 VM_OPS_DO(VM_OP_ENUM) |
142 VMOp_Terminating |
135 VMOp_Terminating |
143 }; |
136 }; |
144 |
137 |
150 |
143 |
151 // The VM operation name array |
144 // The VM operation name array |
152 static const char* _names[]; |
145 static const char* _names[]; |
153 |
146 |
154 public: |
147 public: |
155 VM_Operation() { _calling_thread = NULL; _next = NULL; _prev = NULL; } |
148 VM_Operation() : _calling_thread(NULL), _timestamp(0), _next(NULL), _prev(NULL) {} |
156 virtual ~VM_Operation() {} |
|
157 |
149 |
158 // VM operation support (used by VM thread) |
150 // VM operation support (used by VM thread) |
159 Thread* calling_thread() const { return _calling_thread; } |
151 Thread* calling_thread() const { return _calling_thread; } |
160 void set_calling_thread(Thread* thread); |
152 void set_calling_thread(Thread* thread); |
161 |
153 |
172 // If doit_prologue() returns true the VM operation will proceed, and |
164 // If doit_prologue() returns true the VM operation will proceed, and |
173 // doit_epilogue() will be called by the JavaThread once the VM operation |
165 // doit_epilogue() will be called by the JavaThread once the VM operation |
174 // completes. If doit_prologue() returns false the VM operation is cancelled. |
166 // completes. If doit_prologue() returns false the VM operation is cancelled. |
175 virtual void doit() = 0; |
167 virtual void doit() = 0; |
176 virtual bool doit_prologue() { return true; }; |
168 virtual bool doit_prologue() { return true; }; |
177 virtual void doit_epilogue() {}; // Note: Not called if mode is: _concurrent |
169 virtual void doit_epilogue() {}; |
178 |
|
179 // Type test |
|
180 virtual bool is_methodCompiler() const { return false; } |
|
181 |
170 |
182 // Linking |
171 // Linking |
183 VM_Operation *next() const { return _next; } |
172 VM_Operation *next() const { return _next; } |
184 VM_Operation *prev() const { return _prev; } |
173 VM_Operation *prev() const { return _prev; } |
185 void set_next(VM_Operation *next) { _next = next; } |
174 void set_next(VM_Operation *next) { _next = next; } |
186 void set_prev(VM_Operation *prev) { _prev = prev; } |
175 void set_prev(VM_Operation *prev) { _prev = prev; } |
187 |
176 |
188 // Configuration. Override these appropriately in subclasses. |
177 // Configuration. Override these appropriately in subclasses. |
189 virtual VMOp_Type type() const = 0; |
178 virtual VMOp_Type type() const = 0; |
190 virtual Mode evaluation_mode() const { return _safepoint; } |
|
191 virtual bool allow_nested_vm_operations() const { return false; } |
179 virtual bool allow_nested_vm_operations() const { return false; } |
192 virtual bool is_cheap_allocated() const { return false; } |
|
193 virtual void oops_do(OopClosure* f) { /* do nothing */ }; |
180 virtual void oops_do(OopClosure* f) { /* do nothing */ }; |
194 |
181 |
195 // CAUTION: <don't hang yourself with following rope> |
182 // An operation can either be done inside a safepoint |
196 // If you override these methods, make sure that the evaluation |
183 // or concurrently with Java threads running. |
197 // of these methods is race-free and non-blocking, since these |
184 virtual bool evaluate_at_safepoint() const { return true; } |
198 // methods may be evaluated either by the mutators or by the |
|
199 // vm thread, either concurrently with mutators or with the mutators |
|
200 // stopped. In other words, taking locks is verboten, and if there |
|
201 // are any races in evaluating the conditions, they'd better be benign. |
|
202 virtual bool evaluate_at_safepoint() const { |
|
203 return evaluation_mode() == _safepoint || |
|
204 evaluation_mode() == _async_safepoint; |
|
205 } |
|
206 virtual bool evaluate_concurrently() const { |
|
207 return evaluation_mode() == _concurrent || |
|
208 evaluation_mode() == _async_safepoint; |
|
209 } |
|
210 |
|
211 static const char* mode_to_string(Mode mode); |
|
212 |
185 |
213 // Debugging |
186 // Debugging |
214 virtual void print_on_error(outputStream* st) const; |
187 virtual void print_on_error(outputStream* st) const; |
215 virtual const char* name() const { return _names[type()]; } |
188 virtual const char* name() const { return _names[type()]; } |
216 static const char* name(int type) { |
189 static const char* name(int type) { |
252 oop target_thread() const { return _thread; } |
225 oop target_thread() const { return _thread; } |
253 oop throwable() const { return _throwable;} |
226 oop throwable() const { return _throwable;} |
254 void doit(); |
227 void doit(); |
255 // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated |
228 // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated |
256 bool allow_nested_vm_operations() const { return true; } |
229 bool allow_nested_vm_operations() const { return true; } |
257 Mode evaluation_mode() const { return _async_safepoint; } |
|
258 bool is_cheap_allocated() const { return true; } |
|
259 |
230 |
260 // GC support |
231 // GC support |
261 void oops_do(OopClosure* f) { |
232 void oops_do(OopClosure* f) { |
262 f->do_oop(&_thread); f->do_oop(&_throwable); |
233 f->do_oop(&_thread); f->do_oop(&_throwable); |
263 } |
234 } |
293 |
264 |
294 // empty vm op, when forcing a safepoint due to inline cache buffers being full |
265 // empty vm op, when forcing a safepoint due to inline cache buffers being full |
295 class VM_ICBufferFull: public VM_ForceSafepoint { |
266 class VM_ICBufferFull: public VM_ForceSafepoint { |
296 public: |
267 public: |
297 VMOp_Type type() const { return VMOp_ICBufferFull; } |
268 VMOp_Type type() const { return VMOp_ICBufferFull; } |
298 }; |
|
299 |
|
300 // empty asynchronous vm op, when forcing a safepoint to scavenge monitors |
|
301 class VM_ScavengeMonitors: public VM_ForceSafepoint { |
|
302 public: |
|
303 VMOp_Type type() const { return VMOp_ScavengeMonitors; } |
|
304 Mode evaluation_mode() const { return _async_safepoint; } |
|
305 bool is_cheap_allocated() const { return true; } |
|
306 }; |
269 }; |
307 |
270 |
308 // Base class for invoking parts of a gtest in a safepoint. |
271 // Base class for invoking parts of a gtest in a safepoint. |
309 // Derived classes provide the doit method. |
272 // Derived classes provide the doit method. |
310 // Typically also need to transition the gtest thread from native to VM. |
273 // Typically also need to transition the gtest thread from native to VM. |