Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiEnvBase.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | e522a00b91aa 070d523b96a7 |
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:
1144
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1144
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:
1144
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "jvmtifiles/jvmtiEnv.hpp" | |
28 #include "oops/objArrayKlass.hpp" | |
29 #include "oops/objArrayOop.hpp" | |
30 #include "prims/jvmtiEnvBase.hpp" | |
31 #include "prims/jvmtiEventController.inline.hpp" | |
32 #include "prims/jvmtiExtensions.hpp" | |
33 #include "prims/jvmtiImpl.hpp" | |
34 #include "prims/jvmtiManageCapabilities.hpp" | |
35 #include "prims/jvmtiTagMap.hpp" | |
36 #include "prims/jvmtiThreadState.inline.hpp" | |
37 #include "runtime/biasedLocking.hpp" | |
38 #include "runtime/deoptimization.hpp" | |
39 #include "runtime/interfaceSupport.hpp" | |
40 #include "runtime/jfieldIDWorkaround.hpp" | |
41 #include "runtime/objectMonitor.hpp" | |
42 #include "runtime/objectMonitor.inline.hpp" | |
43 #include "runtime/signature.hpp" | |
44 #include "runtime/vframe.hpp" | |
45 #include "runtime/vframe_hp.hpp" | |
46 #include "runtime/vmThread.hpp" | |
47 #include "runtime/vm_operations.hpp" | |
0 | 48 |
49 /////////////////////////////////////////////////////////////// | |
50 // | |
51 // JvmtiEnvBase | |
52 // | |
53 | |
54 JvmtiEnvBase* JvmtiEnvBase::_head_environment = NULL; | |
55 | |
56 bool JvmtiEnvBase::_globally_initialized = false; | |
57 volatile bool JvmtiEnvBase::_needs_clean_up = false; | |
58 | |
59 jvmtiPhase JvmtiEnvBase::_phase = JVMTI_PHASE_PRIMORDIAL; | |
60 | |
61 volatile int JvmtiEnvBase::_dying_thread_env_iteration_count = 0; | |
62 | |
63 extern jvmtiInterface_1_ jvmti_Interface; | |
64 extern jvmtiInterface_1_ jvmtiTrace_Interface; | |
65 | |
66 | |
67 // perform initializations that must occur before any JVMTI environments | |
68 // are released but which should only be initialized once (no matter | |
69 // how many environments are created). | |
70 void | |
71 JvmtiEnvBase::globally_initialize() { | |
72 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); | |
73 assert(_globally_initialized == false, "bad call"); | |
74 | |
75 JvmtiManageCapabilities::initialize(); | |
76 | |
77 #ifndef JVMTI_KERNEL | |
78 // register extension functions and events | |
79 JvmtiExtensions::register_extensions(); | |
80 #endif // !JVMTI_KERNEL | |
81 | |
82 #ifdef JVMTI_TRACE | |
83 JvmtiTrace::initialize(); | |
84 #endif | |
85 | |
86 _globally_initialized = true; | |
87 } | |
88 | |
89 | |
90 void | |
91 JvmtiEnvBase::initialize() { | |
92 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); | |
93 | |
94 // Add this environment to the end of the environment list (order is important) | |
95 { | |
96 // This block of code must not contain any safepoints, as list deallocation | |
97 // (which occurs at a safepoint) cannot occur simultaneously with this list | |
98 // addition. Note: No_Safepoint_Verifier cannot, currently, be used before | |
99 // threads exist. | |
100 JvmtiEnvIterator it; | |
101 JvmtiEnvBase *previous_env = NULL; | |
102 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { | |
103 previous_env = env; | |
104 } | |
105 if (previous_env == NULL) { | |
106 _head_environment = this; | |
107 } else { | |
108 previous_env->set_next_environment(this); | |
109 } | |
110 } | |
111 | |
112 if (_globally_initialized == false) { | |
113 globally_initialize(); | |
114 } | |
115 } | |
116 | |
117 | |
611
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
118 bool |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
119 JvmtiEnvBase::is_valid() { |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
120 jint value = 0; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
121 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
122 // This object might not be a JvmtiEnvBase so we can't assume |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
123 // the _magic field is properly aligned. Get the value in a safe |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
124 // way and then check against JVMTI_MAGIC. |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
125 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
126 switch (sizeof(_magic)) { |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
127 case 2: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
128 value = Bytes::get_native_u2((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
129 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
130 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
131 case 4: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
132 value = Bytes::get_native_u4((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
133 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
134 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
135 case 8: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
136 value = Bytes::get_native_u8((address)&_magic); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
137 break; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
138 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
139 default: |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
140 guarantee(false, "_magic field is an unexpected size"); |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
141 } |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
142 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
143 return value == JVMTI_MAGIC; |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
144 } |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
145 |
2f716c0acb64
6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents:
609
diff
changeset
|
146 |
1122 | 147 bool |
1121 | 148 JvmtiEnvBase::use_version_1_0_semantics() { |
149 int major, minor, micro; | |
150 | |
151 JvmtiExport::decode_version_values(_version, &major, &minor, µ); | |
152 return major == 1 && minor == 0; // micro version doesn't matter here | |
153 } | |
154 | |
155 | |
156 bool | |
157 JvmtiEnvBase::use_version_1_1_semantics() { | |
158 int major, minor, micro; | |
159 | |
160 JvmtiExport::decode_version_values(_version, &major, &minor, µ); | |
161 return major == 1 && minor == 1; // micro version doesn't matter here | |
162 } | |
163 | |
1988 | 164 bool |
165 JvmtiEnvBase::use_version_1_2_semantics() { | |
166 int major, minor, micro; | |
167 | |
168 JvmtiExport::decode_version_values(_version, &major, &minor, µ); | |
169 return major == 1 && minor == 2; // micro version doesn't matter here | |
170 } | |
171 | |
1121 | 172 |
173 JvmtiEnvBase::JvmtiEnvBase(jint version) : _env_event_enable() { | |
174 _version = version; | |
0 | 175 _env_local_storage = NULL; |
176 _tag_map = NULL; | |
177 _native_method_prefix_count = 0; | |
178 _native_method_prefixes = NULL; | |
179 _next = NULL; | |
180 _class_file_load_hook_ever_enabled = false; | |
181 | |
182 // Moot since ClassFileLoadHook not yet enabled. | |
183 // But "true" will give a more predictable ClassFileLoadHook behavior | |
184 // for environment creation during ClassFileLoadHook. | |
185 _is_retransformable = true; | |
186 | |
187 // all callbacks initially NULL | |
188 memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks)); | |
189 | |
190 // all capabilities initially off | |
191 memset(&_current_capabilities, 0, sizeof(_current_capabilities)); | |
192 | |
193 // all prohibited capabilities initially off | |
194 memset(&_prohibited_capabilities, 0, sizeof(_prohibited_capabilities)); | |
195 | |
196 _magic = JVMTI_MAGIC; | |
197 | |
198 JvmtiEventController::env_initialize((JvmtiEnv*)this); | |
199 | |
200 #ifdef JVMTI_TRACE | |
371 | 201 _jvmti_external.functions = TraceJVMTI != NULL ? &jvmtiTrace_Interface : &jvmti_Interface; |
0 | 202 #else |
203 _jvmti_external.functions = &jvmti_Interface; | |
204 #endif | |
205 } | |
206 | |
207 | |
208 void | |
209 JvmtiEnvBase::dispose() { | |
210 | |
211 #ifdef JVMTI_TRACE | |
212 JvmtiTrace::shutdown(); | |
213 #endif | |
214 | |
215 // Dispose of event info and let the event controller call us back | |
216 // in a locked state (env_dispose, below) | |
217 JvmtiEventController::env_dispose(this); | |
218 } | |
219 | |
220 void | |
221 JvmtiEnvBase::env_dispose() { | |
222 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); | |
223 | |
224 // We have been entered with all events disabled on this environment. | |
225 // A race to re-enable events (by setting callbacks) is prevented by | |
226 // checking for a valid environment when setting callbacks (while | |
227 // holding the JvmtiThreadState_lock). | |
228 | |
229 // Mark as invalid. | |
230 _magic = DISPOSED_MAGIC; | |
231 | |
232 // Relinquish all capabilities. | |
233 jvmtiCapabilities *caps = get_capabilities(); | |
234 JvmtiManageCapabilities::relinquish_capabilities(caps, caps, caps); | |
235 | |
236 // Same situation as with events (see above) | |
237 set_native_method_prefixes(0, NULL); | |
238 | |
239 #ifndef JVMTI_KERNEL | |
240 JvmtiTagMap* tag_map_to_deallocate = _tag_map; | |
241 set_tag_map(NULL); | |
242 // A tag map can be big, deallocate it now | |
243 if (tag_map_to_deallocate != NULL) { | |
244 delete tag_map_to_deallocate; | |
245 } | |
246 #endif // !JVMTI_KERNEL | |
247 | |
248 _needs_clean_up = true; | |
249 } | |
250 | |
251 | |
252 JvmtiEnvBase::~JvmtiEnvBase() { | |
253 assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); | |
254 | |
255 // There is a small window of time during which the tag map of a | |
256 // disposed environment could have been reallocated. | |
257 // Make sure it is gone. | |
258 #ifndef JVMTI_KERNEL | |
259 JvmtiTagMap* tag_map_to_deallocate = _tag_map; | |
260 set_tag_map(NULL); | |
261 // A tag map can be big, deallocate it now | |
262 if (tag_map_to_deallocate != NULL) { | |
263 delete tag_map_to_deallocate; | |
264 } | |
265 #endif // !JVMTI_KERNEL | |
266 | |
267 _magic = BAD_MAGIC; | |
268 } | |
269 | |
270 | |
271 void | |
272 JvmtiEnvBase::periodic_clean_up() { | |
273 assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); | |
274 | |
275 // JvmtiEnvBase reference is saved in JvmtiEnvThreadState. So | |
276 // clean up JvmtiThreadState before deleting JvmtiEnv pointer. | |
277 JvmtiThreadState::periodic_clean_up(); | |
278 | |
279 // Unlink all invalid environments from the list of environments | |
280 // and deallocate them | |
281 JvmtiEnvIterator it; | |
282 JvmtiEnvBase* previous_env = NULL; | |
283 JvmtiEnvBase* env = it.first(); | |
284 while (env != NULL) { | |
285 if (env->is_valid()) { | |
286 previous_env = env; | |
287 env = it.next(env); | |
288 } else { | |
289 // This one isn't valid, remove it from the list and deallocate it | |
290 JvmtiEnvBase* defunct_env = env; | |
291 env = it.next(env); | |
292 if (previous_env == NULL) { | |
293 _head_environment = env; | |
294 } else { | |
295 previous_env->set_next_environment(env); | |
296 } | |
297 delete defunct_env; | |
298 } | |
299 } | |
300 | |
301 } | |
302 | |
303 | |
304 void | |
305 JvmtiEnvBase::check_for_periodic_clean_up() { | |
306 assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); | |
307 | |
308 class ThreadInsideIterationClosure: public ThreadClosure { | |
309 private: | |
310 bool _inside; | |
311 public: | |
312 ThreadInsideIterationClosure() : _inside(false) {}; | |
313 | |
314 void do_thread(Thread* thread) { | |
315 _inside |= thread->is_inside_jvmti_env_iteration(); | |
316 } | |
317 | |
318 bool is_inside_jvmti_env_iteration() { | |
319 return _inside; | |
320 } | |
321 }; | |
322 | |
323 if (_needs_clean_up) { | |
324 // Check if we are currently iterating environment, | |
325 // deallocation should not occur if we are | |
326 ThreadInsideIterationClosure tiic; | |
327 Threads::threads_do(&tiic); | |
328 if (!tiic.is_inside_jvmti_env_iteration() && | |
329 !is_inside_dying_thread_env_iteration()) { | |
330 _needs_clean_up = false; | |
331 JvmtiEnvBase::periodic_clean_up(); | |
332 } | |
333 } | |
334 } | |
335 | |
336 | |
337 void | |
338 JvmtiEnvBase::record_first_time_class_file_load_hook_enabled() { | |
339 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), | |
340 "sanity check"); | |
341 | |
342 if (!_class_file_load_hook_ever_enabled) { | |
343 _class_file_load_hook_ever_enabled = true; | |
344 | |
345 if (get_capabilities()->can_retransform_classes) { | |
346 _is_retransformable = true; | |
347 } else { | |
348 _is_retransformable = false; | |
349 | |
350 // cannot add retransform capability after ClassFileLoadHook has been enabled | |
351 get_prohibited_capabilities()->can_retransform_classes = 1; | |
352 } | |
353 } | |
354 } | |
355 | |
356 | |
357 void | |
358 JvmtiEnvBase::record_class_file_load_hook_enabled() { | |
359 if (!_class_file_load_hook_ever_enabled) { | |
360 if (Threads::number_of_threads() == 0) { | |
361 record_first_time_class_file_load_hook_enabled(); | |
362 } else { | |
363 MutexLocker mu(JvmtiThreadState_lock); | |
364 record_first_time_class_file_load_hook_enabled(); | |
365 } | |
366 } | |
367 } | |
368 | |
369 | |
370 jvmtiError | |
371 JvmtiEnvBase::set_native_method_prefixes(jint prefix_count, char** prefixes) { | |
372 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), | |
373 "sanity check"); | |
374 | |
375 int old_prefix_count = get_native_method_prefix_count(); | |
376 char **old_prefixes = get_native_method_prefixes(); | |
377 | |
378 // allocate and install the new prefixex | |
379 if (prefix_count == 0 || !is_valid()) { | |
380 _native_method_prefix_count = 0; | |
381 _native_method_prefixes = NULL; | |
382 } else { | |
383 // there are prefixes, allocate an array to hold them, and fill it | |
6197 | 384 char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*), mtInternal); |
0 | 385 if (new_prefixes == NULL) { |
386 return JVMTI_ERROR_OUT_OF_MEMORY; | |
387 } | |
388 for (int i = 0; i < prefix_count; i++) { | |
389 char* prefix = prefixes[i]; | |
390 if (prefix == NULL) { | |
391 for (int j = 0; j < (i-1); j++) { | |
392 os::free(new_prefixes[j]); | |
393 } | |
394 os::free(new_prefixes); | |
395 return JVMTI_ERROR_NULL_POINTER; | |
396 } | |
397 prefix = os::strdup(prefixes[i]); | |
398 if (prefix == NULL) { | |
399 for (int j = 0; j < (i-1); j++) { | |
400 os::free(new_prefixes[j]); | |
401 } | |
402 os::free(new_prefixes); | |
403 return JVMTI_ERROR_OUT_OF_MEMORY; | |
404 } | |
405 new_prefixes[i] = prefix; | |
406 } | |
407 _native_method_prefix_count = prefix_count; | |
408 _native_method_prefixes = new_prefixes; | |
409 } | |
410 | |
411 // now that we know the new prefixes have been successfully installed we can | |
412 // safely remove the old ones | |
413 if (old_prefix_count != 0) { | |
414 for (int i = 0; i < old_prefix_count; i++) { | |
415 os::free(old_prefixes[i]); | |
416 } | |
417 os::free(old_prefixes); | |
418 } | |
419 | |
420 return JVMTI_ERROR_NONE; | |
421 } | |
422 | |
423 | |
424 // Collect all the prefixes which have been set in any JVM TI environments | |
425 // by the SetNativeMethodPrefix(es) functions. Be sure to maintain the | |
426 // order of environments and the order of prefixes within each environment. | |
427 // Return in a resource allocated array. | |
428 char** | |
429 JvmtiEnvBase::get_all_native_method_prefixes(int* count_ptr) { | |
430 assert(Threads::number_of_threads() == 0 || | |
431 SafepointSynchronize::is_at_safepoint() || | |
432 JvmtiThreadState_lock->is_locked(), | |
433 "sanity check"); | |
434 | |
435 int total_count = 0; | |
436 GrowableArray<char*>* prefix_array =new GrowableArray<char*>(5); | |
437 | |
438 JvmtiEnvIterator it; | |
439 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { | |
440 int prefix_count = env->get_native_method_prefix_count(); | |
441 char** prefixes = env->get_native_method_prefixes(); | |
442 for (int j = 0; j < prefix_count; j++) { | |
443 // retrieve a prefix and so that it is safe against asynchronous changes | |
444 // copy it into the resource area | |
445 char* prefix = prefixes[j]; | |
446 char* prefix_copy = NEW_RESOURCE_ARRAY(char, strlen(prefix)+1); | |
447 strcpy(prefix_copy, prefix); | |
448 prefix_array->at_put_grow(total_count++, prefix_copy); | |
449 } | |
450 } | |
451 | |
452 char** all_prefixes = NEW_RESOURCE_ARRAY(char*, total_count); | |
453 char** p = all_prefixes; | |
454 for (int i = 0; i < total_count; ++i) { | |
455 *p++ = prefix_array->at(i); | |
456 } | |
457 *count_ptr = total_count; | |
458 return all_prefixes; | |
459 } | |
460 | |
461 void | |
462 JvmtiEnvBase::set_event_callbacks(const jvmtiEventCallbacks* callbacks, | |
463 jint size_of_callbacks) { | |
464 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); | |
465 | |
466 size_t byte_cnt = sizeof(jvmtiEventCallbacks); | |
467 | |
468 // clear in either case to be sure we got any gap between sizes | |
469 memset(&_event_callbacks, 0, byte_cnt); | |
470 | |
471 // Now that JvmtiThreadState_lock is held, prevent a possible race condition where events | |
472 // are re-enabled by a call to set event callbacks where the DisposeEnvironment | |
473 // occurs after the boiler-plate environment check and before the lock is acquired. | |
474 if (callbacks != NULL && is_valid()) { | |
475 if (size_of_callbacks < (jint)byte_cnt) { | |
476 byte_cnt = size_of_callbacks; | |
477 } | |
478 memcpy(&_event_callbacks, callbacks, byte_cnt); | |
479 } | |
480 } | |
481 | |
482 // Called from JVMTI entry points which perform stack walking. If the | |
483 // associated JavaThread is the current thread, then wait_for_suspend | |
484 // is not used. Otherwise, it determines if we should wait for the | |
485 // "other" thread to complete external suspension. (NOTE: in future | |
486 // releases the suspension mechanism should be reimplemented so this | |
487 // is not necessary.) | |
488 // | |
489 bool | |
490 JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) { | |
491 // "other" threads require special handling | |
492 if (thr != JavaThread::current()) { | |
493 if (wait_for_suspend) { | |
494 // We are allowed to wait for the external suspend to complete | |
495 // so give the other thread a chance to get suspended. | |
496 if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount, | |
497 SuspendRetryDelay, bits)) { | |
498 // didn't make it so let the caller know | |
499 return false; | |
500 } | |
501 } | |
502 // We aren't allowed to wait for the external suspend to complete | |
503 // so if the other thread isn't externally suspended we need to | |
504 // let the caller know. | |
505 else if (!thr->is_ext_suspend_completed_with_lock(bits)) { | |
506 return false; | |
507 } | |
508 } | |
509 | |
510 return true; | |
511 } | |
512 | |
513 | |
514 // In the fullness of time, all users of the method should instead | |
515 // directly use allocate, besides being cleaner and faster, this will | |
516 // mean much better out of memory handling | |
517 unsigned char * | |
518 JvmtiEnvBase::jvmtiMalloc(jlong size) { | |
519 unsigned char* mem; | |
520 jvmtiError result = allocate(size, &mem); | |
521 assert(result == JVMTI_ERROR_NONE, "Allocate failed"); | |
522 return mem; | |
523 } | |
524 | |
525 | |
526 // | |
527 // Threads | |
528 // | |
529 | |
530 jobject * | |
531 JvmtiEnvBase::new_jobjectArray(int length, Handle *handles) { | |
532 if (length == 0) { | |
533 return NULL; | |
534 } | |
535 | |
536 jobject *objArray = (jobject *) jvmtiMalloc(sizeof(jobject) * length); | |
537 NULL_CHECK(objArray, NULL); | |
538 | |
539 for (int i=0; i<length; i++) { | |
540 objArray[i] = jni_reference(handles[i]); | |
541 } | |
542 return objArray; | |
543 } | |
544 | |
545 jthread * | |
546 JvmtiEnvBase::new_jthreadArray(int length, Handle *handles) { | |
547 return (jthread *) new_jobjectArray(length,handles); | |
548 } | |
549 | |
550 jthreadGroup * | |
551 JvmtiEnvBase::new_jthreadGroupArray(int length, Handle *handles) { | |
552 return (jthreadGroup *) new_jobjectArray(length,handles); | |
553 } | |
554 | |
555 | |
556 JavaThread * | |
557 JvmtiEnvBase::get_JavaThread(jthread jni_thread) { | |
558 oop t = JNIHandles::resolve_external_guard(jni_thread); | |
1142 | 559 if (t == NULL || !t->is_a(SystemDictionary::Thread_klass())) { |
0 | 560 return NULL; |
561 } | |
562 // The following returns NULL if the thread has not yet run or is in | |
563 // process of exiting | |
564 return java_lang_Thread::thread(t); | |
565 } | |
566 | |
567 | |
568 // return the vframe on the specified thread and depth, NULL if no such frame | |
569 vframe* | |
570 JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) { | |
571 if (!java_thread->has_last_Java_frame()) { | |
572 return NULL; | |
573 } | |
574 RegisterMap reg_map(java_thread); | |
575 vframe *vf = java_thread->last_java_vframe(®_map); | |
576 int d = 0; | |
577 while ((vf != NULL) && (d < depth)) { | |
578 vf = vf->java_sender(); | |
579 d++; | |
580 } | |
581 return vf; | |
582 } | |
583 | |
584 | |
585 // | |
586 // utilities: JNI objects | |
587 // | |
588 | |
589 | |
590 jclass | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
591 JvmtiEnvBase::get_jni_class_non_null(Klass* k) { |
0 | 592 assert(k != NULL, "k != NULL"); |
593 return (jclass)jni_reference(Klass::cast(k)->java_mirror()); | |
594 } | |
595 | |
596 #ifndef JVMTI_KERNEL | |
597 | |
598 // | |
599 // Field Information | |
600 // | |
601 | |
602 bool | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
603 JvmtiEnvBase::get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd) { |
0 | 604 if (!jfieldIDWorkaround::is_valid_jfieldID(k, field)) { |
605 return false; | |
606 } | |
607 bool found = false; | |
608 if (jfieldIDWorkaround::is_static_jfieldID(field)) { | |
609 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
610 found = id->find_local_field(fd); |
0 | 611 } else { |
612 // Non-static field. The fieldID is really the offset of the field within the object. | |
613 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
614 found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, fd); |
0 | 615 } |
616 return found; | |
617 } | |
618 | |
619 // | |
620 // Object Monitor Information | |
621 // | |
622 | |
623 // | |
624 // Count the number of objects for a lightweight monitor. The hobj | |
625 // parameter is object that owns the monitor so this routine will | |
626 // count the number of times the same object was locked by frames | |
627 // in java_thread. | |
628 // | |
629 jint | |
630 JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) { | |
631 jint ret = 0; | |
632 if (!java_thread->has_last_Java_frame()) { | |
633 return ret; // no Java frames so no monitors | |
634 } | |
635 | |
636 ResourceMark rm; | |
637 HandleMark hm; | |
638 RegisterMap reg_map(java_thread); | |
639 | |
640 for(javaVFrame *jvf=java_thread->last_java_vframe(®_map); jvf != NULL; | |
641 jvf = jvf->java_sender()) { | |
642 GrowableArray<MonitorInfo*>* mons = jvf->monitors(); | |
643 if (!mons->is_empty()) { | |
644 for (int i = 0; i < mons->length(); i++) { | |
645 MonitorInfo *mi = mons->at(i); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
611
diff
changeset
|
646 if (mi->owner_is_scalar_replaced()) continue; |
0 | 647 |
648 // see if owner of the monitor is our object | |
649 if (mi->owner() != NULL && mi->owner() == hobj()) { | |
650 ret++; | |
651 } | |
652 } | |
653 } | |
654 } | |
655 return ret; | |
656 } | |
657 | |
658 | |
659 | |
660 jvmtiError | |
661 JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) { | |
662 #ifdef ASSERT | |
663 uint32_t debug_bits = 0; | |
664 #endif | |
665 assert((SafepointSynchronize::is_at_safepoint() || | |
666 is_thread_fully_suspended(java_thread, false, &debug_bits)), | |
667 "at safepoint or target thread is suspended"); | |
668 oop obj = NULL; | |
669 ObjectMonitor *mon = java_thread->current_waiting_monitor(); | |
670 if (mon == NULL) { | |
671 // thread is not doing an Object.wait() call | |
672 mon = java_thread->current_pending_monitor(); | |
673 if (mon != NULL) { | |
674 // The thread is trying to enter() or raw_enter() an ObjectMonitor. | |
675 obj = (oop)mon->object(); | |
676 // If obj == NULL, then ObjectMonitor is raw which doesn't count | |
677 // as contended for this API | |
678 } | |
679 // implied else: no contended ObjectMonitor | |
680 } else { | |
681 // thread is doing an Object.wait() call | |
682 obj = (oop)mon->object(); | |
683 assert(obj != NULL, "Object.wait() should have an object"); | |
684 } | |
685 | |
686 if (obj == NULL) { | |
687 *monitor_ptr = NULL; | |
688 } else { | |
689 HandleMark hm; | |
690 Handle hobj(obj); | |
691 *monitor_ptr = jni_reference(calling_thread, hobj); | |
692 } | |
693 return JVMTI_ERROR_NONE; | |
694 } | |
695 | |
696 | |
697 jvmtiError | |
698 JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread, | |
699 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) { | |
700 jvmtiError err = JVMTI_ERROR_NONE; | |
701 #ifdef ASSERT | |
702 uint32_t debug_bits = 0; | |
703 #endif | |
704 assert((SafepointSynchronize::is_at_safepoint() || | |
705 is_thread_fully_suspended(java_thread, false, &debug_bits)), | |
706 "at safepoint or target thread is suspended"); | |
707 | |
708 if (java_thread->has_last_Java_frame()) { | |
709 ResourceMark rm; | |
710 HandleMark hm; | |
711 RegisterMap reg_map(java_thread); | |
712 | |
713 int depth = 0; | |
714 for (javaVFrame *jvf = java_thread->last_java_vframe(®_map); jvf != NULL; | |
715 jvf = jvf->java_sender()) { | |
716 if (depth++ < MaxJavaStackTraceDepth) { // check for stack too deep | |
717 // add locked objects for this frame into list | |
718 err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1); | |
719 if (err != JVMTI_ERROR_NONE) { | |
720 return err; | |
721 } | |
722 } | |
723 } | |
724 } | |
725 | |
726 // Get off stack monitors. (e.g. acquired via jni MonitorEnter). | |
727 JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this); | |
728 ObjectSynchronizer::monitors_iterate(&jmc); | |
729 err = jmc.error(); | |
730 | |
731 return err; | |
732 } | |
733 | |
734 // Save JNI local handles for any objects that this frame owns. | |
735 jvmtiError | |
736 JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread, | |
737 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) { | |
738 jvmtiError err = JVMTI_ERROR_NONE; | |
739 ResourceMark rm; | |
740 | |
741 GrowableArray<MonitorInfo*>* mons = jvf->monitors(); | |
742 if (mons->is_empty()) { | |
743 return err; // this javaVFrame holds no monitors | |
744 } | |
745 | |
746 HandleMark hm; | |
747 oop wait_obj = NULL; | |
748 { | |
749 // save object of current wait() call (if any) for later comparison | |
750 ObjectMonitor *mon = java_thread->current_waiting_monitor(); | |
751 if (mon != NULL) { | |
752 wait_obj = (oop)mon->object(); | |
753 } | |
754 } | |
755 oop pending_obj = NULL; | |
756 { | |
757 // save object of current enter() call (if any) for later comparison | |
758 ObjectMonitor *mon = java_thread->current_pending_monitor(); | |
759 if (mon != NULL) { | |
760 pending_obj = (oop)mon->object(); | |
761 } | |
762 } | |
763 | |
764 for (int i = 0; i < mons->length(); i++) { | |
765 MonitorInfo *mi = mons->at(i); | |
766 | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
611
diff
changeset
|
767 if (mi->owner_is_scalar_replaced()) continue; |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
611
diff
changeset
|
768 |
0 | 769 oop obj = mi->owner(); |
770 if (obj == NULL) { | |
771 // this monitor doesn't have an owning object so skip it | |
772 continue; | |
773 } | |
774 | |
775 if (wait_obj == obj) { | |
776 // the thread is waiting on this monitor so it isn't really owned | |
777 continue; | |
778 } | |
779 | |
780 if (pending_obj == obj) { | |
781 // the thread is pending on this monitor so it isn't really owned | |
782 continue; | |
783 } | |
784 | |
785 if (owned_monitors_list->length() > 0) { | |
786 // Our list has at least one object on it so we have to check | |
787 // for recursive object locking | |
788 bool found = false; | |
789 for (int j = 0; j < owned_monitors_list->length(); j++) { | |
790 jobject jobj = ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(j))->monitor; | |
791 oop check = JNIHandles::resolve(jobj); | |
792 if (check == obj) { | |
793 found = true; // we found the object | |
794 break; | |
795 } | |
796 } | |
797 | |
798 if (found) { | |
799 // already have this object so don't include it | |
800 continue; | |
801 } | |
802 } | |
803 | |
804 // add the owning object to our list | |
805 jvmtiMonitorStackDepthInfo *jmsdi; | |
806 err = allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi); | |
807 if (err != JVMTI_ERROR_NONE) { | |
808 return err; | |
809 } | |
810 Handle hobj(obj); | |
811 jmsdi->monitor = jni_reference(calling_thread, hobj); | |
812 jmsdi->stack_depth = stack_depth; | |
813 owned_monitors_list->append(jmsdi); | |
814 } | |
815 | |
816 return err; | |
817 } | |
818 | |
819 jvmtiError | |
820 JvmtiEnvBase::get_stack_trace(JavaThread *java_thread, | |
821 jint start_depth, jint max_count, | |
822 jvmtiFrameInfo* frame_buffer, jint* count_ptr) { | |
823 #ifdef ASSERT | |
824 uint32_t debug_bits = 0; | |
825 #endif | |
826 assert((SafepointSynchronize::is_at_safepoint() || | |
827 is_thread_fully_suspended(java_thread, false, &debug_bits)), | |
828 "at safepoint or target thread is suspended"); | |
829 int count = 0; | |
830 if (java_thread->has_last_Java_frame()) { | |
831 RegisterMap reg_map(java_thread); | |
832 Thread* current_thread = Thread::current(); | |
833 ResourceMark rm(current_thread); | |
834 javaVFrame *jvf = java_thread->last_java_vframe(®_map); | |
835 HandleMark hm(current_thread); | |
836 if (start_depth != 0) { | |
837 if (start_depth > 0) { | |
838 for (int j = 0; j < start_depth && jvf != NULL; j++) { | |
839 jvf = jvf->java_sender(); | |
840 } | |
841 if (jvf == NULL) { | |
842 // start_depth is deeper than the stack depth | |
843 return JVMTI_ERROR_ILLEGAL_ARGUMENT; | |
844 } | |
845 } else { // start_depth < 0 | |
846 // we are referencing the starting depth based on the oldest | |
847 // part of the stack. | |
848 // optimize to limit the number of times that java_sender() is called | |
849 javaVFrame *jvf_cursor = jvf; | |
850 javaVFrame *jvf_prev = NULL; | |
851 javaVFrame *jvf_prev_prev; | |
852 int j = 0; | |
853 while (jvf_cursor != NULL) { | |
854 jvf_prev_prev = jvf_prev; | |
855 jvf_prev = jvf_cursor; | |
856 for (j = 0; j > start_depth && jvf_cursor != NULL; j--) { | |
857 jvf_cursor = jvf_cursor->java_sender(); | |
858 } | |
859 } | |
860 if (j == start_depth) { | |
861 // previous pointer is exactly where we want to start | |
862 jvf = jvf_prev; | |
863 } else { | |
864 // we need to back up further to get to the right place | |
865 if (jvf_prev_prev == NULL) { | |
866 // the -start_depth is greater than the stack depth | |
867 return JVMTI_ERROR_ILLEGAL_ARGUMENT; | |
868 } | |
869 // j now is the number of frames on the stack starting with | |
870 // jvf_prev, we start from jvf_prev_prev and move older on | |
871 // the stack that many, the result is -start_depth frames | |
872 // remaining. | |
873 jvf = jvf_prev_prev; | |
874 for (; j < 0; j++) { | |
875 jvf = jvf->java_sender(); | |
876 } | |
877 } | |
878 } | |
879 } | |
880 for (; count < max_count && jvf != NULL; count++) { | |
881 frame_buffer[count].method = jvf->method()->jmethod_id(); | |
882 frame_buffer[count].location = (jvf->method()->is_native() ? -1 : jvf->bci()); | |
883 jvf = jvf->java_sender(); | |
884 } | |
885 } else { | |
886 if (start_depth != 0) { | |
887 // no frames and there is a starting depth | |
888 return JVMTI_ERROR_ILLEGAL_ARGUMENT; | |
889 } | |
890 } | |
891 *count_ptr = count; | |
892 return JVMTI_ERROR_NONE; | |
893 } | |
894 | |
895 jvmtiError | |
896 JvmtiEnvBase::get_frame_count(JvmtiThreadState *state, jint *count_ptr) { | |
897 assert((state != NULL), | |
898 "JavaThread should create JvmtiThreadState before calling this method"); | |
899 *count_ptr = state->count_frames(); | |
900 return JVMTI_ERROR_NONE; | |
901 } | |
902 | |
903 jvmtiError | |
904 JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth, | |
905 jmethodID* method_ptr, jlocation* location_ptr) { | |
906 #ifdef ASSERT | |
907 uint32_t debug_bits = 0; | |
908 #endif | |
909 assert((SafepointSynchronize::is_at_safepoint() || | |
910 is_thread_fully_suspended(java_thread, false, &debug_bits)), | |
911 "at safepoint or target thread is suspended"); | |
912 Thread* current_thread = Thread::current(); | |
913 ResourceMark rm(current_thread); | |
914 | |
915 vframe *vf = vframeFor(java_thread, depth); | |
916 if (vf == NULL) { | |
917 return JVMTI_ERROR_NO_MORE_FRAMES; | |
918 } | |
919 | |
920 // vframeFor should return a java frame. If it doesn't | |
921 // it means we've got an internal error and we return the | |
922 // error in product mode. In debug mode we will instead | |
923 // attempt to cast the vframe to a javaVFrame and will | |
924 // cause an assertion/crash to allow further diagnosis. | |
925 #ifdef PRODUCT | |
926 if (!vf->is_java_frame()) { | |
927 return JVMTI_ERROR_INTERNAL; | |
928 } | |
929 #endif | |
930 | |
931 HandleMark hm(current_thread); | |
932 javaVFrame *jvf = javaVFrame::cast(vf); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
933 Method* method = jvf->method(); |
0 | 934 if (method->is_native()) { |
935 *location_ptr = -1; | |
936 } else { | |
937 *location_ptr = jvf->bci(); | |
938 } | |
939 *method_ptr = method->jmethod_id(); | |
940 | |
941 return JVMTI_ERROR_NONE; | |
942 } | |
943 | |
944 | |
945 jvmtiError | |
946 JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) { | |
947 HandleMark hm; | |
948 Handle hobj; | |
949 | |
950 bool at_safepoint = SafepointSynchronize::is_at_safepoint(); | |
951 | |
952 // Check arguments | |
953 { | |
954 oop mirror = JNIHandles::resolve_external_guard(object); | |
955 NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT); | |
956 NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER); | |
957 | |
958 hobj = Handle(mirror); | |
959 } | |
960 | |
961 JavaThread *owning_thread = NULL; | |
962 ObjectMonitor *mon = NULL; | |
963 jvmtiMonitorUsage ret = { | |
964 NULL, 0, 0, NULL, 0, NULL | |
965 }; | |
966 | |
967 uint32_t debug_bits = 0; | |
968 // first derive the object's owner and entry_count (if any) | |
969 { | |
970 // Revoke any biases before querying the mark word | |
971 if (SafepointSynchronize::is_at_safepoint()) { | |
972 BiasedLocking::revoke_at_safepoint(hobj); | |
973 } else { | |
974 BiasedLocking::revoke_and_rebias(hobj, false, calling_thread); | |
975 } | |
976 | |
977 address owner = NULL; | |
978 { | |
979 markOop mark = hobj()->mark(); | |
980 | |
981 if (!mark->has_monitor()) { | |
982 // this object has a lightweight monitor | |
983 | |
984 if (mark->has_locker()) { | |
985 owner = (address)mark->locker(); // save the address of the Lock word | |
986 } | |
987 // implied else: no owner | |
988 } else { | |
989 // this object has a heavyweight monitor | |
990 mon = mark->monitor(); | |
991 | |
992 // The owner field of a heavyweight monitor may be NULL for no | |
993 // owner, a JavaThread * or it may still be the address of the | |
994 // Lock word in a JavaThread's stack. A monitor can be inflated | |
995 // by a non-owning JavaThread, but only the owning JavaThread | |
996 // can change the owner field from the Lock word to the | |
997 // JavaThread * and it may not have done that yet. | |
998 owner = (address)mon->owner(); | |
999 } | |
1000 } | |
1001 | |
1002 if (owner != NULL) { | |
1003 // This monitor is owned so we have to find the owning JavaThread. | |
1004 // Since owning_thread_from_monitor_owner() grabs a lock, GC can | |
1005 // move our object at this point. However, our owner value is safe | |
1006 // since it is either the Lock word on a stack or a JavaThread *. | |
1007 owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint); | |
1008 assert(owning_thread != NULL, "sanity check"); | |
1009 if (owning_thread != NULL) { // robustness | |
1010 // The monitor's owner either has to be the current thread, at safepoint | |
1011 // or it has to be suspended. Any of these conditions will prevent both | |
1012 // contending and waiting threads from modifying the state of | |
1013 // the monitor. | |
1014 if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) { | |
1015 return JVMTI_ERROR_THREAD_NOT_SUSPENDED; | |
1016 } | |
1017 HandleMark hm; | |
1018 Handle th(owning_thread->threadObj()); | |
1019 ret.owner = (jthread)jni_reference(calling_thread, th); | |
1020 } | |
1021 // implied else: no owner | |
1022 } | |
1023 | |
1024 if (owning_thread != NULL) { // monitor is owned | |
1025 if ((address)owning_thread == owner) { | |
1026 // the owner field is the JavaThread * | |
1027 assert(mon != NULL, | |
1028 "must have heavyweight monitor with JavaThread * owner"); | |
1029 ret.entry_count = mon->recursions() + 1; | |
1030 } else { | |
1031 // The owner field is the Lock word on the JavaThread's stack | |
1032 // so the recursions field is not valid. We have to count the | |
1033 // number of recursive monitor entries the hard way. We pass | |
1034 // a handle to survive any GCs along the way. | |
1035 ResourceMark rm; | |
1036 ret.entry_count = count_locked_objects(owning_thread, hobj); | |
1037 } | |
1038 } | |
1039 // implied else: entry_count == 0 | |
1040 } | |
1041 | |
1042 int nWant,nWait; | |
1043 if (mon != NULL) { | |
1044 // this object has a heavyweight monitor | |
1045 nWant = mon->contentions(); // # of threads contending for monitor | |
1046 nWait = mon->waiters(); // # of threads in Object.wait() | |
1047 ret.waiter_count = nWant + nWait; | |
1048 ret.notify_waiter_count = nWait; | |
1049 } else { | |
1050 // this object has a lightweight monitor | |
1051 ret.waiter_count = 0; | |
1052 ret.notify_waiter_count = 0; | |
1053 } | |
1054 | |
1055 // Allocate memory for heavyweight and lightweight monitor. | |
1056 jvmtiError err; | |
1057 err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters); | |
1058 if (err != JVMTI_ERROR_NONE) { | |
1059 return err; | |
1060 } | |
1061 err = allocate(ret.notify_waiter_count * sizeof(jthread *), | |
1062 (unsigned char**)&ret.notify_waiters); | |
1063 if (err != JVMTI_ERROR_NONE) { | |
1064 deallocate((unsigned char*)ret.waiters); | |
1065 return err; | |
1066 } | |
1067 | |
1068 // now derive the rest of the fields | |
1069 if (mon != NULL) { | |
1070 // this object has a heavyweight monitor | |
1071 | |
1072 // Number of waiters may actually be less than the waiter count. | |
1073 // So NULL out memory so that unused memory will be NULL. | |
1074 memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *)); | |
1075 memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *)); | |
1076 | |
1077 if (ret.waiter_count > 0) { | |
1078 // we have contending and/or waiting threads | |
1079 HandleMark hm; | |
1080 if (nWant > 0) { | |
1081 // we have contending threads | |
1082 ResourceMark rm; | |
1083 // get_pending_threads returns only java thread so we do not need to | |
1084 // check for non java threads. | |
1085 GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads( | |
1086 nWant, (address)mon, !at_safepoint); | |
1087 if (wantList->length() < nWant) { | |
1088 // robustness: the pending list has gotten smaller | |
1089 nWant = wantList->length(); | |
1090 } | |
1091 for (int i = 0; i < nWant; i++) { | |
1092 JavaThread *pending_thread = wantList->at(i); | |
1093 // If the monitor has no owner, then a non-suspended contending | |
1094 // thread could potentially change the state of the monitor by | |
1095 // entering it. The JVM/TI spec doesn't allow this. | |
1096 if (owning_thread == NULL && !at_safepoint & | |
1097 !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) { | |
1098 if (ret.owner != NULL) { | |
1099 destroy_jni_reference(calling_thread, ret.owner); | |
1100 } | |
1101 for (int j = 0; j < i; j++) { | |
1102 destroy_jni_reference(calling_thread, ret.waiters[j]); | |
1103 } | |
1104 deallocate((unsigned char*)ret.waiters); | |
1105 deallocate((unsigned char*)ret.notify_waiters); | |
1106 return JVMTI_ERROR_THREAD_NOT_SUSPENDED; | |
1107 } | |
1108 Handle th(pending_thread->threadObj()); | |
1109 ret.waiters[i] = (jthread)jni_reference(calling_thread, th); | |
1110 } | |
1111 } | |
1112 if (nWait > 0) { | |
1113 // we have threads in Object.wait() | |
1114 int offset = nWant; // add after any contending threads | |
1115 ObjectWaiter *waiter = mon->first_waiter(); | |
1116 for (int i = 0, j = 0; i < nWait; i++) { | |
1117 if (waiter == NULL) { | |
1118 // robustness: the waiting list has gotten smaller | |
1119 nWait = j; | |
1120 break; | |
1121 } | |
1122 Thread *t = mon->thread_of_waiter(waiter); | |
1123 if (t != NULL && t->is_Java_thread()) { | |
1124 JavaThread *wjava_thread = (JavaThread *)t; | |
1125 // If the thread was found on the ObjectWaiter list, then | |
1126 // it has not been notified. This thread can't change the | |
1127 // state of the monitor so it doesn't need to be suspended. | |
1128 Handle th(wjava_thread->threadObj()); | |
1129 ret.waiters[offset + j] = (jthread)jni_reference(calling_thread, th); | |
1130 ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th); | |
1131 } | |
1132 waiter = mon->next_waiter(waiter); | |
1133 } | |
1134 } | |
1135 } | |
1136 | |
1137 // Adjust count. nWant and nWait count values may be less than original. | |
1138 ret.waiter_count = nWant + nWait; | |
1139 ret.notify_waiter_count = nWait; | |
1140 } else { | |
1141 // this object has a lightweight monitor and we have nothing more | |
1142 // to do here because the defaults are just fine. | |
1143 } | |
1144 | |
1145 // we don't update return parameter unless everything worked | |
1146 *info_ptr = ret; | |
1147 | |
1148 return JVMTI_ERROR_NONE; | |
1149 } | |
1150 | |
1151 ResourceTracker::ResourceTracker(JvmtiEnv* env) { | |
1152 _env = env; | |
6197 | 1153 _allocations = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<unsigned char*>(20, true); |
0 | 1154 _failed = false; |
1155 } | |
1156 ResourceTracker::~ResourceTracker() { | |
1157 if (_failed) { | |
1158 for (int i=0; i<_allocations->length(); i++) { | |
1159 _env->deallocate(_allocations->at(i)); | |
1160 } | |
1161 } | |
1162 delete _allocations; | |
1163 } | |
1164 | |
1165 jvmtiError ResourceTracker::allocate(jlong size, unsigned char** mem_ptr) { | |
1166 unsigned char *ptr; | |
1167 jvmtiError err = _env->allocate(size, &ptr); | |
1168 if (err == JVMTI_ERROR_NONE) { | |
1169 _allocations->append(ptr); | |
1170 *mem_ptr = ptr; | |
1171 } else { | |
1172 *mem_ptr = NULL; | |
1173 _failed = true; | |
1174 } | |
1175 return err; | |
1176 } | |
1177 | |
1178 unsigned char* ResourceTracker::allocate(jlong size) { | |
1179 unsigned char* ptr; | |
1180 allocate(size, &ptr); | |
1181 return ptr; | |
1182 } | |
1183 | |
1184 char* ResourceTracker::strdup(const char* str) { | |
1185 char *dup_str = (char*)allocate(strlen(str)+1); | |
1186 if (dup_str != NULL) { | |
1187 strcpy(dup_str, str); | |
1188 } | |
1189 return dup_str; | |
1190 } | |
1191 | |
1192 struct StackInfoNode { | |
1193 struct StackInfoNode *next; | |
1194 jvmtiStackInfo info; | |
1195 }; | |
1196 | |
1197 // Create a jvmtiStackInfo inside a linked list node and create a | |
1198 // buffer for the frame information, both allocated as resource objects. | |
1199 // Fill in both the jvmtiStackInfo and the jvmtiFrameInfo. | |
1200 // Note that either or both of thr and thread_oop | |
1201 // may be null if the thread is new or has exited. | |
1202 void | |
1203 VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) { | |
1204 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
1205 | |
1206 jint state = 0; | |
1207 struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode); | |
1208 jvmtiStackInfo *infop = &(node->info); | |
1209 node->next = head(); | |
1210 set_head(node); | |
1211 infop->frame_count = 0; | |
1212 infop->thread = jt; | |
1213 | |
1214 if (thread_oop != NULL) { | |
1215 // get most state bits | |
1216 state = (jint)java_lang_Thread::get_thread_status(thread_oop); | |
1217 } | |
1218 | |
1219 if (thr != NULL) { // add more state bits if there is a JavaThead to query | |
1220 // same as is_being_ext_suspended() but without locking | |
1221 if (thr->is_ext_suspended() || thr->is_external_suspend()) { | |
1222 state |= JVMTI_THREAD_STATE_SUSPENDED; | |
1223 } | |
1224 JavaThreadState jts = thr->thread_state(); | |
1225 if (jts == _thread_in_native) { | |
1226 state |= JVMTI_THREAD_STATE_IN_NATIVE; | |
1227 } | |
1228 OSThread* osThread = thr->osthread(); | |
1229 if (osThread != NULL && osThread->interrupted()) { | |
1230 state |= JVMTI_THREAD_STATE_INTERRUPTED; | |
1231 } | |
1232 } | |
1233 infop->state = state; | |
1234 | |
1235 if (thr != NULL || (state & JVMTI_THREAD_STATE_ALIVE) != 0) { | |
1236 infop->frame_buffer = NEW_RESOURCE_ARRAY(jvmtiFrameInfo, max_frame_count()); | |
1237 env()->get_stack_trace(thr, 0, max_frame_count(), | |
1238 infop->frame_buffer, &(infop->frame_count)); | |
1239 } else { | |
1240 infop->frame_buffer = NULL; | |
1241 infop->frame_count = 0; | |
1242 } | |
1243 _frame_count_total += infop->frame_count; | |
1244 } | |
1245 | |
1246 // Based on the stack information in the linked list, allocate memory | |
1247 // block to return and fill it from the info in the linked list. | |
1248 void | |
1249 VM_GetMultipleStackTraces::allocate_and_fill_stacks(jint thread_count) { | |
1250 // do I need to worry about alignment issues? | |
1251 jlong alloc_size = thread_count * sizeof(jvmtiStackInfo) | |
1252 + _frame_count_total * sizeof(jvmtiFrameInfo); | |
1253 env()->allocate(alloc_size, (unsigned char **)&_stack_info); | |
1254 | |
1255 // pointers to move through the newly allocated space as it is filled in | |
1256 jvmtiStackInfo *si = _stack_info + thread_count; // bottom of stack info | |
1257 jvmtiFrameInfo *fi = (jvmtiFrameInfo *)si; // is the top of frame info | |
1258 | |
1259 // copy information in resource area into allocated buffer | |
1260 // insert stack info backwards since linked list is backwards | |
1261 // insert frame info forwards | |
1262 // walk the StackInfoNodes | |
1263 for (struct StackInfoNode *sin = head(); sin != NULL; sin = sin->next) { | |
1264 jint frame_count = sin->info.frame_count; | |
1265 size_t frames_size = frame_count * sizeof(jvmtiFrameInfo); | |
1266 --si; | |
1267 memcpy(si, &(sin->info), sizeof(jvmtiStackInfo)); | |
1268 if (frames_size == 0) { | |
1269 si->frame_buffer = NULL; | |
1270 } else { | |
1271 memcpy(fi, sin->info.frame_buffer, frames_size); | |
1272 si->frame_buffer = fi; // point to the new allocated copy of the frames | |
1273 fi += frame_count; | |
1274 } | |
1275 } | |
1276 assert(si == _stack_info, "the last copied stack info must be the first record"); | |
1277 assert((unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size, | |
1278 "the last copied frame info must be the last record"); | |
1279 } | |
1280 | |
1281 | |
1282 void | |
1283 VM_GetThreadListStackTraces::doit() { | |
1284 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
1285 | |
1286 ResourceMark rm; | |
1287 for (int i = 0; i < _thread_count; ++i) { | |
1288 jthread jt = _thread_list[i]; | |
1289 oop thread_oop = JNIHandles::resolve_external_guard(jt); | |
1142 | 1290 if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) { |
0 | 1291 set_result(JVMTI_ERROR_INVALID_THREAD); |
1292 return; | |
1293 } | |
1294 fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop); | |
1295 } | |
1296 allocate_and_fill_stacks(_thread_count); | |
1297 } | |
1298 | |
1299 void | |
1300 VM_GetAllStackTraces::doit() { | |
1301 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); | |
1302 | |
1303 ResourceMark rm; | |
1304 _final_thread_count = 0; | |
1305 for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) { | |
1306 oop thread_oop = jt->threadObj(); | |
1307 if (thread_oop != NULL && | |
1308 !jt->is_exiting() && | |
1309 java_lang_Thread::is_alive(thread_oop) && | |
1310 !jt->is_hidden_from_external_view()) { | |
1311 ++_final_thread_count; | |
1312 // Handle block of the calling thread is used to create local refs. | |
1313 fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop), | |
1314 jt, thread_oop); | |
1315 } | |
1316 } | |
1317 allocate_and_fill_stacks(_final_thread_count); | |
1318 } | |
1319 | |
1320 // Verifies that the top frame is a java frame in an expected state. | |
1321 // Deoptimizes frame if needed. | |
1322 // Checks that the frame method signature matches the return type (tos). | |
1323 // HandleMark must be defined in the caller only. | |
1324 // It is to keep a ret_ob_h handle alive after return to the caller. | |
1325 jvmtiError | |
1326 JvmtiEnvBase::check_top_frame(JavaThread* current_thread, JavaThread* java_thread, | |
1327 jvalue value, TosState tos, Handle* ret_ob_h) { | |
1328 ResourceMark rm(current_thread); | |
1329 | |
1330 vframe *vf = vframeFor(java_thread, 0); | |
1331 NULL_CHECK(vf, JVMTI_ERROR_NO_MORE_FRAMES); | |
1332 | |
1333 javaVFrame *jvf = (javaVFrame*) vf; | |
1334 if (!vf->is_java_frame() || jvf->method()->is_native()) { | |
1335 return JVMTI_ERROR_OPAQUE_FRAME; | |
1336 } | |
1337 | |
1338 // If the frame is a compiled one, need to deoptimize it. | |
1339 if (vf->is_compiled_frame()) { | |
1340 if (!vf->fr().can_be_deoptimized()) { | |
1341 return JVMTI_ERROR_OPAQUE_FRAME; | |
1342 } | |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1552
diff
changeset
|
1343 Deoptimization::deoptimize_frame(java_thread, jvf->fr().id()); |
0 | 1344 } |
1345 | |
1346 // Get information about method return type | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1988
diff
changeset
|
1347 Symbol* signature = jvf->method()->signature(); |
0 | 1348 |
1349 ResultTypeFinder rtf(signature); | |
1350 TosState fr_tos = as_TosState(rtf.type()); | |
1351 if (fr_tos != tos) { | |
1352 if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) { | |
1353 return JVMTI_ERROR_TYPE_MISMATCH; | |
1354 } | |
1355 } | |
1356 | |
1357 // Check that the jobject class matches the return type signature. | |
1358 jobject jobj = value.l; | |
1359 if (tos == atos && jobj != NULL) { // NULL reference is allowed | |
1360 Handle ob_h = Handle(current_thread, JNIHandles::resolve_external_guard(jobj)); | |
1361 NULL_CHECK(ob_h, JVMTI_ERROR_INVALID_OBJECT); | |
1362 KlassHandle ob_kh = KlassHandle(current_thread, ob_h()->klass()); | |
1363 NULL_CHECK(ob_kh, JVMTI_ERROR_INVALID_OBJECT); | |
1364 | |
1365 // Method return type signature. | |
1366 char* ty_sign = 1 + strchr(signature->as_C_string(), ')'); | |
1367 | |
1368 if (!VM_GetOrSetLocal::is_assignable(ty_sign, Klass::cast(ob_kh()), current_thread)) { | |
1369 return JVMTI_ERROR_TYPE_MISMATCH; | |
1370 } | |
1371 *ret_ob_h = ob_h; | |
1372 } | |
1373 return JVMTI_ERROR_NONE; | |
1374 } /* end check_top_frame */ | |
1375 | |
1376 | |
1377 // ForceEarlyReturn<type> follows the PopFrame approach in many aspects. | |
1378 // Main difference is on the last stage in the interpreter. | |
1379 // The PopFrame stops method execution to continue execution | |
1380 // from the same method call instruction. | |
1381 // The ForceEarlyReturn forces return from method so the execution | |
1382 // continues at the bytecode following the method call. | |
1383 | |
1384 // Threads_lock NOT held, java_thread not protected by lock | |
1385 // java_thread - pre-checked | |
1386 | |
1387 jvmtiError | |
1388 JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) { | |
1389 JavaThread* current_thread = JavaThread::current(); | |
1390 HandleMark hm(current_thread); | |
1391 uint32_t debug_bits = 0; | |
1392 | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1393 // retrieve or create the state |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1394 JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread); |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1395 if (state == NULL) { |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1396 return JVMTI_ERROR_THREAD_NOT_ALIVE; |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1397 } |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
470
diff
changeset
|
1398 |
0 | 1399 // Check if java_thread is fully suspended |
1400 if (!is_thread_fully_suspended(java_thread, | |
1401 true /* wait for suspend completion */, | |
1402 &debug_bits)) { | |
1403 return JVMTI_ERROR_THREAD_NOT_SUSPENDED; | |
1404 } | |
1405 | |
1406 // Check to see if a ForceEarlyReturn was already in progress | |
1407 if (state->is_earlyret_pending()) { | |
1408 // Probably possible for JVMTI clients to trigger this, but the | |
1409 // JPDA backend shouldn't allow this to happen | |
1410 return JVMTI_ERROR_INTERNAL; | |
1411 } | |
1412 { | |
1413 // The same as for PopFrame. Workaround bug: | |
1414 // 4812902: popFrame hangs if the method is waiting at a synchronize | |
1415 // Catch this condition and return an error to avoid hanging. | |
1416 // Now JVMTI spec allows an implementation to bail out with an opaque | |
1417 // frame error. | |
1418 OSThread* osThread = java_thread->osthread(); | |
1419 if (osThread->get_state() == MONITOR_WAIT) { | |
1420 return JVMTI_ERROR_OPAQUE_FRAME; | |
1421 } | |
1422 } | |
1423 Handle ret_ob_h = Handle(); | |
1424 jvmtiError err = check_top_frame(current_thread, java_thread, value, tos, &ret_ob_h); | |
1425 if (err != JVMTI_ERROR_NONE) { | |
1426 return err; | |
1427 } | |
1428 assert(tos != atos || value.l == NULL || ret_ob_h() != NULL, | |
1429 "return object oop must not be NULL if jobject is not NULL"); | |
1430 | |
1431 // Update the thread state to reflect that the top frame must be | |
1432 // forced to return. | |
1433 // The current frame will be returned later when the suspended | |
1434 // thread is resumed and right before returning from VM to Java. | |
1435 // (see call_VM_base() in assembler_<cpu>.cpp). | |
1436 | |
1437 state->set_earlyret_pending(); | |
1438 state->set_earlyret_oop(ret_ob_h()); | |
1439 state->set_earlyret_value(value, tos); | |
1440 | |
1441 // Set pending step flag for this early return. | |
1442 // It is cleared when next step event is posted. | |
1443 state->set_pending_step_for_earlyret(); | |
1444 | |
1445 return JVMTI_ERROR_NONE; | |
1446 } /* end force_early_return */ | |
1447 | |
1448 void | |
1449 JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) { | |
1450 if ( _error != JVMTI_ERROR_NONE) { | |
1451 // Error occurred in previous iteration so no need to add | |
1452 // to the list. | |
1453 return; | |
1454 } | |
1455 if (mon->owner() == _java_thread ) { | |
1456 // Filter out on stack monitors collected during stack walk. | |
1457 oop obj = (oop)mon->object(); | |
1458 bool found = false; | |
1459 for (int j = 0; j < _owned_monitors_list->length(); j++) { | |
1460 jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor; | |
1461 oop check = JNIHandles::resolve(jobj); | |
1462 if (check == obj) { | |
1463 // On stack monitor already collected during the stack walk. | |
1464 found = true; | |
1465 break; | |
1466 } | |
1467 } | |
1468 if (found == false) { | |
1469 // This is off stack monitor (e.g. acquired via jni MonitorEnter). | |
1470 jvmtiError err; | |
1471 jvmtiMonitorStackDepthInfo *jmsdi; | |
1472 err = _env->allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi); | |
1473 if (err != JVMTI_ERROR_NONE) { | |
1474 _error = err; | |
1475 return; | |
1476 } | |
1477 Handle hobj(obj); | |
1478 jmsdi->monitor = _env->jni_reference(_calling_thread, hobj); | |
1479 // stack depth is unknown for this monitor. | |
1480 jmsdi->stack_depth = -1; | |
1481 _owned_monitors_list->append(jmsdi); | |
1482 } | |
1483 } | |
1484 } | |
1485 | |
1486 #endif // !JVMTI_KERNEL |