Bug Summary

File:jdk/src/hotspot/share/prims/jvmtiEnvBase.cpp
Warning:line 1225, 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
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)
;
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)
;
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)
; }
;
957 NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER)if ((info_ptr) == __null) { return (JVMTI_ERROR_NULL_POINTER)
; }
;
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 = {
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()) {
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 != NULL__null) {
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 != NULL__null) { // monitor is owned
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 != NULL__null) {
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);
1031 if (err != JVMTI_ERROR_NONE) {
1032 return err;
1033 }
1034 err = allocate(ret.notify_waiter_count * sizeof(jthread *),
1035 (unsigned char**)&ret.notify_waiters);
1036 if (err != JVMTI_ERROR_NONE) {
1037 deallocate((unsigned char*)ret.waiters);
1038 return err;
1039 }
1040
1041 // now derive the rest of the fields
1042 if (mon != NULL__null) {
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 *));
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) {
6
Assuming 'sin' is not equal to NULL
7
Loop condition is true. Entering loop body
1222 jint frame_count = sin->info.frame_count;
1223 size_t frames_size = frame_count * sizeof(jvmtiFrameInfo);
1224 --si;
8
Null pointer value stored to 'si'
1225 memcpy(si, &(sin->info), sizeof(jvmtiStackInfo));
9
Null pointer passed to 1st parameter expecting 'nonnull'
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)
;
1
Assuming the condition is false
2
Taking false branch
3
Loop condition is false. Exiting loop
1281
1282 ResourceMark rm;
1283 _final_thread_count = 0;
1284 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
4
Loop condition is false. Execution continues on line 1296
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);
5
Calling 'MultipleStackTracesCollector::allocate_and_fill_stacks'
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}