Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/vm_operations.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | bd02caa94611 |
children | 5f24d0319e54 |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. |
0 | 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // The following classes are used for operations | |
26 // initiated by a Java thread but that must | |
27 // take place in the VMThread. | |
28 | |
29 #define VM_OP_ENUM(type) VMOp_##type, | |
30 | |
31 // Note: When new VM_XXX comes up, add 'XXX' to the template table. | |
32 #define VM_OPS_DO(template) \ | |
33 template(Dummy) \ | |
34 template(ThreadStop) \ | |
35 template(ThreadDump) \ | |
36 template(PrintThreads) \ | |
37 template(FindDeadlocks) \ | |
38 template(ForceSafepoint) \ | |
39 template(ForceAsyncSafepoint) \ | |
40 template(Deoptimize) \ | |
41 template(DeoptimizeFrame) \ | |
42 template(DeoptimizeAll) \ | |
43 template(ZombieAll) \ | |
44 template(Verify) \ | |
45 template(PrintJNI) \ | |
46 template(HeapDumper) \ | |
47 template(DeoptimizeTheWorld) \ | |
48 template(GC_HeapInspection) \ | |
49 template(GenCollectFull) \ | |
50 template(GenCollectFullConcurrent) \ | |
51 template(GenCollectForAllocation) \ | |
139
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
0
diff
changeset
|
52 template(GenCollectForPermanentAllocation) \ |
0 | 53 template(ParallelGCFailedAllocation) \ |
54 template(ParallelGCFailedPermanentAllocation) \ | |
55 template(ParallelGCSystemGC) \ | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
139
diff
changeset
|
56 template(CGC_Operation) \ |
0 | 57 template(CMS_Initial_Mark) \ |
58 template(CMS_Final_Remark) \ | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
139
diff
changeset
|
59 template(G1CollectFull) \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
139
diff
changeset
|
60 template(G1CollectForAllocation) \ |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
139
diff
changeset
|
61 template(G1IncCollectionPause) \ |
0 | 62 template(EnableBiasedLocking) \ |
63 template(RevokeBias) \ | |
64 template(BulkRevokeBias) \ | |
65 template(PopulateDumpSharedSpace) \ | |
66 template(JNIFunctionTableCopier) \ | |
67 template(RedefineClasses) \ | |
68 template(GetOwnedMonitorInfo) \ | |
69 template(GetObjectMonitorUsage) \ | |
70 template(GetCurrentContendedMonitor) \ | |
71 template(GetStackTrace) \ | |
72 template(GetMultipleStackTraces) \ | |
73 template(GetAllStackTraces) \ | |
74 template(GetThreadListStackTraces) \ | |
75 template(GetFrameCount) \ | |
76 template(GetFrameLocation) \ | |
77 template(ChangeBreakpoints) \ | |
78 template(GetOrSetLocal) \ | |
79 template(GetCurrentLocation) \ | |
80 template(EnterInterpOnlyMode) \ | |
81 template(ChangeSingleStep) \ | |
82 template(HeapWalkOperation) \ | |
83 template(HeapIterateOperation) \ | |
84 template(ReportJavaOutOfMemory) \ | |
85 template(Exit) \ | |
86 | |
87 class VM_Operation: public CHeapObj { | |
88 public: | |
89 enum Mode { | |
90 _safepoint, // blocking, safepoint, vm_op C-heap allocated | |
91 _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated | |
92 _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated | |
93 _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated | |
94 }; | |
95 | |
96 enum VMOp_Type { | |
97 VM_OPS_DO(VM_OP_ENUM) | |
98 VMOp_Terminating | |
99 }; | |
100 | |
101 private: | |
102 Thread* _calling_thread; | |
103 ThreadPriority _priority; | |
104 long _timestamp; | |
105 VM_Operation* _next; | |
106 VM_Operation* _prev; | |
107 | |
108 // The VM operation name array | |
109 static const char* _names[]; | |
110 | |
111 public: | |
112 VM_Operation() { _calling_thread = NULL; _next = NULL; _prev = NULL; } | |
113 virtual ~VM_Operation() {} | |
114 | |
115 // VM operation support (used by VM thread) | |
116 Thread* calling_thread() const { return _calling_thread; } | |
117 ThreadPriority priority() { return _priority; } | |
118 void set_calling_thread(Thread* thread, ThreadPriority priority); | |
119 | |
120 long timestamp() const { return _timestamp; } | |
121 void set_timestamp(long timestamp) { _timestamp = timestamp; } | |
122 | |
123 // Called by VM thread - does in turn invoke doit(). Do not override this | |
124 void evaluate(); | |
125 | |
126 // evaluate() is called by the VMThread and in turn calls doit(). | |
127 // If the thread invoking VMThread::execute((VM_Operation*) is a JavaThread, | |
128 // doit_prologue() is called in that thread before transferring control to | |
129 // the VMThread. | |
130 // If doit_prologue() returns true the VM operation will proceed, and | |
131 // doit_epilogue() will be called by the JavaThread once the VM operation | |
132 // completes. If doit_prologue() returns false the VM operation is cancelled. | |
133 virtual void doit() = 0; | |
134 virtual bool doit_prologue() { return true; }; | |
135 virtual void doit_epilogue() {}; // Note: Not called if mode is: _concurrent | |
136 | |
137 // Type test | |
138 virtual bool is_methodCompiler() const { return false; } | |
139 | |
140 // Linking | |
141 VM_Operation *next() const { return _next; } | |
142 VM_Operation *prev() const { return _prev; } | |
143 void set_next(VM_Operation *next) { _next = next; } | |
144 void set_prev(VM_Operation *prev) { _prev = prev; } | |
145 | |
146 // Configuration. Override these appropriatly in subclasses. | |
147 virtual VMOp_Type type() const = 0; | |
148 virtual Mode evaluation_mode() const { return _safepoint; } | |
149 virtual bool allow_nested_vm_operations() const { return false; } | |
150 virtual bool is_cheap_allocated() const { return false; } | |
151 virtual void oops_do(OopClosure* f) { /* do nothing */ }; | |
152 | |
153 // CAUTION: <don't hang yourself with following rope> | |
154 // If you override these methods, make sure that the evaluation | |
155 // of these methods is race-free and non-blocking, since these | |
156 // methods may be evaluated either by the mutators or by the | |
157 // vm thread, either concurrently with mutators or with the mutators | |
158 // stopped. In other words, taking locks is verboten, and if there | |
159 // are any races in evaluating the conditions, they'd better be benign. | |
160 virtual bool evaluate_at_safepoint() const { | |
161 return evaluation_mode() == _safepoint || | |
162 evaluation_mode() == _async_safepoint; | |
163 } | |
164 virtual bool evaluate_concurrently() const { | |
165 return evaluation_mode() == _concurrent || | |
166 evaluation_mode() == _async_safepoint; | |
167 } | |
168 | |
169 // Debugging | |
170 void print_on_error(outputStream* st) const; | |
171 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 #ifndef PRODUCT | |
177 void print_on(outputStream* st) const { print_on_error(st); } | |
178 #endif | |
179 }; | |
180 | |
181 class VM_ThreadStop: public VM_Operation { | |
182 private: | |
183 oop _thread; // The Thread that the Throwable is thrown against | |
184 oop _throwable; // The Throwable thrown at the target Thread | |
185 public: | |
186 // All oops are passed as JNI handles, since there is no guarantee that a GC might happen before the | |
187 // VM operation is executed. | |
188 VM_ThreadStop(oop thread, oop throwable) { | |
189 _thread = thread; | |
190 _throwable = throwable; | |
191 } | |
192 VMOp_Type type() const { return VMOp_ThreadStop; } | |
193 oop target_thread() const { return _thread; } | |
194 oop throwable() const { return _throwable;} | |
195 void doit(); | |
196 // We deoptimize if top-most frame is compiled - this might require a C2I adapter to be generated | |
197 bool allow_nested_vm_operations() const { return true; } | |
198 Mode evaluation_mode() const { return _async_safepoint; } | |
199 bool is_cheap_allocated() const { return true; } | |
200 | |
201 // GC support | |
202 void oops_do(OopClosure* f) { | |
203 f->do_oop(&_thread); f->do_oop(&_throwable); | |
204 } | |
205 }; | |
206 | |
207 // dummy vm op, evaluated just to force a safepoint | |
208 class VM_ForceSafepoint: public VM_Operation { | |
209 public: | |
210 VM_ForceSafepoint() {} | |
211 void doit() {} | |
212 VMOp_Type type() const { return VMOp_ForceSafepoint; } | |
213 }; | |
214 | |
215 // dummy vm op, evaluated just to force a safepoint | |
216 class VM_ForceAsyncSafepoint: public VM_Operation { | |
217 public: | |
218 VM_ForceAsyncSafepoint() {} | |
219 void doit() {} | |
220 VMOp_Type type() const { return VMOp_ForceAsyncSafepoint; } | |
221 Mode evaluation_mode() const { return _async_safepoint; } | |
222 bool is_cheap_allocated() const { return true; } | |
223 }; | |
224 | |
225 class VM_Deoptimize: public VM_Operation { | |
226 public: | |
227 VM_Deoptimize() {} | |
228 VMOp_Type type() const { return VMOp_Deoptimize; } | |
229 void doit(); | |
230 bool allow_nested_vm_operations() const { return true; } | |
231 }; | |
232 | |
233 class VM_DeoptimizeFrame: public VM_Operation { | |
234 private: | |
235 JavaThread* _thread; | |
236 intptr_t* _id; | |
237 public: | |
238 VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id); | |
239 VMOp_Type type() const { return VMOp_DeoptimizeFrame; } | |
240 void doit(); | |
241 bool allow_nested_vm_operations() const { return true; } | |
242 }; | |
243 | |
244 #ifndef PRODUCT | |
245 class VM_DeoptimizeAll: public VM_Operation { | |
246 private: | |
247 KlassHandle _dependee; | |
248 public: | |
249 VM_DeoptimizeAll() {} | |
250 VMOp_Type type() const { return VMOp_DeoptimizeAll; } | |
251 void doit(); | |
252 bool allow_nested_vm_operations() const { return true; } | |
253 }; | |
254 | |
255 | |
256 class VM_ZombieAll: public VM_Operation { | |
257 public: | |
258 VM_ZombieAll() {} | |
259 VMOp_Type type() const { return VMOp_ZombieAll; } | |
260 void doit(); | |
261 bool allow_nested_vm_operations() const { return true; } | |
262 }; | |
263 #endif // PRODUCT | |
264 | |
265 class VM_Verify: public VM_Operation { | |
266 private: | |
267 KlassHandle _dependee; | |
268 public: | |
269 VM_Verify() {} | |
270 VMOp_Type type() const { return VMOp_Verify; } | |
271 void doit(); | |
272 }; | |
273 | |
274 | |
275 class VM_PrintThreads: public VM_Operation { | |
276 private: | |
277 outputStream* _out; | |
278 bool _print_concurrent_locks; | |
279 public: | |
280 VM_PrintThreads() { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; } | |
281 VM_PrintThreads(outputStream* out, bool print_concurrent_locks) { _out = out; _print_concurrent_locks = print_concurrent_locks; } | |
282 VMOp_Type type() const { return VMOp_PrintThreads; } | |
283 void doit(); | |
284 bool doit_prologue(); | |
285 void doit_epilogue(); | |
286 }; | |
287 | |
288 class VM_PrintJNI: public VM_Operation { | |
289 private: | |
290 outputStream* _out; | |
291 public: | |
292 VM_PrintJNI() { _out = tty; } | |
293 VM_PrintJNI(outputStream* out) { _out = out; } | |
294 VMOp_Type type() const { return VMOp_PrintJNI; } | |
295 void doit(); | |
296 }; | |
297 | |
298 class DeadlockCycle; | |
299 class VM_FindDeadlocks: public VM_Operation { | |
300 private: | |
301 bool _concurrent_locks; | |
302 DeadlockCycle* _deadlocks; | |
303 outputStream* _out; | |
304 | |
305 public: | |
306 VM_FindDeadlocks(bool concurrent_locks) : _concurrent_locks(concurrent_locks), _out(NULL), _deadlocks(NULL) {}; | |
307 VM_FindDeadlocks(outputStream* st) : _concurrent_locks(true), _out(st), _deadlocks(NULL) {}; | |
308 ~VM_FindDeadlocks(); | |
309 | |
310 DeadlockCycle* result() { return _deadlocks; }; | |
311 VMOp_Type type() const { return VMOp_FindDeadlocks; } | |
312 void doit(); | |
313 bool doit_prologue(); | |
314 }; | |
315 | |
316 class ThreadDumpResult; | |
317 class ThreadSnapshot; | |
318 class ThreadConcurrentLocks; | |
319 | |
320 class VM_ThreadDump : public VM_Operation { | |
321 private: | |
322 ThreadDumpResult* _result; | |
323 int _num_threads; | |
324 GrowableArray<instanceHandle>* _threads; | |
325 int _max_depth; | |
326 bool _with_locked_monitors; | |
327 bool _with_locked_synchronizers; | |
328 | |
329 ThreadSnapshot* snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl); | |
330 | |
331 public: | |
332 VM_ThreadDump(ThreadDumpResult* result, | |
333 int max_depth, // -1 indicates entire stack | |
334 bool with_locked_monitors, | |
335 bool with_locked_synchronizers); | |
336 | |
337 VM_ThreadDump(ThreadDumpResult* result, | |
338 GrowableArray<instanceHandle>* threads, | |
339 int num_threads, // -1 indicates entire stack | |
340 int max_depth, | |
341 bool with_locked_monitors, | |
342 bool with_locked_synchronizers); | |
343 | |
344 VMOp_Type type() const { return VMOp_ThreadDump; } | |
345 void doit(); | |
346 bool doit_prologue(); | |
347 void doit_epilogue(); | |
348 }; | |
349 | |
350 | |
351 class VM_Exit: public VM_Operation { | |
352 private: | |
353 int _exit_code; | |
354 static volatile bool _vm_exited; | |
355 static Thread * _shutdown_thread; | |
356 static void wait_if_vm_exited(); | |
357 public: | |
358 VM_Exit(int exit_code) { | |
359 _exit_code = exit_code; | |
360 } | |
361 static int wait_for_threads_in_native_to_block(); | |
362 static int set_vm_exited(); | |
363 static bool vm_exited() { return _vm_exited; } | |
364 static void block_if_vm_exited() { | |
365 if (_vm_exited) { | |
366 wait_if_vm_exited(); | |
367 } | |
368 } | |
369 VMOp_Type type() const { return VMOp_Exit; } | |
370 void doit(); | |
371 }; |