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