< prev index next >

src/hotspot/share/jfr/jni/jfrJavaSupport.cpp

Print this page

 33 #include "jfr/support/jfrThreadId.hpp"
 34 #include "logging/log.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "oops/instanceOop.hpp"
 37 #include "oops/klass.inline.hpp"
 38 #include "oops/oop.inline.hpp"
 39 #include "oops/objArrayKlass.hpp"
 40 #include "oops/objArrayOop.inline.hpp"
 41 #include "runtime/handles.inline.hpp"
 42 #include "runtime/fieldDescriptor.inline.hpp"
 43 #include "runtime/java.hpp"
 44 #include "runtime/jniHandles.inline.hpp"
 45 #include "runtime/semaphore.inline.hpp"
 46 #include "runtime/synchronizer.hpp"
 47 #include "runtime/thread.inline.hpp"
 48 #include "runtime/threadSMR.hpp"
 49 #include "utilities/growableArray.hpp"
 50 #include "classfile/vmSymbols.hpp"
 51 
 52 #ifdef ASSERT
 53 void JfrJavaSupport::check_java_thread_in_vm(JavaThread* t) {
 54   assert(t != NULL, "invariant");
 55   assert(t->thread_state() == _thread_in_vm, "invariant");





 56 }
 57 
 58 void JfrJavaSupport::check_java_thread_in_native(JavaThread* t) {
 59   assert(t != NULL, "invariant");
 60   assert(t->thread_state() == _thread_in_native, "invariant");
 61 }
 62 
 63 static void check_new_unstarted_java_thread(JavaThread* t) {
 64   assert(t != NULL, "invariant");
 65   assert(t->thread_state() == _thread_new, "invariant");




 66 }
 67 #endif
 68 
 69 /*
 70  *  Handles and references
 71  */
 72 jobject JfrJavaSupport::local_jni_handle(const oop obj, JavaThread* t) {
 73   DEBUG_ONLY(check_java_thread_in_vm(t));
 74   return t->active_handles()->allocate_handle(obj);
 75 }
 76 
 77 jobject JfrJavaSupport::local_jni_handle(const jobject handle, JavaThread* t) {
 78   DEBUG_ONLY(check_java_thread_in_vm(t));
 79   const oop obj = JNIHandles::resolve(handle);
 80   return obj == NULL ? NULL : local_jni_handle(obj, t);
 81 }
 82 
 83 void JfrJavaSupport::destroy_local_jni_handle(jobject handle) {
 84   JNIHandles::destroy_local(handle);
 85 }

