Bug Summary

File:jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp
Warning:line 1047, column 5
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name jvmtiEnvBase.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp

/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp

1/*
2 * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "classfile/classLoaderDataGraph.hpp"
27#include "classfile/javaClasses.hpp"
28#include "classfile/moduleEntry.hpp"
29#include "jvmtifiles/jvmtiEnv.hpp"
30#include "memory/iterator.hpp"
31#include "memory/resourceArea.hpp"
32#include "oops/klass.inline.hpp"
33#include "oops/objArrayKlass.hpp"
34#include "oops/objArrayOop.hpp"
35#include "oops/oop.inline.hpp"
36#include "oops/oopHandle.inline.hpp"
37#include "prims/jvmtiEnvBase.hpp"
38#include "prims/jvmtiEventController.inline.hpp"
39#include "prims/jvmtiExtensions.hpp"
40#include "prims/jvmtiImpl.hpp"
41#include "prims/jvmtiManageCapabilities.hpp"
42#include "prims/jvmtiTagMap.hpp"
43#include "prims/jvmtiThreadState.inline.hpp"
44#include "runtime/deoptimization.hpp"
45#include "runtime/frame.inline.hpp"
46#include "runtime/handles.inline.hpp"
47#include "runtime/interfaceSupport.inline.hpp"
48#include "runtime/jfieldIDWorkaround.hpp"
49#include "runtime/jniHandles.inline.hpp"
50#include "runtime/objectMonitor.inline.hpp"
51#include "runtime/osThread.hpp"
52#include "runtime/signature.hpp"
53#include "runtime/thread.inline.hpp"
54#include "runtime/threadSMR.hpp"
55#include "runtime/vframe.inline.hpp"
56#include "runtime/vframe_hp.hpp"
57#include "runtime/vmThread.hpp"
58#include "runtime/vmOperations.hpp"
59
60
61///////////////////////////////////////////////////////////////
62//
63// JvmtiEnvBase
64//
65
66JvmtiEnvBase* JvmtiEnvBase::_head_environment = NULL__null;
67
68bool JvmtiEnvBase::_globally_initialized = false;
69volatile bool JvmtiEnvBase::_needs_clean_up = false;
70
71jvmtiPhase JvmtiEnvBase::_phase = JVMTI_PHASE_PRIMORDIAL;
72
73volatile int JvmtiEnvBase::_dying_thread_env_iteration_count = 0;
74
75extern jvmtiInterface_1_ jvmti_Interface;
76extern jvmtiInterface_1_ jvmtiTrace_Interface;
77
78
79// perform initializations that must occur before any JVMTI environments
80// are released but which should only be initialized once (no matter
81// how many environments are created).
82void
83JvmtiEnvBase::globally_initialize() {
84 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 84, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
85 assert(_globally_initialized == false, "bad call")do { if (!(_globally_initialized == false)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 85, "assert(" "_globally_initialized == false" ") failed", "bad call"
); ::breakpoint(); } } while (0)
;
86
87 JvmtiManageCapabilities::initialize();
88
89 // register extension functions and events
90 JvmtiExtensions::register_extensions();
91
92#ifdef JVMTI_TRACE
93 JvmtiTrace::initialize();
94#endif
95
96 _globally_initialized = true;
97}
98
99
100void
101JvmtiEnvBase::initialize() {
102 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 102, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
103
104 // Add this environment to the end of the environment list (order is important)
105 {
106 // This block of code must not contain any safepoints, as list deallocation
107 // (which occurs at a safepoint) cannot occur simultaneously with this list
108 // addition. Note: NoSafepointVerifier cannot, currently, be used before
109 // threads exist.
110 JvmtiEnvIterator it;
111 JvmtiEnvBase *previous_env = NULL__null;
112 for (JvmtiEnvBase* env = it.first(); env != NULL__null; env = it.next(env)) {
113 previous_env = env;
114 }
115 if (previous_env == NULL__null) {
116 _head_environment = this;
117 } else {
118 previous_env->set_next_environment(this);
119 }
120 }
121
122 if (_globally_initialized == false) {
123 globally_initialize();
124 }
125}
126
127jvmtiPhase
128JvmtiEnvBase::phase() {
129 // For the JVMTI environments possessed the can_generate_early_vmstart:
130 // replace JVMTI_PHASE_PRIMORDIAL with JVMTI_PHASE_START
131 if (_phase == JVMTI_PHASE_PRIMORDIAL &&
132 JvmtiExport::early_vmstart_recorded() &&
133 early_vmstart_env()) {
134 return JVMTI_PHASE_START;
135 }
136 return _phase; // Normal case
137}
138
139bool
140JvmtiEnvBase::is_valid() {
141 jint value = 0;
142
143 // This object might not be a JvmtiEnvBase so we can't assume
144 // the _magic field is properly aligned. Get the value in a safe
145 // way and then check against JVMTI_MAGIC.
146
147 switch (sizeof(_magic)) {
148 case 2:
149 value = Bytes::get_native_u2((address)&_magic);
150 break;
151
152 case 4:
153 value = Bytes::get_native_u4((address)&_magic);
154 break;
155
156 case 8:
157 value = Bytes::get_native_u8((address)&_magic);
158 break;
159
160 default:
161 guarantee(false, "_magic field is an unexpected size")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 161, "guarantee(" "false" ") failed", "_magic field is an unexpected size"
); ::breakpoint(); } } while (0)
;
162 }
163
164 return value == JVMTI_MAGIC;
165}
166
167
168bool
169JvmtiEnvBase::use_version_1_0_semantics() {
170 int major, minor, micro;
171
172 JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
173 return major == 1 && minor == 0; // micro version doesn't matter here
174}
175
176
177bool
178JvmtiEnvBase::use_version_1_1_semantics() {
179 int major, minor, micro;
180
181 JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
182 return major == 1 && minor == 1; // micro version doesn't matter here
183}
184
185bool
186JvmtiEnvBase::use_version_1_2_semantics() {
187 int major, minor, micro;
188
189 JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
190 return major == 1 && minor == 2; // micro version doesn't matter here
191}
192
193
194JvmtiEnvBase::JvmtiEnvBase(jint version) : _env_event_enable() {
195 _version = version;
196 _env_local_storage = NULL__null;
197 _tag_map = NULL__null;
198 _native_method_prefix_count = 0;
199 _native_method_prefixes = NULL__null;
200 _next = NULL__null;
201 _class_file_load_hook_ever_enabled = false;
202
203 // Moot since ClassFileLoadHook not yet enabled.
204 // But "true" will give a more predictable ClassFileLoadHook behavior
205 // for environment creation during ClassFileLoadHook.
206 _is_retransformable = true;
207
208 // all callbacks initially NULL
209 memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks));
210
211 // all capabilities initially off
212 memset(&_current_capabilities, 0, sizeof(_current_capabilities));
213
214 // all prohibited capabilities initially off
215 memset(&_prohibited_capabilities, 0, sizeof(_prohibited_capabilities));
216
217 _magic = JVMTI_MAGIC;
218
219 JvmtiEventController::env_initialize((JvmtiEnv*)this);
220
221#ifdef JVMTI_TRACE
222 _jvmti_external.functions = TraceJVMTI != NULL__null ? &jvmtiTrace_Interface : &jvmti_Interface;
223#else
224 _jvmti_external.functions = &jvmti_Interface;
225#endif
226}
227
228
229void
230JvmtiEnvBase::dispose() {
231
232#ifdef JVMTI_TRACE
233 JvmtiTrace::shutdown();
234#endif
235
236 // Dispose of event info and let the event controller call us back
237 // in a locked state (env_dispose, below)
238 JvmtiEventController::env_dispose(this);
239}
240
241void
242JvmtiEnvBase::env_dispose() {
243 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 243, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
244
245 // We have been entered with all events disabled on this environment.
246 // A race to re-enable events (by setting callbacks) is prevented by
247 // checking for a valid environment when setting callbacks (while
248 // holding the JvmtiThreadState_lock).
249
250 // Mark as invalid.
251 _magic = DISPOSED_MAGIC;
252
253 // Relinquish all capabilities.
254 jvmtiCapabilities *caps = get_capabilities();
255 JvmtiManageCapabilities::relinquish_capabilities(caps, caps, caps);
256
257 // Same situation as with events (see above)
258 set_native_method_prefixes(0, NULL__null);
259
260 JvmtiTagMap* tag_map_to_clear = tag_map_acquire();
261 // A tag map can be big, clear it now to save memory until
262 // the destructor runs.
263 if (tag_map_to_clear != NULL__null) {
264 tag_map_to_clear->clear();
265 }
266
267 _needs_clean_up = true;
268}
269
270
271JvmtiEnvBase::~JvmtiEnvBase() {
272 assert(SafepointSynchronize::is_at_safepoint(), "sanity check")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 272, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "sanity check"); ::breakpoint(); } } while (0)
;
273
274 // There is a small window of time during which the tag map of a
275 // disposed environment could have been reallocated.
276 // Make sure it is gone.
277 JvmtiTagMap* tag_map_to_deallocate = _tag_map;
278 set_tag_map(NULL__null);
279 // A tag map can be big, deallocate it now
280 if (tag_map_to_deallocate != NULL__null) {
281 delete tag_map_to_deallocate;
282 }
283
284 _magic = BAD_MAGIC;
285}
286
287
288void
289JvmtiEnvBase::periodic_clean_up() {
290 assert(SafepointSynchronize::is_at_safepoint(), "sanity check")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 290, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "sanity check"); ::breakpoint(); } } while (0)
;
291
292 // JvmtiEnvBase reference is saved in JvmtiEnvThreadState. So
293 // clean up JvmtiThreadState before deleting JvmtiEnv pointer.
294 JvmtiThreadState::periodic_clean_up();
295
296 // Unlink all invalid environments from the list of environments
297 // and deallocate them
298 JvmtiEnvIterator it;
299 JvmtiEnvBase* previous_env = NULL__null;
300 JvmtiEnvBase* env = it.first();
301 while (env != NULL__null) {
302 if (env->is_valid()) {
303 previous_env = env;
304 env = it.next(env);
305 } else {
306 // This one isn't valid, remove it from the list and deallocate it
307 JvmtiEnvBase* defunct_env = env;
308 env = it.next(env);
309 if (previous_env == NULL__null) {
310 _head_environment = env;
311 } else {
312 previous_env->set_next_environment(env);
313 }
314 delete defunct_env;
315 }
316 }
317
318}
319
320
321void
322JvmtiEnvBase::check_for_periodic_clean_up() {
323 assert(SafepointSynchronize::is_at_safepoint(), "sanity check")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 323, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "sanity check"); ::breakpoint(); } } while (0)
;
324
325 class ThreadInsideIterationClosure: public ThreadClosure {
326 private:
327 bool _inside;
328 public:
329 ThreadInsideIterationClosure() : _inside(false) {};
330
331 void do_thread(Thread* thread) {
332 _inside |= thread->is_inside_jvmti_env_iteration();
333 }
334
335 bool is_inside_jvmti_env_iteration() {
336 return _inside;
337 }
338 };
339
340 if (_needs_clean_up) {
341 // Check if we are currently iterating environment,
342 // deallocation should not occur if we are
343 ThreadInsideIterationClosure tiic;
344 Threads::threads_do(&tiic);
345 if (!tiic.is_inside_jvmti_env_iteration() &&
346 !is_inside_dying_thread_env_iteration()) {
347 _needs_clean_up = false;
348 JvmtiEnvBase::periodic_clean_up();
349 }
350 }
351}
352
353
354void
355JvmtiEnvBase::record_first_time_class_file_load_hook_enabled() {
356 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 357, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
357 "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 357, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
358
359 if (!_class_file_load_hook_ever_enabled) {
360 _class_file_load_hook_ever_enabled = true;
361
362 if (get_capabilities()->can_retransform_classes) {
363 _is_retransformable = true;
364 } else {
365 _is_retransformable = false;
366
367 // cannot add retransform capability after ClassFileLoadHook has been enabled
368 get_prohibited_capabilities()->can_retransform_classes = 1;
369 }
370 }
371}
372
373
374void
375JvmtiEnvBase::record_class_file_load_hook_enabled() {
376 if (!_class_file_load_hook_ever_enabled) {
377 if (Threads::number_of_threads() == 0) {
378 record_first_time_class_file_load_hook_enabled();
379 } else {
380 MutexLocker mu(JvmtiThreadState_lock);
381 record_first_time_class_file_load_hook_enabled();
382 }
383 }
384}
385
386
387jvmtiError
388JvmtiEnvBase::set_native_method_prefixes(jint prefix_count, char** prefixes) {
389 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 390, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
390 "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 390, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
391
392 int old_prefix_count = get_native_method_prefix_count();
393 char **old_prefixes = get_native_method_prefixes();
394
395 // allocate and install the new prefixex
396 if (prefix_count == 0 || !is_valid()) {
397 _native_method_prefix_count = 0;
398 _native_method_prefixes = NULL__null;
399 } else {
400 // there are prefixes, allocate an array to hold them, and fill it
401 char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*), mtInternal);
402 if (new_prefixes == NULL__null) {
403 return JVMTI_ERROR_OUT_OF_MEMORY;
404 }
405 for (int i = 0; i < prefix_count; i++) {
406 char* prefix = prefixes[i];
407 if (prefix == NULL__null) {
408 for (int j = 0; j < (i-1); j++) {
409 os::free(new_prefixes[j]);
410 }
411 os::free(new_prefixes);
412 return JVMTI_ERROR_NULL_POINTER;
413 }
414 prefix = os::strdup(prefixes[i]);
415 if (prefix == NULL__null) {
416 for (int j = 0; j < (i-1); j++) {
417 os::free(new_prefixes[j]);
418 }
419 os::free(new_prefixes);
420 return JVMTI_ERROR_OUT_OF_MEMORY;
421 }
422 new_prefixes[i] = prefix;
423 }
424 _native_method_prefix_count = prefix_count;
425 _native_method_prefixes = new_prefixes;
426 }
427
428 // now that we know the new prefixes have been successfully installed we can
429 // safely remove the old ones
430 if (old_prefix_count != 0) {
431 for (int i = 0; i < old_prefix_count; i++) {
432 os::free(old_prefixes[i]);
433 }
434 os::free(old_prefixes);
435 }
436
437 return JVMTI_ERROR_NONE;
438}
439
440
441// Collect all the prefixes which have been set in any JVM TI environments
442// by the SetNativeMethodPrefix(es) functions. Be sure to maintain the
443// order of environments and the order of prefixes within each environment.
444// Return in a resource allocated array.
445char**
446JvmtiEnvBase::get_all_native_method_prefixes(int* count_ptr) {
447 assert(Threads::number_of_threads() == 0 ||do { if (!(Threads::number_of_threads() == 0 || SafepointSynchronize
::is_at_safepoint() || JvmtiThreadState_lock->is_locked())
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 450, "assert(" "Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
448 SafepointSynchronize::is_at_safepoint() ||do { if (!(Threads::number_of_threads() == 0 || SafepointSynchronize
::is_at_safepoint() || JvmtiThreadState_lock->is_locked())
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 450, "assert(" "Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
449 JvmtiThreadState_lock->is_locked(),do { if (!(Threads::number_of_threads() == 0 || SafepointSynchronize
::is_at_safepoint() || JvmtiThreadState_lock->is_locked())
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 450, "assert(" "Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
450 "sanity check")do { if (!(Threads::number_of_threads() == 0 || SafepointSynchronize
::is_at_safepoint() || JvmtiThreadState_lock->is_locked())
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 450, "assert(" "Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint() || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
451
452 int total_count = 0;
453 GrowableArray<char*>* prefix_array =new GrowableArray<char*>(5);
454
455 JvmtiEnvIterator it;
456 for (JvmtiEnvBase* env = it.first(); env != NULL__null; env = it.next(env)) {
457 int prefix_count = env->get_native_method_prefix_count();
458 char** prefixes = env->get_native_method_prefixes();
459 for (int j = 0; j < prefix_count; j++) {
460 // retrieve a prefix and so that it is safe against asynchronous changes
461 // copy it into the resource area
462 char* prefix = prefixes[j];
463 char* prefix_copy = NEW_RESOURCE_ARRAY(char, strlen(prefix)+1)(char*) resource_allocate_bytes((strlen(prefix)+1) * sizeof(char
))
;
464 strcpy(prefix_copy, prefix);
465 prefix_array->at_put_grow(total_count++, prefix_copy);
466 }
467 }
468
469 char** all_prefixes = NEW_RESOURCE_ARRAY(char*, total_count)(char**) resource_allocate_bytes((total_count) * sizeof(char*
))
;
470 char** p = all_prefixes;
471 for (int i = 0; i < total_count; ++i) {
472 *p++ = prefix_array->at(i);
473 }
474 *count_ptr = total_count;
475 return all_prefixes;
476}
477
478void
479JvmtiEnvBase::set_event_callbacks(const jvmtiEventCallbacks* callbacks,
480 jint size_of_callbacks) {
481 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check")do { if (!(Threads::number_of_threads() == 0 || JvmtiThreadState_lock
->is_locked())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 481, "assert(" "Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked()"
") failed", "sanity check"); ::breakpoint(); } } while (0)
;
482
483 size_t byte_cnt = sizeof(jvmtiEventCallbacks);
484
485 // clear in either case to be sure we got any gap between sizes
486 memset(&_event_callbacks, 0, byte_cnt);
487
488 // Now that JvmtiThreadState_lock is held, prevent a possible race condition where events
489 // are re-enabled by a call to set event callbacks where the DisposeEnvironment
490 // occurs after the boiler-plate environment check and before the lock is acquired.
491 if (callbacks != NULL__null && is_valid()) {
492 if (size_of_callbacks < (jint)byte_cnt) {
493 byte_cnt = size_of_callbacks;
494 }
495 memcpy(&_event_callbacks, callbacks, byte_cnt);
496 }
497}
498
499
500// In the fullness of time, all users of the method should instead
501// directly use allocate, besides being cleaner and faster, this will
502// mean much better out of memory handling
503unsigned char *
504JvmtiEnvBase::jvmtiMalloc(jlong size) {
505 unsigned char* mem = NULL__null;
506 jvmtiError result = allocate(size, &mem);
507 assert(result == JVMTI_ERROR_NONE, "Allocate failed")do { if (!(result == JVMTI_ERROR_NONE)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 507, "assert(" "result == JVMTI_ERROR_NONE" ") failed", "Allocate failed"
); ::breakpoint(); } } while (0)
;
508 return mem;
509}
510
511
512// Handle management
513
514jobject JvmtiEnvBase::jni_reference(Handle hndl) {
515 return JNIHandles::make_local(hndl());
516}
517
518jobject JvmtiEnvBase::jni_reference(JavaThread *thread, Handle hndl) {
519 return JNIHandles::make_local(thread, hndl());
520}
521
522void JvmtiEnvBase::destroy_jni_reference(jobject jobj) {
523 JNIHandles::destroy_local(jobj);
524}
525
526void JvmtiEnvBase::destroy_jni_reference(JavaThread *thread, jobject jobj) {
527 JNIHandles::destroy_local(jobj); // thread is unused.
528}
529
530//
531// Threads
532//
533
534jobject *
535JvmtiEnvBase::new_jobjectArray(int length, Handle *handles) {
536 if (length == 0) {
537 return NULL__null;
538 }
539
540 jobject *objArray = (jobject *) jvmtiMalloc(sizeof(jobject) * length);
541 NULL_CHECK(objArray, NULL)if ((objArray) == __null) { return (__null); };
542
543 for (int i=0; i<length; i++) {
544 objArray[i] = jni_reference(handles[i]);
545 }
546 return objArray;
547}
548
549jthread *
550JvmtiEnvBase::new_jthreadArray(int length, Handle *handles) {
551 return (jthread *) new_jobjectArray(length,handles);
552}
553
554jthreadGroup *
555JvmtiEnvBase::new_jthreadGroupArray(int length, Handle *handles) {
556 return (jthreadGroup *) new_jobjectArray(length,handles);
557}
558
559// return the vframe on the specified thread and depth, NULL if no such frame
560// The thread and the oops in the returned vframe might not have been process.
561vframe*
562JvmtiEnvBase::vframeForNoProcess(JavaThread* java_thread, jint depth) {
563 if (!java_thread->has_last_Java_frame()) {
564 return NULL__null;
565 }
566 RegisterMap reg_map(java_thread, true /* update_map */, false /* process_frames */);
567 vframe *vf = java_thread->last_java_vframe(&reg_map);
568 int d = 0;
569 while ((vf != NULL__null) && (d < depth)) {
570 vf = vf->java_sender();
571 d++;
572 }
573 return vf;
574}
575
576
577//
578// utilities: JNI objects
579//
580
581
582jclass
583JvmtiEnvBase::get_jni_class_non_null(Klass* k) {
584 assert(k != NULL, "k != NULL")do { if (!(k != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 584, "assert(" "k != __null" ") failed", "k != NULL"); ::breakpoint
(); } } while (0)
;
585 Thread *thread = Thread::current();
586 return (jclass)jni_reference(Handle(thread, k->java_mirror()));
587}
588
589//
590// Field Information
591//
592
593bool
594JvmtiEnvBase::get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd) {
595 if (!jfieldIDWorkaround::is_valid_jfieldID(k, field)) {
596 return false;
597 }
598 bool found = false;
599 if (jfieldIDWorkaround::is_static_jfieldID(field)) {
600 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field);
601 found = id->find_local_field(fd);
602 } else {
603 // Non-static field. The fieldID is really the offset of the field within the object.
604 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field);
605 found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, fd);
606 }
607 return found;
608}
609
610//
611// Object Monitor Information
612//
613
614//
615// Count the number of objects for a lightweight monitor. The hobj
616// parameter is object that owns the monitor so this routine will
617// count the number of times the same object was locked by frames
618// in java_thread.
619//
620jint
621JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
622 jint ret = 0;
623 if (!java_thread->has_last_Java_frame()) {
624 return ret; // no Java frames so no monitors
625 }
626
627 Thread* current_thread = Thread::current();
628 ResourceMark rm(current_thread);
629 HandleMark hm(current_thread);
630 RegisterMap reg_map(java_thread);
631
632 for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL__null;
633 jvf = jvf->java_sender()) {
634 GrowableArray<MonitorInfo*>* mons = jvf->monitors();
635 if (!mons->is_empty()) {
636 for (int i = 0; i < mons->length(); i++) {
637 MonitorInfo *mi = mons->at(i);
638 if (mi->owner_is_scalar_replaced()) continue;
639
640 // see if owner of the monitor is our object
641 if (mi->owner() != NULL__null && mi->owner() == hobj()) {
642 ret++;
643 }
644 }
645 }
646 }
647 return ret;
648}
649
650
651
652jvmtiError
653JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
654 Thread *current_thread = Thread::current();
655 assert(java_thread->is_handshake_safe_for(current_thread),do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 656, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
656 "call by myself or at handshake")do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 656, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
;
657 oop obj = NULL__null;
658 // The ObjectMonitor* can't be async deflated since we are either
659 // at a safepoint or the calling thread is operating on itself so
660 // it cannot leave the underlying wait()/enter() call.
661 ObjectMonitor *mon = java_thread->current_waiting_monitor();
662 if (mon == NULL__null) {
663 // thread is not doing an Object.wait() call
664 mon = java_thread->current_pending_monitor();
665 if (mon != NULL__null) {
666 // The thread is trying to enter() an ObjectMonitor.
667 obj = mon->object();
668 assert(obj != NULL, "ObjectMonitor should have a valid object!")do { if (!(obj != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 668, "assert(" "obj != __null" ") failed", "ObjectMonitor should have a valid object!"
); ::breakpoint(); } } while (0)
;
669 }
670 // implied else: no contended ObjectMonitor
671 } else {
672 // thread is doing an Object.wait() call
673 obj = mon->object();
674 assert(obj != NULL, "Object.wait() should have an object")do { if (!(obj != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 674, "assert(" "obj != __null" ") failed", "Object.wait() should have an object"
); ::breakpoint(); } } while (0)
;
675 }
676
677 if (obj == NULL__null) {
678 *monitor_ptr = NULL__null;
679 } else {
680 HandleMark hm(current_thread);
681 Handle hobj(current_thread, obj);
682 *monitor_ptr = jni_reference(calling_thread, hobj);
683 }
684 return JVMTI_ERROR_NONE;
685}
686
687
688jvmtiError
689JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
690 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
691 // Note:
692 // calling_thread is the thread that requested the list of monitors for java_thread.
693 // java_thread is the thread owning the monitors.
694 // current_thread is the thread executing this code, can be a non-JavaThread (e.g. VM Thread).
695 // And they all may be different threads.
696 jvmtiError err = JVMTI_ERROR_NONE;
697 Thread *current_thread = Thread::current();
698 assert(java_thread->is_handshake_safe_for(current_thread),do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 699, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
699 "call by myself or at handshake")do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 699, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
;
700
701 if (java_thread->has_last_Java_frame()) {
702 ResourceMark rm(current_thread);
703 HandleMark hm(current_thread);
704 RegisterMap reg_map(java_thread);
705
706 int depth = 0;
707 for (javaVFrame *jvf = java_thread->last_java_vframe(&reg_map); jvf != NULL__null;
708 jvf = jvf->java_sender()) {
709 if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) { // check for stack too deep
710 // add locked objects for this frame into list
711 err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
712 if (err != JVMTI_ERROR_NONE) {
713 return err;
714 }
715 }
716 }
717 }
718
719 // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
720 JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
721 ObjectSynchronizer::monitors_iterate(&jmc, java_thread);
722 err = jmc.error();
723
724 return err;
725}
726
727// Save JNI local handles for any objects that this frame owns.
728jvmtiError
729JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
730 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {
731 jvmtiError err = JVMTI_ERROR_NONE;
732 Thread* current_thread = Thread::current();
733 ResourceMark rm(current_thread);
734 HandleMark hm(current_thread);
735
736 GrowableArray<MonitorInfo*>* mons = jvf->monitors();
737 if (mons->is_empty()) {
738 return err; // this javaVFrame holds no monitors
739 }
740
741 oop wait_obj = NULL__null;
742 {
743 // The ObjectMonitor* can't be async deflated since we are either
744 // at a safepoint or the calling thread is operating on itself so
745 // it cannot leave the underlying wait() call.
746 // Save object of current wait() call (if any) for later comparison.
747 ObjectMonitor *mon = java_thread->current_waiting_monitor();
748 if (mon != NULL__null) {
749 wait_obj = mon->object();
750 }
751 }
752 oop pending_obj = NULL__null;
753 {
754 // The ObjectMonitor* can't be async deflated since we are either
755 // at a safepoint or the calling thread is operating on itself so
756 // it cannot leave the underlying enter() call.
757 // Save object of current enter() call (if any) for later comparison.
758 ObjectMonitor *mon = java_thread->current_pending_monitor();
759 if (mon != NULL__null) {
760 pending_obj = mon->object();
761 }
762 }
763
764 for (int i = 0; i < mons->length(); i++) {
765 MonitorInfo *mi = mons->at(i);
766
767 if (mi->owner_is_scalar_replaced()) continue;
768
769 oop obj = mi->owner();
770 if (obj == NULL__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(Thread::current(), 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
819jvmtiError
820JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
821 jint start_depth, jint max_count,
822 jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
823#ifdef ASSERT1
824 uint32_t debug_bits = 0;
825#endif
826 Thread *current_thread = Thread::current();
827 assert(SafepointSynchronize::is_at_safepoint() ||do { if (!(SafepointSynchronize::is_at_safepoint() || java_thread
->is_handshake_safe_for(current_thread))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 829, "assert(" "SafepointSynchronize::is_at_safepoint() || java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
828 java_thread->is_handshake_safe_for(current_thread),do { if (!(SafepointSynchronize::is_at_safepoint() || java_thread
->is_handshake_safe_for(current_thread))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 829, "assert(" "SafepointSynchronize::is_at_safepoint() || java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
829 "call by myself / at safepoint / at handshake")do { if (!(SafepointSynchronize::is_at_safepoint() || java_thread
->is_handshake_safe_for(current_thread))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 829, "assert(" "SafepointSynchronize::is_at_safepoint() || java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
;
830 int count = 0;
831 if (java_thread->has_last_Java_frame()) {
832 RegisterMap reg_map(java_thread, false /* update_map */, false /* process_frames */);
833 ResourceMark rm(current_thread);
834 javaVFrame *jvf = java_thread->last_java_vframe(&reg_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__null; j++) {
839 jvf = jvf->java_sender();
840 }
841 if (jvf == NULL__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__null;
851 javaVFrame *jvf_prev_prev = NULL__null;
852 int j = 0;
853 while (jvf_cursor != NULL__null) {
854 jvf_prev_prev = jvf_prev;
855 jvf_prev = jvf_cursor;
856 for (j = 0; j > start_depth && jvf_cursor != NULL__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__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__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
895jvmtiError
896JvmtiEnvBase::get_frame_count(JvmtiThreadState *state, jint *count_ptr) {
897 assert((state != NULL),do { if (!((state != __null))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 898, "assert(" "(state != __null)" ") failed", "JavaThread should create JvmtiThreadState before calling this method"
); ::breakpoint(); } } while (0)
898 "JavaThread should create JvmtiThreadState before calling this method")do { if (!((state != __null))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 898, "assert(" "(state != __null)" ") failed", "JavaThread should create JvmtiThreadState before calling this method"
); ::breakpoint(); } } while (0)
;
899 *count_ptr = state->count_frames();
900 return JVMTI_ERROR_NONE;
901}
902
903jvmtiError
904JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth,
905 jmethodID* method_ptr, jlocation* location_ptr) {
906#ifdef ASSERT1
907 uint32_t debug_bits = 0;
908#endif
909 Thread* current_thread = Thread::current();
910 assert(java_thread->is_handshake_safe_for(current_thread),do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 911, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
911 "call by myself or at handshake")do { if (!(java_thread->is_handshake_safe_for(current_thread
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 911, "assert(" "java_thread->is_handshake_safe_for(current_thread)"
") failed", "call by myself or at handshake"); ::breakpoint(
); } } while (0)
;
912 ResourceMark rm(current_thread);
913
914 vframe *vf = vframeForNoProcess(java_thread, depth);
915 if (vf == NULL__null) {
916 return JVMTI_ERROR_NO_MORE_FRAMES;
917 }
918
919 // vframeFor should return a java frame. If it doesn't
920 // it means we've got an internal error and we return the
921 // error in product mode. In debug mode we will instead
922 // attempt to cast the vframe to a javaVFrame and will
923 // cause an assertion/crash to allow further diagnosis.
924#ifdef PRODUCT
925 if (!vf->is_java_frame()) {
926 return JVMTI_ERROR_INTERNAL;
927 }
928#endif
929
930 HandleMark hm(current_thread);
931 javaVFrame *jvf = javaVFrame::cast(vf);
932 Method* method = jvf->method();
933 if (method->is_native()) {
934 *location_ptr = -1;
935 } else {
936 *location_ptr = jvf->bci();
937 }
938 *method_ptr = method->jmethod_id();
939
940 return JVMTI_ERROR_NONE;
941}
942
943
944jvmtiError
945JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
946 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 946, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint"); ::breakpoint(); } } while (0)
;
1
Assuming the condition is false
2
Taking false branch
3
Loop condition is false. Exiting loop
947 Thread* current_thread = VMThread::vm_thread();
948 assert(current_thread == Thread::current(), "must be")do { if (!(current_thread == Thread::current())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 948, "assert(" "current_thread == Thread::current()" ") failed"
, "must be"); ::breakpoint(); } } while (0)
;
4
Assuming the condition is true
5
Taking false branch
6
Loop condition is false. Exiting loop
949
950 HandleMark hm(current_thread);
951 Handle hobj;
952
953 // Check arguments
954 {
955 oop mirror = JNIHandles::resolve_external_guard(object);
956 NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT)if ((mirror) == __null) { return (JVMTI_ERROR_INVALID_OBJECT)
; }
;
7
Calling 'oop::operator=='
10
Returning from 'oop::operator=='
11
Taking false branch
957 NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER)if ((info_ptr) == __null) { return (JVMTI_ERROR_NULL_POINTER)
; }
;
12
Assuming the condition is false
13
Taking false branch
958
959 hobj = Handle(current_thread, mirror);
960 }
961
962 ThreadsListHandle tlh(current_thread);
963 JavaThread *owning_thread = NULL__null;
964 ObjectMonitor *mon = NULL__null;
965 jvmtiMonitorUsage ret = {
14
'ret.waiters' initialized to a null pointer value
966 NULL__null, 0, 0, NULL__null, 0, NULL__null
967 };
968
969 uint32_t debug_bits = 0;
970 // first derive the object's owner and entry_count (if any)
971 {
972 address owner = NULL__null;
973 {
974 markWord mark = hobj()->mark();
975
976 if (!mark.has_monitor()) {
15
Taking false branch
977 // this object has a lightweight monitor
978
979 if (mark.has_locker()) {
980 owner = (address)mark.locker(); // save the address of the Lock word
981 }
982 // implied else: no owner
983 } else {
984 // this object has a heavyweight monitor
985 mon = mark.monitor();
986
987 // The owner field of a heavyweight monitor may be NULL for no
988 // owner, a JavaThread * or it may still be the address of the
989 // Lock word in a JavaThread's stack. A monitor can be inflated
990 // by a non-owning JavaThread, but only the owning JavaThread
991 // can change the owner field from the Lock word to the
992 // JavaThread * and it may not have done that yet.
993 owner = (address)mon->owner();
994 }
995 }
996
997 if (owner
15.1
'owner' is equal to NULL
15.1
'owner' is equal to NULL
15.1
'owner' is equal to NULL
!= NULL__null) {
16
Taking false branch
998 // This monitor is owned so we have to find the owning JavaThread.
999 owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
1000 assert(owning_thread != NULL, "owning JavaThread must not be NULL")do { if (!(owning_thread != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1000, "assert(" "owning_thread != __null" ") failed", "owning JavaThread must not be NULL"
); ::breakpoint(); } } while (0)
;
1001 Handle th(current_thread, owning_thread->threadObj());
1002 ret.owner = (jthread)jni_reference(calling_thread, th);
1003 }
1004
1005 if (owning_thread
16.1
'owning_thread' is equal to NULL
16.1
'owning_thread' is equal to NULL
16.1
'owning_thread' is equal to NULL
!= NULL__null) { // monitor is owned
17
Taking false branch
1006 // The recursions field of a monitor does not reflect recursions
1007 // as lightweight locks before inflating the monitor are not included.
1008 // We have to count the number of recursive monitor entries the hard way.
1009 // We pass a handle to survive any GCs along the way.
1010 ret.entry_count = count_locked_objects(owning_thread, hobj);
1011 }
1012 // implied else: entry_count == 0
1013 }
1014
1015 jint nWant = 0, nWait = 0;
1016 if (mon
17.1
'mon' is not equal to NULL
17.1
'mon' is not equal to NULL
17.1
'mon' is not equal to NULL
!= NULL__null) {
18
Taking true branch
1017 // this object has a heavyweight monitor
1018 nWant = mon->contentions(); // # of threads contending for monitor
1019 nWait = mon->waiters(); // # of threads in Object.wait()
1020 ret.waiter_count = nWant + nWait;
1021 ret.notify_waiter_count = nWait;
1022 } else {
1023 // this object has a lightweight monitor
1024 ret.waiter_count = 0;
1025 ret.notify_waiter_count = 0;
1026 }
1027
1028 // Allocate memory for heavyweight and lightweight monitor.
1029 jvmtiError err;
1030 err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
19
Calling 'JvmtiEnvBase::allocate'
23
Returning from 'JvmtiEnvBase::allocate'
1031 if (err
23.1
'err' is equal to JVMTI_ERROR_NONE
23.1
'err' is equal to JVMTI_ERROR_NONE
23.1
'err' is equal to JVMTI_ERROR_NONE
!= JVMTI_ERROR_NONE) {
24
Taking false branch
1032 return err;
1033 }
1034 err = allocate(ret.notify_waiter_count * sizeof(jthread *),
1035 (unsigned char**)&ret.notify_waiters);
1036 if (err
24.1
'err' is equal to JVMTI_ERROR_NONE
24.1
'err' is equal to JVMTI_ERROR_NONE
24.1
'err' is equal to JVMTI_ERROR_NONE
!= JVMTI_ERROR_NONE) {
25
Taking false branch
1037 deallocate((unsigned char*)ret.waiters);
1038 return err;
1039 }
1040
1041 // now derive the rest of the fields
1042 if (mon
25.1
'mon' is not equal to NULL
25.1
'mon' is not equal to NULL
25.1
'mon' is not equal to NULL
!= NULL__null) {
26
Taking true branch
1043 // this object has a heavyweight monitor
1044
1045 // Number of waiters may actually be less than the waiter count.
1046 // So NULL out memory so that unused memory will be NULL.
1047 memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
27
Null pointer passed to 1st parameter expecting 'nonnull'
1048 memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
1049
1050 if (ret.waiter_count > 0) {
1051 // we have contending and/or waiting threads
1052 if (nWant > 0) {
1053 // we have contending threads
1054 ResourceMark rm(current_thread);
1055 // get_pending_threads returns only java thread so we do not need to
1056 // check for non java threads.
1057 GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon);
1058 if (wantList->length() < nWant) {
1059 // robustness: the pending list has gotten smaller
1060 nWant = wantList->length();
1061 }
1062 for (int i = 0; i < nWant; i++) {
1063 JavaThread *pending_thread = wantList->at(i);
1064 Handle th(current_thread, pending_thread->threadObj());
1065 ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
1066 }
1067 }
1068 if (nWait > 0) {
1069 // we have threads in Object.wait()
1070 int offset = nWant; // add after any contending threads
1071 ObjectWaiter *waiter = mon->first_waiter();
1072 for (int i = 0, j = 0; i < nWait; i++) {
1073 if (waiter == NULL__null) {
1074 // robustness: the waiting list has gotten smaller
1075 nWait = j;
1076 break;
1077 }
1078 JavaThread *w = mon->thread_of_waiter(waiter);
1079 if (w != NULL__null) {
1080 // If the thread was found on the ObjectWaiter list, then
1081 // it has not been notified. This thread can't change the
1082 // state of the monitor so it doesn't need to be suspended.
1083 Handle th(current_thread, w->threadObj());
1084 ret.waiters[offset + j] = (jthread)jni_reference(calling_thread, th);
1085 ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th);
1086 }
1087 waiter = mon->next_waiter(waiter);
1088 }
1089 }
1090 } // ThreadsListHandle is destroyed here.
1091
1092 // Adjust count. nWant and nWait count values may be less than original.
1093 ret.waiter_count = nWant + nWait;
1094 ret.notify_waiter_count = nWait;
1095 } else {
1096 // this object has a lightweight monitor and we have nothing more
1097 // to do here because the defaults are just fine.
1098 }
1099
1100 // we don't update return parameter unless everything worked
1101 *info_ptr = ret;
1102
1103 return JVMTI_ERROR_NONE;
1104}
1105
1106ResourceTracker::ResourceTracker(JvmtiEnv* env) {
1107 _env = env;
1108 _allocations = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<unsigned char*>(20, mtServiceability);
1109 _failed = false;
1110}
1111ResourceTracker::~ResourceTracker() {
1112 if (_failed) {
1113 for (int i=0; i<_allocations->length(); i++) {
1114 _env->deallocate(_allocations->at(i));
1115 }
1116 }
1117 delete _allocations;
1118}
1119
1120jvmtiError ResourceTracker::allocate(jlong size, unsigned char** mem_ptr) {
1121 unsigned char *ptr;
1122 jvmtiError err = _env->allocate(size, &ptr);
1123 if (err == JVMTI_ERROR_NONE) {
1124 _allocations->append(ptr);
1125 *mem_ptr = ptr;
1126 } else {
1127 *mem_ptr = NULL__null;
1128 _failed = true;
1129 }
1130 return err;
1131 }
1132
1133unsigned char* ResourceTracker::allocate(jlong size) {
1134 unsigned char* ptr;
1135 allocate(size, &ptr);
1136 return ptr;
1137}
1138
1139char* ResourceTracker::strdup(const char* str) {
1140 char *dup_str = (char*)allocate(strlen(str)+1);
1141 if (dup_str != NULL__null) {
1142 strcpy(dup_str, str);
1143 }
1144 return dup_str;
1145}
1146
1147struct StackInfoNode {
1148 struct StackInfoNode *next;
1149 jvmtiStackInfo info;
1150};
1151
1152// Create a jvmtiStackInfo inside a linked list node and create a
1153// buffer for the frame information, both allocated as resource objects.
1154// Fill in both the jvmtiStackInfo and the jvmtiFrameInfo.
1155// Note that either or both of thr and thread_oop
1156// may be null if the thread is new or has exited.
1157void
1158MultipleStackTracesCollector::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
1159#ifdef ASSERT1
1160 Thread *current_thread = Thread::current();
1161 assert(SafepointSynchronize::is_at_safepoint() ||do { if (!(SafepointSynchronize::is_at_safepoint() || thr->
is_handshake_safe_for(current_thread))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1163, "assert(" "SafepointSynchronize::is_at_safepoint() || thr->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
1162 thr->is_handshake_safe_for(current_thread),do { if (!(SafepointSynchronize::is_at_safepoint() || thr->
is_handshake_safe_for(current_thread))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1163, "assert(" "SafepointSynchronize::is_at_safepoint() || thr->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
1163 "call by myself / at safepoint / at handshake")do { if (!(SafepointSynchronize::is_at_safepoint() || thr->
is_handshake_safe_for(current_thread))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1163, "assert(" "SafepointSynchronize::is_at_safepoint() || thr->is_handshake_safe_for(current_thread)"
") failed", "call by myself / at safepoint / at handshake");
::breakpoint(); } } while (0)
;
1164#endif
1165
1166 jint state = 0;
1167 struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode)(struct StackInfoNode*) resource_allocate_bytes((1) * sizeof(
struct StackInfoNode))
;
1168 jvmtiStackInfo *infop = &(node->info);
1169 node->next = head();
1170 set_head(node);
1171 infop->frame_count = 0;
1172 infop->thread = jt;
1173
1174 if (thread_oop != NULL__null) {
1175 // get most state bits
1176 state = (jint)java_lang_Thread::get_thread_status(thread_oop);
1177 }
1178
1179 if (thr != NULL__null) { // add more state bits if there is a JavaThead to query
1180 if (thr->is_suspended()) {
1181 state |= JVMTI_THREAD_STATE_SUSPENDED;
1182 }
1183 JavaThreadState jts = thr->thread_state();
1184 if (jts == _thread_in_native) {
1185 state |= JVMTI_THREAD_STATE_IN_NATIVE;
1186 }
1187 if (thr->is_interrupted(false)) {
1188 state |= JVMTI_THREAD_STATE_INTERRUPTED;
1189 }
1190 }
1191 infop->state = state;
1192
1193 if (thr != NULL__null && (state & JVMTI_THREAD_STATE_ALIVE) != 0) {
1194 infop->frame_buffer = NEW_RESOURCE_ARRAY(jvmtiFrameInfo, max_frame_count())(jvmtiFrameInfo*) resource_allocate_bytes((max_frame_count())
* sizeof(jvmtiFrameInfo))
;
1195 env()->get_stack_trace(thr, 0, max_frame_count(),
1196 infop->frame_buffer, &(infop->frame_count));
1197 } else {
1198 infop->frame_buffer = NULL__null;
1199 infop->frame_count = 0;
1200 }
1201 _frame_count_total += infop->frame_count;
1202}
1203
1204// Based on the stack information in the linked list, allocate memory
1205// block to return and fill it from the info in the linked list.
1206void
1207MultipleStackTracesCollector::allocate_and_fill_stacks(jint thread_count) {
1208 // do I need to worry about alignment issues?
1209 jlong alloc_size = thread_count * sizeof(jvmtiStackInfo)
1210 + _frame_count_total * sizeof(jvmtiFrameInfo);
1211 env()->allocate(alloc_size, (unsigned char **)&_stack_info);
1212
1213 // pointers to move through the newly allocated space as it is filled in
1214 jvmtiStackInfo *si = _stack_info + thread_count; // bottom of stack info
1215 jvmtiFrameInfo *fi = (jvmtiFrameInfo *)si; // is the top of frame info
1216
1217 // copy information in resource area into allocated buffer
1218 // insert stack info backwards since linked list is backwards
1219 // insert frame info forwards
1220 // walk the StackInfoNodes
1221 for (struct StackInfoNode *sin = head(); sin != NULL__null; sin = sin->next) {
1222 jint frame_count = sin->info.frame_count;
1223 size_t frames_size = frame_count * sizeof(jvmtiFrameInfo);
1224 --si;
1225 memcpy(si, &(sin->info), sizeof(jvmtiStackInfo));
1226 if (frames_size == 0) {
1227 si->frame_buffer = NULL__null;
1228 } else {
1229 memcpy(fi, sin->info.frame_buffer, frames_size);
1230 si->frame_buffer = fi; // point to the new allocated copy of the frames
1231 fi += frame_count;
1232 }
1233 }
1234 assert(si == _stack_info, "the last copied stack info must be the first record")do { if (!(si == _stack_info)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1234, "assert(" "si == _stack_info" ") failed", "the last copied stack info must be the first record"
); ::breakpoint(); } } while (0)
;
1235 assert((unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size,do { if (!((unsigned char *)fi == ((unsigned char *)_stack_info
) + alloc_size)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1236, "assert(" "(unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size"
") failed", "the last copied frame info must be the last record"
); ::breakpoint(); } } while (0)
1236 "the last copied frame info must be the last record")do { if (!((unsigned char *)fi == ((unsigned char *)_stack_info
) + alloc_size)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1236, "assert(" "(unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size"
") failed", "the last copied frame info must be the last record"
); ::breakpoint(); } } while (0)
;
1237}
1238
1239
1240void
1241VM_GetThreadListStackTraces::doit() {
1242 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1242, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint"); ::breakpoint(); } } while (0)
;
1243
1244 ResourceMark rm;
1245 ThreadsListHandle tlh;
1246 for (int i = 0; i < _thread_count; ++i) {
1247 jthread jt = _thread_list[i];
1248 JavaThread* java_thread = NULL__null;
1249 oop thread_oop = NULL__null;
1250 jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), jt, &java_thread, &thread_oop);
1251 if (err != JVMTI_ERROR_NONE) {
1252 // We got an error code so we don't have a JavaThread *, but
1253 // only return an error from here if we didn't get a valid
1254 // thread_oop.
1255 if (thread_oop == NULL__null) {
1256 _collector.set_result(err);
1257 return;
1258 }
1259 // We have a valid thread_oop.
1260 }
1261 _collector.fill_frames(jt, java_thread, thread_oop);
1262 }
1263 _collector.allocate_and_fill_stacks(_thread_count);
1264}
1265
1266void
1267GetSingleStackTraceClosure::do_thread(Thread *target) {
1268 JavaThread *jt = JavaThread::cast(target);
1269 oop thread_oop = jt->threadObj();
1270
1271 if (!jt->is_exiting() && thread_oop != NULL__null) {
1272 ResourceMark rm;
1273 _collector.fill_frames(_jthread, jt, thread_oop);
1274 _collector.allocate_and_fill_stacks(1);
1275 }
1276}
1277
1278void
1279VM_GetAllStackTraces::doit() {
1280 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1280, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint"); ::breakpoint(); } } while (0)
;
1281
1282 ResourceMark rm;
1283 _final_thread_count = 0;
1284 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
1285 oop thread_oop = jt->threadObj();
1286 if (thread_oop != NULL__null &&
1287 !jt->is_exiting() &&
1288 java_lang_Thread::is_alive(thread_oop) &&
1289 !jt->is_hidden_from_external_view()) {
1290 ++_final_thread_count;
1291 // Handle block of the calling thread is used to create local refs.
1292 _collector.fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
1293 jt, thread_oop);
1294 }
1295 }
1296 _collector.allocate_and_fill_stacks(_final_thread_count);
1297}
1298
1299// Verifies that the top frame is a java frame in an expected state.
1300// Deoptimizes frame if needed.
1301// Checks that the frame method signature matches the return type (tos).
1302// HandleMark must be defined in the caller only.
1303// It is to keep a ret_ob_h handle alive after return to the caller.
1304jvmtiError
1305JvmtiEnvBase::check_top_frame(Thread* current_thread, JavaThread* java_thread,
1306 jvalue value, TosState tos, Handle* ret_ob_h) {
1307 ResourceMark rm(current_thread);
1308
1309 vframe *vf = vframeForNoProcess(java_thread, 0);
1310 NULL_CHECK(vf, JVMTI_ERROR_NO_MORE_FRAMES)if ((vf) == __null) { return (JVMTI_ERROR_NO_MORE_FRAMES); };
1311
1312 javaVFrame *jvf = (javaVFrame*) vf;
1313 if (!vf->is_java_frame() || jvf->method()->is_native()) {
1314 return JVMTI_ERROR_OPAQUE_FRAME;
1315 }
1316
1317 // If the frame is a compiled one, need to deoptimize it.
1318 if (vf->is_compiled_frame()) {
1319 if (!vf->fr().can_be_deoptimized()) {
1320 return JVMTI_ERROR_OPAQUE_FRAME;
1321 }
1322 Deoptimization::deoptimize_frame(java_thread, jvf->fr().id());
1323 }
1324
1325 // Get information about method return type
1326 Symbol* signature = jvf->method()->signature();
1327
1328 ResultTypeFinder rtf(signature);
1329 TosState fr_tos = as_TosState(rtf.type());
1330 if (fr_tos != tos) {
1331 if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) {
1332 return JVMTI_ERROR_TYPE_MISMATCH;
1333 }
1334 }
1335
1336 // Check that the jobject class matches the return type signature.
1337 jobject jobj = value.l;
1338 if (tos == atos && jobj != NULL__null) { // NULL reference is allowed
1339 Handle ob_h(current_thread, JNIHandles::resolve_external_guard(jobj));
1340 NULL_CHECK(ob_h, JVMTI_ERROR_INVALID_OBJECT)if ((ob_h) == __null) { return (JVMTI_ERROR_INVALID_OBJECT); };
1341 Klass* ob_k = ob_h()->klass();
1342 NULL_CHECK(ob_k, JVMTI_ERROR_INVALID_OBJECT)if ((ob_k) == __null) { return (JVMTI_ERROR_INVALID_OBJECT); };
1343
1344 // Method return type signature.
1345 char* ty_sign = 1 + strchr(signature->as_C_string(), JVM_SIGNATURE_ENDFUNC);
1346
1347 if (!VM_GetOrSetLocal::is_assignable(ty_sign, ob_k, current_thread)) {
1348 return JVMTI_ERROR_TYPE_MISMATCH;
1349 }
1350 *ret_ob_h = ob_h;
1351 }
1352 return JVMTI_ERROR_NONE;
1353} /* end check_top_frame */
1354
1355
1356// ForceEarlyReturn<type> follows the PopFrame approach in many aspects.
1357// Main difference is on the last stage in the interpreter.
1358// The PopFrame stops method execution to continue execution
1359// from the same method call instruction.
1360// The ForceEarlyReturn forces return from method so the execution
1361// continues at the bytecode following the method call.
1362
1363// java_thread - protected by ThreadsListHandle and pre-checked
1364
1365jvmtiError
1366JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) {
1367 // retrieve or create the state
1368 JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
1369 if (state == NULL__null) {
1370 return JVMTI_ERROR_THREAD_NOT_ALIVE;
1371 }
1372
1373 // Eagerly reallocate scalar replaced objects.
1374 JavaThread* current_thread = JavaThread::current();
1375 EscapeBarrier eb(true, current_thread, java_thread);
1376 if (!eb.deoptimize_objects(0)) {
1377 // Reallocation of scalar replaced objects failed -> return with error
1378 return JVMTI_ERROR_OUT_OF_MEMORY;
1379 }
1380
1381 SetForceEarlyReturn op(state, value, tos);
1382 if (java_thread == current_thread) {
1383 op.doit(java_thread, true /* self */);
1384 } else {
1385 Handshake::execute(&op, java_thread);
1386 }
1387 return op.result();
1388}
1389
1390void
1391SetForceEarlyReturn::doit(Thread *target, bool self) {
1392 JavaThread* java_thread = JavaThread::cast(target);
1393 Thread* current_thread = Thread::current();
1394 HandleMark hm(current_thread);
1395
1396 if (java_thread->is_exiting()) {
1397 return; /* JVMTI_ERROR_THREAD_NOT_ALIVE (default) */
1398 }
1399 if (!self) {
1400 if (!java_thread->is_suspended()) {
1401 _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1402 return;
1403 }
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 _result = JVMTI_ERROR_INTERNAL;
1411 return;
1412 }
1413 {
1414 // The same as for PopFrame. Workaround bug:
1415 // 4812902: popFrame hangs if the method is waiting at a synchronize
1416 // Catch this condition and return an error to avoid hanging.
1417 // Now JVMTI spec allows an implementation to bail out with an opaque
1418 // frame error.
1419 OSThread* osThread = java_thread->osthread();
1420 if (osThread->get_state() == MONITOR_WAIT) {
1421 _result = JVMTI_ERROR_OPAQUE_FRAME;
1422 return;
1423 }
1424 }
1425
1426 Handle ret_ob_h;
1427 _result = JvmtiEnvBase::check_top_frame(current_thread, java_thread, _value, _tos, &ret_ob_h);
1428 if (_result != JVMTI_ERROR_NONE) {
1429 return;
1430 }
1431 assert(_tos != atos || _value.l == NULL || ret_ob_h() != NULL,do { if (!(_tos != atos || _value.l == __null || ret_ob_h() !=
__null)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1432, "assert(" "_tos != atos || _value.l == __null || ret_ob_h() != __null"
") failed", "return object oop must not be NULL if jobject is not NULL"
); ::breakpoint(); } } while (0)
1432 "return object oop must not be NULL if jobject is not NULL")do { if (!(_tos != atos || _value.l == __null || ret_ob_h() !=
__null)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1432, "assert(" "_tos != atos || _value.l == __null || ret_ob_h() != __null"
") failed", "return object oop must not be NULL if jobject is not NULL"
); ::breakpoint(); } } while (0)
;
1433
1434 // Update the thread state to reflect that the top frame must be
1435 // forced to return.
1436 // The current frame will be returned later when the suspended
1437 // thread is resumed and right before returning from VM to Java.
1438 // (see call_VM_base() in assembler_<cpu>.cpp).
1439
1440 _state->set_earlyret_pending();
1441 _state->set_earlyret_oop(ret_ob_h());
1442 _state->set_earlyret_value(_value, _tos);
1443
1444 // Set pending step flag for this early return.
1445 // It is cleared when next step event is posted.
1446 _state->set_pending_step_for_earlyret();
1447}
1448
1449void
1450JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
1451 if ( _error != JVMTI_ERROR_NONE) {
1452 // Error occurred in previous iteration so no need to add
1453 // to the list.
1454 return;
1455 }
1456 // Filter out on stack monitors collected during stack walk.
1457 oop obj = 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(Thread::current(), 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
1485GrowableArray<OopHandle>* JvmtiModuleClosure::_tbl = NULL__null;
1486
1487void JvmtiModuleClosure::do_module(ModuleEntry* entry) {
1488 assert_locked_or_safepoint(Module_lock);
1489 OopHandle module = entry->module_handle();
1490 guarantee(module.resolve() != NULL, "module object is NULL")do { if (!(module.resolve() != __null)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1490, "guarantee(" "module.resolve() != NULL" ") failed", "module object is NULL"
); ::breakpoint(); } } while (0)
;
1491 _tbl->push(module);
1492}
1493
1494jvmtiError
1495JvmtiModuleClosure::get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr) {
1496 ResourceMark rm;
1497 MutexLocker mcld(ClassLoaderDataGraph_lock);
1498 MutexLocker ml(Module_lock);
1499
1500 _tbl = new GrowableArray<OopHandle>(77);
1501 if (_tbl == NULL__null) {
1502 return JVMTI_ERROR_OUT_OF_MEMORY;
1503 }
1504
1505 // Iterate over all the modules loaded to the system.
1506 ClassLoaderDataGraph::modules_do(&do_module);
1507
1508 jint len = _tbl->length();
1509 guarantee(len > 0, "at least one module must be present")do { if (!(len > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1509, "guarantee(" "len > 0" ") failed", "at least one module must be present"
); ::breakpoint(); } } while (0)
;
1510
1511 jobject* array = (jobject*)env->jvmtiMalloc((jlong)(len * sizeof(jobject)));
1512 if (array == NULL__null) {
1513 return JVMTI_ERROR_OUT_OF_MEMORY;
1514 }
1515 for (jint idx = 0; idx < len; idx++) {
1516 array[idx] = JNIHandles::make_local(_tbl->at(idx).resolve());
1517 }
1518 _tbl = NULL__null;
1519 *modules_ptr = array;
1520 *module_count_ptr = len;
1521 return JVMTI_ERROR_NONE;
1522}
1523
1524void
1525UpdateForPopTopFrameClosure::doit(Thread *target, bool self) {
1526 Thread* current_thread = Thread::current();
1527 HandleMark hm(current_thread);
1528 JavaThread* java_thread = JavaThread::cast(target);
1529
1530 if (java_thread->is_exiting()) {
1531 return; /* JVMTI_ERROR_THREAD_NOT_ALIVE (default) */
1532 }
1533 assert(java_thread == _state->get_thread(), "Must be")do { if (!(java_thread == _state->get_thread())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1533, "assert(" "java_thread == _state->get_thread()" ") failed"
, "Must be"); ::breakpoint(); } } while (0)
;
1534
1535 if (!self && !java_thread->is_suspended()) {
1536 _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1537 return;
1538 }
1539
1540 // Check to see if a PopFrame was already in progress
1541 if (java_thread->popframe_condition() != JavaThread::popframe_inactive) {
1542 // Probably possible for JVMTI clients to trigger this, but the
1543 // JPDA backend shouldn't allow this to happen
1544 _result = JVMTI_ERROR_INTERNAL;
1545 return;
1546 }
1547
1548 // Was workaround bug
1549 // 4812902: popFrame hangs if the method is waiting at a synchronize
1550 // Catch this condition and return an error to avoid hanging.
1551 // Now JVMTI spec allows an implementation to bail out with an opaque frame error.
1552 OSThread* osThread = java_thread->osthread();
1553 if (osThread->get_state() == MONITOR_WAIT) {
1554 _result = JVMTI_ERROR_OPAQUE_FRAME;
1555 return;
1556 }
1557
1558 ResourceMark rm(current_thread);
1559 // Check if there is more than one Java frame in this thread, that the top two frames
1560 // are Java (not native) frames, and that there is no intervening VM frame
1561 int frame_count = 0;
1562 bool is_interpreted[2];
1563 intptr_t *frame_sp[2];
1564 // The 2-nd arg of constructor is needed to stop iterating at java entry frame.
1565 for (vframeStream vfs(java_thread, true, false /* process_frames */); !vfs.at_end(); vfs.next()) {
1566 methodHandle mh(current_thread, vfs.method());
1567 if (mh->is_native()) {
1568 _result = JVMTI_ERROR_OPAQUE_FRAME;
1569 return;
1570 }
1571 is_interpreted[frame_count] = vfs.is_interpreted_frame();
1572 frame_sp[frame_count] = vfs.frame_id();
1573 if (++frame_count > 1) break;
1574 }
1575 if (frame_count < 2) {
1576 // We haven't found two adjacent non-native Java frames on the top.
1577 // There can be two situations here:
1578 // 1. There are no more java frames
1579 // 2. Two top java frames are separated by non-java native frames
1580 if(JvmtiEnvBase::vframeForNoProcess(java_thread, 1) == NULL__null) {
1581 _result = JVMTI_ERROR_NO_MORE_FRAMES;
1582 return;
1583 } else {
1584 // Intervening non-java native or VM frames separate java frames.
1585 // Current implementation does not support this. See bug #5031735.
1586 // In theory it is possible to pop frames in such cases.
1587 _result = JVMTI_ERROR_OPAQUE_FRAME;
1588 return;
1589 }
1590 }
1591
1592 // If any of the top 2 frames is a compiled one, need to deoptimize it
1593 for (int i = 0; i < 2; i++) {
1594 if (!is_interpreted[i]) {
1595 Deoptimization::deoptimize_frame(java_thread, frame_sp[i]);
1596 }
1597 }
1598
1599 // Update the thread state to reflect that the top frame is popped
1600 // so that cur_stack_depth is maintained properly and all frameIDs
1601 // are invalidated.
1602 // The current frame will be popped later when the suspended thread
1603 // is resumed and right before returning from VM to Java.
1604 // (see call_VM_base() in assembler_<cpu>.cpp).
1605
1606 // It's fine to update the thread state here because no JVMTI events
1607 // shall be posted for this PopFrame.
1608
1609 _state->update_for_pop_top_frame();
1610 java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);
1611 // Set pending step flag for this popframe and it is cleared when next
1612 // step event is posted.
1613 _state->set_pending_step_for_popframe();
1614 _result = JVMTI_ERROR_NONE;
1615}
1616
1617void
1618SetFramePopClosure::doit(Thread *target, bool self) {
1619 ResourceMark rm;
1620 JavaThread* java_thread = JavaThread::cast(target);
1621
1622 if (java_thread->is_exiting()) {
1623 return; /* JVMTI_ERROR_THREAD_NOT_ALIVE (default) */
1624 }
1625 assert(_state->get_thread() == java_thread, "Must be")do { if (!(_state->get_thread() == java_thread)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1625, "assert(" "_state->get_thread() == java_thread" ") failed"
, "Must be"); ::breakpoint(); } } while (0)
;
1626
1627 if (!self && !java_thread->is_suspended()) {
1628 _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1629 return;
1630 }
1631
1632 vframe *vf = JvmtiEnvBase::vframeForNoProcess(java_thread, _depth);
1633 if (vf == NULL__null) {
1634 _result = JVMTI_ERROR_NO_MORE_FRAMES;
1635 return;
1636 }
1637
1638 if (!vf->is_java_frame() || ((javaVFrame*) vf)->method()->is_native()) {
1639 _result = JVMTI_ERROR_OPAQUE_FRAME;
1640 return;
1641 }
1642
1643 assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL")do { if (!(vf->frame_pointer() != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1643, "assert(" "vf->frame_pointer() != __null" ") failed"
, "frame pointer mustn't be NULL"); ::breakpoint(); } } while
(0)
;
1644 int frame_number = _state->count_frames() - _depth;
1645 _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
1646 _result = JVMTI_ERROR_NONE;
1647}
1648
1649void
1650GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
1651 JavaThread *jt = JavaThread::cast(target);
1652 if (!jt->is_exiting() && (jt->threadObj() != NULL__null)) {
1653 _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
1654 jt,
1655 _owned_monitors_list);
1656 }
1657}
1658
1659void
1660GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
1661 JavaThread *jt = JavaThread::cast(target);
1662 if (!jt->is_exiting() && (jt->threadObj() != NULL__null)) {
1663 _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,
1664 jt,
1665 _owned_monitor_ptr);
1666 }
1667}
1668
1669void
1670GetStackTraceClosure::do_thread(Thread *target) {
1671 JavaThread *jt = JavaThread::cast(target);
1672 if (!jt->is_exiting() && jt->threadObj() != NULL__null) {
1673 _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
1674 _start_depth, _max_count,
1675 _frame_buffer, _count_ptr);
1676 }
1677}
1678
1679void
1680GetFrameCountClosure::do_thread(Thread *target) {
1681 JavaThread* jt = _state->get_thread();
1682 assert(target == jt, "just checking")do { if (!(target == jt)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp"
, 1682, "assert(" "target == jt" ") failed", "just checking")
; ::breakpoint(); } } while (0)
;
1683 if (!jt->is_exiting() && jt->threadObj() != NULL__null) {
1684 _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
1685 }
1686}
1687
1688void
1689GetFrameLocationClosure::do_thread(Thread *target) {
1690 JavaThread *jt = JavaThread::cast(target);
1691 if (!jt->is_exiting() && jt->threadObj() != NULL__null) {
1692 _result = ((JvmtiEnvBase*)_env)->get_frame_location(jt, _depth,
1693 _method_ptr, _location_ptr);
1694 }
1695}

