113 _jthread = NULL;
114 }
115 }
116
117 ~JvmtiThreadEventTransition() {
118 if (_jthread != NULL)
119 ThreadStateTransition::transition_from_native(_jthread, _saved_state);
120 }
121 };
122
123
124 ///////////////////////////////////////////////////////////////
125 //
126 // JvmtiEventMark
127 //
128
129 class JvmtiEventMark : public StackObj {
130 private:
131 JavaThread *_thread;
132 JNIEnv* _jni_env;
133 bool _exception_detected;
134 bool _exception_caught;
135 #if 0
136 JNIHandleBlock* _hblock;
137 #endif
138
139 public:
140 JvmtiEventMark(JavaThread *thread) : _thread(thread),
141 _jni_env(thread->jni_environment()) {
142 #if 0
143 _hblock = thread->active_handles();
144 _hblock->clear_thoroughly(); // so we can be safe
145 #else
146 // we want to use the code above - but that needs the JNIHandle changes - later...
147 // for now, steal JNI push local frame code
148 JvmtiThreadState *state = thread->jvmti_thread_state();
149 // we are before an event.
150 // Save current jvmti thread exception state.
151 if (state != NULL) {
152 _exception_detected = state->is_exception_detected();
153 _exception_caught = state->is_exception_caught();
154 } else {
155 _exception_detected = false;
156 _exception_caught = false;
157 }
158
159 JNIHandleBlock* old_handles = thread->active_handles();
160 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
161 assert(new_handles != NULL, "should not be NULL");
162 new_handles->set_pop_frame_link(old_handles);
163 thread->set_active_handles(new_handles);
164 #endif
165 assert(thread == JavaThread::current(), "thread must be current!");
166 thread->frame_anchor()->make_walkable(thread);
167 };
168
169 ~JvmtiEventMark() {
170 #if 0
171 _hblock->clear(); // for consistency with future correct behavior
172 #else
173 // we want to use the code above - but that needs the JNIHandle changes - later...
174 // for now, steal JNI pop local frame code
175 JNIHandleBlock* old_handles = _thread->active_handles();
176 JNIHandleBlock* new_handles = old_handles->pop_frame_link();
177 assert(new_handles != NULL, "should not be NULL");
178 _thread->set_active_handles(new_handles);
179 // Note that we set the pop_frame_link to NULL explicitly, otherwise
180 // the release_block call will release the blocks.
181 old_handles->set_pop_frame_link(NULL);
182 JNIHandleBlock::release_block(old_handles, _thread); // may block
183 #endif
184
185 JvmtiThreadState* state = _thread->jvmti_thread_state();
186 // we are continuing after an event.
187 if (state != NULL) {
188 // Restore the jvmti thread exception state.
189 if (_exception_detected) {
190 state->set_exception_detected();
191 }
192 if (_exception_caught) {
193 state->set_exception_caught();
194 }
195 }
196 }
197
198 #if 0
199 jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); }
200 #else
201 // we want to use the code above - but that needs the JNIHandle changes - later...
202 // for now, use regular make_local
203 jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); }
204 #endif
205
206 jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }
207
208 jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); }
209
210 JNIEnv* jni_env() { return _jni_env; }
211 };
212
213 class JvmtiThreadEventMark : public JvmtiEventMark {
214 private:
1370 EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("[%s] Evt Single Step sent %s.%s @ " INTX_FORMAT,
1371 JvmtiTrace::safe_get_thread_name(thread),
1372 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1373 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1374 location - mh()->code_base() ));
1375
1376 JvmtiEnv *env = ets->get_env();
1377 JvmtiLocationEventMark jem(thread, mh, location);
1378 JvmtiJavaThreadEventTransition jet(thread);
1379 jvmtiEventSingleStep callback = env->callbacks()->SingleStep;
1380 if (callback != NULL) {
1381 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1382 jem.jni_methodID(), jem.location());
1383 }
1384
1385 ets->set_single_stepping_posted();
1386 }
1387 }
1388 }
1389
1390
1391 void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {
1392 HandleMark hm(thread);
1393 methodHandle mh(thread, method);
1394 Handle exception_handle(thread, exception);
1395
1396 JvmtiThreadState *state = thread->jvmti_thread_state();
1397 if (state == NULL) {
1398 return;
1399 }
1400
1401 EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("[%s] Trg Exception thrown triggered",
1402 JvmtiTrace::safe_get_thread_name(thread)));
1403 if (!state->is_exception_detected()) {
1404 state->set_exception_detected();
1405 JvmtiEnvThreadStateIterator it(state);
1406 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1407 if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {
1408
1409 EVT_TRACE(JVMTI_EVENT_EXCEPTION,
1410 ("[%s] Evt Exception thrown sent %s.%s @ " INTX_FORMAT,
2272
2273 ////////////////////////////////////////////////////////////////////////////////////////////////
2274
2275 void JvmtiExport::cleanup_thread(JavaThread* thread) {
2276 assert(JavaThread::current() == thread, "thread is not current");
2277 MutexLocker mu(JvmtiThreadState_lock);
2278
2279 if (thread->jvmti_thread_state() != NULL) {
2280 // This has to happen after the thread state is removed, which is
2281 // why it is not in post_thread_end_event like its complement
2282 // Maybe both these functions should be rolled into the posts?
2283 JvmtiEventController::thread_ended(thread);
2284 }
2285 }
2286
2287 void JvmtiExport::clear_detected_exception(JavaThread* thread) {
2288 assert(JavaThread::current() == thread, "thread is not current");
2289
2290 JvmtiThreadState* state = thread->jvmti_thread_state();
2291 if (state != NULL) {
2292 state->clear_exception_detected();
2293 }
2294 }
2295
2296 void JvmtiExport::oops_do(OopClosure* f) {
2297 JvmtiCurrentBreakpoints::oops_do(f);
2298 JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f);
2299 }
2300
2301 void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
2302 JvmtiTagMap::weak_oops_do(is_alive, f);
2303 }
2304
2305 void JvmtiExport::gc_epilogue() {
2306 JvmtiCurrentBreakpoints::gc_epilogue();
2307 }
2308
2309 // Onload raw monitor transition.
2310 void JvmtiExport::transition_pending_onload_raw_monitors() {
2311 JvmtiPendingMonitors::transition_raw_monitors();
2312 }
|
113 _jthread = NULL;
114 }
115 }
116
117 ~JvmtiThreadEventTransition() {
118 if (_jthread != NULL)
119 ThreadStateTransition::transition_from_native(_jthread, _saved_state);
120 }
121 };
122
123
124 ///////////////////////////////////////////////////////////////
125 //
126 // JvmtiEventMark
127 //
128
129 class JvmtiEventMark : public StackObj {
130 private:
131 JavaThread *_thread;
132 JNIEnv* _jni_env;
133 JvmtiThreadState::ExceptionState _exception_state;
134 #if 0
135 JNIHandleBlock* _hblock;
136 #endif
137
138 public:
139 JvmtiEventMark(JavaThread *thread) : _thread(thread),
140 _jni_env(thread->jni_environment()) {
141 #if 0
142 _hblock = thread->active_handles();
143 _hblock->clear_thoroughly(); // so we can be safe
144 #else
145 // we want to use the code above - but that needs the JNIHandle changes - later...
146 // for now, steal JNI push local frame code
147 JvmtiThreadState *state = thread->jvmti_thread_state();
148 // we are before an event.
149 // Save current jvmti thread exception state.
150 if (state != NULL) {
151 state->save_exception_state(&_exception_state);
152 }
153 else {
154 // For safety ...
155 _exception_state = JvmtiThreadState::ES_CLEARED;
156 }
157
158 JNIHandleBlock* old_handles = thread->active_handles();
159 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
160 assert(new_handles != NULL, "should not be NULL");
161 new_handles->set_pop_frame_link(old_handles);
162 thread->set_active_handles(new_handles);
163 #endif
164 assert(thread == JavaThread::current(), "thread must be current!");
165 thread->frame_anchor()->make_walkable(thread);
166 };
167
168 ~JvmtiEventMark() {
169 #if 0
170 _hblock->clear(); // for consistency with future correct behavior
171 #else
172 // we want to use the code above - but that needs the JNIHandle changes - later...
173 // for now, steal JNI pop local frame code
174 JNIHandleBlock* old_handles = _thread->active_handles();
175 JNIHandleBlock* new_handles = old_handles->pop_frame_link();
176 assert(new_handles != NULL, "should not be NULL");
177 _thread->set_active_handles(new_handles);
178 // Note that we set the pop_frame_link to NULL explicitly, otherwise
179 // the release_block call will release the blocks.
180 old_handles->set_pop_frame_link(NULL);
181 JNIHandleBlock::release_block(old_handles, _thread); // may block
182 #endif
183
184 JvmtiThreadState* state = _thread->jvmti_thread_state();
185 // we are continuing after an event.
186 if (state != NULL) {
187 // Restore the jvmti thread exception state.
188 state->restore_exception_state(_exception_state);
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
200 jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }
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:
1364 EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("[%s] Evt Single Step sent %s.%s @ " INTX_FORMAT,
1365 JvmtiTrace::safe_get_thread_name(thread),
1366 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1367 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1368 location - mh()->code_base() ));
1369
1370 JvmtiEnv *env = ets->get_env();
1371 JvmtiLocationEventMark jem(thread, mh, location);
1372 JvmtiJavaThreadEventTransition jet(thread);
1373 jvmtiEventSingleStep callback = env->callbacks()->SingleStep;
1374 if (callback != NULL) {
1375 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1376 jem.jni_methodID(), jem.location());
1377 }
1378
1379 ets->set_single_stepping_posted();
1380 }
1381 }
1382 }
1383
1384 void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {
1385 HandleMark hm(thread);
1386 methodHandle mh(thread, method);
1387 Handle exception_handle(thread, exception);
1388
1389 JvmtiThreadState *state = thread->jvmti_thread_state();
1390 if (state == NULL) {
1391 return;
1392 }
1393
1394 EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("[%s] Trg Exception thrown triggered",
1395 JvmtiTrace::safe_get_thread_name(thread)));
1396 if (!state->is_exception_detected()) {
1397 state->set_exception_detected();
1398 JvmtiEnvThreadStateIterator it(state);
1399 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1400 if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {
1401
1402 EVT_TRACE(JVMTI_EVENT_EXCEPTION,
1403 ("[%s] Evt Exception thrown sent %s.%s @ " INTX_FORMAT,
2265
2266 ////////////////////////////////////////////////////////////////////////////////////////////////
2267
2268 void JvmtiExport::cleanup_thread(JavaThread* thread) {
2269 assert(JavaThread::current() == thread, "thread is not current");
2270 MutexLocker mu(JvmtiThreadState_lock);
2271
2272 if (thread->jvmti_thread_state() != NULL) {
2273 // This has to happen after the thread state is removed, which is
2274 // why it is not in post_thread_end_event like its complement
2275 // Maybe both these functions should be rolled into the posts?
2276 JvmtiEventController::thread_ended(thread);
2277 }
2278 }
2279
2280 void JvmtiExport::clear_detected_exception(JavaThread* thread) {
2281 assert(JavaThread::current() == thread, "thread is not current");
2282
2283 JvmtiThreadState* state = thread->jvmti_thread_state();
2284 if (state != NULL) {
2285 state->clear_exception_state();
2286 }
2287 }
2288
2289 void JvmtiExport::oops_do(OopClosure* f) {
2290 JvmtiCurrentBreakpoints::oops_do(f);
2291 JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f);
2292 }
2293
2294 void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
2295 JvmtiTagMap::weak_oops_do(is_alive, f);
2296 }
2297
2298 void JvmtiExport::gc_epilogue() {
2299 JvmtiCurrentBreakpoints::gc_epilogue();
2300 }
2301
2302 // Onload raw monitor transition.
2303 void JvmtiExport::transition_pending_onload_raw_monitors() {
2304 JvmtiPendingMonitors::transition_raw_monitors();
2305 }
|