372     case T_DOUBLE:
373       result->set_jdouble(h_oop->double_field(fd->offset()));
374       break;
375     case T_LONG:
376       result->set_jlong(h_oop->long_field(fd->offset()));
377       break;
378     case T_OBJECT:
379       result->set_oop(h_oop->obj_field(fd->offset()));
380       break;
381     default:
382       ShouldNotReachHere();
383   }
384 }
385 
386 static bool find_field(const InstanceKlass* ik,
387                        Symbol* name_symbol,
388                        Symbol* signature_symbol,
389                        fieldDescriptor* fd,
390                        bool is_static = false,
391                        bool allow_super = false) {

392   if (allow_super || is_static) {
393     return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL;
394   }
395   return ik->find_local_field(name_symbol, signature_symbol, fd);
396 }
397 
398 static void lookup_field(JfrJavaArguments* args, const InstanceKlass* ik, fieldDescriptor* fd, bool static_field) {
399   assert(args != NULL, "invariant");
400   assert(ik != NULL, "invariant");
401   assert(ik->is_initialized(), "invariant");
402   assert(fd != NULL, "invariant");
403   find_field(ik, args->name(), args->signature(), fd, static_field, true);
404 }
405 
406 static void read_field(JfrJavaArguments* args, JavaValue* result, Thread* thread) {
407   const bool static_field = !args->has_receiver();
408   fieldDescriptor fd;
409   const InstanceKlass* const ik = static_cast<InstanceKlass*>(args->klass());
410   lookup_field(args, ik, &fd, static_field);
411   assert(fd.offset() > 0, "invariant");

702   assert(is_thread_excluded(thread), "invariant");
703   assert(exclusion_list != NULL, "invariant");
704   const int idx = find_exclusion_thread_idx(thread);
705   assert(idx >= 0, "invariant");
706   assert(idx < exclusion_list->length(), "invariant");
707   JfrJavaSupport::destroy_global_weak_jni_handle(exclusion_list->at(idx));
708   exclusion_list->delete_at(idx);
709   assert(thread_is_not_excluded(thread), "invariant");
710   if (0 == exclusion_list->length()) {
711     delete exclusion_list;
712     exclusion_list = NULL;
713   }
714 }
715 
716 static void remove_thread_from_exclusion_list(jobject thread) {
717   ThreadExclusionListAccess lock;
718   remove_thread_from_exclusion_list(as_handle(thread));
719 }
720 
721 // includes removal
722 static bool check_exclusion_state_on_thread_start(JavaThread* jt) {
723   Handle h_obj(jt, jt->threadObj());
724   ThreadExclusionListAccess lock;
725   if (thread_is_not_excluded(h_obj)) {
726     return false;
727   }
728   remove_thread_from_exclusion_list(h_obj);
729   return true;
730 }
731 
732 static JavaThread* get_native(jobject thread) {
733   ThreadsListHandle tlh;
734   JavaThread* native_thread = NULL;
735   (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL);
736   return native_thread;
737 }
738 
739 jlong JfrJavaSupport::jfr_thread_id(jobject thread) {
740   JavaThread* native_thread = get_native(thread);
741   return native_thread != NULL ? JFR_THREAD_ID(native_thread) : 0;
742 }
743 
744 void JfrJavaSupport::exclude(jobject thread) {
745   JavaThread* native_thread = get_native(thread);
746   if (native_thread != NULL) {
747     JfrThreadLocal::exclude(native_thread);
748   } else {
749     // not started yet, track the thread oop
750     add_thread_to_exclusion_list(thread);
751   }
752 }

