Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiEnvBase.hpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | 39556eae08af |
children | db9981fd3124 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1122
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1122
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1122
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_PRIMS_JVMTIENVBASE_HPP |
26 #define SHARE_VM_PRIMS_JVMTIENVBASE_HPP | |
27 | |
28 #include "classfile/classLoader.hpp" | |
29 #include "prims/jvmtiEnvThreadState.hpp" | |
30 #include "prims/jvmtiEventController.hpp" | |
31 #include "prims/jvmtiThreadState.hpp" | |
32 #include "runtime/fieldDescriptor.hpp" | |
33 #include "runtime/frame.hpp" | |
34 #include "runtime/handles.inline.hpp" | |
35 #include "runtime/thread.hpp" | |
36 #include "runtime/vm_operations.hpp" | |
37 #include "utilities/growableArray.hpp" | |
0 | 38 |
39 // | |
40 // Forward Declarations | |
41 // | |
42 | |
43 class JvmtiEnv; | |
44 class JvmtiThreadState; | |
45 class JvmtiRawMonitor; // for jvmtiEnv.hpp | |
46 class JvmtiEventControllerPrivate; | |
47 class JvmtiTagMap; | |
48 | |
49 | |
50 | |
51 // One JvmtiEnv object is created per jvmti attachment; | |
52 // done via JNI GetEnv() call. Multiple attachments are | |
53 // allowed in jvmti. | |
54 | |
6197 | 55 class JvmtiEnvBase : public CHeapObj<mtInternal> { |
0 | 56 |
57 private: | |
58 | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
59 #if INCLUDE_JVMTI |
0 | 60 static JvmtiEnvBase* _head_environment; // head of environment list |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
61 #endif // INCLUDE_JVMTI |
0 | 62 |
63 static bool _globally_initialized; | |
64 static jvmtiPhase _phase; | |
65 static volatile int _dying_thread_env_iteration_count; | |
66 | |
67 public: | |
68 | |
69 enum { | |
70 JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 + 33, /* version: 1.0.33 */ | |
1988 | 71 JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102, /* version: 1.1.102 */ |
6919 | 72 JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 + 2 /* version: 1.2.2 */ |
0 | 73 }; |
74 | |
75 static jvmtiPhase get_phase() { return _phase; } | |
76 static void set_phase(jvmtiPhase phase) { _phase = phase; } | |
77 static bool is_vm_live() { return _phase == JVMTI_PHASE_LIVE; } | |
78 | |
79 static void entering_dying_thread_env_iteration() { ++_dying_thread_env_iteration_count; } | |
80 static void leaving_dying_thread_env_iteration() { --_dying_thread_env_iteration_count; } | |
81 static bool is_inside_dying_thread_env_iteration(){ return _dying_thread_env_iteration_count > 0; } | |
82 | |
83 private: | |
84 | |
85 enum { | |
86 JVMTI_MAGIC = 0x71EE, | |
87 DISPOSED_MAGIC = 0xDEFC, | |
88 BAD_MAGIC = 0xDEAD | |
89 }; | |
90 | |
91 jvmtiEnv _jvmti_external; | |
92 jint _magic; | |
1121 | 93 jint _version; // version value passed to JNI GetEnv() |
0 | 94 JvmtiEnvBase* _next; |
95 bool _is_retransformable; | |
96 const void *_env_local_storage; // per env agent allocated data. | |
97 jvmtiEventCallbacks _event_callbacks; | |
98 jvmtiExtEventCallbacks _ext_event_callbacks; | |
99 JvmtiTagMap* _tag_map; | |
100 JvmtiEnvEventEnable _env_event_enable; | |
101 jvmtiCapabilities _current_capabilities; | |
102 jvmtiCapabilities _prohibited_capabilities; | |
103 volatile bool _class_file_load_hook_ever_enabled; | |
104 static volatile bool _needs_clean_up; | |
105 char** _native_method_prefixes; | |
106 int _native_method_prefix_count; | |
107 | |
108 protected: | |
1121 | 109 JvmtiEnvBase(jint version); |
0 | 110 ~JvmtiEnvBase(); |
111 void dispose(); | |
112 void env_dispose(); | |
113 | |
114 void set_env_local_storage(const void* data) { _env_local_storage = data; } | |
115 const void* get_env_local_storage() { return _env_local_storage; } | |
116 | |
117 void record_class_file_load_hook_enabled(); | |
118 void record_first_time_class_file_load_hook_enabled(); | |
119 | |
120 char** get_native_method_prefixes() { return _native_method_prefixes; } | |
121 int get_native_method_prefix_count() { return _native_method_prefix_count; } | |
122 jvmtiError set_native_method_prefixes(jint prefix_count, char** prefixes); | |
123 | |
124 private: | |
125 friend class JvmtiEventControllerPrivate; | |
126 void initialize(); | |
127 void set_event_callbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks); | |
128 static void globally_initialize(); | |
129 static void periodic_clean_up(); | |
130 | |
131 friend class JvmtiEnvIterator; | |
132 JvmtiEnv* next_environment() { return (JvmtiEnv*)_next; } | |
133 void set_next_environment(JvmtiEnvBase* env) { _next = env; } | |
6854
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
134 static JvmtiEnv* head_environment() { |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
135 JVMTI_ONLY(return (JvmtiEnv*)_head_environment); |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
136 NOT_JVMTI(return NULL); |
fb19af007ffc
7189254: Change makefiles for more flexibility to override defaults
jprovino
parents:
6725
diff
changeset
|
137 } |
0 | 138 |
139 public: | |
140 | |
611
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
0
diff
changeset
|
141 bool is_valid(); |
0 | 142 |
1121 | 143 bool use_version_1_0_semantics(); // agent asked for version 1.0 |
144 bool use_version_1_1_semantics(); // agent asked for version 1.1 | |
1988 | 145 bool use_version_1_2_semantics(); // agent asked for version 1.2 |
1121 | 146 |
0 | 147 bool is_retransformable() { return _is_retransformable; } |
148 | |
149 static ByteSize jvmti_external_offset() { | |
150 return byte_offset_of(JvmtiEnvBase, _jvmti_external); | |
151 }; | |
152 | |
153 static JvmtiEnv* JvmtiEnv_from_jvmti_env(jvmtiEnv *env) { | |
154 return (JvmtiEnv*)((intptr_t)env - in_bytes(jvmti_external_offset())); | |
155 }; | |
156 | |
157 jvmtiCapabilities *get_capabilities() { return &_current_capabilities; } | |
158 | |
159 jvmtiCapabilities *get_prohibited_capabilities() { return &_prohibited_capabilities; } | |
160 | |
161 static char** get_all_native_method_prefixes(int* count_ptr); | |
162 | |
163 // This test will answer true when all environments have been disposed and some have | |
164 // not yet been deallocated. As a result, this test should only be used as an | |
165 // optimization for the no environment case. | |
166 static bool environments_might_exist() { | |
167 return head_environment() != NULL; | |
168 } | |
169 | |
170 static void check_for_periodic_clean_up(); | |
171 | |
172 JvmtiEnvEventEnable *env_event_enable() { | |
173 return &_env_event_enable; | |
174 } | |
175 | |
176 jvmtiError allocate(jlong size, unsigned char** mem_ptr) { | |
177 if (size < 0) { | |
178 return JVMTI_ERROR_ILLEGAL_ARGUMENT; | |
179 } | |
180 if (size == 0) { | |
181 *mem_ptr = NULL; | |
182 } else { | |
6197 | 183 *mem_ptr = (unsigned char *)os::malloc((size_t)size, mtInternal); |
0 | 184 if (*mem_ptr == NULL) { |
185 return JVMTI_ERROR_OUT_OF_MEMORY; | |
186 } | |
187 } | |
188 return JVMTI_ERROR_NONE; | |
189 } | |
190 | |
191 jvmtiError deallocate(unsigned char* mem) { | |
192 if (mem != NULL) { | |
6197 | 193 os::free(mem, mtInternal); |
0 | 194 } |
195 return JVMTI_ERROR_NONE; | |
196 } | |
197 | |
198 | |
199 // Memory functions | |
200 unsigned char* jvmtiMalloc(jlong size); // don't use this - call allocate | |
201 | |
202 // method to create a local handle | |
203 jobject jni_reference(Handle hndl) { | |
204 return JNIHandles::make_local(hndl()); | |
205 } | |
206 | |
207 // method to create a local handle. | |
208 // This function allows caller to specify which | |
209 // threads local handle table to use. | |
210 jobject jni_reference(JavaThread *thread, Handle hndl) { | |
211 return JNIHandles::make_local(thread, hndl()); | |
212 } | |
213 | |
214 // method to destroy a local handle | |
215 void destroy_jni_reference(jobject jobj) { | |
216 JNIHandles::destroy_local(jobj); | |
217 } | |
218 | |
219 // method to destroy a local handle. | |
220 // This function allows caller to specify which | |
221 // threads local handle table to use although currently it is | |
222 // not used. | |
223 void destroy_jni_reference(JavaThread *thread, jobject jobj) { | |
224 destroy_jni_reference(jobj); | |
225 } | |
226 | |
227 jvmtiEnv* jvmti_external() { return &_jvmti_external; }; | |
228 | |
229 // Event Dispatch | |
230 | |
231 bool has_callback(jvmtiEvent event_type) { | |
232 assert(event_type >= JVMTI_MIN_EVENT_TYPE_VAL && | |
233 event_type <= JVMTI_MAX_EVENT_TYPE_VAL, "checking"); | |
234 return ((void**)&_event_callbacks)[event_type-JVMTI_MIN_EVENT_TYPE_VAL] != NULL; | |
235 } | |
236 | |
237 jvmtiEventCallbacks* callbacks() { | |
238 return &_event_callbacks; | |
239 } | |
240 | |
241 jvmtiExtEventCallbacks* ext_callbacks() { | |
242 return &_ext_event_callbacks; | |
243 } | |
244 | |
245 void set_tag_map(JvmtiTagMap* tag_map) { | |
246 _tag_map = tag_map; | |
247 } | |
248 | |
249 JvmtiTagMap* tag_map() { | |
250 return _tag_map; | |
251 } | |
252 | |
253 | |
254 // return true if event is enabled globally or for any thread | |
255 // True only if there is a callback for it. | |
256 bool is_enabled(jvmtiEvent event_type) { | |
257 return _env_event_enable.is_enabled(event_type); | |
258 } | |
259 | |
260 // Random Utilities | |
261 | |
262 protected: | |
263 // helper methods for creating arrays of global JNI Handles from local Handles | |
264 // allocated into environment specific storage | |
265 jobject * new_jobjectArray(int length, Handle *handles); | |
266 jthread * new_jthreadArray(int length, Handle *handles); | |
267 jthreadGroup * new_jthreadGroupArray(int length, Handle *handles); | |
268 | |
269 // convert from JNIHandle to JavaThread * | |
270 JavaThread * get_JavaThread(jthread jni_thread); | |
271 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
272 // convert to a jni jclass from a non-null Klass* |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
273 jclass get_jni_class_non_null(Klass* k); |
0 | 274 |
275 jint count_locked_objects(JavaThread *java_thread, Handle hobj); | |
276 jvmtiError get_locked_objects_in_frame(JavaThread *calling_thread, | |
277 JavaThread* java_thread, | |
278 javaVFrame *jvf, | |
279 GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, | |
280 jint depth); | |
281 vframe* vframeFor(JavaThread* java_thread, jint depth); | |
282 | |
283 public: | |
284 // get a field descriptor for the specified class and field | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
285 static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd); |
0 | 286 // test for suspend - most (all?) of these should go away |
287 static bool is_thread_fully_suspended(JavaThread *thread, | |
288 bool wait_for_suspend, | |
289 uint32_t *bits); | |
290 | |
291 | |
292 // JVMTI API helper functions which are called at safepoint or thread is suspended. | |
293 jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr); | |
294 jvmtiError get_frame_location(JavaThread* java_thread, jint depth, | |
295 jmethodID* method_ptr, jlocation* location_ptr); | |
296 jvmtiError get_object_monitor_usage(JavaThread *calling_thread, | |
297 jobject object, jvmtiMonitorUsage* info_ptr); | |
298 jvmtiError get_stack_trace(JavaThread *java_thread, | |
299 jint stack_depth, jint max_count, | |
300 jvmtiFrameInfo* frame_buffer, jint* count_ptr); | |
301 jvmtiError get_current_contended_monitor(JavaThread *calling_thread, | |
302 JavaThread *java_thread, | |
303 jobject *monitor_ptr); | |
304 jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread, | |
305 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list); | |
306 jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread, | |
307 jvalue value, TosState tos, Handle* ret_ob_h); | |
308 jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos); | |
309 }; | |
310 | |
311 // This class is the only safe means of iterating through environments. | |
312 // Note that this iteratation includes invalid environments pending | |
313 // deallocation -- in fact, some uses depend on this behavior. | |
314 | |
315 class JvmtiEnvIterator : public StackObj { | |
316 private: | |
317 bool _entry_was_marked; | |
318 public: | |
319 JvmtiEnvIterator() { | |
320 if (Threads::number_of_threads() == 0) { | |
321 _entry_was_marked = false; // we are single-threaded, no need | |
322 } else { | |
323 Thread::current()->entering_jvmti_env_iteration(); | |
324 _entry_was_marked = true; | |
325 } | |
326 } | |
327 ~JvmtiEnvIterator() { | |
328 if (_entry_was_marked) { | |
329 Thread::current()->leaving_jvmti_env_iteration(); | |
330 } | |
331 } | |
332 JvmtiEnv* first() { return JvmtiEnvBase::head_environment(); } | |
333 JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); } | |
334 }; | |
335 | |
336 | |
337 // VM operation to get monitor information with stack depth. | |
338 class VM_GetOwnedMonitorInfo : public VM_Operation { | |
339 private: | |
340 JvmtiEnv *_env; | |
341 JavaThread* _calling_thread; | |
342 JavaThread *_java_thread; | |
343 jvmtiError _result; | |
344 GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list; | |
345 | |
346 public: | |
347 VM_GetOwnedMonitorInfo(JvmtiEnv* env, JavaThread* calling_thread, | |
348 JavaThread* java_thread, | |
349 GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list) { | |
350 _env = env; | |
351 _calling_thread = calling_thread; | |
352 _java_thread = java_thread; | |
353 _owned_monitors_list = owned_monitor_list; | |
354 _result = JVMTI_ERROR_NONE; | |
355 } | |
356 VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; } | |
357 void doit() { | |
358 ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread, | |
359 _owned_monitors_list); | |
360 } | |
361 jvmtiError result() { return _result; } | |
362 }; | |
363 | |
364 | |
365 // VM operation to get object monitor usage. | |
366 class VM_GetObjectMonitorUsage : public VM_Operation { | |
367 private: | |
368 JvmtiEnv *_env; | |
369 jobject _object; | |
370 JavaThread* _calling_thread; | |
371 jvmtiMonitorUsage* _info_ptr; | |
372 jvmtiError _result; | |
373 | |
374 public: | |
375 VM_GetObjectMonitorUsage(JvmtiEnv *env, JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) { | |
376 _env = env; | |
377 _object = object; | |
378 _calling_thread = calling_thread; | |
379 _info_ptr = info_ptr; | |
380 } | |
381 VMOp_Type type() const { return VMOp_GetObjectMonitorUsage; } | |
382 jvmtiError result() { return _result; } | |
383 void doit() { | |
384 _result = ((JvmtiEnvBase*) _env)->get_object_monitor_usage(_calling_thread, _object, _info_ptr); | |
385 } | |
386 | |
387 }; | |
388 | |
389 // VM operation to get current contended monitor. | |
390 class VM_GetCurrentContendedMonitor : public VM_Operation { | |
391 private: | |
392 JvmtiEnv *_env; | |
393 JavaThread *_calling_thread; | |
394 JavaThread *_java_thread; | |
395 jobject *_owned_monitor_ptr; | |
396 jvmtiError _result; | |
397 | |
398 public: | |
399 VM_GetCurrentContendedMonitor(JvmtiEnv *env, JavaThread *calling_thread, JavaThread *java_thread, jobject *mon_ptr) { | |
400 _env = env; | |
401 _calling_thread = calling_thread; | |
402 _java_thread = java_thread; | |
403 _owned_monitor_ptr = mon_ptr; | |
404 } | |
405 VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } | |
406 jvmtiError result() { return _result; } | |
407 void doit() { | |
408 _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); | |
409 } | |
410 }; | |
411 | |
412 // VM operation to get stack trace at safepoint. | |
413 class VM_GetStackTrace : public VM_Operation { | |
414 private: | |
415 JvmtiEnv *_env; | |
416 JavaThread *_java_thread; | |
417 jint _start_depth; | |
418 jint _max_count; | |
419 jvmtiFrameInfo *_frame_buffer; | |
420 jint *_count_ptr; | |
421 jvmtiError _result; | |
422 | |
423 public: | |
424 VM_GetStackTrace(JvmtiEnv *env, JavaThread *java_thread, | |
425 jint start_depth, jint max_count, | |
426 jvmtiFrameInfo* frame_buffer, jint* count_ptr) { | |
427 _env = env; | |
428 _java_thread = java_thread; | |
429 _start_depth = start_depth; | |
430 _max_count = max_count; | |
431 _frame_buffer = frame_buffer; | |
432 _count_ptr = count_ptr; | |
433 } | |
434 jvmtiError result() { return _result; } | |
435 VMOp_Type type() const { return VMOp_GetStackTrace; } | |
436 void doit() { | |
437 _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread, | |
438 _start_depth, _max_count, | |
439 _frame_buffer, _count_ptr); | |
440 } | |
441 }; | |
442 | |
443 // forward declaration | |
444 struct StackInfoNode; | |
445 | |
446 // VM operation to get stack trace at safepoint. | |
447 class VM_GetMultipleStackTraces : public VM_Operation { | |
448 private: | |
449 JvmtiEnv *_env; | |
450 jint _max_frame_count; | |
451 jvmtiStackInfo *_stack_info; | |
452 jvmtiError _result; | |
453 int _frame_count_total; | |
454 struct StackInfoNode *_head; | |
455 | |
456 JvmtiEnvBase *env() { return (JvmtiEnvBase *)_env; } | |
457 jint max_frame_count() { return _max_frame_count; } | |
458 struct StackInfoNode *head() { return _head; } | |
459 void set_head(StackInfoNode *head) { _head = head; } | |
460 | |
461 protected: | |
462 void set_result(jvmtiError result) { _result = result; } | |
463 void fill_frames(jthread jt, JavaThread *thr, oop thread_oop); | |
464 void allocate_and_fill_stacks(jint thread_count); | |
465 | |
466 public: | |
467 VM_GetMultipleStackTraces(JvmtiEnv *env, jint max_frame_count) { | |
468 _env = env; | |
469 _max_frame_count = max_frame_count; | |
470 _frame_count_total = 0; | |
471 _head = NULL; | |
472 _result = JVMTI_ERROR_NONE; | |
473 } | |
474 VMOp_Type type() const { return VMOp_GetMultipleStackTraces; } | |
475 jvmtiStackInfo *stack_info() { return _stack_info; } | |
476 jvmtiError result() { return _result; } | |
477 }; | |
478 | |
479 | |
480 // VM operation to get stack trace at safepoint. | |
481 class VM_GetAllStackTraces : public VM_GetMultipleStackTraces { | |
482 private: | |
483 JavaThread *_calling_thread; | |
484 jint _final_thread_count; | |
485 | |
486 public: | |
487 VM_GetAllStackTraces(JvmtiEnv *env, JavaThread *calling_thread, | |
488 jint max_frame_count) | |
489 : VM_GetMultipleStackTraces(env, max_frame_count) { | |
490 _calling_thread = calling_thread; | |
491 } | |
492 VMOp_Type type() const { return VMOp_GetAllStackTraces; } | |
493 void doit(); | |
494 jint final_thread_count() { return _final_thread_count; } | |
495 }; | |
496 | |
497 // VM operation to get stack trace at safepoint. | |
498 class VM_GetThreadListStackTraces : public VM_GetMultipleStackTraces { | |
499 private: | |
500 jint _thread_count; | |
501 const jthread* _thread_list; | |
502 | |
503 public: | |
504 VM_GetThreadListStackTraces(JvmtiEnv *env, jint thread_count, const jthread* thread_list, jint max_frame_count) | |
505 : VM_GetMultipleStackTraces(env, max_frame_count) { | |
506 _thread_count = thread_count; | |
507 _thread_list = thread_list; | |
508 } | |
509 VMOp_Type type() const { return VMOp_GetThreadListStackTraces; } | |
510 void doit(); | |
511 }; | |
512 | |
513 | |
514 // VM operation to count stack frames at safepoint. | |
515 class VM_GetFrameCount : public VM_Operation { | |
516 private: | |
517 JvmtiEnv *_env; | |
518 JvmtiThreadState *_state; | |
519 jint *_count_ptr; | |
520 jvmtiError _result; | |
521 | |
522 public: | |
523 VM_GetFrameCount(JvmtiEnv *env, JvmtiThreadState *state, jint *count_ptr) { | |
524 _env = env; | |
525 _state = state; | |
526 _count_ptr = count_ptr; | |
527 } | |
528 VMOp_Type type() const { return VMOp_GetFrameCount; } | |
529 jvmtiError result() { return _result; } | |
530 void doit() { | |
531 _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr); | |
532 } | |
533 }; | |
534 | |
535 // VM operation to frame location at safepoint. | |
536 class VM_GetFrameLocation : public VM_Operation { | |
537 private: | |
538 JvmtiEnv *_env; | |
539 JavaThread* _java_thread; | |
540 jint _depth; | |
541 jmethodID* _method_ptr; | |
542 jlocation* _location_ptr; | |
543 jvmtiError _result; | |
544 | |
545 public: | |
546 VM_GetFrameLocation(JvmtiEnv *env, JavaThread* java_thread, jint depth, | |
547 jmethodID* method_ptr, jlocation* location_ptr) { | |
548 _env = env; | |
549 _java_thread = java_thread; | |
550 _depth = depth; | |
551 _method_ptr = method_ptr; | |
552 _location_ptr = location_ptr; | |
553 } | |
554 VMOp_Type type() const { return VMOp_GetFrameLocation; } | |
555 jvmtiError result() { return _result; } | |
556 void doit() { | |
557 _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth, | |
558 _method_ptr, _location_ptr); | |
559 } | |
560 }; | |
561 | |
562 | |
563 // ResourceTracker | |
564 // | |
565 // ResourceTracker works a little like a ResourceMark. All allocates | |
566 // using the resource tracker are recorded. If an allocate using the | |
567 // resource tracker fails the destructor will free any resources | |
568 // that were allocated using the tracker. | |
569 // The motive for this class is to avoid messy error recovery code | |
570 // in situations where multiple allocations are done in sequence. If | |
571 // the second or subsequent allocation fails it avoids any code to | |
572 // release memory allocated in the previous calls. | |
573 // | |
574 // Usage :- | |
575 // ResourceTracker rt(env); | |
576 // : | |
577 // err = rt.allocate(1024, &ptr); | |
578 | |
579 class ResourceTracker : public StackObj { | |
580 private: | |
581 JvmtiEnv* _env; | |
582 GrowableArray<unsigned char*> *_allocations; | |
583 bool _failed; | |
584 public: | |
585 ResourceTracker(JvmtiEnv* env); | |
586 ~ResourceTracker(); | |
587 jvmtiError allocate(jlong size, unsigned char** mem_ptr); | |
588 unsigned char* allocate(jlong size); | |
589 char* strdup(const char* str); | |
590 }; | |
591 | |
592 | |
593 // Jvmti monitor closure to collect off stack monitors. | |
594 class JvmtiMonitorClosure: public MonitorClosure { | |
595 private: | |
596 JavaThread *_java_thread; | |
597 JavaThread *_calling_thread; | |
598 GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list; | |
599 jvmtiError _error; | |
600 JvmtiEnvBase *_env; | |
601 | |
602 public: | |
603 JvmtiMonitorClosure(JavaThread* thread, JavaThread *calling_thread, | |
604 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors, | |
605 JvmtiEnvBase *env) { | |
606 _java_thread = thread; | |
607 _calling_thread = calling_thread; | |
608 _owned_monitors_list = owned_monitors; | |
609 _error = JVMTI_ERROR_NONE; | |
610 _env = env; | |
611 } | |
612 void do_monitor(ObjectMonitor* mon); | |
613 jvmtiError error() { return _error;} | |
614 }; | |
615 | |
1972 | 616 #endif // SHARE_VM_PRIMS_JVMTIENVBASE_HPP |