Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiExport.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | ce8f6bb717c9 |
children | 7848fc12602b |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12117
diff
changeset
|
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "code/nmethod.hpp" | |
28 #include "code/pcDesc.hpp" | |
29 #include "code/scopeDesc.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "jvmtifiles/jvmtiEnv.hpp" | |
32 #include "memory/resourceArea.hpp" | |
33 #include "oops/objArrayKlass.hpp" | |
34 #include "oops/objArrayOop.hpp" | |
35 #include "prims/jvmtiCodeBlobEvents.hpp" | |
36 #include "prims/jvmtiEventController.hpp" | |
37 #include "prims/jvmtiEventController.inline.hpp" | |
38 #include "prims/jvmtiExport.hpp" | |
39 #include "prims/jvmtiImpl.hpp" | |
40 #include "prims/jvmtiManageCapabilities.hpp" | |
41 #include "prims/jvmtiRawMonitor.hpp" | |
42 #include "prims/jvmtiTagMap.hpp" | |
43 #include "prims/jvmtiThreadState.inline.hpp" | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
44 #include "prims/jvmtiRedefineClasses.hpp" |
1972 | 45 #include "runtime/arguments.hpp" |
46 #include "runtime/handles.hpp" | |
47 #include "runtime/interfaceSupport.hpp" | |
48 #include "runtime/objectMonitor.hpp" | |
49 #include "runtime/objectMonitor.inline.hpp" | |
20197
ce8f6bb717c9
8042195: Introduce umbrella header orderAccess.inline.hpp.
goetz
parents:
17937
diff
changeset
|
50 #include "runtime/thread.inline.hpp" |
1972 | 51 #include "runtime/vframe.hpp" |
52 #include "services/attachListener.hpp" | |
53 #include "services/serviceUtil.hpp" | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7469
diff
changeset
|
54 #include "utilities/macros.hpp" |
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7469
diff
changeset
|
55 #if INCLUDE_ALL_GCS |
1972 | 56 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7469
diff
changeset
|
57 #endif // INCLUDE_ALL_GCS |
0 | 58 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12117
diff
changeset
|
59 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12117
diff
changeset
|
60 |
0 | 61 #ifdef JVMTI_TRACE |
62 #define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; } | |
63 #define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; } | |
64 #else | |
65 #define EVT_TRIG_TRACE(evt,out) | |
66 #define EVT_TRACE(evt,out) | |
67 #endif | |
68 | |
69 /////////////////////////////////////////////////////////////// | |
70 // | |
71 // JvmtiEventTransition | |
72 // | |
73 // TO DO -- | |
74 // more handle purging | |
75 | |
76 // Use this for JavaThreads and state is _thread_in_vm. | |
77 class JvmtiJavaThreadEventTransition : StackObj { | |
78 private: | |
79 ResourceMark _rm; | |
80 ThreadToNativeFromVM _transition; | |
81 HandleMark _hm; | |
82 | |
83 public: | |
84 JvmtiJavaThreadEventTransition(JavaThread *thread) : | |
85 _rm(), | |
86 _transition(thread), | |
87 _hm(thread) {}; | |
88 }; | |
89 | |
90 // For JavaThreads which are not in _thread_in_vm state | |
91 // and other system threads use this. | |
92 class JvmtiThreadEventTransition : StackObj { | |
93 private: | |
94 ResourceMark _rm; | |
95 HandleMark _hm; | |
96 JavaThreadState _saved_state; | |
97 JavaThread *_jthread; | |
98 | |
99 public: | |
100 JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm() { | |
101 if (thread->is_Java_thread()) { | |
102 _jthread = (JavaThread *)thread; | |
103 _saved_state = _jthread->thread_state(); | |
104 if (_saved_state == _thread_in_Java) { | |
105 ThreadStateTransition::transition_from_java(_jthread, _thread_in_native); | |
106 } else { | |
107 ThreadStateTransition::transition(_jthread, _saved_state, _thread_in_native); | |
108 } | |
109 } else { | |
110 _jthread = NULL; | |
111 } | |
112 } | |
113 | |
114 ~JvmtiThreadEventTransition() { | |
115 if (_jthread != NULL) | |
116 ThreadStateTransition::transition_from_native(_jthread, _saved_state); | |
117 } | |
118 }; | |
119 | |
120 | |
121 /////////////////////////////////////////////////////////////// | |
122 // | |
123 // JvmtiEventMark | |
124 // | |
125 | |
126 class JvmtiEventMark : public StackObj { | |
127 private: | |
128 JavaThread *_thread; | |
129 JNIEnv* _jni_env; | |
130 bool _exception_detected; | |
131 bool _exception_caught; | |
132 #if 0 | |
133 JNIHandleBlock* _hblock; | |
134 #endif | |
135 | |
136 public: | |
137 JvmtiEventMark(JavaThread *thread) : _thread(thread), | |
138 _jni_env(thread->jni_environment()) { | |
139 #if 0 | |
140 _hblock = thread->active_handles(); | |
141 _hblock->clear_thoroughly(); // so we can be safe | |
142 #else | |
143 // we want to use the code above - but that needs the JNIHandle changes - later... | |
144 // for now, steal JNI push local frame code | |
145 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
146 // we are before an event. | |
147 // Save current jvmti thread exception state. | |
148 if (state != NULL) { | |
149 _exception_detected = state->is_exception_detected(); | |
150 _exception_caught = state->is_exception_caught(); | |
151 } else { | |
152 _exception_detected = false; | |
153 _exception_caught = false; | |
154 } | |
155 | |
156 JNIHandleBlock* old_handles = thread->active_handles(); | |
157 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); | |
158 assert(new_handles != NULL, "should not be NULL"); | |
159 new_handles->set_pop_frame_link(old_handles); | |
160 thread->set_active_handles(new_handles); | |
161 #endif | |
162 assert(thread == JavaThread::current(), "thread must be current!"); | |
163 thread->frame_anchor()->make_walkable(thread); | |
164 }; | |
165 | |
166 ~JvmtiEventMark() { | |
167 #if 0 | |
168 _hblock->clear(); // for consistency with future correct behavior | |
169 #else | |
170 // we want to use the code above - but that needs the JNIHandle changes - later... | |
171 // for now, steal JNI pop local frame code | |
172 JNIHandleBlock* old_handles = _thread->active_handles(); | |
173 JNIHandleBlock* new_handles = old_handles->pop_frame_link(); | |
174 assert(new_handles != NULL, "should not be NULL"); | |
175 _thread->set_active_handles(new_handles); | |
176 // Note that we set the pop_frame_link to NULL explicitly, otherwise | |
177 // the release_block call will release the blocks. | |
178 old_handles->set_pop_frame_link(NULL); | |
179 JNIHandleBlock::release_block(old_handles, _thread); // may block | |
180 #endif | |
181 | |
182 JvmtiThreadState* state = _thread->jvmti_thread_state(); | |
183 // we are continuing after an event. | |
184 if (state != NULL) { | |
185 // Restore the jvmti thread exception state. | |
186 if (_exception_detected) { | |
187 state->set_exception_detected(); | |
188 } | |
189 if (_exception_caught) { | |
190 state->set_exception_caught(); | |
191 } | |
192 } | |
193 } | |
194 | |
195 #if 0 | |
196 jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); } | |
197 #else | |
198 // we want to use the code above - but that needs the JNIHandle changes - later... | |
199 // for now, use regular make_local | |
200 jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); } | |
201 #endif | |
202 | |
6983 | 203 jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); } |
0 | 204 |
205 jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); } | |
206 | |
207 JNIEnv* jni_env() { return _jni_env; } | |
208 }; | |
209 | |
210 class JvmtiThreadEventMark : public JvmtiEventMark { | |
211 private: | |
212 jthread _jt; | |
213 | |
214 public: | |
215 JvmtiThreadEventMark(JavaThread *thread) : | |
216 JvmtiEventMark(thread) { | |
217 _jt = (jthread)(to_jobject(thread->threadObj())); | |
218 }; | |
219 jthread jni_thread() { return _jt; } | |
220 }; | |
221 | |
222 class JvmtiClassEventMark : public JvmtiThreadEventMark { | |
223 private: | |
224 jclass _jc; | |
225 | |
226 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
227 JvmtiClassEventMark(JavaThread *thread, Klass* klass) : |
0 | 228 JvmtiThreadEventMark(thread) { |
229 _jc = to_jclass(klass); | |
230 }; | |
231 jclass jni_class() { return _jc; } | |
232 }; | |
233 | |
234 class JvmtiMethodEventMark : public JvmtiThreadEventMark { | |
235 private: | |
236 jmethodID _mid; | |
237 | |
238 public: | |
239 JvmtiMethodEventMark(JavaThread *thread, methodHandle method) : | |
240 JvmtiThreadEventMark(thread), | |
241 _mid(to_jmethodID(method)) {}; | |
242 jmethodID jni_methodID() { return _mid; } | |
243 }; | |
244 | |
245 class JvmtiLocationEventMark : public JvmtiMethodEventMark { | |
246 private: | |
247 jlocation _loc; | |
248 | |
249 public: | |
250 JvmtiLocationEventMark(JavaThread *thread, methodHandle method, address location) : | |
251 JvmtiMethodEventMark(thread, method), | |
252 _loc(location - method->code_base()) {}; | |
253 jlocation location() { return _loc; } | |
254 }; | |
255 | |
256 class JvmtiExceptionEventMark : public JvmtiLocationEventMark { | |
257 private: | |
258 jobject _exc; | |
259 | |
260 public: | |
261 JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) : | |
262 JvmtiLocationEventMark(thread, method, location), | |
263 _exc(to_jobject(exception())) {}; | |
264 jobject exception() { return _exc; } | |
265 }; | |
266 | |
267 class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark { | |
268 private: | |
269 const char *_class_name; | |
270 jobject _jloader; | |
271 jobject _protection_domain; | |
272 jclass _class_being_redefined; | |
273 | |
274 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
275 JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name, |
0 | 276 Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
277 _class_name = name != NULL? name->as_utf8() : NULL; |
0 | 278 _jloader = (jobject)to_jobject(class_loader()); |
279 _protection_domain = (jobject)to_jobject(prot_domain()); | |
280 if (class_being_redefined == NULL) { | |
281 _class_being_redefined = NULL; | |
282 } else { | |
283 _class_being_redefined = (jclass)to_jclass((*class_being_redefined)()); | |
284 } | |
285 }; | |
286 const char *class_name() { | |
287 return _class_name; | |
288 } | |
289 jobject jloader() { | |
290 return _jloader; | |
291 } | |
292 jobject protection_domain() { | |
293 return _protection_domain; | |
294 } | |
295 jclass class_being_redefined() { | |
296 return _class_being_redefined; | |
297 } | |
298 }; | |
299 | |
300 ////////////////////////////////////////////////////////////////////////////// | |
301 | |
302 int JvmtiExport::_field_access_count = 0; | |
303 int JvmtiExport::_field_modification_count = 0; | |
304 | |
305 bool JvmtiExport::_can_access_local_variables = false; | |
306 bool JvmtiExport::_can_hotswap_or_post_breakpoint = false; | |
307 bool JvmtiExport::_can_modify_any_class = false; | |
308 bool JvmtiExport::_can_walk_any_space = false; | |
309 | |
310 bool JvmtiExport::_has_redefined_a_class = false; | |
311 bool JvmtiExport::_all_dependencies_are_recorded = false; | |
312 | |
313 // | |
314 // field access management | |
315 // | |
316 | |
317 // interpreter generator needs the address of the counter | |
318 address JvmtiExport::get_field_access_count_addr() { | |
319 // We don't grab a lock because we don't want to | |
320 // serialize field access between all threads. This means that a | |
321 // thread on another processor can see the wrong count value and | |
322 // may either miss making a needed call into post_field_access() | |
323 // or will make an unneeded call into post_field_access(). We pay | |
324 // this price to avoid slowing down the VM when we aren't watching | |
325 // field accesses. | |
326 // Other access/mutation safe by virtue of being in VM state. | |
327 return (address)(&_field_access_count); | |
328 } | |
329 | |
330 // | |
331 // field modification management | |
332 // | |
333 | |
334 // interpreter generator needs the address of the counter | |
335 address JvmtiExport::get_field_modification_count_addr() { | |
336 // We don't grab a lock because we don't | |
337 // want to serialize field modification between all threads. This | |
338 // means that a thread on another processor can see the wrong | |
339 // count value and may either miss making a needed call into | |
340 // post_field_modification() or will make an unneeded call into | |
341 // post_field_modification(). We pay this price to avoid slowing | |
342 // down the VM when we aren't watching field modifications. | |
343 // Other access/mutation safe by virtue of being in VM state. | |
344 return (address)(&_field_modification_count); | |
345 } | |
346 | |
347 | |
348 /////////////////////////////////////////////////////////////// | |
349 // Functions needed by java.lang.instrument for starting up javaagent. | |
350 /////////////////////////////////////////////////////////////// | |
351 | |
352 jint | |
353 JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) { | |
1121 | 354 // The JVMTI_VERSION_INTERFACE_JVMTI part of the version number |
355 // has already been validated in JNI GetEnv(). | |
356 int major, minor, micro; | |
357 | |
358 // micro version doesn't matter here (yet?) | |
359 decode_version_values(version, &major, &minor, µ); | |
360 switch (major) { | |
1988 | 361 case 1: |
1121 | 362 switch (minor) { |
1988 | 363 case 0: // version 1.0.<micro> is recognized |
364 case 1: // version 1.1.<micro> is recognized | |
365 case 2: // version 1.2.<micro> is recognized | |
1121 | 366 break; |
367 | |
1988 | 368 default: |
1121 | 369 return JNI_EVERSION; // unsupported minor version number |
370 } | |
371 break; | |
1988 | 372 default: |
1121 | 373 return JNI_EVERSION; // unsupported major version number |
374 } | |
0 | 375 |
376 if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) { | |
377 JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread(); | |
378 // transition code: native to VM | |
379 ThreadInVMfromNative __tiv(current_thread); | |
4045
a6eef545f1a2
7103224: collision between __LEAF define in interfaceSupport.hpp and /usr/include/sys/cdefs.h with gcc
never
parents:
3304
diff
changeset
|
380 VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread) |
0 | 381 debug_only(VMNativeEntryWrapper __vew;) |
382 | |
1121 | 383 JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); |
0 | 384 *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* |
385 return JNI_OK; | |
386 | |
387 } else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { | |
388 // not live, no thread to transition | |
1121 | 389 JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); |
0 | 390 *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* |
391 return JNI_OK; | |
392 | |
393 } else { | |
394 // Called at the wrong time | |
395 *penv = NULL; | |
396 return JNI_EDETACHED; | |
397 } | |
398 } | |
399 | |
1121 | 400 |
401 void | |
402 JvmtiExport::decode_version_values(jint version, int * major, int * minor, | |
403 int * micro) { | |
404 *major = (version & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; | |
405 *minor = (version & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; | |
406 *micro = (version & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; | |
407 } | |
408 | |
0 | 409 void JvmtiExport::enter_primordial_phase() { |
410 JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL); | |
411 } | |
412 | |
413 void JvmtiExport::enter_start_phase() { | |
414 JvmtiManageCapabilities::recompute_always_capabilities(); | |
415 JvmtiEnvBase::set_phase(JVMTI_PHASE_START); | |
416 } | |
417 | |
418 void JvmtiExport::enter_onload_phase() { | |
419 JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD); | |
420 } | |
421 | |
422 void JvmtiExport::enter_live_phase() { | |
423 JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE); | |
424 } | |
425 | |
426 // | |
427 // JVMTI events that the VM posts to the debugger and also startup agent | |
428 // and call the agent's premain() for java.lang.instrument. | |
429 // | |
430 | |
431 void JvmtiExport::post_vm_start() { | |
432 EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" )); | |
433 | |
434 // can now enable some events | |
435 JvmtiEventController::vm_start(); | |
436 | |
437 JvmtiEnvIterator it; | |
438 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
439 if (env->is_enabled(JVMTI_EVENT_VM_START)) { | |
440 EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" )); | |
441 | |
442 JavaThread *thread = JavaThread::current(); | |
443 JvmtiThreadEventMark jem(thread); | |
444 JvmtiJavaThreadEventTransition jet(thread); | |
445 jvmtiEventVMStart callback = env->callbacks()->VMStart; | |
446 if (callback != NULL) { | |
447 (*callback)(env->jvmti_external(), jem.jni_env()); | |
448 } | |
449 } | |
450 } | |
451 } | |
452 | |
453 | |
454 void JvmtiExport::post_vm_initialized() { | |
455 EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" )); | |
456 | |
457 // can now enable events | |
458 JvmtiEventController::vm_init(); | |
459 | |
460 JvmtiEnvIterator it; | |
461 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
462 if (env->is_enabled(JVMTI_EVENT_VM_INIT)) { | |
463 EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" )); | |
464 | |
465 JavaThread *thread = JavaThread::current(); | |
466 JvmtiThreadEventMark jem(thread); | |
467 JvmtiJavaThreadEventTransition jet(thread); | |
468 jvmtiEventVMInit callback = env->callbacks()->VMInit; | |
469 if (callback != NULL) { | |
470 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); | |
471 } | |
472 } | |
473 } | |
474 } | |
475 | |
476 | |
477 void JvmtiExport::post_vm_death() { | |
478 EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" )); | |
479 | |
480 JvmtiEnvIterator it; | |
481 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
482 if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) { | |
483 EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" )); | |
484 | |
485 JavaThread *thread = JavaThread::current(); | |
486 JvmtiEventMark jem(thread); | |
487 JvmtiJavaThreadEventTransition jet(thread); | |
488 jvmtiEventVMDeath callback = env->callbacks()->VMDeath; | |
489 if (callback != NULL) { | |
490 (*callback)(env->jvmti_external(), jem.jni_env()); | |
491 } | |
492 } | |
493 } | |
494 | |
495 JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD); | |
496 JvmtiEventController::vm_death(); | |
497 } | |
498 | |
499 char** | |
500 JvmtiExport::get_all_native_method_prefixes(int* count_ptr) { | |
501 // Have to grab JVMTI thread state lock to be sure environment doesn't | |
502 // go away while we iterate them. No locks during VM bring-up. | |
503 if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { | |
504 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); | |
505 } else { | |
506 MutexLocker mu(JvmtiThreadState_lock); | |
507 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); | |
508 } | |
509 } | |
510 | |
511 class JvmtiClassFileLoadHookPoster : public StackObj { | |
512 private: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
513 Symbol* _h_name; |
0 | 514 Handle _class_loader; |
515 Handle _h_protection_domain; | |
516 unsigned char ** _data_ptr; | |
517 unsigned char ** _end_ptr; | |
518 JavaThread * _thread; | |
519 jint _curr_len; | |
520 unsigned char * _curr_data; | |
521 JvmtiEnv * _curr_env; | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
522 JvmtiCachedClassFileData ** _cached_class_file_ptr; |
0 | 523 JvmtiThreadState * _state; |
524 KlassHandle * _h_class_being_redefined; | |
525 JvmtiClassLoadKind _load_kind; | |
526 | |
527 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
528 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader, |
0 | 529 Handle h_protection_domain, |
530 unsigned char **data_ptr, unsigned char **end_ptr, | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
531 JvmtiCachedClassFileData **cache_ptr) { |
0 | 532 _h_name = h_name; |
533 _class_loader = class_loader; | |
534 _h_protection_domain = h_protection_domain; | |
535 _data_ptr = data_ptr; | |
536 _end_ptr = end_ptr; | |
537 _thread = JavaThread::current(); | |
538 _curr_len = *end_ptr - *data_ptr; | |
539 _curr_data = *data_ptr; | |
540 _curr_env = NULL; | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
541 _cached_class_file_ptr = cache_ptr; |
0 | 542 |
543 _state = _thread->jvmti_thread_state(); | |
544 if (_state != NULL) { | |
545 _h_class_being_redefined = _state->get_class_being_redefined(); | |
546 _load_kind = _state->get_class_load_kind(); | |
547 // Clear class_being_redefined flag here. The action | |
548 // from agent handler could generate a new class file load | |
549 // hook event and if it is not cleared the new event generated | |
550 // from regular class file load could have this stale redefined | |
551 // class handle info. | |
552 _state->clear_class_being_redefined(); | |
553 } else { | |
554 // redefine and retransform will always set the thread state | |
555 _h_class_being_redefined = (KlassHandle *) NULL; | |
556 _load_kind = jvmti_class_load_kind_load; | |
557 } | |
558 } | |
559 | |
560 void post() { | |
561 // EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, | |
562 // ("JVMTI [%s] class file load hook event triggered", | |
563 // JvmtiTrace::safe_get_thread_name(_thread))); | |
564 post_all_envs(); | |
565 copy_modified_data(); | |
566 } | |
567 | |
568 private: | |
569 void post_all_envs() { | |
570 if (_load_kind != jvmti_class_load_kind_retransform) { | |
571 // for class load and redefine, | |
572 // call the non-retransformable agents | |
573 JvmtiEnvIterator it; | |
574 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
575 if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { | |
576 // non-retransformable agents cannot retransform back, | |
577 // so no need to cache the original class file bytes | |
578 post_to_env(env, false); | |
579 } | |
580 } | |
581 } | |
582 JvmtiEnvIterator it; | |
583 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
584 // retransformable agents get all events | |
585 if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { | |
586 // retransformable agents need to cache the original class file | |
587 // bytes if changes are made via the ClassFileLoadHook | |
588 post_to_env(env, true); | |
589 } | |
590 } | |
591 } | |
592 | |
593 void post_to_env(JvmtiEnv* env, bool caching_needed) { | |
594 unsigned char *new_data = NULL; | |
595 jint new_len = 0; | |
596 // EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, | |
597 // ("JVMTI [%s] class file load hook event sent %s data_ptr = %d, data_len = %d", | |
598 // JvmtiTrace::safe_get_thread_name(_thread), | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
599 // _h_name == NULL ? "NULL" : _h_name->as_utf8(), |
0 | 600 // _curr_data, _curr_len )); |
601 JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, | |
602 _h_protection_domain, | |
603 _h_class_being_redefined); | |
604 JvmtiJavaThreadEventTransition jet(_thread); | |
605 JNIEnv* jni_env = (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)? | |
606 NULL : jem.jni_env(); | |
607 jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook; | |
608 if (callback != NULL) { | |
609 (*callback)(env->jvmti_external(), jni_env, | |
610 jem.class_being_redefined(), | |
611 jem.jloader(), jem.class_name(), | |
612 jem.protection_domain(), | |
613 _curr_len, _curr_data, | |
614 &new_len, &new_data); | |
615 } | |
616 if (new_data != NULL) { | |
617 // this agent has modified class data. | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
618 if (caching_needed && *_cached_class_file_ptr == NULL) { |
0 | 619 // data has been changed by the new retransformable agent |
620 // and it hasn't already been cached, cache it | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
621 JvmtiCachedClassFileData *p; |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
622 p = (JvmtiCachedClassFileData *)os::malloc( |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
623 offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal); |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
624 if (p == NULL) { |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
625 vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len, |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
626 OOM_MALLOC_ERROR, |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
627 "unable to allocate cached copy of original class bytes"); |
10263
0b7f78069732
8008255: jvmtiExport.cpp::post_to_env() does not check malloc() return
rbackman
parents:
8003
diff
changeset
|
628 } |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
629 p->length = _curr_len; |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
630 memcpy(p->data, _curr_data, _curr_len); |
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
631 *_cached_class_file_ptr = p; |
0 | 632 } |
633 | |
634 if (_curr_data != *_data_ptr) { | |
635 // curr_data is previous agent modified class data. | |
636 // And this has been changed by the new agent so | |
637 // we can delete it now. | |
638 _curr_env->Deallocate(_curr_data); | |
639 } | |
640 | |
641 // Class file data has changed by the current agent. | |
642 _curr_data = new_data; | |
643 _curr_len = new_len; | |
644 // Save the current agent env we need this to deallocate the | |
645 // memory allocated by this agent. | |
646 _curr_env = env; | |
647 } | |
648 } | |
649 | |
650 void copy_modified_data() { | |
651 // if one of the agent has modified class file data. | |
652 // Copy modified class data to new resources array. | |
653 if (_curr_data != *_data_ptr) { | |
654 *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len); | |
655 memcpy(*_data_ptr, _curr_data, _curr_len); | |
656 *_end_ptr = *_data_ptr + _curr_len; | |
657 _curr_env->Deallocate(_curr_data); | |
658 } | |
659 } | |
660 }; | |
661 | |
662 bool JvmtiExport::_should_post_class_file_load_hook = false; | |
663 | |
664 // this entry is for class file load hook on class load, redefine and retransform | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
665 void JvmtiExport::post_class_file_load_hook(Symbol* h_name, |
0 | 666 Handle class_loader, |
667 Handle h_protection_domain, | |
668 unsigned char **data_ptr, | |
669 unsigned char **end_ptr, | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
670 JvmtiCachedClassFileData **cache_ptr) { |
0 | 671 JvmtiClassFileLoadHookPoster poster(h_name, class_loader, |
672 h_protection_domain, | |
673 data_ptr, end_ptr, | |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10299
diff
changeset
|
674 cache_ptr); |
0 | 675 poster.post(); |
676 } | |
677 | |
678 void JvmtiExport::report_unsupported(bool on) { | |
679 // If any JVMTI service is turned on, we need to exit before native code | |
680 // tries to access nonexistant services. | |
681 if (on) { | |
682 vm_exit_during_initialization("Java Kernel does not support JVMTI."); | |
683 } | |
684 } | |
685 | |
686 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
687 static inline Klass* oop_to_klass(oop obj) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
688 Klass* k = obj->klass(); |
0 | 689 |
690 // if the object is a java.lang.Class then return the java mirror | |
1142 | 691 if (k == SystemDictionary::Class_klass()) { |
0 | 692 if (!java_lang_Class::is_primitive(obj)) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
693 k = java_lang_Class::as_Klass(obj); |
0 | 694 assert(k != NULL, "class for non-primitive mirror must exist"); |
695 } | |
696 } | |
697 return k; | |
698 } | |
699 | |
700 class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark { | |
701 private: | |
702 jobject _jobj; | |
703 jlong _size; | |
704 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
705 JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) { |
0 | 706 _jobj = (jobject)to_jobject(obj); |
707 _size = obj->size() * wordSize; | |
708 }; | |
709 jobject jni_jobject() { return _jobj; } | |
710 jlong size() { return _size; } | |
711 }; | |
712 | |
713 class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark { | |
714 private: | |
715 jint _code_size; | |
716 const void *_code_data; | |
717 jint _map_length; | |
718 jvmtiAddrLocationMap *_map; | |
719 const void *_compile_info; | |
720 public: | |
1184
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
721 JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL) |
0 | 722 : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { |
1748 | 723 _code_data = nm->insts_begin(); |
724 _code_size = nm->insts_size(); | |
1184
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
725 _compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL. |
0 | 726 JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length); |
727 } | |
728 ~JvmtiCompiledMethodLoadEventMark() { | |
6197 | 729 FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map, mtInternal); |
0 | 730 } |
731 | |
732 jint code_size() { return _code_size; } | |
733 const void *code_data() { return _code_data; } | |
734 jint map_length() { return _map_length; } | |
735 const jvmtiAddrLocationMap* map() { return _map; } | |
736 const void *compile_info() { return _compile_info; } | |
737 }; | |
738 | |
739 | |
740 | |
741 class JvmtiMonitorEventMark : public JvmtiThreadEventMark { | |
742 private: | |
743 jobject _jobj; | |
744 public: | |
745 JvmtiMonitorEventMark(JavaThread *thread, oop object) | |
746 : JvmtiThreadEventMark(thread){ | |
747 _jobj = to_jobject(object); | |
748 } | |
749 jobject jni_object() { return _jobj; } | |
750 }; | |
751 | |
752 /////////////////////////////////////////////////////////////// | |
753 // | |
754 // pending CompiledMethodUnload support | |
755 // | |
756 | |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
757 void JvmtiExport::post_compiled_method_unload( |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
758 jmethodID method, const void *code_begin) { |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
759 JavaThread* thread = JavaThread::current(); |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
760 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
761 ("JVMTI [%s] method compile unload event triggered", |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
762 JvmtiTrace::safe_get_thread_name(thread))); |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
763 |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
764 // post the event for each environment that has this event enabled. |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
765 JvmtiEnvIterator it; |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
766 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
767 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
768 |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
769 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
770 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
771 JvmtiTrace::safe_get_thread_name(thread), method)); |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
772 |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
773 ResourceMark rm(thread); |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
774 |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
775 JvmtiEventMark jem(thread); |
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
776 JvmtiJavaThreadEventTransition jet(thread); |
1577
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
777 jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
778 if (callback != NULL) { |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
779 (*callback)(env->jvmti_external(), method, code_begin); |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
780 } |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
781 } |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
782 } |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
783 } |
852d0157c696
6956931: assert(SafepointSynchronize::is_at_safepoint()) failed: must be executed at a safepoint
never
parents:
1397
diff
changeset
|
784 |
0 | 785 /////////////////////////////////////////////////////////////// |
786 // | |
787 // JvmtiExport | |
788 // | |
789 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
790 void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, address location) { |
0 | 791 HandleMark hm(thread); |
792 methodHandle mh(thread, method); | |
793 | |
794 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
795 if (state == NULL) { | |
796 return; | |
797 } | |
798 EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered", | |
799 JvmtiTrace::safe_get_thread_name(thread))); | |
800 JvmtiEnvThreadStateIterator it(state); | |
801 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
802 ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT); | |
803 if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) { | |
804 ThreadState old_os_state = thread->osthread()->get_state(); | |
805 thread->osthread()->set_state(BREAKPOINTED); | |
806 EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d", | |
807 JvmtiTrace::safe_get_thread_name(thread), | |
808 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
809 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
810 location - mh()->code_base() )); | |
811 | |
812 JvmtiEnv *env = ets->get_env(); | |
813 JvmtiLocationEventMark jem(thread, mh, location); | |
814 JvmtiJavaThreadEventTransition jet(thread); | |
815 jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint; | |
816 if (callback != NULL) { | |
817 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
818 jem.jni_methodID(), jem.location()); | |
819 } | |
820 | |
821 ets->set_breakpoint_posted(); | |
822 thread->osthread()->set_state(old_os_state); | |
823 } | |
824 } | |
825 } | |
826 | |
827 ////////////////////////////////////////////////////////////////////////////// | |
828 | |
829 bool JvmtiExport::_can_get_source_debug_extension = false; | |
830 bool JvmtiExport::_can_maintain_original_method_order = false; | |
831 bool JvmtiExport::_can_post_interpreter_events = false; | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1185
diff
changeset
|
832 bool JvmtiExport::_can_post_on_exceptions = false; |
0 | 833 bool JvmtiExport::_can_post_breakpoint = false; |
834 bool JvmtiExport::_can_post_field_access = false; | |
835 bool JvmtiExport::_can_post_field_modification = false; | |
836 bool JvmtiExport::_can_post_method_entry = false; | |
837 bool JvmtiExport::_can_post_method_exit = false; | |
838 bool JvmtiExport::_can_pop_frame = false; | |
839 bool JvmtiExport::_can_force_early_return = false; | |
840 | |
841 bool JvmtiExport::_should_post_single_step = false; | |
842 bool JvmtiExport::_should_post_field_access = false; | |
843 bool JvmtiExport::_should_post_field_modification = false; | |
844 bool JvmtiExport::_should_post_class_load = false; | |
845 bool JvmtiExport::_should_post_class_prepare = false; | |
846 bool JvmtiExport::_should_post_class_unload = false; | |
847 bool JvmtiExport::_should_post_thread_life = false; | |
848 bool JvmtiExport::_should_clean_up_heap_objects = false; | |
849 bool JvmtiExport::_should_post_native_method_bind = false; | |
850 bool JvmtiExport::_should_post_dynamic_code_generated = false; | |
851 bool JvmtiExport::_should_post_data_dump = false; | |
852 bool JvmtiExport::_should_post_compiled_method_load = false; | |
853 bool JvmtiExport::_should_post_compiled_method_unload = false; | |
854 bool JvmtiExport::_should_post_monitor_contended_enter = false; | |
855 bool JvmtiExport::_should_post_monitor_contended_entered = false; | |
856 bool JvmtiExport::_should_post_monitor_wait = false; | |
857 bool JvmtiExport::_should_post_monitor_waited = false; | |
858 bool JvmtiExport::_should_post_garbage_collection_start = false; | |
859 bool JvmtiExport::_should_post_garbage_collection_finish = false; | |
860 bool JvmtiExport::_should_post_object_free = false; | |
861 bool JvmtiExport::_should_post_resource_exhausted = false; | |
862 bool JvmtiExport::_should_post_vm_object_alloc = false; | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1185
diff
changeset
|
863 bool JvmtiExport::_should_post_on_exceptions = false; |
0 | 864 |
865 //////////////////////////////////////////////////////////////////////////////////////////////// | |
866 | |
867 | |
868 // | |
869 // JVMTI single step management | |
870 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
871 void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, address location) { |
0 | 872 assert(JvmtiExport::should_post_single_step(), "must be single stepping"); |
873 | |
874 HandleMark hm(thread); | |
875 methodHandle mh(thread, method); | |
876 | |
877 // update information about current location and post a step event | |
878 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
879 if (state == NULL) { | |
880 return; | |
881 } | |
882 EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered", | |
883 JvmtiTrace::safe_get_thread_name(thread))); | |
884 if (!state->hide_single_stepping()) { | |
885 if (state->is_pending_step_for_popframe()) { | |
886 state->process_pending_step_for_popframe(); | |
887 } | |
888 if (state->is_pending_step_for_earlyret()) { | |
889 state->process_pending_step_for_earlyret(); | |
890 } | |
891 JvmtiExport::post_single_step(thread, mh(), location); | |
892 } | |
893 } | |
894 | |
895 | |
896 void JvmtiExport::expose_single_stepping(JavaThread *thread) { | |
897 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
898 if (state != NULL) { | |
899 state->clear_hide_single_stepping(); | |
900 } | |
901 } | |
902 | |
903 | |
904 bool JvmtiExport::hide_single_stepping(JavaThread *thread) { | |
905 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
906 if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { | |
907 state->set_hide_single_stepping(); | |
908 return true; | |
909 } else { | |
910 return false; | |
911 } | |
912 } | |
913 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
914 void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) { |
0 | 915 HandleMark hm(thread); |
916 KlassHandle kh(thread, klass); | |
917 | |
918 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Trg Class Load triggered", | |
919 JvmtiTrace::safe_get_thread_name(thread))); | |
920 JvmtiThreadState* state = thread->jvmti_thread_state(); | |
921 if (state == NULL) { | |
922 return; | |
923 } | |
924 JvmtiEnvThreadStateIterator it(state); | |
925 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
926 if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) { | |
927 EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Evt Class Load sent %s", | |
928 JvmtiTrace::safe_get_thread_name(thread), | |
6983 | 929 kh()==NULL? "NULL" : kh()->external_name() )); |
0 | 930 |
931 JvmtiEnv *env = ets->get_env(); | |
932 JvmtiClassEventMark jem(thread, kh()); | |
933 JvmtiJavaThreadEventTransition jet(thread); | |
934 jvmtiEventClassLoad callback = env->callbacks()->ClassLoad; | |
935 if (callback != NULL) { | |
936 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class()); | |
937 } | |
938 } | |
939 } | |
940 } | |
941 | |
942 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
943 void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) { |
0 | 944 HandleMark hm(thread); |
945 KlassHandle kh(thread, klass); | |
946 | |
947 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Trg Class Prepare triggered", | |
948 JvmtiTrace::safe_get_thread_name(thread))); | |
949 JvmtiThreadState* state = thread->jvmti_thread_state(); | |
950 if (state == NULL) { | |
951 return; | |
952 } | |
953 JvmtiEnvThreadStateIterator it(state); | |
954 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
955 if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) { | |
956 EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Evt Class Prepare sent %s", | |
957 JvmtiTrace::safe_get_thread_name(thread), | |
6983 | 958 kh()==NULL? "NULL" : kh()->external_name() )); |
0 | 959 |
960 JvmtiEnv *env = ets->get_env(); | |
961 JvmtiClassEventMark jem(thread, kh()); | |
962 JvmtiJavaThreadEventTransition jet(thread); | |
963 jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare; | |
964 if (callback != NULL) { | |
965 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class()); | |
966 } | |
967 } | |
968 } | |
969 } | |
970 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
971 void JvmtiExport::post_class_unload(Klass* klass) { |
0 | 972 Thread *thread = Thread::current(); |
973 HandleMark hm(thread); | |
974 KlassHandle kh(thread, klass); | |
975 | |
976 EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Trg Class Unload triggered" )); | |
977 if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { | |
978 assert(thread->is_VM_thread(), "wrong thread"); | |
979 | |
980 // get JavaThread for whom we are proxy | |
981 JavaThread *real_thread = | |
982 (JavaThread *)((VMThread *)thread)->vm_operation()->calling_thread(); | |
983 | |
984 JvmtiEnvIterator it; | |
985 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
986 if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { | |
987 EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Evt Class Unload sent %s", | |
6983 | 988 kh()==NULL? "NULL" : kh()->external_name() )); |
0 | 989 |
990 // do everything manually, since this is a proxy - needs special care | |
991 JNIEnv* jni_env = real_thread->jni_environment(); | |
992 jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj()); | |
6983 | 993 jclass jk = (jclass)JNIHandles::make_local(real_thread, kh()->java_mirror()); |
0 | 994 |
995 // Before we call the JVMTI agent, we have to set the state in the | |
996 // thread for which we are proxying. | |
997 JavaThreadState prev_state = real_thread->thread_state(); | |
998 assert(prev_state == _thread_blocked, "JavaThread should be at safepoint"); | |
999 real_thread->set_thread_state(_thread_in_native); | |
1000 | |
1001 jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload; | |
1002 if (callback != NULL) { | |
1003 (*callback)(env->jvmti_external(), jni_env, jt, jk); | |
1004 } | |
1005 | |
1006 assert(real_thread->thread_state() == _thread_in_native, | |
1007 "JavaThread should be in native"); | |
1008 real_thread->set_thread_state(prev_state); | |
1009 | |
1010 JNIHandles::destroy_local(jk); | |
1011 JNIHandles::destroy_local(jt); | |
1012 } | |
1013 } | |
1014 } | |
1015 } | |
1016 | |
1017 | |
1018 void JvmtiExport::post_thread_start(JavaThread *thread) { | |
1019 assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); | |
1020 | |
1021 EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Trg Thread Start event triggered", | |
1022 JvmtiTrace::safe_get_thread_name(thread))); | |
1023 | |
1024 // do JVMTI thread initialization (if needed) | |
1025 JvmtiEventController::thread_started(thread); | |
1026 | |
1027 // Do not post thread start event for hidden java thread. | |
1028 if (JvmtiEventController::is_enabled(JVMTI_EVENT_THREAD_START) && | |
1029 !thread->is_hidden_from_external_view()) { | |
1030 JvmtiEnvIterator it; | |
1031 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1032 if (env->is_enabled(JVMTI_EVENT_THREAD_START)) { | |
1033 EVT_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Evt Thread Start event sent", | |
1034 JvmtiTrace::safe_get_thread_name(thread) )); | |
1035 | |
1036 JvmtiThreadEventMark jem(thread); | |
1037 JvmtiJavaThreadEventTransition jet(thread); | |
1038 jvmtiEventThreadStart callback = env->callbacks()->ThreadStart; | |
1039 if (callback != NULL) { | |
1040 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); | |
1041 } | |
1042 } | |
1043 } | |
1044 } | |
1045 } | |
1046 | |
1047 | |
1048 void JvmtiExport::post_thread_end(JavaThread *thread) { | |
1049 EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Trg Thread End event triggered", | |
1050 JvmtiTrace::safe_get_thread_name(thread))); | |
1051 | |
1052 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1053 if (state == NULL) { | |
1054 return; | |
1055 } | |
1056 | |
1057 // Do not post thread end event for hidden java thread. | |
1058 if (state->is_enabled(JVMTI_EVENT_THREAD_END) && | |
1059 !thread->is_hidden_from_external_view()) { | |
1060 | |
1061 JvmtiEnvThreadStateIterator it(state); | |
1062 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1063 if (ets->is_enabled(JVMTI_EVENT_THREAD_END)) { | |
1064 EVT_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Evt Thread End event sent", | |
1065 JvmtiTrace::safe_get_thread_name(thread) )); | |
1066 | |
1067 JvmtiEnv *env = ets->get_env(); | |
1068 JvmtiThreadEventMark jem(thread); | |
1069 JvmtiJavaThreadEventTransition jet(thread); | |
1070 jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd; | |
1071 if (callback != NULL) { | |
1072 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); | |
1073 } | |
1074 } | |
1075 } | |
1076 } | |
1077 } | |
1078 | |
1079 void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) { | |
1080 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at safepoint"); | |
1081 assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking"); | |
1082 | |
1083 EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Trg Object Free triggered" )); | |
1084 EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Evt Object Free sent")); | |
1085 | |
1086 jvmtiEventObjectFree callback = env->callbacks()->ObjectFree; | |
1087 if (callback != NULL) { | |
1088 (*callback)(env->jvmti_external(), tag); | |
1089 } | |
1090 } | |
1091 | |
1092 void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const char* description) { | |
1093 EVT_TRIG_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Trg resource exhausted event triggered" )); | |
1094 | |
1095 JvmtiEnvIterator it; | |
1096 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1097 if (env->is_enabled(JVMTI_EVENT_RESOURCE_EXHAUSTED)) { | |
1098 EVT_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Evt resource exhausted event sent" )); | |
1099 | |
1100 JavaThread *thread = JavaThread::current(); | |
1101 JvmtiThreadEventMark jem(thread); | |
1102 JvmtiJavaThreadEventTransition jet(thread); | |
1103 jvmtiEventResourceExhausted callback = env->callbacks()->ResourceExhausted; | |
1104 if (callback != NULL) { | |
1105 (*callback)(env->jvmti_external(), jem.jni_env(), | |
1106 resource_exhausted_flags, NULL, description); | |
1107 } | |
1108 } | |
1109 } | |
1110 } | |
1111 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1112 void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame current_frame) { |
0 | 1113 HandleMark hm(thread); |
1114 methodHandle mh(thread, method); | |
1115 | |
1116 EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Trg Method Entry triggered %s.%s", | |
1117 JvmtiTrace::safe_get_thread_name(thread), | |
1118 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1119 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); | |
1120 | |
1121 JvmtiThreadState* state = thread->jvmti_thread_state(); | |
1122 if (state == NULL || !state->is_interp_only_mode()) { | |
1123 // for any thread that actually wants method entry, interp_only_mode is set | |
1124 return; | |
1125 } | |
1126 | |
1127 state->incr_cur_stack_depth(); | |
1128 | |
1129 if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) { | |
1130 JvmtiEnvThreadStateIterator it(state); | |
1131 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1132 if (ets->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) { | |
1133 EVT_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Evt Method Entry sent %s.%s", | |
1134 JvmtiTrace::safe_get_thread_name(thread), | |
1135 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1136 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); | |
1137 | |
1138 JvmtiEnv *env = ets->get_env(); | |
1139 JvmtiMethodEventMark jem(thread, mh); | |
1140 JvmtiJavaThreadEventTransition jet(thread); | |
1141 jvmtiEventMethodEntry callback = env->callbacks()->MethodEntry; | |
1142 if (callback != NULL) { | |
1143 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_methodID()); | |
1144 } | |
1145 } | |
1146 } | |
1147 } | |
1148 } | |
1149 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1150 void JvmtiExport::post_method_exit(JavaThread *thread, Method* method, frame current_frame) { |
0 | 1151 HandleMark hm(thread); |
1152 methodHandle mh(thread, method); | |
1153 | |
1154 EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Trg Method Exit triggered %s.%s", | |
1155 JvmtiTrace::safe_get_thread_name(thread), | |
1156 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1157 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); | |
1158 | |
1159 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1160 if (state == NULL || !state->is_interp_only_mode()) { | |
1161 // for any thread that actually wants method exit, interp_only_mode is set | |
1162 return; | |
1163 } | |
1164 | |
1165 // return a flag when a method terminates by throwing an exception | |
1166 // i.e. if an exception is thrown and it's not caught by the current method | |
1167 bool exception_exit = state->is_exception_detected() && !state->is_exception_caught(); | |
1168 | |
1169 | |
1170 if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { | |
1171 Handle result; | |
1172 jvalue value; | |
1173 value.j = 0L; | |
1174 | |
1175 // if the method hasn't been popped because of an exception then we populate | |
1176 // the return_value parameter for the callback. At this point we only have | |
1177 // the address of a "raw result" and we just call into the interpreter to | |
1178 // convert this into a jvalue. | |
1179 if (!exception_exit) { | |
1180 oop oop_result; | |
1181 BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); | |
1182 if (type == T_OBJECT || type == T_ARRAY) { | |
1183 result = Handle(thread, oop_result); | |
1184 } | |
1185 } | |
1186 | |
1187 JvmtiEnvThreadStateIterator it(state); | |
1188 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1189 if (ets->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { | |
1190 EVT_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Evt Method Exit sent %s.%s", | |
1191 JvmtiTrace::safe_get_thread_name(thread), | |
1192 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1193 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); | |
1194 | |
1195 JvmtiEnv *env = ets->get_env(); | |
1196 JvmtiMethodEventMark jem(thread, mh); | |
1197 if (result.not_null()) { | |
1198 value.l = JNIHandles::make_local(thread, result()); | |
1199 } | |
1200 JvmtiJavaThreadEventTransition jet(thread); | |
1201 jvmtiEventMethodExit callback = env->callbacks()->MethodExit; | |
1202 if (callback != NULL) { | |
1203 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1204 jem.jni_methodID(), exception_exit, value); | |
1205 } | |
1206 } | |
1207 } | |
1208 } | |
1209 | |
1210 if (state->is_enabled(JVMTI_EVENT_FRAME_POP)) { | |
1211 JvmtiEnvThreadStateIterator it(state); | |
1212 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1213 int cur_frame_number = state->cur_stack_depth(); | |
1214 | |
1215 if (ets->is_frame_pop(cur_frame_number)) { | |
1216 // we have a NotifyFramePop entry for this frame. | |
1217 // now check that this env/thread wants this event | |
1218 if (ets->is_enabled(JVMTI_EVENT_FRAME_POP)) { | |
1219 EVT_TRACE(JVMTI_EVENT_FRAME_POP, ("JVMTI [%s] Evt Frame Pop sent %s.%s", | |
1220 JvmtiTrace::safe_get_thread_name(thread), | |
1221 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1222 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); | |
1223 | |
1224 // we also need to issue a frame pop event for this frame | |
1225 JvmtiEnv *env = ets->get_env(); | |
1226 JvmtiMethodEventMark jem(thread, mh); | |
1227 JvmtiJavaThreadEventTransition jet(thread); | |
1228 jvmtiEventFramePop callback = env->callbacks()->FramePop; | |
1229 if (callback != NULL) { | |
1230 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1231 jem.jni_methodID(), exception_exit); | |
1232 } | |
1233 } | |
1234 // remove the frame's entry | |
1235 ets->clear_frame_pop(cur_frame_number); | |
1236 } | |
1237 } | |
1238 } | |
1239 | |
1240 state->decr_cur_stack_depth(); | |
1241 } | |
1242 | |
1243 | |
1244 // Todo: inline this for optimization | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1245 void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address location) { |
0 | 1246 HandleMark hm(thread); |
1247 methodHandle mh(thread, method); | |
1248 | |
1249 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1250 if (state == NULL) { | |
1251 return; | |
1252 } | |
1253 JvmtiEnvThreadStateIterator it(state); | |
1254 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1255 ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP); | |
1256 if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { | |
1257 EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d", | |
1258 JvmtiTrace::safe_get_thread_name(thread), | |
1259 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1260 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1261 location - mh()->code_base() )); | |
1262 | |
1263 JvmtiEnv *env = ets->get_env(); | |
1264 JvmtiLocationEventMark jem(thread, mh, location); | |
1265 JvmtiJavaThreadEventTransition jet(thread); | |
1266 jvmtiEventSingleStep callback = env->callbacks()->SingleStep; | |
1267 if (callback != NULL) { | |
1268 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1269 jem.jni_methodID(), jem.location()); | |
1270 } | |
1271 | |
1272 ets->set_single_stepping_posted(); | |
1273 } | |
1274 } | |
1275 } | |
1276 | |
1277 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1278 void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) { |
0 | 1279 HandleMark hm(thread); |
1280 methodHandle mh(thread, method); | |
1281 Handle exception_handle(thread, exception); | |
1282 | |
1283 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1284 if (state == NULL) { | |
1285 return; | |
1286 } | |
1287 | |
1288 EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("JVMTI [%s] Trg Exception thrown triggered", | |
1289 JvmtiTrace::safe_get_thread_name(thread))); | |
1290 if (!state->is_exception_detected()) { | |
1291 state->set_exception_detected(); | |
1292 JvmtiEnvThreadStateIterator it(state); | |
1293 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1294 if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) { | |
1295 | |
1296 EVT_TRACE(JVMTI_EVENT_EXCEPTION, | |
1297 ("JVMTI [%s] Evt Exception thrown sent %s.%s @ %d", | |
1298 JvmtiTrace::safe_get_thread_name(thread), | |
1299 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1300 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1301 location - mh()->code_base() )); | |
1302 | |
1303 JvmtiEnv *env = ets->get_env(); | |
1304 JvmtiExceptionEventMark jem(thread, mh, location, exception_handle); | |
1305 | |
1306 // It's okay to clear these exceptions here because we duplicate | |
1307 // this lookup in InterpreterRuntime::exception_handler_for_exception. | |
1308 EXCEPTION_MARK; | |
1309 | |
1310 bool should_repeat; | |
1311 vframeStream st(thread); | |
1312 assert(!st.at_end(), "cannot be at end"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1313 Method* current_method = NULL; |
7469
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1314 // A GC may occur during the Method::fast_exception_handler_bci_for() |
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1315 // call below if it needs to load the constraint class. Using a |
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1316 // methodHandle to keep the 'current_method' from being deallocated |
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1317 // if GC happens. |
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1318 methodHandle current_mh = methodHandle(thread, current_method); |
0 | 1319 int current_bci = -1; |
1320 do { | |
1321 current_method = st.method(); | |
7469
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1322 current_mh = methodHandle(thread, current_method); |
0 | 1323 current_bci = st.bci(); |
1324 do { | |
1325 should_repeat = false; | |
1326 KlassHandle eh_klass(thread, exception_handle()->klass()); | |
7469
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1327 current_bci = Method::fast_exception_handler_bci_for( |
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1328 current_mh, eh_klass, current_bci, THREAD); |
0 | 1329 if (HAS_PENDING_EXCEPTION) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1330 exception_handle = Handle(thread, PENDING_EXCEPTION); |
0 | 1331 CLEAR_PENDING_EXCEPTION; |
1332 should_repeat = true; | |
1333 } | |
1334 } while (should_repeat && (current_bci != -1)); | |
1335 st.next(); | |
1336 } while ((current_bci < 0) && (!st.at_end())); | |
1337 | |
1338 jmethodID catch_jmethodID; | |
1339 if (current_bci < 0) { | |
1340 catch_jmethodID = 0; | |
1341 current_bci = 0; | |
1342 } else { | |
7469
0c8717a92b2d
8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9.
jiangli
parents:
6985
diff
changeset
|
1343 catch_jmethodID = jem.to_jmethodID(current_mh); |
0 | 1344 } |
1345 | |
1346 JvmtiJavaThreadEventTransition jet(thread); | |
1347 jvmtiEventException callback = env->callbacks()->Exception; | |
1348 if (callback != NULL) { | |
1349 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1350 jem.jni_methodID(), jem.location(), | |
1351 jem.exception(), | |
1352 catch_jmethodID, current_bci); | |
1353 } | |
1354 } | |
1355 } | |
1356 } | |
1357 | |
1358 // frames may get popped because of this throw, be safe - invalidate cached depth | |
1359 state->invalidate_cur_stack_depth(); | |
1360 } | |
1361 | |
1362 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1363 void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) { |
0 | 1364 HandleMark hm(thread); |
1365 methodHandle mh(thread, method); | |
1366 Handle exception_handle(thread, exception); | |
1367 | |
1368 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1369 if (state == NULL) { | |
1370 return; | |
1371 } | |
1372 EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH, | |
1373 ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s%d - %s", | |
1374 JvmtiTrace::safe_get_thread_name(thread), | |
1375 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1376 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1377 location==0? "no location:" : "", | |
1378 location==0? 0 : location - mh()->code_base(), | |
1379 in_handler_frame? "in handler frame" : "not handler frame" )); | |
1380 | |
1381 if (state->is_exception_detected()) { | |
1382 | |
1383 state->invalidate_cur_stack_depth(); | |
1384 if (!in_handler_frame) { | |
1385 // Not in exception handler. | |
1386 if(state->is_interp_only_mode()) { | |
1387 // method exit and frame pop events are posted only in interp mode. | |
1388 // When these events are enabled code should be in running in interp mode. | |
1389 JvmtiExport::post_method_exit(thread, method, thread->last_frame()); | |
1390 // The cached cur_stack_depth might have changed from the | |
1391 // operations of frame pop or method exit. We are not 100% sure | |
1392 // the cached cur_stack_depth is still valid depth so invalidate | |
1393 // it. | |
1394 state->invalidate_cur_stack_depth(); | |
1395 } | |
1396 } else { | |
1397 // In exception handler frame. Report exception catch. | |
1398 assert(location != NULL, "must be a known location"); | |
1399 // Update cur_stack_depth - the frames above the current frame | |
1400 // have been unwound due to this exception: | |
1401 assert(!state->is_exception_caught(), "exception must not be caught yet."); | |
1402 state->set_exception_caught(); | |
1403 | |
1404 JvmtiEnvThreadStateIterator it(state); | |
1405 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1406 if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) { | |
1407 EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH, | |
1408 ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ %d", | |
1409 JvmtiTrace::safe_get_thread_name(thread), | |
1410 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1411 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1412 location - mh()->code_base() )); | |
1413 | |
1414 JvmtiEnv *env = ets->get_env(); | |
1415 JvmtiExceptionEventMark jem(thread, mh, location, exception_handle); | |
1416 JvmtiJavaThreadEventTransition jet(thread); | |
1417 jvmtiEventExceptionCatch callback = env->callbacks()->ExceptionCatch; | |
1418 if (callback != NULL) { | |
1419 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1420 jem.jni_methodID(), jem.location(), | |
1421 jem.exception()); | |
1422 } | |
1423 } | |
1424 } | |
1425 } | |
1426 } | |
1427 } | |
1428 | |
1429 oop JvmtiExport::jni_GetField_probe(JavaThread *thread, jobject jobj, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1430 Klass* klass, jfieldID fieldID, bool is_static) { |
0 | 1431 if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) { |
1432 // At least one field access watch is set so we have more work | |
1433 // to do. This wrapper is used by entry points that allow us | |
1434 // to create handles in post_field_access_by_jni(). | |
1435 post_field_access_by_jni(thread, obj, klass, fieldID, is_static); | |
1436 // event posting can block so refetch oop if we were passed a jobj | |
1437 if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); | |
1438 } | |
1439 return obj; | |
1440 } | |
1441 | |
1442 oop JvmtiExport::jni_GetField_probe_nh(JavaThread *thread, jobject jobj, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1443 Klass* klass, jfieldID fieldID, bool is_static) { |
0 | 1444 if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) { |
1445 // At least one field access watch is set so we have more work | |
1446 // to do. This wrapper is used by "quick" entry points that don't | |
1447 // allow us to create handles in post_field_access_by_jni(). We | |
1448 // override that with a ResetNoHandleMark. | |
1449 ResetNoHandleMark rnhm; | |
1450 post_field_access_by_jni(thread, obj, klass, fieldID, is_static); | |
1451 // event posting can block so refetch oop if we were passed a jobj | |
1452 if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); | |
1453 } | |
1454 return obj; | |
1455 } | |
1456 | |
1457 void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1458 Klass* klass, jfieldID fieldID, bool is_static) { |
0 | 1459 // We must be called with a Java context in order to provide reasonable |
1460 // values for the klazz, method, and location fields. The callers of this | |
1461 // function don't make the call unless there is a Java context. | |
1462 assert(thread->has_last_Java_frame(), "must be called with a Java context"); | |
1463 | |
1464 ResourceMark rm; | |
1465 fieldDescriptor fd; | |
1466 // if get_field_descriptor finds fieldID to be invalid, then we just bail | |
1467 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd); | |
1468 assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID"); | |
1469 if (!valid_fieldID) return; | |
1470 // field accesses are not watched so bail | |
1471 if (!fd.is_field_access_watched()) return; | |
1472 | |
1473 HandleMark hm(thread); | |
1474 KlassHandle h_klass(thread, klass); | |
1475 Handle h_obj; | |
1476 if (!is_static) { | |
1477 // non-static field accessors have an object, but we need a handle | |
1478 assert(obj != NULL, "non-static needs an object"); | |
1479 h_obj = Handle(thread, obj); | |
1480 } | |
1481 post_field_access(thread, | |
1482 thread->last_frame().interpreter_frame_method(), | |
1483 thread->last_frame().interpreter_frame_bcp(), | |
1484 h_klass, h_obj, fieldID); | |
1485 } | |
1486 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1487 void JvmtiExport::post_field_access(JavaThread *thread, Method* method, |
0 | 1488 address location, KlassHandle field_klass, Handle object, jfieldID field) { |
1489 | |
1490 HandleMark hm(thread); | |
1491 methodHandle mh(thread, method); | |
1492 | |
1493 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1494 if (state == NULL) { | |
1495 return; | |
1496 } | |
1497 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Trg Field Access event triggered", | |
1498 JvmtiTrace::safe_get_thread_name(thread))); | |
1499 JvmtiEnvThreadStateIterator it(state); | |
1500 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1501 if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) { | |
1502 EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ %d", | |
1503 JvmtiTrace::safe_get_thread_name(thread), | |
1504 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1505 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1506 location - mh()->code_base() )); | |
1507 | |
1508 JvmtiEnv *env = ets->get_env(); | |
1509 JvmtiLocationEventMark jem(thread, mh, location); | |
1510 jclass field_jclass = jem.to_jclass(field_klass()); | |
1511 jobject field_jobject = jem.to_jobject(object()); | |
1512 JvmtiJavaThreadEventTransition jet(thread); | |
1513 jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess; | |
1514 if (callback != NULL) { | |
1515 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1516 jem.jni_methodID(), jem.location(), | |
1517 field_jclass, field_jobject, field); | |
1518 } | |
1519 } | |
1520 } | |
1521 } | |
1522 | |
1523 oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1524 Klass* klass, jfieldID fieldID, bool is_static, |
0 | 1525 char sig_type, jvalue *value) { |
1526 if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) { | |
1527 // At least one field modification watch is set so we have more work | |
1528 // to do. This wrapper is used by entry points that allow us | |
1529 // to create handles in post_field_modification_by_jni(). | |
1530 post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value); | |
1531 // event posting can block so refetch oop if we were passed a jobj | |
1532 if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); | |
1533 } | |
1534 return obj; | |
1535 } | |
1536 | |
1537 oop JvmtiExport::jni_SetField_probe_nh(JavaThread *thread, jobject jobj, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1538 Klass* klass, jfieldID fieldID, bool is_static, |
0 | 1539 char sig_type, jvalue *value) { |
1540 if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) { | |
1541 // At least one field modification watch is set so we have more work | |
1542 // to do. This wrapper is used by "quick" entry points that don't | |
1543 // allow us to create handles in post_field_modification_by_jni(). We | |
1544 // override that with a ResetNoHandleMark. | |
1545 ResetNoHandleMark rnhm; | |
1546 post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value); | |
1547 // event posting can block so refetch oop if we were passed a jobj | |
1548 if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); | |
1549 } | |
1550 return obj; | |
1551 } | |
1552 | |
1553 void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1554 Klass* klass, jfieldID fieldID, bool is_static, |
0 | 1555 char sig_type, jvalue *value) { |
1556 // We must be called with a Java context in order to provide reasonable | |
1557 // values for the klazz, method, and location fields. The callers of this | |
1558 // function don't make the call unless there is a Java context. | |
1559 assert(thread->has_last_Java_frame(), "must be called with Java context"); | |
1560 | |
1561 ResourceMark rm; | |
1562 fieldDescriptor fd; | |
1563 // if get_field_descriptor finds fieldID to be invalid, then we just bail | |
1564 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd); | |
1565 assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID"); | |
1566 if (!valid_fieldID) return; | |
1567 // field modifications are not watched so bail | |
1568 if (!fd.is_field_modification_watched()) return; | |
1569 | |
1570 HandleMark hm(thread); | |
1571 | |
1572 Handle h_obj; | |
1573 if (!is_static) { | |
1574 // non-static field accessors have an object, but we need a handle | |
1575 assert(obj != NULL, "non-static needs an object"); | |
1576 h_obj = Handle(thread, obj); | |
1577 } | |
1578 KlassHandle h_klass(thread, klass); | |
1579 post_field_modification(thread, | |
1580 thread->last_frame().interpreter_frame_method(), | |
1581 thread->last_frame().interpreter_frame_bcp(), | |
1582 h_klass, h_obj, fieldID, sig_type, value); | |
1583 } | |
1584 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1585 void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method, |
0 | 1586 address location, KlassHandle field_klass, Handle object, jfieldID field, |
1587 char sig_type, jvalue *value) { | |
1588 | |
1589 if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') { | |
1590 // 'I' instructions are used for byte, char, short and int. | |
1591 // determine which it really is, and convert | |
1592 fieldDescriptor fd; | |
1593 bool found = JvmtiEnv::get_field_descriptor(field_klass(), field, &fd); | |
1594 // should be found (if not, leave as is) | |
1595 if (found) { | |
1596 jint ival = value->i; | |
1597 // convert value from int to appropriate type | |
1598 switch (fd.field_type()) { | |
1599 case T_BOOLEAN: | |
1600 sig_type = 'Z'; | |
1601 value->i = 0; // clear it | |
1602 value->z = (jboolean)ival; | |
1603 break; | |
1604 case T_BYTE: | |
1605 sig_type = 'B'; | |
1606 value->i = 0; // clear it | |
1607 value->b = (jbyte)ival; | |
1608 break; | |
1609 case T_CHAR: | |
1610 sig_type = 'C'; | |
1611 value->i = 0; // clear it | |
1612 value->c = (jchar)ival; | |
1613 break; | |
1614 case T_SHORT: | |
1615 sig_type = 'S'; | |
1616 value->i = 0; // clear it | |
1617 value->s = (jshort)ival; | |
1618 break; | |
1619 case T_INT: | |
1620 // nothing to do | |
1621 break; | |
1622 default: | |
1623 // this is an integer instruction, should be one of above | |
1624 ShouldNotReachHere(); | |
1625 break; | |
1626 } | |
1627 } | |
1628 } | |
1629 | |
10299
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1630 assert(sig_type != '[', "array should have sig_type == 'L'"); |
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1631 bool handle_created = false; |
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1632 |
0 | 1633 // convert oop to JNI handle. |
10299
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1634 if (sig_type == 'L') { |
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1635 handle_created = true; |
0 | 1636 value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l); |
1637 } | |
1638 | |
1639 post_field_modification(thread, method, location, field_klass, object, field, sig_type, value); | |
1640 | |
1641 // Destroy the JNI handle allocated above. | |
10299
f49e0508a38a
4965252: JvmtiExport::post_raw_field_modification jni ref handling is odd
rbackman
parents:
10263
diff
changeset
|
1642 if (handle_created) { |
0 | 1643 JNIHandles::destroy_local(value->l); |
1644 } | |
1645 } | |
1646 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1647 void JvmtiExport::post_field_modification(JavaThread *thread, Method* method, |
0 | 1648 address location, KlassHandle field_klass, Handle object, jfieldID field, |
1649 char sig_type, jvalue *value_ptr) { | |
1650 | |
1651 HandleMark hm(thread); | |
1652 methodHandle mh(thread, method); | |
1653 | |
1654 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1655 if (state == NULL) { | |
1656 return; | |
1657 } | |
1658 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION, | |
1659 ("JVMTI [%s] Trg Field Modification event triggered", | |
1660 JvmtiTrace::safe_get_thread_name(thread))); | |
1661 | |
1662 JvmtiEnvThreadStateIterator it(state); | |
1663 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
1664 if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) { | |
1665 EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION, | |
1666 ("JVMTI [%s] Evt Field Modification event sent %s.%s @ %d", | |
1667 JvmtiTrace::safe_get_thread_name(thread), | |
1668 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), | |
1669 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), | |
1670 location - mh()->code_base() )); | |
1671 | |
1672 JvmtiEnv *env = ets->get_env(); | |
1673 JvmtiLocationEventMark jem(thread, mh, location); | |
1674 jclass field_jclass = jem.to_jclass(field_klass()); | |
1675 jobject field_jobject = jem.to_jobject(object()); | |
1676 JvmtiJavaThreadEventTransition jet(thread); | |
1677 jvmtiEventFieldModification callback = env->callbacks()->FieldModification; | |
1678 if (callback != NULL) { | |
1679 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
1680 jem.jni_methodID(), jem.location(), | |
1681 field_jclass, field_jobject, field, sig_type, *value_ptr); | |
1682 } | |
1683 } | |
1684 } | |
1685 } | |
1686 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1687 void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) { |
0 | 1688 JavaThread* thread = JavaThread::current(); |
1689 assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); | |
1690 | |
1691 HandleMark hm(thread); | |
1692 methodHandle mh(thread, method); | |
1693 | |
1694 EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Trg Native Method Bind event triggered", | |
1695 JvmtiTrace::safe_get_thread_name(thread))); | |
1696 | |
1697 if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) { | |
1698 JvmtiEnvIterator it; | |
1699 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1700 if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) { | |
1701 EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent", | |
1702 JvmtiTrace::safe_get_thread_name(thread) )); | |
1703 | |
1704 JvmtiMethodEventMark jem(thread, mh); | |
1705 JvmtiJavaThreadEventTransition jet(thread); | |
1706 JNIEnv* jni_env = JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env(); | |
1707 jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind; | |
1708 if (callback != NULL) { | |
1709 (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(), | |
1710 jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr); | |
1711 } | |
1712 } | |
1713 } | |
1714 } | |
1715 } | |
1716 | |
1184
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1717 // Returns a record containing inlining information for the given nmethod |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1718 jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) { |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1719 jint numstackframes = 0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1720 jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1721 record->header.kind = JVMTI_CMLR_INLINE_INFO; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1722 record->header.next = NULL; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1723 record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1724 record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1725 record->numpcs = 0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1726 for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) { |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1727 if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1728 record->numpcs++; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1729 } |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1730 record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs)); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1731 int scope = 0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1732 for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) { |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1733 if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1734 void* pc_address = (void*)p->real_pc(nm); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1735 assert(pc_address != NULL, "pc_address must be non-null"); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1736 record->pcinfo[scope].pc = pc_address; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1737 numstackframes=0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1738 for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) { |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1739 numstackframes++; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1740 } |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1741 assert(numstackframes != 0, "numstackframes must be nonzero."); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1742 record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1743 record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1744 record->pcinfo[scope].numstackframes = numstackframes; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1745 int stackframe = 0; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1746 for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) { |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1747 // sd->method() can be NULL for stubs but not for nmethods. To be completely robust, include an assert that we should never see a null sd->method() |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
1748 assert(sd->method() != NULL, "sd->method() cannot be null."); |
1184
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1749 record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id(); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1750 record->pcinfo[scope].bcis[stackframe] = sd->bci(); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1751 stackframe++; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1752 } |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1753 scope++; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1754 } |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1755 return record; |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1756 } |
0 | 1757 |
1758 void JvmtiExport::post_compiled_method_load(nmethod *nm) { | |
1759 JavaThread* thread = JavaThread::current(); | |
1760 | |
1761 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, | |
1762 ("JVMTI [%s] method compile load event triggered", | |
1763 JvmtiTrace::safe_get_thread_name(thread))); | |
1764 | |
1765 JvmtiEnvIterator it; | |
1766 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1767 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) { | |
1768 | |
1769 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, | |
1770 ("JVMTI [%s] class compile method load event sent %s.%s ", | |
1771 JvmtiTrace::safe_get_thread_name(thread), | |
1772 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(), | |
1773 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string())); | |
1774 ResourceMark rm(thread); | |
2195
bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
kamg
parents:
2177
diff
changeset
|
1775 HandleMark hm(thread); |
1184
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1776 |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1777 // Add inlining information |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1778 jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm); |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1779 // Pass inlining information through the void pointer |
7fbf850d87b7
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
dcubed
parents:
1121
diff
changeset
|
1780 JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord); |
0 | 1781 JvmtiJavaThreadEventTransition jet(thread); |
1782 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; | |
1783 if (callback != NULL) { | |
1784 (*callback)(env->jvmti_external(), jem.jni_methodID(), | |
1785 jem.code_size(), jem.code_data(), jem.map_length(), | |
1786 jem.map(), jem.compile_info()); | |
1787 } | |
1788 } | |
1789 } | |
1790 } | |
1791 | |
1792 | |
1793 // post a COMPILED_METHOD_LOAD event for a given environment | |
1794 void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length, | |
1795 const void *code_begin, const jint map_length, | |
1796 const jvmtiAddrLocationMap* map) | |
1797 { | |
1798 JavaThread* thread = JavaThread::current(); | |
1799 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, | |
1800 ("JVMTI [%s] method compile load event triggered (by GenerateEvents)", | |
1801 JvmtiTrace::safe_get_thread_name(thread))); | |
1802 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) { | |
1803 | |
1804 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, | |
1805 ("JVMTI [%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT, | |
1806 JvmtiTrace::safe_get_thread_name(thread), method)); | |
1807 | |
1808 JvmtiEventMark jem(thread); | |
1809 JvmtiJavaThreadEventTransition jet(thread); | |
1810 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; | |
1811 if (callback != NULL) { | |
1812 (*callback)(env->jvmti_external(), method, | |
1813 length, code_begin, map_length, | |
1814 map, NULL); | |
1815 } | |
1816 } | |
1817 } | |
1818 | |
1819 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { | |
3304
0cddebc420d8
7039447: 2/1 java profiling is broken in build 139 (garbage in function name)
dcubed
parents:
2301
diff
changeset
|
1820 assert(name != NULL && name[0] != '\0', "sanity check"); |
0cddebc420d8
7039447: 2/1 java profiling is broken in build 139 (garbage in function name)
dcubed
parents:
2301
diff
changeset
|
1821 |
0 | 1822 JavaThread* thread = JavaThread::current(); |
2301
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1823 // In theory everyone coming thru here is in_vm but we need to be certain |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1824 // because a callee will do a vm->native transition |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1825 ThreadInVMfromUnknown __tiv; |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1826 |
0 | 1827 EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, |
1828 ("JVMTI [%s] method dynamic code generated event triggered", | |
1829 JvmtiTrace::safe_get_thread_name(thread))); | |
1830 JvmtiEnvIterator it; | |
1831 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1832 if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) { | |
1833 EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, | |
1834 ("JVMTI [%s] dynamic code generated event sent for %s", | |
1835 JvmtiTrace::safe_get_thread_name(thread), name)); | |
1836 JvmtiEventMark jem(thread); | |
1837 JvmtiJavaThreadEventTransition jet(thread); | |
1838 jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char)); | |
1839 jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated; | |
1840 if (callback != NULL) { | |
1841 (*callback)(env->jvmti_external(), name, (void*)code_begin, length); | |
1842 } | |
1843 } | |
1844 } | |
1845 } | |
1846 | |
1847 void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) { | |
1848 jvmtiPhase phase = JvmtiEnv::get_phase(); | |
1849 if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) { | |
1850 post_dynamic_code_generated_internal(name, code_begin, code_end); | |
2301
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1851 } else { |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1852 // It may not be safe to post the event from this thread. Defer all |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1853 // postings to the service thread so that it can perform them in a safe |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1854 // context and in-order. |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1855 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1856 JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event( |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1857 name, code_begin, code_end); |
f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
kamg
parents:
2195
diff
changeset
|
1858 JvmtiDeferredEventQueue::enqueue(event); |
0 | 1859 } |
1860 } | |
1861 | |
1862 | |
1863 // post a DYNAMIC_CODE_GENERATED event for a given environment | |
1864 // used by GenerateEvents | |
1865 void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name, | |
1866 const void *code_begin, const void *code_end) | |
1867 { | |
1868 JavaThread* thread = JavaThread::current(); | |
1869 EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, | |
1870 ("JVMTI [%s] dynamic code generated event triggered (by GenerateEvents)", | |
1871 JvmtiTrace::safe_get_thread_name(thread))); | |
1872 if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) { | |
1873 EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, | |
1874 ("JVMTI [%s] dynamic code generated event sent for %s", | |
1875 JvmtiTrace::safe_get_thread_name(thread), name)); | |
1876 JvmtiEventMark jem(thread); | |
1877 JvmtiJavaThreadEventTransition jet(thread); | |
1878 jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char)); | |
1879 jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated; | |
1880 if (callback != NULL) { | |
1881 (*callback)(env->jvmti_external(), name, (void*)code_begin, length); | |
1882 } | |
1883 } | |
1884 } | |
1885 | |
1886 // post a DynamicCodeGenerated event while holding locks in the VM. | |
1887 void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* name, | |
1888 address code_begin, address code_end) | |
1889 { | |
1890 // register the stub with the current dynamic code event collector | |
1891 JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
1892 // state can only be NULL if the current thread is exiting which |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
1893 // should not happen since we're trying to post an event |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
1894 guarantee(state != NULL, "attempt to register stub via an exiting thread"); |
0 | 1895 JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector(); |
1896 guarantee(collector != NULL, "attempt to register stub without event collector"); | |
1897 collector->register_stub(name, code_begin, code_end); | |
1898 } | |
1899 | |
1900 // Collect all the vm internally allocated objects which are visible to java world | |
1901 void JvmtiExport::record_vm_internal_object_allocation(oop obj) { | |
1902 Thread* thread = ThreadLocalStorage::thread(); | |
1903 if (thread != NULL && thread->is_Java_thread()) { | |
1904 // Can not take safepoint here. | |
1905 No_Safepoint_Verifier no_sfpt; | |
1906 // Can not take safepoint here so can not use state_for to get | |
1907 // jvmti thread state. | |
1908 JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state(); | |
1909 if (state != NULL ) { | |
1910 // state is non NULL when VMObjectAllocEventCollector is enabled. | |
1911 JvmtiVMObjectAllocEventCollector *collector; | |
1912 collector = state->get_vm_object_alloc_event_collector(); | |
1913 if (collector != NULL && collector->is_enabled()) { | |
1914 // Don't record classes as these will be notified via the ClassLoad | |
1915 // event. | |
1142 | 1916 if (obj->klass() != SystemDictionary::Class_klass()) { |
0 | 1917 collector->record_allocation(obj); |
1918 } | |
1919 } | |
1920 } | |
1921 } | |
1922 } | |
1923 | |
1924 void JvmtiExport::post_garbage_collection_finish() { | |
1925 Thread *thread = Thread::current(); // this event is posted from VM-Thread. | |
1926 EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, | |
1927 ("JVMTI [%s] garbage collection finish event triggered", | |
1928 JvmtiTrace::safe_get_thread_name(thread))); | |
1929 JvmtiEnvIterator it; | |
1930 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1931 if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)) { | |
1932 EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, | |
1933 ("JVMTI [%s] garbage collection finish event sent ", | |
1934 JvmtiTrace::safe_get_thread_name(thread))); | |
1935 JvmtiThreadEventTransition jet(thread); | |
1936 // JNIEnv is NULL here because this event is posted from VM Thread | |
1937 jvmtiEventGarbageCollectionFinish callback = env->callbacks()->GarbageCollectionFinish; | |
1938 if (callback != NULL) { | |
1939 (*callback)(env->jvmti_external()); | |
1940 } | |
1941 } | |
1942 } | |
1943 } | |
1944 | |
1945 void JvmtiExport::post_garbage_collection_start() { | |
1946 Thread* thread = Thread::current(); // this event is posted from vm-thread. | |
1947 EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START, | |
1948 ("JVMTI [%s] garbage collection start event triggered", | |
1949 JvmtiTrace::safe_get_thread_name(thread))); | |
1950 JvmtiEnvIterator it; | |
1951 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1952 if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_START)) { | |
1953 EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START, | |
1954 ("JVMTI [%s] garbage collection start event sent ", | |
1955 JvmtiTrace::safe_get_thread_name(thread))); | |
1956 JvmtiThreadEventTransition jet(thread); | |
1957 // JNIEnv is NULL here because this event is posted from VM Thread | |
1958 jvmtiEventGarbageCollectionStart callback = env->callbacks()->GarbageCollectionStart; | |
1959 if (callback != NULL) { | |
1960 (*callback)(env->jvmti_external()); | |
1961 } | |
1962 } | |
1963 } | |
1964 } | |
1965 | |
1966 void JvmtiExport::post_data_dump() { | |
1967 Thread *thread = Thread::current(); | |
1968 EVT_TRIG_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST, | |
1969 ("JVMTI [%s] data dump request event triggered", | |
1970 JvmtiTrace::safe_get_thread_name(thread))); | |
1971 JvmtiEnvIterator it; | |
1972 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
1973 if (env->is_enabled(JVMTI_EVENT_DATA_DUMP_REQUEST)) { | |
1974 EVT_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST, | |
1975 ("JVMTI [%s] data dump request event sent ", | |
1976 JvmtiTrace::safe_get_thread_name(thread))); | |
1977 JvmtiThreadEventTransition jet(thread); | |
1978 // JNIEnv is NULL here because this event is posted from VM Thread | |
1979 jvmtiEventDataDumpRequest callback = env->callbacks()->DataDumpRequest; | |
1980 if (callback != NULL) { | |
1981 (*callback)(env->jvmti_external()); | |
1982 } | |
1983 } | |
1984 } | |
1985 } | |
1986 | |
1987 void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) { | |
1988 oop object = (oop)obj_mntr->object(); | |
1989 if (!ServiceUtil::visible_oop(object)) { | |
1990 // Ignore monitor contended enter for vm internal object. | |
1991 return; | |
1992 } | |
1993 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
1994 if (state == NULL) { | |
1995 return; | |
1996 } | |
1997 | |
1998 HandleMark hm(thread); | |
1999 Handle h(thread, object); | |
2000 | |
2001 EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, | |
2002 ("JVMTI [%s] montior contended enter event triggered", | |
2003 JvmtiTrace::safe_get_thread_name(thread))); | |
2004 | |
2005 JvmtiEnvThreadStateIterator it(state); | |
2006 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
2007 if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) { | |
2008 EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, | |
2009 ("JVMTI [%s] monitor contended enter event sent", | |
2010 JvmtiTrace::safe_get_thread_name(thread))); | |
2011 JvmtiMonitorEventMark jem(thread, h()); | |
2012 JvmtiEnv *env = ets->get_env(); | |
2013 JvmtiThreadEventTransition jet(thread); | |
2014 jvmtiEventMonitorContendedEnter callback = env->callbacks()->MonitorContendedEnter; | |
2015 if (callback != NULL) { | |
2016 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object()); | |
2017 } | |
2018 } | |
2019 } | |
2020 } | |
2021 | |
2022 void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) { | |
2023 oop object = (oop)obj_mntr->object(); | |
2024 if (!ServiceUtil::visible_oop(object)) { | |
2025 // Ignore monitor contended entered for vm internal object. | |
2026 return; | |
2027 } | |
2028 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
2029 if (state == NULL) { | |
2030 return; | |
2031 } | |
2032 | |
2033 HandleMark hm(thread); | |
2034 Handle h(thread, object); | |
2035 | |
2036 EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, | |
2037 ("JVMTI [%s] montior contended entered event triggered", | |
2038 JvmtiTrace::safe_get_thread_name(thread))); | |
2039 | |
2040 JvmtiEnvThreadStateIterator it(state); | |
2041 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
2042 if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) { | |
2043 EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, | |
2044 ("JVMTI [%s] monitor contended enter event sent", | |
2045 JvmtiTrace::safe_get_thread_name(thread))); | |
2046 JvmtiMonitorEventMark jem(thread, h()); | |
2047 JvmtiEnv *env = ets->get_env(); | |
2048 JvmtiThreadEventTransition jet(thread); | |
2049 jvmtiEventMonitorContendedEntered callback = env->callbacks()->MonitorContendedEntered; | |
2050 if (callback != NULL) { | |
2051 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object()); | |
2052 } | |
2053 } | |
2054 } | |
2055 } | |
2056 | |
2057 void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object, | |
2058 jlong timeout) { | |
2059 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
2060 if (state == NULL) { | |
2061 return; | |
2062 } | |
2063 | |
2064 HandleMark hm(thread); | |
2065 Handle h(thread, object); | |
2066 | |
2067 EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT, | |
2068 ("JVMTI [%s] montior wait event triggered", | |
2069 JvmtiTrace::safe_get_thread_name(thread))); | |
2070 | |
2071 JvmtiEnvThreadStateIterator it(state); | |
2072 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
2073 if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAIT)) { | |
2074 EVT_TRACE(JVMTI_EVENT_MONITOR_WAIT, | |
2075 ("JVMTI [%s] monitor wait event sent ", | |
2076 JvmtiTrace::safe_get_thread_name(thread))); | |
2077 JvmtiMonitorEventMark jem(thread, h()); | |
2078 JvmtiEnv *env = ets->get_env(); | |
2079 JvmtiThreadEventTransition jet(thread); | |
2080 jvmtiEventMonitorWait callback = env->callbacks()->MonitorWait; | |
2081 if (callback != NULL) { | |
2082 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
2083 jem.jni_object(), timeout); | |
2084 } | |
2085 } | |
2086 } | |
2087 } | |
2088 | |
2089 void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) { | |
2090 oop object = (oop)obj_mntr->object(); | |
2091 if (!ServiceUtil::visible_oop(object)) { | |
2092 // Ignore monitor waited for vm internal object. | |
2093 return; | |
2094 } | |
2095 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
2096 if (state == NULL) { | |
2097 return; | |
2098 } | |
2099 | |
2100 HandleMark hm(thread); | |
2101 Handle h(thread, object); | |
2102 | |
2103 EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED, | |
2104 ("JVMTI [%s] montior waited event triggered", | |
2105 JvmtiTrace::safe_get_thread_name(thread))); | |
2106 | |
2107 JvmtiEnvThreadStateIterator it(state); | |
2108 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
2109 if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAITED)) { | |
2110 EVT_TRACE(JVMTI_EVENT_MONITOR_WAITED, | |
2111 ("JVMTI [%s] monitor waited event sent ", | |
2112 JvmtiTrace::safe_get_thread_name(thread))); | |
2113 JvmtiMonitorEventMark jem(thread, h()); | |
2114 JvmtiEnv *env = ets->get_env(); | |
2115 JvmtiThreadEventTransition jet(thread); | |
2116 jvmtiEventMonitorWaited callback = env->callbacks()->MonitorWaited; | |
2117 if (callback != NULL) { | |
2118 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
2119 jem.jni_object(), timed_out); | |
2120 } | |
2121 } | |
2122 } | |
2123 } | |
2124 | |
2125 | |
2126 void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) { | |
2127 EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Trg vm object alloc triggered", | |
2128 JvmtiTrace::safe_get_thread_name(thread))); | |
2129 if (object == NULL) { | |
2130 return; | |
2131 } | |
2132 HandleMark hm(thread); | |
2133 Handle h(thread, object); | |
2134 JvmtiEnvIterator it; | |
2135 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { | |
2136 if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) { | |
2137 EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s", | |
2138 JvmtiTrace::safe_get_thread_name(thread), | |
6983 | 2139 object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name())); |
0 | 2140 |
2141 JvmtiVMObjectAllocEventMark jem(thread, h()); | |
2142 JvmtiJavaThreadEventTransition jet(thread); | |
2143 jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc; | |
2144 if (callback != NULL) { | |
2145 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), | |
2146 jem.jni_jobject(), jem.jni_class(), jem.size()); | |
2147 } | |
2148 } | |
2149 } | |
2150 } | |
2151 | |
2152 //////////////////////////////////////////////////////////////////////////////////////////////// | |
2153 | |
2154 void JvmtiExport::cleanup_thread(JavaThread* thread) { | |
2155 assert(JavaThread::current() == thread, "thread is not current"); | |
2126
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2156 MutexLocker mu(JvmtiThreadState_lock); |
0 | 2157 |
2126
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2158 if (thread->jvmti_thread_state() != NULL) { |
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2159 // This has to happen after the thread state is removed, which is |
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2160 // why it is not in post_thread_end_event like its complement |
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2161 // Maybe both these functions should be rolled into the posts? |
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2162 JvmtiEventController::thread_ended(thread); |
db2b0f8c1cef
6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents:
2125
diff
changeset
|
2163 } |
0 | 2164 } |
2165 | |
2166 void JvmtiExport::oops_do(OopClosure* f) { | |
2167 JvmtiCurrentBreakpoints::oops_do(f); | |
2168 JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f); | |
2169 } | |
2170 | |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2171 void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2172 JvmtiTagMap::weak_oops_do(is_alive, f); |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2173 } |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2174 |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2175 void JvmtiExport::gc_epilogue() { |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2176 JvmtiCurrentBreakpoints::gc_epilogue(); |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2177 } |
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
2126
diff
changeset
|
2178 |
0 | 2179 // Onload raw monitor transition. |
2180 void JvmtiExport::transition_pending_onload_raw_monitors() { | |
2181 JvmtiPendingMonitors::transition_raw_monitors(); | |
2182 } | |
2183 | |
2184 //////////////////////////////////////////////////////////////////////////////////////////////// | |
2185 | |
2186 // type for the Agent_OnAttach entry point | |
2187 extern "C" { | |
2188 typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *); | |
2189 } | |
2190 | |
2191 jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) { | |
2192 char ebuf[1024]; | |
2193 char buffer[JVM_MAXPATHLEN]; | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6725
diff
changeset
|
2194 void* library = NULL; |
0 | 2195 jint result = JNI_ERR; |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2196 const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2197 size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols); |
0 | 2198 |
2199 // get agent name and options | |
2200 const char* agent = op->arg(0); | |
2201 const char* absParam = op->arg(1); | |
2202 const char* options = op->arg(2); | |
2203 | |
2204 // The abs paramter should be "true" or "false" | |
2205 bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0); | |
2206 | |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2207 // Initially marked as invalid. It will be set to valid if we can find the agent |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2208 AgentLibrary *agent_lib = new AgentLibrary(agent, options, is_absolute_path, NULL); |
0 | 2209 |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2210 // Check for statically linked in agent. If not found then if the path is |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2211 // absolute we attempt to load the library. Otherwise we try to load it |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2212 // from the standard dll directory. |
0 | 2213 |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2214 if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2215 if (is_absolute_path) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2216 library = os::dll_load(agent, ebuf, sizeof ebuf); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2217 } else { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2218 // Try to load the agent from the standard dll directory |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2219 if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2220 agent)) { |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6725
diff
changeset
|
2221 library = os::dll_load(buffer, ebuf, sizeof ebuf); |
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6725
diff
changeset
|
2222 } |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2223 if (library == NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2224 // not found - try local path |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2225 char ns[1] = {0}; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2226 if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2227 library = os::dll_load(buffer, ebuf, sizeof ebuf); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2228 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2229 } |
0 | 2230 } |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2231 if (library != NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2232 agent_lib->set_os_lib(library); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2233 agent_lib->set_valid(); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2234 } |
0 | 2235 } |
2236 // If the library was loaded then we attempt to invoke the Agent_OnAttach | |
2237 // function | |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2238 if (agent_lib->valid()) { |
0 | 2239 // Lookup the Agent_OnAttach function |
2240 OnAttachEntry_t on_attach_entry = NULL; | |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2241 on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t, |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2242 os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries)); |
0 | 2243 if (on_attach_entry == NULL) { |
2244 // Agent_OnAttach missing - unload library | |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2245 if (!agent_lib->is_static_lib()) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2246 os::dll_unload(library); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2247 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2248 delete agent_lib; |
0 | 2249 } else { |
2250 // Invoke the Agent_OnAttach function | |
2251 JavaThread* THREAD = JavaThread::current(); | |
2252 { | |
2253 extern struct JavaVM_ main_vm; | |
2254 JvmtiThreadEventMark jem(THREAD); | |
2255 JvmtiJavaThreadEventTransition jet(THREAD); | |
2256 | |
2257 result = (*on_attach_entry)(&main_vm, (char*)options, NULL); | |
2258 } | |
2259 | |
2260 // Agent_OnAttach may have used JNI | |
2261 if (HAS_PENDING_EXCEPTION) { | |
2262 CLEAR_PENDING_EXCEPTION; | |
2263 } | |
2264 | |
2265 // If OnAttach returns JNI_OK then we add it to the list of | |
2266 // agent libraries so that we can call Agent_OnUnload later. | |
2267 if (result == JNI_OK) { | |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2268 Arguments::add_loaded_agent(agent_lib); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2269 } else { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11148
diff
changeset
|
2270 delete agent_lib; |
0 | 2271 } |
2272 | |
2273 // Agent_OnAttach executed so completion status is JNI_OK | |
2274 st->print_cr("%d", result); | |
2275 result = JNI_OK; | |
2276 } | |
2277 } | |
2278 return result; | |
2279 } | |
2280 | |
2281 //////////////////////////////////////////////////////////////////////////////////////////////// | |
2282 | |
2283 // Setup current current thread for event collection. | |
2284 void JvmtiEventCollector::setup_jvmti_thread_state() { | |
2285 // set this event collector to be the current one. | |
2286 JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
2287 // state can only be NULL if the current thread is exiting which |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
2288 // should not happen since we're trying to configure for event collection |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
342
diff
changeset
|
2289 guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state"); |
0 | 2290 if (is_vm_object_alloc_event()) { |
2291 _prev = state->get_vm_object_alloc_event_collector(); | |
2292 state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this); | |
2293 } else if (is_dynamic_code_event()) { | |
2294 _prev = state->get_dynamic_code_event_collector(); | |
2295 state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this); | |
2296 } | |
2297 } | |
2298 | |
2299 // Unset current event collection in this thread and reset it with previous | |
2300 // collector. | |
2301 void JvmtiEventCollector::unset_jvmti_thread_state() { | |
2302 JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state(); | |
2303 if (state != NULL) { | |
2304 // restore the previous event collector (if any) | |
2305 if (is_vm_object_alloc_event()) { | |
2306 if (state->get_vm_object_alloc_event_collector() == this) { | |
2307 state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev); | |
2308 } else { | |
2309 // this thread's jvmti state was created during the scope of | |
2310 // the event collector. | |
2311 } | |
2312 } else { | |
2313 if (is_dynamic_code_event()) { | |
2314 if (state->get_dynamic_code_event_collector() == this) { | |
2315 state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev); | |
2316 } else { | |
2317 // this thread's jvmti state was created during the scope of | |
2318 // the event collector. | |
2319 } | |
2320 } | |
2321 } | |
2322 } | |
2323 } | |
2324 | |
2325 // create the dynamic code event collector | |
2326 JvmtiDynamicCodeEventCollector::JvmtiDynamicCodeEventCollector() : _code_blobs(NULL) { | |
2327 if (JvmtiExport::should_post_dynamic_code_generated()) { | |
2328 setup_jvmti_thread_state(); | |
2329 } | |
2330 } | |
2331 | |
2332 // iterate over any code blob descriptors collected and post a | |
2333 // DYNAMIC_CODE_GENERATED event to the profiler. | |
2334 JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() { | |
2335 assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events"); | |
2336 // iterate over any code blob descriptors that we collected | |
2337 if (_code_blobs != NULL) { | |
2338 for (int i=0; i<_code_blobs->length(); i++) { | |
2339 JvmtiCodeBlobDesc* blob = _code_blobs->at(i); | |
2340 JvmtiExport::post_dynamic_code_generated(blob->name(), blob->code_begin(), blob->code_end()); | |
2341 FreeHeap(blob); | |
2342 } | |
2343 delete _code_blobs; | |
2344 } | |
2345 unset_jvmti_thread_state(); | |
2346 } | |
2347 | |
2348 // register a stub | |
2349 void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) { | |
2350 if (_code_blobs == NULL) { | |
6197 | 2351 _code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(1,true); |
0 | 2352 } |
2353 _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end)); | |
2354 } | |
2355 | |
2356 // Setup current thread to record vm allocated objects. | |
2357 JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() : _allocated(NULL) { | |
2358 if (JvmtiExport::should_post_vm_object_alloc()) { | |
2359 _enable = true; | |
2360 setup_jvmti_thread_state(); | |
2361 } else { | |
2362 _enable = false; | |
2363 } | |
2364 } | |
2365 | |
2366 // Post vm_object_alloc event for vm allocated objects visible to java | |
2367 // world. | |
2368 JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() { | |
2369 if (_allocated != NULL) { | |
2370 set_enabled(false); | |
2371 for (int i = 0; i < _allocated->length(); i++) { | |
2372 oop obj = _allocated->at(i); | |
2373 if (ServiceUtil::visible_oop(obj)) { | |
2374 JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj); | |
2375 } | |
2376 } | |
2377 delete _allocated; | |
2378 } | |
2379 unset_jvmti_thread_state(); | |
2380 } | |
2381 | |
2382 void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) { | |
2383 assert(is_enabled(), "VM object alloc event collector is not enabled"); | |
2384 if (_allocated == NULL) { | |
6197 | 2385 _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true); |
0 | 2386 } |
2387 _allocated->push(obj); | |
2388 } | |
2389 | |
2390 // GC support. | |
2391 void JvmtiVMObjectAllocEventCollector::oops_do(OopClosure* f) { | |
2392 if (_allocated != NULL) { | |
2393 for(int i=_allocated->length() - 1; i >= 0; i--) { | |
2394 if (_allocated->at(i) != NULL) { | |
2395 f->do_oop(_allocated->adr_at(i)); | |
2396 } | |
2397 } | |
2398 } | |
2399 } | |
2400 | |
2401 void JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) { | |
2402 // no-op if jvmti not enabled | |
2403 if (!JvmtiEnv::environments_might_exist()) { | |
2404 return; | |
2405 } | |
2406 | |
2407 // Runs at safepoint. So no need to acquire Threads_lock. | |
2408 for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) { | |
2409 JvmtiThreadState *state = jthr->jvmti_thread_state(); | |
2410 if (state != NULL) { | |
2411 JvmtiVMObjectAllocEventCollector *collector; | |
2412 collector = state->get_vm_object_alloc_event_collector(); | |
2413 while (collector != NULL) { | |
2414 collector->oops_do(f); | |
2415 collector = (JvmtiVMObjectAllocEventCollector *)collector->get_prev(); | |
2416 } | |
2417 } | |
2418 } | |
2419 } | |
2420 | |
2421 | |
2422 // Disable collection of VMObjectAlloc events | |
2423 NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) { | |
2424 // a no-op if VMObjectAlloc event is not enabled | |
2425 if (!JvmtiExport::should_post_vm_object_alloc()) { | |
2426 return; | |
2427 } | |
2428 Thread* thread = ThreadLocalStorage::thread(); | |
2429 if (thread != NULL && thread->is_Java_thread()) { | |
2430 JavaThread* current_thread = (JavaThread*)thread; | |
2431 JvmtiThreadState *state = current_thread->jvmti_thread_state(); | |
2432 if (state != NULL) { | |
2433 JvmtiVMObjectAllocEventCollector *collector; | |
2434 collector = state->get_vm_object_alloc_event_collector(); | |
2435 if (collector != NULL && collector->is_enabled()) { | |
2436 _collector = collector; | |
2437 _collector->set_enabled(false); | |
2438 } | |
2439 } | |
2440 } | |
2441 } | |
2442 | |
2443 // Re-Enable collection of VMObjectAlloc events (if previously enabled) | |
2444 NoJvmtiVMObjectAllocMark::~NoJvmtiVMObjectAllocMark() { | |
2445 if (was_enabled()) { | |
2446 _collector->set_enabled(true); | |
2447 } | |
2448 }; | |
2449 | |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
1988
diff
changeset
|
2450 JvmtiGCMarker::JvmtiGCMarker() { |
0 | 2451 // if there aren't any JVMTI environments then nothing to do |
2452 if (!JvmtiEnv::environments_might_exist()) { | |
2453 return; | |
2454 } | |
2455 | |
2456 if (JvmtiExport::should_post_garbage_collection_start()) { | |
2457 JvmtiExport::post_garbage_collection_start(); | |
2458 } | |
2459 | |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
1988
diff
changeset
|
2460 if (SafepointSynchronize::is_at_safepoint()) { |
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
1988
diff
changeset
|
2461 // Do clean up tasks that need to be done at a safepoint |
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
1988
diff
changeset
|
2462 JvmtiEnvBase::check_for_periodic_clean_up(); |
0 | 2463 } |
2464 } | |
2465 | |
2466 JvmtiGCMarker::~JvmtiGCMarker() { | |
2467 // if there aren't any JVMTI environments then nothing to do | |
2468 if (!JvmtiEnv::environments_might_exist()) { | |
2469 return; | |
2470 } | |
2471 | |
2472 // JVMTI notify gc finish | |
2473 if (JvmtiExport::should_post_garbage_collection_finish()) { | |
2474 JvmtiExport::post_garbage_collection_finish(); | |
2475 } | |
2476 } |