803 }
804 
805 bool JfrJavaSupport::set_handler(jobject clazz, jobject handler, TRAPS) {
806   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
807   HandleMark hm(THREAD);
808   const Handle h_mirror(Handle(THREAD, JNIHandles::resolve(clazz)));
809   assert(h_mirror.not_null(), "invariant");
810   fieldDescriptor handler_field_descriptor;
811   const Klass* const field_holder = get_handler_field_descriptor(h_mirror, &handler_field_descriptor, THREAD);
812   if (field_holder == NULL) {
813     // The only reason should be that klass initialization failed.
814     return false;
815   }
816   assert(java_lang_Class::as_Klass(h_mirror()) == field_holder, "invariant");
817   const oop handler_oop = JNIHandles::resolve(handler);
818   assert(handler_oop != NULL, "invariant");
819   h_mirror->obj_field_put(handler_field_descriptor.offset(), handler_oop);
820   return true;
821 }
822 
823 void JfrJavaSupport::on_thread_start(Thread* t) {
824   assert(t != NULL, "invariant");
825   assert(Thread::current() == t, "invariant");
826   if (!t->is_Java_thread()) {
827     return;









828   }
829   DEBUG_ONLY(check_new_unstarted_java_thread(JavaThread::cast(t));)
830   HandleMark hm(t);
831   if (check_exclusion_state_on_thread_start(JavaThread::cast(t))) {
832     JfrThreadLocal::exclude(t);









833   }


834 }

 33 #include "jfr/support/jfrThreadId.hpp"
 34 #include "logging/log.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "oops/instanceOop.hpp"
 37 #include "oops/klass.inline.hpp"
 38 #include "oops/oop.inline.hpp"
 39 #include "oops/objArrayKlass.hpp"
 40 #include "oops/objArrayOop.inline.hpp"
 41 #include "runtime/handles.inline.hpp"
 42 #include "runtime/fieldDescriptor.inline.hpp"
 43 #include "runtime/java.hpp"
 44 #include "runtime/jniHandles.inline.hpp"
 45 #include "runtime/semaphore.inline.hpp"
 46 #include "runtime/synchronizer.hpp"
 47 #include "runtime/thread.inline.hpp"
 48 #include "runtime/threadSMR.hpp"
 49 #include "utilities/growableArray.hpp"
 50 #include "classfile/vmSymbols.hpp"
 51 
 52 #ifdef ASSERT
 53 static void check_java_thread_state(JavaThread* t, JavaThreadState state) {
 54   assert(t != NULL, "invariant");
 55   assert(t->is_Java_thread(), "invariant");
 56   assert(t->thread_state() == state, "invariant");
 57 }
 58 
 59 void JfrJavaSupport::check_java_thread_in_vm(JavaThread* t) {
 60   check_java_thread_state(t, _thread_in_vm);
 61 }
 62 
 63 void JfrJavaSupport::check_java_thread_in_native(JavaThread* t) {
 64   check_java_thread_state(t, _thread_in_native);

 65 }
 66 
 67 void JfrJavaSupport::check_java_thread_in_java(JavaThread* t) {
 68   check_java_thread_state(t, _thread_in_Java);
 69 }
 70 
 71 static void check_new_unstarted_java_thread(JavaThread* jt, jobject vthread = NULL) {
 72   if (vthread != NULL) return;
 73   check_java_thread_state(jt, _thread_new);
 74 }
 75 #endif
 76 
 77 /*
 78  *  Handles and references
 79  */
 80 jobject JfrJavaSupport::local_jni_handle(const oop obj, JavaThread* t) {
 81   DEBUG_ONLY(check_java_thread_in_vm(t));
 82   return t->active_handles()->allocate_handle(obj);
 83 }
 84 
 85 jobject JfrJavaSupport::local_jni_handle(const jobject handle, JavaThread* t) {
 86   DEBUG_ONLY(check_java_thread_in_vm(t));
 87   const oop obj = JNIHandles::resolve(handle);
 88   return obj == NULL ? NULL : local_jni_handle(obj, t);
 89 }
 90 
 91 void JfrJavaSupport::destroy_local_jni_handle(jobject handle) {
 92   JNIHandles::destroy_local(handle);
 93 }

380     case T_DOUBLE:
381       result->set_jdouble(h_oop->double_field(fd->offset()));
382       break;
383     case T_LONG:
384       result->set_jlong(h_oop->long_field(fd->offset()));
385       break;
386     case T_OBJECT:
387       result->set_oop(h_oop->obj_field(fd->offset()));
388       break;
389     default:
390       ShouldNotReachHere();
391   }
392 }
393 
394 static bool find_field(const InstanceKlass* ik,
395                        Symbol* name_symbol,
396                        Symbol* signature_symbol,
397                        fieldDescriptor* fd,
398                        bool is_static = false,
399                        bool allow_super = false) {
400   assert(ik != NULL, "invariant");
401   if (allow_super || is_static) {
402     return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL;
403   }
404   return ik->find_local_field(name_symbol, signature_symbol, fd);
405 }
406 
407 static void lookup_field(JfrJavaArguments* args, const InstanceKlass* ik, fieldDescriptor* fd, bool static_field) {
408   assert(args != NULL, "invariant");
409   assert(ik != NULL, "invariant");
410   assert(ik->is_initialized(), "invariant");
411   assert(fd != NULL, "invariant");
412   find_field(ik, args->name(), args->signature(), fd, static_field, true);
413 }
414 
415 static void read_field(JfrJavaArguments* args, JavaValue* result, Thread* thread) {
416   const bool static_field = !args->has_receiver();
417   fieldDescriptor fd;
418   const InstanceKlass* const ik = static_cast<InstanceKlass*>(args->klass());
419   lookup_field(args, ik, &fd, static_field);
420   assert(fd.offset() > 0, "invariant");

711   assert(is_thread_excluded(thread), "invariant");
712   assert(exclusion_list != NULL, "invariant");
713   const int idx = find_exclusion_thread_idx(thread);
714   assert(idx >= 0, "invariant");
715   assert(idx < exclusion_list->length(), "invariant");
716   JfrJavaSupport::destroy_global_weak_jni_handle(exclusion_list->at(idx));
717   exclusion_list->delete_at(idx);
718   assert(thread_is_not_excluded(thread), "invariant");
719   if (0 == exclusion_list->length()) {
720     delete exclusion_list;
721     exclusion_list = NULL;
722   }
723 }
724 
725 static void remove_thread_from_exclusion_list(jobject thread) {
726   ThreadExclusionListAccess lock;
727   remove_thread_from_exclusion_list(as_handle(thread));
728 }
729 
730 // includes removal
731 static bool check_exclusion_state_on_thread_start(Handle h_threadObj) {

732   ThreadExclusionListAccess lock;
733   if (thread_is_not_excluded(h_threadObj)) {
734     return false;
735   }
736   remove_thread_from_exclusion_list(h_threadObj);
737   return true;
738 }
739 
740 JavaThread* JfrJavaSupport::get_native(jobject thread) {
741   ThreadsListHandle tlh;
742   JavaThread* native_thread = NULL;
743   (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL);
744   return native_thread;
745 }
746 
747 jlong JfrJavaSupport::jfr_thread_id(jobject thread) {
748   JavaThread* native_thread = get_native(thread);
749   return native_thread != NULL ? JFR_THREAD_ID(native_thread) : 0;
750 }
751 
752 void JfrJavaSupport::exclude(jobject thread) {
753   JavaThread* native_thread = get_native(thread);
754   if (native_thread != NULL) {
755     JfrThreadLocal::exclude(native_thread);
756   } else {
757     // not started yet, track the thread oop
758     add_thread_to_exclusion_list(thread);
759   }
760 }