/home/daniel/Projects/java/jdk/src/hotspot/share/oops/oopsHierarchy.hpp

1/*
2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_OOPS_OOPSHIERARCHY_HPP
26#define SHARE_OOPS_OOPSHIERARCHY_HPP
27
28#include "metaprogramming/integralConstant.hpp"
29#include "metaprogramming/primitiveConversions.hpp"
30#include "utilities/globalDefinitions.hpp"
31
32// OBJECT hierarchy
33// This hierarchy is a representation hierarchy, i.e. if A is a superclass
34// of B, A's representation is a prefix of B's representation.
35
36// Global offset instead of address for an oop within a java object.
37enum class narrowOop : uint32_t { null = 0 };
38
39// If compressed klass pointers then use narrowKlass.
40typedef juint narrowKlass;
41
42typedef void* OopOrNarrowOopStar;
43
44#ifndef CHECK_UNHANDLED_OOPS1
45
46typedef class oopDesc* oop;
47typedef class instanceOopDesc* instanceOop;
48typedef class arrayOopDesc* arrayOop;
49typedef class objArrayOopDesc* objArrayOop;
50typedef class typeArrayOopDesc* typeArrayOop;
51
52#else
53
54// When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a
55// carefully chosen set of constructors and conversion operators to go
56// to and from the underlying oopDesc pointer type.
57//
58// Because oop and its subclasses <type>Oop are class types, arbitrary
59// conversions are not accepted by the compiler. Applying a cast to
60// an oop will cause the best matched conversion operator to be
61// invoked returning the underlying oopDesc* type if appropriate.
62// No copy constructors, explicit user conversions or operators of
63// numerical type should be defined within the oop class. Most C++
64// compilers will issue a compile time error concerning the overloading
65// ambiguity between operators of numerical and pointer types. If
66// a conversion to or from an oop to a numerical type is needed,
67// use the inline template methods, cast_*_oop, defined below.
68//
69// Converting NULL to oop to Handle implicit is no longer accepted by the
70// compiler because there are too many steps in the conversion. Use Handle()
71// instead, which generates less code anyway.
72
73class Thread;
74class oopDesc;
75
76extern "C" bool CheckUnhandledOops;
77
78class oop {
79 oopDesc* _o;
80
81 void register_oop();
82 void unregister_oop();
83
84 void register_if_checking() {
85 if (CheckUnhandledOops) register_oop();
86 }
87
88public:
89 oop() : _o(nullptr) { register_if_checking(); }
90 oop(const oop& o) : _o(o._o) { register_if_checking(); }
91 oop(oopDesc* o) : _o(o) { register_if_checking(); }
92 ~oop() {
93 if (CheckUnhandledOops) unregister_oop();
94 }
95
96 oopDesc* obj() const { return _o; }
97 oopDesc* operator->() const { return _o; }
98 operator oopDesc* () const { return _o; }
99
100 bool operator==(const oop& o) const { return _o == o._o; }
101 bool operator!=(const oop& o) const { return _o != o._o; }
102
103 bool operator==(std::nullptr_t) const { return _o == nullptr; }
8
Assuming the condition is false
9
Returning zero, which participates in a condition later
104 bool operator!=(std::nullptr_t) const { return _o != nullptr; }
105
106 oop& operator=(const oop& o) { _o = o._o; return *this; }
107};
108
109template<>
110struct PrimitiveConversions::Translate<oop> : public TrueType {
111 typedef oop Value;
112 typedef oopDesc* Decayed;
113
114 static Decayed decay(Value x) { return x.obj(); }
115 static Value recover(Decayed x) { return oop(x); }
116};
117
118#define DEF_OOP(type)class typeOopDesc; class typeOop : public oop { public: typeOop
() : oop() {} typeOop(const typeOop& o) : oop(o) {} typeOop
(const oop& o) : oop(o) {} typeOop(typeOopDesc* o) : oop(
(oopDesc*)o) {} operator typeOopDesc* () const { return (typeOopDesc
*)obj(); } typeOopDesc* operator->() const { return (typeOopDesc
*)obj(); } typeOop& operator=(const typeOop& o) { oop
::operator=(o); return *this; } }; template<> struct PrimitiveConversions
::Translate<typeOop> : public TrueType { typedef typeOop
Value; typedef typeOopDesc* Decayed; static Decayed decay(Value
x) { return (typeOopDesc*)x.obj(); } static Value recover(Decayed
x) { return typeOop(x); } };
\
119 class type##OopDesc; \
120 class type##Oop : public oop { \
121 public: \
122 type##Oop() : oop() {} \
123 type##Oop(const type##Oop& o) : oop(o) {} \
124 type##Oop(const oop& o) : oop(o) {} \
125 type##Oop(type##OopDesc* o) : oop((oopDesc*)o) {} \
126 operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \
127 type##OopDesc* operator->() const { \
128 return (type##OopDesc*)obj(); \
129 } \
130 type##Oop& operator=(const type##Oop& o) { \
131 oop::operator=(o); \
132 return *this; \
133 } \
134 }; \
135 \
136 template<> \
137 struct PrimitiveConversions::Translate<type##Oop> : public TrueType { \
138 typedef type##Oop Value; \
139 typedef type##OopDesc* Decayed; \
140 \
141 static Decayed decay(Value x) { return (type##OopDesc*)x.obj(); } \
142 static Value recover(Decayed x) { return type##Oop(x); } \
143 };
144
145DEF_OOP(instance)class instanceOopDesc; class instanceOop : public oop { public
: instanceOop() : oop() {} instanceOop(const instanceOop&
o) : oop(o) {} instanceOop(const oop& o) : oop(o) {} instanceOop
(instanceOopDesc* o) : oop((oopDesc*)o) {} operator instanceOopDesc
* () const { return (instanceOopDesc*)obj(); } instanceOopDesc
* operator->() const { return (instanceOopDesc*)obj(); } instanceOop
& operator=(const instanceOop& o) { oop::operator=(o)
; return *this; } }; template<> struct PrimitiveConversions
::Translate<instanceOop> : public TrueType { typedef instanceOop
Value; typedef instanceOopDesc* Decayed; static Decayed decay
(Value x) { return (instanceOopDesc*)x.obj(); } static Value recover
(Decayed x) { return instanceOop(x); } };
;
146DEF_OOP(array)class arrayOopDesc; class arrayOop : public oop { public: arrayOop
() : oop() {} arrayOop(const arrayOop& o) : oop(o) {} arrayOop
(const oop& o) : oop(o) {} arrayOop(arrayOopDesc* o) : oop
((oopDesc*)o) {} operator arrayOopDesc* () const { return (arrayOopDesc
*)obj(); } arrayOopDesc* operator->() const { return (arrayOopDesc
*)obj(); } arrayOop& operator=(const arrayOop& o) { oop
::operator=(o); return *this; } }; template<> struct PrimitiveConversions
::Translate<arrayOop> : public TrueType { typedef arrayOop
Value; typedef arrayOopDesc* Decayed; static Decayed decay(Value
x) { return (arrayOopDesc*)x.obj(); } static Value recover(Decayed
x) { return arrayOop(x); } };
;
147DEF_OOP(objArray)class objArrayOopDesc; class objArrayOop : public oop { public
: objArrayOop() : oop() {} objArrayOop(const objArrayOop&
o) : oop(o) {} objArrayOop(const oop& o) : oop(o) {} objArrayOop
(objArrayOopDesc* o) : oop((oopDesc*)o) {} operator objArrayOopDesc
* () const { return (objArrayOopDesc*)obj(); } objArrayOopDesc
* operator->() const { return (objArrayOopDesc*)obj(); } objArrayOop
& operator=(const objArrayOop& o) { oop::operator=(o)
; return *this; } }; template<> struct PrimitiveConversions
::Translate<objArrayOop> : public TrueType { typedef objArrayOop
Value; typedef objArrayOopDesc* Decayed; static Decayed decay
(Value x) { return (objArrayOopDesc*)x.obj(); } static Value recover
(Decayed x) { return objArrayOop(x); } };
;
148DEF_OOP(typeArray)class typeArrayOopDesc; class typeArrayOop : public oop { public
: typeArrayOop() : oop() {} typeArrayOop(const typeArrayOop&
o) : oop(o) {} typeArrayOop(const oop& o) : oop(o) {} typeArrayOop
(typeArrayOopDesc* o) : oop((oopDesc*)o) {} operator typeArrayOopDesc
* () const { return (typeArrayOopDesc*)obj(); } typeArrayOopDesc
* operator->() const { return (typeArrayOopDesc*)obj(); } typeArrayOop
& operator=(const typeArrayOop& o) { oop::operator=(o
); return *this; } }; template<> struct PrimitiveConversions
::Translate<typeArrayOop> : public TrueType { typedef typeArrayOop
Value; typedef typeArrayOopDesc* Decayed; static Decayed decay
(Value x) { return (typeArrayOopDesc*)x.obj(); } static Value
recover(Decayed x) { return typeArrayOop(x); } };
;
149
150#endif // CHECK_UNHANDLED_OOPS
151
152// Cast functions to convert to and from oops.
153template <typename T> inline oop cast_to_oop(T value) {
154 return (oopDesc*)value;
155}
156template <typename T> inline T cast_from_oop(oop o) {
157 return (T)(CHECK_UNHANDLED_OOPS_ONLY((oopDesc*))(oopDesc*)o);
158}
159
160// The metadata hierarchy is separate from the oop hierarchy
161
162// class MetaspaceObj
163class ConstMethod;
164class ConstantPoolCache;
165class MethodData;
166// class Metadata
167class Method;
168class ConstantPool;
169// class CHeapObj
170class CompiledICHolder;
171
172
173// The klass hierarchy is separate from the oop hierarchy.
174
175class Klass;
176class InstanceKlass;
177class InstanceMirrorKlass;
178class InstanceClassLoaderKlass;
179class InstanceRefKlass;
180class ArrayKlass;
181class ObjArrayKlass;
182class TypeArrayKlass;
183
184#endif // SHARE_OOPS_OOPSHIERARCHY_HPP

/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.hpp

1/*
2 * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_PRIMS_JVMTIENVBASE_HPP
26#define SHARE_PRIMS_JVMTIENVBASE_HPP
27
28#include "prims/jvmtiEnvThreadState.hpp"
29#include "prims/jvmtiEventController.hpp"
30#include "prims/jvmtiThreadState.hpp"
31#include "oops/oopHandle.hpp"
32#include "runtime/atomic.hpp"
33#include "runtime/fieldDescriptor.hpp"
34#include "runtime/frame.hpp"
35#include "runtime/thread.hpp"
36#include "runtime/vmOperation.hpp"
37#include "utilities/growableArray.hpp"
38#include "utilities/macros.hpp"
39
40//
41// Forward Declarations
42//
43
44class JvmtiEnv;
45class JvmtiThreadState;
46class JvmtiRawMonitor; // for jvmtiEnv.hpp
47class JvmtiEventControllerPrivate;
48class 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
56class JvmtiEnvBase : public CHeapObj<mtInternal> {
57
58 private:
59
60#if INCLUDE_JVMTI1
61 static JvmtiEnvBase* _head_environment; // head of environment list
62#endif // INCLUDE_JVMTI
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 */
72 JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102, /* version: 1.1.102 */
73 JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 + 2 /* version: 1.2.2 */
74 };
75
76 static jvmtiPhase get_phase() { return _phase; }
77 static jvmtiPhase get_phase(jvmtiEnv* env) { return ((JvmtiEnvBase*)JvmtiEnv_from_jvmti_env(env))->phase(); }
78 static void set_phase(jvmtiPhase phase) { _phase = phase; }
79 static bool is_vm_live() { return _phase == JVMTI_PHASE_LIVE; }
80
81 static void entering_dying_thread_env_iteration() { ++_dying_thread_env_iteration_count; }
82 static void leaving_dying_thread_env_iteration() { --_dying_thread_env_iteration_count; }
83 static bool is_inside_dying_thread_env_iteration(){ return _dying_thread_env_iteration_count > 0; }
84
85 private:
86
87 enum {
88 JVMTI_MAGIC = 0x71EE,
89 DISPOSED_MAGIC = 0xDEFC,
90 BAD_MAGIC = 0xDEAD
91 };
92
93 jvmtiEnv _jvmti_external;
94 jint _magic;
95 jint _version; // version value passed to JNI GetEnv()
96 JvmtiEnvBase* _next;
97 bool _is_retransformable;
98 const void *_env_local_storage; // per env agent allocated data.
99 jvmtiEventCallbacks _event_callbacks;
100 jvmtiExtEventCallbacks _ext_event_callbacks;
101 JvmtiTagMap* volatile _tag_map;
102 JvmtiEnvEventEnable _env_event_enable;
103 jvmtiCapabilities _current_capabilities;
104 jvmtiCapabilities _prohibited_capabilities;
105 volatile bool _class_file_load_hook_ever_enabled;
106 static volatile bool _needs_clean_up;
107 char** _native_method_prefixes;
108 int _native_method_prefix_count;
109
110 protected:
111 JvmtiEnvBase(jint version);
112 ~JvmtiEnvBase();
113 void dispose();
114 void env_dispose();
115
116 void set_env_local_storage(const void* data) { _env_local_storage = data; }
117 const void* get_env_local_storage() { return _env_local_storage; }
118
119 void record_class_file_load_hook_enabled();
120 void record_first_time_class_file_load_hook_enabled();
121
122 char** get_native_method_prefixes() { return _native_method_prefixes; }
123 int get_native_method_prefix_count() { return _native_method_prefix_count; }
124 jvmtiError set_native_method_prefixes(jint prefix_count, char** prefixes);
125
126 private:
127 friend class JvmtiEventControllerPrivate;
128 void initialize();
129 void set_event_callbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks);
130 static void globally_initialize();
131 static void periodic_clean_up();
132
133 friend class JvmtiEnvIterator;
134 JvmtiEnv* next_environment() { return (JvmtiEnv*)_next; }
135 void set_next_environment(JvmtiEnvBase* env) { _next = env; }
136 static JvmtiEnv* head_environment() {
137 JVMTI_ONLY(return (JvmtiEnv*)_head_environment)return (JvmtiEnv*)_head_environment;
138 NOT_JVMTI(return NULL);
139 }
140
141 public:
142
143 jvmtiPhase phase();
144 bool is_valid();
145
146 bool use_version_1_0_semantics(); // agent asked for version 1.0
147 bool use_version_1_1_semantics(); // agent asked for version 1.1
148 bool use_version_1_2_semantics(); // agent asked for version 1.2
149
150 bool is_retransformable() { return _is_retransformable; }
151
152 static ByteSize jvmti_external_offset() {
153 return byte_offset_of(JvmtiEnvBase, _jvmti_external)in_ByteSize((int)(size_t)((intx)&(((JvmtiEnvBase*)16)->
_jvmti_external) - 16))
;
154 };
155
156 static JvmtiEnv* JvmtiEnv_from_jvmti_env(jvmtiEnv *env) {
157 return (JvmtiEnv*)((intptr_t)env - in_bytes(jvmti_external_offset()));
158 };
159
160 jvmtiCapabilities *get_capabilities() { return &_current_capabilities; }
161
162 jvmtiCapabilities *get_prohibited_capabilities() { return &_prohibited_capabilities; }
163
164 bool early_class_hook_env() {
165 return get_capabilities()->can_generate_early_class_hook_events != 0
166 && get_capabilities()->can_generate_all_class_hook_events != 0;
167 }
168
169 bool early_vmstart_env() {
170 return get_capabilities()->can_generate_early_vmstart != 0;
171 }
172
173 static char** get_all_native_method_prefixes(int* count_ptr);
174
175 // This test will answer true when all environments have been disposed and some have
176 // not yet been deallocated. As a result, this test should only be used as an
177 // optimization for the no environment case.
178 static bool environments_might_exist() {
179 return head_environment() != NULL__null;
180 }
181
182 static void check_for_periodic_clean_up();
183
184 JvmtiEnvEventEnable *env_event_enable() {
185 return &_env_event_enable;
186 }
187
188 jvmtiError allocate(jlong size, unsigned char** mem_ptr) {
189 if (size
19.1
'size' is >= 0
19.1
'size' is >= 0
19.1
'size' is >= 0
< 0) {
20
Taking false branch
190 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
191 }
192 if (size == 0) {
21
Assuming 'size' is equal to 0
22
Taking true branch
193 *mem_ptr = NULL__null;
194 } else {
195 *mem_ptr = (unsigned char *)os::malloc((size_t)size, mtInternal);
196 if (*mem_ptr == NULL__null) {
197 return JVMTI_ERROR_OUT_OF_MEMORY;
198 }
199 }
200 return JVMTI_ERROR_NONE;
201 }
202
203 jvmtiError deallocate(unsigned char* mem) {
204 if (mem != NULL__null) {
205 os::free(mem);
206 }
207 return JVMTI_ERROR_NONE;
208 }
209
210
211 // Memory functions
212 unsigned char* jvmtiMalloc(jlong size); // don't use this - call allocate
213
214 // method to create a local handle
215 jobject jni_reference(Handle hndl);
216
217 // method to create a local handle.
218 // This function allows caller to specify which
219 // threads local handle table to use.
220 jobject jni_reference(JavaThread *thread, Handle hndl);
221
222 // method to destroy a local handle
223 void destroy_jni_reference(jobject jobj);
224
225 // method to destroy a local handle.
226 // This function allows caller to specify which
227 // threads local handle table to use.
228 void destroy_jni_reference(JavaThread *thread, jobject jobj);
229
230 jvmtiEnv* jvmti_external() { return &_jvmti_external; };
231
232// Event Dispatch
233
234 bool has_callback(jvmtiEvent event_type) {
235 assert(event_type >= JVMTI_MIN_EVENT_TYPE_VAL &&do { if (!(event_type >= JVMTI_MIN_EVENT_TYPE_VAL &&
event_type <= JVMTI_MAX_EVENT_TYPE_VAL)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.hpp"
, 236, "assert(" "event_type >= JVMTI_MIN_EVENT_TYPE_VAL && event_type <= JVMTI_MAX_EVENT_TYPE_VAL"
") failed", "checking"); ::breakpoint(); } } while (0)
236 event_type <= JVMTI_MAX_EVENT_TYPE_VAL, "checking")do { if (!(event_type >= JVMTI_MIN_EVENT_TYPE_VAL &&
event_type <= JVMTI_MAX_EVENT_TYPE_VAL)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/prims/jvmtiEnvBase.hpp"
, 236, "assert(" "event_type >= JVMTI_MIN_EVENT_TYPE_VAL && event_type <= JVMTI_MAX_EVENT_TYPE_VAL"
") failed", "checking"); ::breakpoint(); } } while (0)
;
237 return ((void**)&_event_callbacks)[event_type-JVMTI_MIN_EVENT_TYPE_VAL] != NULL__null;
238 }
239
240 jvmtiEventCallbacks* callbacks() {
241 return &_event_callbacks;
242 }
243
244 jvmtiExtEventCallbacks* ext_callbacks() {
245 return &_ext_event_callbacks;
246 }
247
248 void set_tag_map(JvmtiTagMap* tag_map) {
249 _tag_map = tag_map;
250 }
251
252 JvmtiTagMap* tag_map() {
253 return _tag_map;
254 }
255
256 JvmtiTagMap* tag_map_acquire() {
257 return Atomic::load_acquire(&_tag_map);
258 }
259
260 void release_set_tag_map(JvmtiTagMap* tag_map) {
261 Atomic::release_store(&_tag_map, tag_map);
262 }
263
264 // return true if event is enabled globally or for any thread
265 // True only if there is a callback for it.
266 bool is_enabled(jvmtiEvent event_type) {
267 return _env_event_enable.is_enabled(event_type);
268 }
269
270// Random Utilities
271
272 protected:
273 // helper methods for creating arrays of global JNI Handles from local Handles
274 // allocated into environment specific storage
275 jobject * new_jobjectArray(int length, Handle *handles);
276 jthread * new_jthreadArray(int length, Handle *handles);
277 jthreadGroup * new_jthreadGroupArray(int length, Handle *handles);
278
279 // convert to a jni jclass from a non-null Klass*
280 jclass get_jni_class_non_null(Klass* k);
281
282 jint count_locked_objects(JavaThread *java_thread, Handle hobj);
283 jvmtiError get_locked_objects_in_frame(JavaThread *calling_thread,
284 JavaThread* java_thread,
285 javaVFrame *jvf,
286 GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list,
287 jint depth);
288 public:
289 static vframe* vframeForNoProcess(JavaThread* java_thread, jint depth);
290
291 // get a field descriptor for the specified class and field
292 static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
293
294 // JVMTI API helper functions which are called when target thread is suspended
295 // or at safepoint / thread local handshake.
296 jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
297 jvmtiError get_frame_location(JavaThread* java_thread, jint depth,
298 jmethodID* method_ptr, jlocation* location_ptr);
299 jvmtiError get_object_monitor_usage(JavaThread *calling_thread,
300 jobject object, jvmtiMonitorUsage* info_ptr);
301 jvmtiError get_stack_trace(JavaThread *java_thread,
302 jint stack_depth, jint max_count,
303 jvmtiFrameInfo* frame_buffer, jint* count_ptr);
304 jvmtiError get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread,
305 jobject *monitor_ptr);
306 jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
307 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
308 static jvmtiError check_top_frame(Thread* current_thread, JavaThread* java_thread,
309 jvalue value, TosState tos, Handle* ret_ob_h);
310 jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos);
311};
312
313// This class is the only safe means of iterating through environments.
314// Note that this iteratation includes invalid environments pending
315// deallocation -- in fact, some uses depend on this behavior.
316
317class JvmtiEnvIterator : public StackObj {
318 private:
319 bool _entry_was_marked;
320 public:
321 JvmtiEnvIterator() {
322 if (Threads::number_of_threads() == 0) {
323 _entry_was_marked = false; // we are single-threaded, no need
324 } else {
325 Thread::current()->entering_jvmti_env_iteration();
326 _entry_was_marked = true;
327 }
328 }
329 ~JvmtiEnvIterator() {
330 if (_entry_was_marked) {
331 Thread::current()->leaving_jvmti_env_iteration();
332 }
333 }
334 JvmtiEnv* first() { return JvmtiEnvBase::head_environment(); }
335 JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }
336};
337
338class JvmtiHandshakeClosure : public HandshakeClosure {
339 protected:
340 jvmtiError _result;
341 public:
342 JvmtiHandshakeClosure(const char* name)
343 : HandshakeClosure(name),
344 _result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
345 jvmtiError result() { return _result; }
346};
347
348class SetForceEarlyReturn : public JvmtiHandshakeClosure {
349private:
350 JvmtiThreadState* _state;
351 jvalue _value;
352 TosState _tos;
353public:
354 SetForceEarlyReturn(JvmtiThreadState* state, jvalue value, TosState tos)
355 : JvmtiHandshakeClosure("SetForceEarlyReturn"),
356 _state(state),
357 _value(value),
358 _tos(tos) {}
359 void do_thread(Thread *target) {
360 doit(target, false /* self */);
361 }
362 void doit(Thread *target, bool self);
363};
364
365// HandshakeClosure to update for pop top frame.
366class UpdateForPopTopFrameClosure : public JvmtiHandshakeClosure {
367private:
368 JvmtiThreadState* _state;
369
370public:
371 UpdateForPopTopFrameClosure(JvmtiThreadState* state)
372 : JvmtiHandshakeClosure("UpdateForPopTopFrame"),
373 _state(state) {}
374 void do_thread(Thread *target) {
375 doit(target, false /* self */);
376 }
377 void doit(Thread *target, bool self);
378};
379
380// HandshakeClosure to set frame pop.
381class SetFramePopClosure : public JvmtiHandshakeClosure {
382private:
383 JvmtiEnv *_env;
384 JvmtiThreadState* _state;
385 jint _depth;
386
387public:
388 SetFramePopClosure(JvmtiEnv *env, JvmtiThreadState* state, jint depth)
389 : JvmtiHandshakeClosure("SetFramePop"),
390 _env(env),
391 _state(state),
392 _depth(depth) {}
393 void do_thread(Thread *target) {
394 doit(target, false /* self */);
395 }
396 void doit(Thread *target, bool self);
397};
398
399// HandshakeClosure to get monitor information with stack depth.
400class GetOwnedMonitorInfoClosure : public JvmtiHandshakeClosure {
401private:
402 JavaThread* _calling_thread;
403 JvmtiEnv *_env;
404 GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
405
406public:
407 GetOwnedMonitorInfoClosure(JavaThread* calling_thread, JvmtiEnv* env,
408 GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list)
409 : JvmtiHandshakeClosure("GetOwnedMonitorInfo"),
410 _calling_thread(calling_thread),
411 _env(env),
412 _owned_monitors_list(owned_monitor_list) {}
413 void do_thread(Thread *target);
414};
415
416
417// VM operation to get object monitor usage.
418class VM_GetObjectMonitorUsage : public VM_Operation {
419private:
420 JvmtiEnv *_env;
421 jobject _object;
422 JavaThread* _calling_thread;
423 jvmtiMonitorUsage* _info_ptr;
424 jvmtiError _result;
425
426public:
427 VM_GetObjectMonitorUsage(JvmtiEnv *env, JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
428 _env = env;
429 _object = object;
430 _calling_thread = calling_thread;
431 _info_ptr = info_ptr;
432 }
433 VMOp_Type type() const { return VMOp_GetObjectMonitorUsage; }
434 jvmtiError result() { return _result; }
435 void doit() {
436 _result = ((JvmtiEnvBase*) _env)->get_object_monitor_usage(_calling_thread, _object, _info_ptr);
437 }
438
439};
440
441// HandshakeClosure to get current contended monitor.
442class GetCurrentContendedMonitorClosure : public JvmtiHandshakeClosure {
443private:
444 JavaThread *_calling_thread;
445 JvmtiEnv *_env;
446 jobject *_owned_monitor_ptr;
447
448public:
449 GetCurrentContendedMonitorClosure(JavaThread* calling_thread, JvmtiEnv *env, jobject *mon_ptr)
450 : JvmtiHandshakeClosure("GetCurrentContendedMonitor"),
451 _calling_thread(calling_thread),
452 _env(env),
453 _owned_monitor_ptr(mon_ptr) {}
454 void do_thread(Thread *target);
455};
456
457// HandshakeClosure to get stack trace.
458class GetStackTraceClosure : public JvmtiHandshakeClosure {
459private:
460 JvmtiEnv *_env;
461 jint _start_depth;
462 jint _max_count;
463 jvmtiFrameInfo *_frame_buffer;
464 jint *_count_ptr;
465
466public:
467 GetStackTraceClosure(JvmtiEnv *env, jint start_depth, jint max_count,
468 jvmtiFrameInfo* frame_buffer, jint* count_ptr)
469 : JvmtiHandshakeClosure("GetStackTrace"),
470 _env(env),
471 _start_depth(start_depth),
472 _max_count(max_count),
473 _frame_buffer(frame_buffer),
474 _count_ptr(count_ptr) {}
475 void do_thread(Thread *target);
476};
477
478// forward declaration
479struct StackInfoNode;
480
481// Get stack trace at safepoint or at direct handshake.
482class MultipleStackTracesCollector {
483private:
484 JvmtiEnv *_env;
485 jint _max_frame_count;
486 jvmtiStackInfo *_stack_info;
487 jvmtiError _result;
488 int _frame_count_total;
489 struct StackInfoNode *_head;
490
491 JvmtiEnvBase *env() { return (JvmtiEnvBase *)_env; }
492 jint max_frame_count() { return _max_frame_count; }
493 struct StackInfoNode *head() { return _head; }
494 void set_head(StackInfoNode *head) { _head = head; }
495
496public:
497 MultipleStackTracesCollector(JvmtiEnv *env, jint max_frame_count)
498 : _env(env),
499 _max_frame_count(max_frame_count),
500 _stack_info(NULL__null),
501 _result(JVMTI_ERROR_NONE),
502 _frame_count_total(0),
503 _head(NULL__null) {
504 }
505 void set_result(jvmtiError result) { _result = result; }
506 void fill_frames(jthread jt, JavaThread *thr, oop thread_oop);
507 void allocate_and_fill_stacks(jint thread_count);
508 jvmtiStackInfo *stack_info() { return _stack_info; }
509 jvmtiError result() { return _result; }
510};
511
512
513// VM operation to get stack trace at safepoint.
514class VM_GetAllStackTraces : public VM_Operation {
515private:
516 JavaThread *_calling_thread;
517 jint _final_thread_count;
518 MultipleStackTracesCollector _collector;
519
520public:
521 VM_GetAllStackTraces(JvmtiEnv *env, JavaThread *calling_thread,
522 jint max_frame_count)
523 : _calling_thread(calling_thread),
524 _final_thread_count(0),
525 _collector(env, max_frame_count) {
526 }
527 VMOp_Type type() const { return VMOp_GetAllStackTraces; }
528 void doit();
529 jint final_thread_count() { return _final_thread_count; }
530 jvmtiStackInfo *stack_info() { return _collector.stack_info(); }
531 jvmtiError result() { return _collector.result(); }
532};
533
534// VM operation to get stack trace at safepoint.
535class VM_GetThreadListStackTraces : public VM_Operation {
536private:
537 jint _thread_count;
538 const jthread* _thread_list;
539 MultipleStackTracesCollector _collector;
540
541public:
542 VM_GetThreadListStackTraces(JvmtiEnv *env, jint thread_count, const jthread* thread_list, jint max_frame_count)
543 : _thread_count(thread_count),
544 _thread_list(thread_list),
545 _collector(env, max_frame_count) {
546 }
547 VMOp_Type type() const { return VMOp_GetThreadListStackTraces; }
548 void doit();
549 jvmtiStackInfo *stack_info() { return _collector.stack_info(); }
550 jvmtiError result() { return _collector.result(); }
551};
552
553// HandshakeClosure to get single stack trace.
554class GetSingleStackTraceClosure : public HandshakeClosure {
555private:
556 JavaThread *_calling_thread;
557 jthread _jthread;
558 MultipleStackTracesCollector _collector;
559
560public:
561 GetSingleStackTraceClosure(JvmtiEnv *env, JavaThread *calling_thread,
562 jthread thread, jint max_frame_count)
563 : HandshakeClosure("GetSingleStackTrace"),
564 _calling_thread(calling_thread),
565 _jthread(thread),
566 _collector(env, max_frame_count) {
567 }
568 void do_thread(Thread *target);
569 jvmtiStackInfo *stack_info() { return _collector.stack_info(); }
570 jvmtiError result() { return _collector.result(); }
571};
572
573// HandshakeClosure to count stack frames.
574class GetFrameCountClosure : public JvmtiHandshakeClosure {
575private:
576 JvmtiEnv *_env;
577 JvmtiThreadState *_state;
578 jint *_count_ptr;
579
580public:
581 GetFrameCountClosure(JvmtiEnv *env, JvmtiThreadState *state, jint *count_ptr)
582 : JvmtiHandshakeClosure("GetFrameCount"),
583 _env(env),
584 _state(state),
585 _count_ptr(count_ptr) {}
586 void do_thread(Thread *target);
587};
588
589// HandshakeClosure to get frame location.
590class GetFrameLocationClosure : public JvmtiHandshakeClosure {
591private:
592 JvmtiEnv *_env;
593 jint _depth;
594 jmethodID* _method_ptr;
595 jlocation* _location_ptr;
596
597public:
598 GetFrameLocationClosure(JvmtiEnv *env, jint depth,
599 jmethodID* method_ptr, jlocation* location_ptr)
600 : JvmtiHandshakeClosure("GetFrameLocation"),
601 _env(env),
602 _depth(depth),
603 _method_ptr(method_ptr),
604 _location_ptr(location_ptr) {}
605 void do_thread(Thread *target);
606};
607
608
609// ResourceTracker
610//
611// ResourceTracker works a little like a ResourceMark. All allocates
612// using the resource tracker are recorded. If an allocate using the
613// resource tracker fails the destructor will free any resources
614// that were allocated using the tracker.
615// The motive for this class is to avoid messy error recovery code
616// in situations where multiple allocations are done in sequence. If
617// the second or subsequent allocation fails it avoids any code to
618// release memory allocated in the previous calls.
619//
620// Usage :-
621// ResourceTracker rt(env);
622// :
623// err = rt.allocate(1024, &ptr);
624
625class ResourceTracker : public StackObj {
626 private:
627 JvmtiEnv* _env;
628 GrowableArray<unsigned char*> *_allocations;
629 bool _failed;
630 public:
631 ResourceTracker(JvmtiEnv* env);
632 ~ResourceTracker();
633 jvmtiError allocate(jlong size, unsigned char** mem_ptr);
634 unsigned char* allocate(jlong size);
635 char* strdup(const char* str);
636};
637
638
639// Jvmti monitor closure to collect off stack monitors.
640class JvmtiMonitorClosure: public MonitorClosure {
641 private:
642 JavaThread *_calling_thread;
643 GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
644 jvmtiError _error;
645 JvmtiEnvBase *_env;
646
647 public:
648 JvmtiMonitorClosure(JavaThread *calling_thread,
649 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors,
650 JvmtiEnvBase *env) {
651 _calling_thread = calling_thread;
652 _owned_monitors_list = owned_monitors;
653 _error = JVMTI_ERROR_NONE;
654 _env = env;
655 }
656 void do_monitor(ObjectMonitor* mon);
657 jvmtiError error() { return _error;}
658};
659
660
661// Jvmti module closure to collect all modules loaded to the system.
662class JvmtiModuleClosure : public StackObj {
663private:
664 static GrowableArray<OopHandle> *_tbl; // Protected with Module_lock
665
666 static void do_module(ModuleEntry* entry);
667public:
668 jvmtiError get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr);
669};
670
671#endif // SHARE_PRIMS_JVMTIENVBASE_HPP