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