811 }
812 
813 bool JfrJavaSupport::set_handler(jobject clazz, jobject handler, TRAPS) {
814   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
815   HandleMark hm(THREAD);
816   const Handle h_mirror(Handle(THREAD, JNIHandles::resolve(clazz)));
817   assert(h_mirror.not_null(), "invariant");
818   fieldDescriptor handler_field_descriptor;
819   const Klass* const field_holder = get_handler_field_descriptor(h_mirror, &handler_field_descriptor, THREAD);
820   if (field_holder == NULL) {
821     // The only reason should be that klass initialization failed.
822     return false;
823   }
824   assert(java_lang_Class::as_Klass(h_mirror()) == field_holder, "invariant");
825   const oop handler_oop = JNIHandles::resolve(handler);
826   assert(handler_oop != NULL, "invariant");
827   h_mirror->obj_field_put(handler_field_descriptor.offset(), handler_oop);
828   return true;
829 }
830 
831 bool JfrJavaSupport::on_thread_start(JavaThread* jt, jobject vthread) {
832   assert(jt != NULL, "invariant");
833   assert(Thread::current() == jt, "invariant");
834   DEBUG_ONLY(check_new_unstarted_java_thread(jt, vthread);)
835   HandleMark hm(jt);
836   const oop threadObj = vthread != NULL ? resolve_non_null(vthread) : jt->threadObj();
837   Handle h_obj(jt, threadObj);
838   if (check_exclusion_state_on_thread_start(h_obj)) {
839     if (vthread != NULL) {
840       exclude(vthread);
841     } else {
842       JfrThreadLocal::exclude(jt);
843     }
844     return false;
845   }
846   return true;
847 }
848 
849 bool JfrJavaSupport::compute_field_offset(int &dest_offset,
850                                           Klass* klass,
851                                           Symbol* name_symbol,
852                                           Symbol* signature_symbol,
853                                           bool is_static,
854                                           bool allow_super) {
855   fieldDescriptor fd;
856   const InstanceKlass* const ik = InstanceKlass::cast(klass);
857   if (!find_field(ik, name_symbol, signature_symbol, &fd, is_static, allow_super)) {
858     return false;
859   }
860   dest_offset = fd.offset();
861   return true;
862 }
< prev index next >