|
416 env, k->java_mirror());
417 return cls;
418 JNI_END
419
420
421
422 static bool first_time_FindClass = true;
423
424 #ifndef USDT2
425 DT_RETURN_MARK_DECL(FindClass, jclass);
426 #else /* USDT2 */
427 DT_RETURN_MARK_DECL(FindClass, jclass
428 , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
429 #endif /* USDT2 */
430
431 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
432 JNIWrapper("FindClass");
433 #ifndef USDT2
434 DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
435 #else /* USDT2 */
436 HOTSPOT_JNI_FINDCLASS_ENTRY(env, (char *)name);
437 #endif /* USDT2 */
438
439 jclass result = NULL;
440 DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
441
442 // Remember if we are the first invocation of jni_FindClass
443 bool first_time = first_time_FindClass;
444 first_time_FindClass = false;
445
446 // Sanity check the name: it cannot be null or larger than the maximum size
447 // name we can fit in the constant pool.
448 if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
449 THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
450 }
451
452 //%note jni_3
453 Handle loader;
454 Handle protection_domain;
455 // Find calling class
456 instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
493 // rather than just allowing invocation counter to overflow and decay.
494 // Controlled by flag DelayCompilationDuringStartup.
495 if (first_time && !CompileTheWorld)
496 CompilationPolicy::completed_vm_startup();
497
498 return result;
499 JNI_END
500
501 #ifndef USDT2
502 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
503 #else /* USDT2 */
504 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
505 , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
506 #endif /* USDT2 */
507
508 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
509 JNIWrapper("FromReflectedMethod");
510 #ifndef USDT2
511 DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);
512 #else /* USDT2 */
513 HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(env, method);
514 #endif /* USDT2 */
515 jmethodID ret = NULL;
516 DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
517
518 // method is a handle to a java.lang.reflect.Method object
519 oop reflected = JNIHandles::resolve_non_null(method);
520 oop mirror = NULL;
521 int slot = 0;
522
523 if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
524 mirror = java_lang_reflect_Constructor::clazz(reflected);
525 slot = java_lang_reflect_Constructor::slot(reflected);
526 } else {
527 assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
528 mirror = java_lang_reflect_Method::clazz(reflected);
529 slot = java_lang_reflect_Method::slot(reflected);
530 }
531 Klass* k = java_lang_Class::as_Klass(mirror);
532
533 KlassHandle k1(THREAD, k);
534 // Make sure class is initialized before handing id's out to methods
535 k1()->initialize(CHECK_NULL);
536 Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot);
537 ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted
538 return ret;
539 JNI_END
540
541 #ifndef USDT2
542 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
543 #else /* USDT2 */
544 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
545 , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
546 #endif /* USDT2 */
547
548 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
549 JNIWrapper("FromReflectedField");
550 #ifndef USDT2
551 DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);
552 #else /* USDT2 */
553 HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(env, field);
554 #endif /* USDT2 */
555 jfieldID ret = NULL;
556 DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
557
558 // field is a handle to a java.lang.reflect.Field object
559 oop reflected = JNIHandles::resolve_non_null(field);
560 oop mirror = java_lang_reflect_Field::clazz(reflected);
561 Klass* k = java_lang_Class::as_Klass(mirror);
562 int slot = java_lang_reflect_Field::slot(reflected);
563 int modifiers = java_lang_reflect_Field::modifiers(reflected);
564
565 KlassHandle k1(THREAD, k);
566 // Make sure class is initialized before handing id's out to fields
567 k1()->initialize(CHECK_NULL);
568
569 // First check if this is a static field
570 if (modifiers & JVM_ACC_STATIC) {
571 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
572 JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);
573 assert(id != NULL, "corrupt Field object");
581 // The jfieldID is the offset of the field within the object
582 // It may also have hash bits for k, if VerifyJNIFields is turned on.
583 intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
584 assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
585 ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
586 return ret;
587 JNI_END
588
589 #ifndef USDT2
590 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
591 #else /* USDT2 */
592 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
593 , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
594 #endif /* USDT2 */
595
596 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
597 JNIWrapper("ToReflectedMethod");
598 #ifndef USDT2
599 DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);
600 #else /* USDT2 */
601 HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
602 #endif /* USDT2 */
603 jobject ret = NULL;
604 DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
605
606 methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
607 assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
608 oop reflection_method;
609 if (m->is_initializer()) {
610 reflection_method = Reflection::new_constructor(m, CHECK_NULL);
611 } else {
612 reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL);
613 }
614 ret = JNIHandles::make_local(env, reflection_method);
615 return ret;
616 JNI_END
617
618 #ifndef USDT2
619 DT_RETURN_MARK_DECL(GetSuperclass, jclass);
620 #else /* USDT2 */
621 DT_RETURN_MARK_DECL(GetSuperclass, jclass
622 , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
623 #endif /* USDT2 */
624
625 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
626 JNIWrapper("GetSuperclass");
627 #ifndef USDT2
628 DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);
629 #else /* USDT2 */
630 HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
631 #endif /* USDT2 */
632 jclass obj = NULL;
633 DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
634
635 oop mirror = JNIHandles::resolve_non_null(sub);
636 // primitive classes return NULL
637 if (java_lang_Class::is_primitive(mirror)) return NULL;
638
639 // Rules of Class.getSuperClass as implemented by KLass::java_super:
640 // arrays return Object
641 // interfaces return NULL
642 // proper classes return Klass::super()
643 Klass* k = java_lang_Class::as_Klass(mirror);
644 if (k->is_interface()) return NULL;
645
646 // return mirror for superclass
647 Klass* super = k->java_super();
648 // super2 is the value computed by the compiler's getSuperClass intrinsic:
649 debug_only(Klass* super2 = ( k->oop_is_array()
650 ? SystemDictionary::Object_klass()
651 : k->super() ) );
652 assert(super == super2,
653 "java_super computation depends on interface, array, other super");
654 obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
655 return obj;
656 JNI_END
657
658 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
659 JNIWrapper("IsSubclassOf");
660 #ifndef USDT2
661 DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);
662 #else /* USDT2 */
663 HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
664 #endif /* USDT2 */
665 oop sub_mirror = JNIHandles::resolve_non_null(sub);
666 oop super_mirror = JNIHandles::resolve_non_null(super);
667 if (java_lang_Class::is_primitive(sub_mirror) ||
668 java_lang_Class::is_primitive(super_mirror)) {
669 jboolean ret = (sub_mirror == super_mirror);
670 #ifndef USDT2
671 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
672 #else /* USDT2 */
673 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
674 #endif /* USDT2 */
675 return ret;
676 }
677 Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
678 Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
679 assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
680 jboolean ret = sub_klass->is_subtype_of(super_klass) ?
681 JNI_TRUE : JNI_FALSE;
682 #ifndef USDT2
683 DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
684 #else /* USDT2 */
685 HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
686 #endif /* USDT2 */
687 return ret;
688 JNI_END
689
690 #ifndef USDT2
691 DT_RETURN_MARK_DECL(Throw, jint);
692 #else /* USDT2 */
693 DT_RETURN_MARK_DECL(Throw, jint
694 , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
695 #endif /* USDT2 */
696
697 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
698 JNIWrapper("Throw");
699 #ifndef USDT2
700 DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);
701 #else /* USDT2 */
702 HOTSPOT_JNI_THROW_ENTRY(env, obj);
703 #endif /* USDT2 */
704 jint ret = JNI_OK;
705 DT_RETURN_MARK(Throw, jint, (const jint&)ret);
706
707 THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
708 ShouldNotReachHere();
709 JNI_END
710
711 #ifndef USDT2
712 DT_RETURN_MARK_DECL(ThrowNew, jint);
713 #else /* USDT2 */
714 DT_RETURN_MARK_DECL(ThrowNew, jint
715 , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
716 #endif /* USDT2 */
717
718 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
719 JNIWrapper("ThrowNew");
720 #ifndef USDT2
721 DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);
722 #else /* USDT2 */
723 HOTSPOT_JNI_THROWNEW_ENTRY(env, clazz, (char *) message);
724 #endif /* USDT2 */
725 jint ret = JNI_OK;
726 DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
727
728 InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
729 Symbol* name = k->name();
730 Handle class_loader (THREAD, k->class_loader());
731 Handle protection_domain (THREAD, k->protection_domain());
732 THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
733 ShouldNotReachHere();
734 JNI_END
735
736
737 // JNI functions only transform a pending async exception to a synchronous
738 // exception in ExceptionOccurred and ExceptionCheck calls, since
739 // delivering an async exception in other places won't change the native
740 // code's control flow and would be harmful when native code further calls
741 // JNI functions with a pending exception. Async exception is also checked
742 // during the call, so ExceptionOccurred/ExceptionCheck won't return
743 // false but deliver the async exception at the very end during
744 // state transition.
745
746 static void jni_check_async_exceptions(JavaThread *thread) {
747 assert(thread == Thread::current(), "must be itself");
748 thread->check_and_handle_async_exceptions();
749 }
750
751 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
752 JNIWrapper("ExceptionOccurred");
753 #ifndef USDT2
754 DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);
755 #else /* USDT2 */
756 HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(env);
757 #endif /* USDT2 */
758 jni_check_async_exceptions(thread);
759 oop exception = thread->pending_exception();
760 jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
761 #ifndef USDT2
762 DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);
763 #else /* USDT2 */
764 HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(ret);
765 #endif /* USDT2 */
766 return ret;
767 JNI_END
768
769
770 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
771 JNIWrapper("ExceptionDescribe");
772 #ifndef USDT2
773 DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);
774 #else /* USDT2 */
775 HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(env);
776 #endif /* USDT2 */
777 if (thread->has_pending_exception()) {
778 Handle ex(thread, thread->pending_exception());
779 thread->clear_pending_exception();
780 if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {
781 // Don't print anything if we are being killed.
782 } else {
783 jio_fprintf(defaultStream::error_stream(), "Exception ");
784 if (thread != NULL && thread->threadObj() != NULL) {
785 ResourceMark rm(THREAD);
786 jio_fprintf(defaultStream::error_stream(),
787 "in thread \"%s\" ", thread->get_thread_name());
788 }
789 if (ex->is_a(SystemDictionary::Throwable_klass())) {
790 JavaValue result(T_VOID);
791 JavaCalls::call_virtual(&result,
792 ex,
793 KlassHandle(THREAD,
794 SystemDictionary::Throwable_klass()),
795 vmSymbols::printStackTrace_name(),
796 vmSymbols::void_method_signature(),
797 THREAD);
798 // If an exception is thrown in the call it gets thrown away. Not much
799 // we can do with it. The native code that calls this, does not check
800 // for the exception - hence, it might still be in the thread when DestroyVM gets
801 // called, potentially causing a few asserts to trigger - since no pending exception
802 // is expected.
803 CLEAR_PENDING_EXCEPTION;
804 } else {
805 ResourceMark rm(THREAD);
806 jio_fprintf(defaultStream::error_stream(),
807 ". Uncaught exception of type %s.",
808 ex->klass()->external_name());
809 }
810 }
811 }
812 #ifndef USDT2
813 DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);
814 #else /* USDT2 */
815 HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN();
816 #endif /* USDT2 */
817 JNI_END
818
819
820 JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))
821 JNIWrapper("ExceptionClear");
822 #ifndef USDT2
823 DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);
824 #else /* USDT2 */
825 HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(env);
826 #endif /* USDT2 */
827
828 // The jni code might be using this API to clear java thrown exception.
829 // So just mark jvmti thread exception state as exception caught.
830 JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
831 if (state != NULL && state->is_exception_detected()) {
832 state->set_exception_caught();
833 }
834 thread->clear_pending_exception();
835 #ifndef USDT2
836 DTRACE_PROBE(hotspot_jni, ExceptionClear__return);
837 #else /* USDT2 */
838 HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN();
839 #endif /* USDT2 */
840 JNI_END
841
842
843 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
844 JNIWrapper("FatalError");
845 #ifndef USDT2
846 DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
847 #else /* USDT2 */
848 HOTSPOT_JNI_FATALERROR_ENTRY(env, (char *) msg);
849 #endif /* USDT2 */
850 tty->print_cr("FATAL ERROR in native method: %s", msg);
851 thread->print_stack();
852 os::abort(); // Dump core and abort
853 JNI_END
854
855
856 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
857 JNIWrapper("PushLocalFrame");
858 #ifndef USDT2
859 DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);
860 #else /* USDT2 */
861 HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(env, capacity);
862 #endif /* USDT2 */
863 //%note jni_11
864 if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
865 #ifndef USDT2
866 DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
867 #else /* USDT2 */
868 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN((uint32_t)JNI_ERR);
869 #endif /* USDT2 */
870 return JNI_ERR;
871 }
872 JNIHandleBlock* old_handles = thread->active_handles();
873 JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
874 assert(new_handles != NULL, "should not be NULL");
875 new_handles->set_pop_frame_link(old_handles);
876 thread->set_active_handles(new_handles);
877 jint ret = JNI_OK;
878 #ifndef USDT2
879 DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);
880 #else /* USDT2 */
881 HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(ret);
882 #endif /* USDT2 */
883 return ret;
884 JNI_END
885
886
887 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
888 JNIWrapper("PopLocalFrame");
889 #ifndef USDT2
890 DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);
891 #else /* USDT2 */
892 HOTSPOT_JNI_POPLOCALFRAME_ENTRY(env, result);
893 #endif /* USDT2 */
894 //%note jni_11
895 Handle result_handle(thread, JNIHandles::resolve(result));
896 JNIHandleBlock* old_handles = thread->active_handles();
897 JNIHandleBlock* new_handles = old_handles->pop_frame_link();
898 if (new_handles != NULL) {
899 // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
900 // This way code will still work if PopLocalFrame is called without a corresponding
901 // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
902 // the release_block call will release the blocks.
903 thread->set_active_handles(new_handles);
904 old_handles->set_pop_frame_link(NULL); // clear link we won't release new_handles below
905 JNIHandleBlock::release_block(old_handles, thread); // may block
906 result = JNIHandles::make_local(thread, result_handle());
907 }
908 #ifndef USDT2
909 DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);
910 #else /* USDT2 */
911 HOTSPOT_JNI_POPLOCALFRAME_RETURN(result);
912 #endif /* USDT2 */
913 return result;
914 JNI_END
915
916
917 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
918 JNIWrapper("NewGlobalRef");
919 #ifndef USDT2
920 DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);
921 #else /* USDT2 */
922 HOTSPOT_JNI_NEWGLOBALREF_ENTRY(env, ref);
923 #endif /* USDT2 */
924 Handle ref_handle(thread, JNIHandles::resolve(ref));
925 jobject ret = JNIHandles::make_global(ref_handle);
926 #ifndef USDT2
927 DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);
928 #else /* USDT2 */
929 HOTSPOT_JNI_NEWGLOBALREF_RETURN(ret);
930 #endif /* USDT2 */
931 return ret;
932 JNI_END
933
934 // Must be JNI_ENTRY (with HandleMark)
935 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
936 JNIWrapper("DeleteGlobalRef");
937 #ifndef USDT2
938 DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);
939 #else /* USDT2 */
940 HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(env, ref);
941 #endif /* USDT2 */
942 JNIHandles::destroy_global(ref);
943 #ifndef USDT2
944 DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);
945 #else /* USDT2 */
946 HOTSPOT_JNI_DELETEGLOBALREF_RETURN();
947 #endif /* USDT2 */
948 JNI_END
949
950 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
951 JNIWrapper("DeleteLocalRef");
952 #ifndef USDT2
953 DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);
954 #else /* USDT2 */
955 HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
956 #endif /* USDT2 */
957 JNIHandles::destroy_local(obj);
958 #ifndef USDT2
959 DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);
960 #else /* USDT2 */
961 HOTSPOT_JNI_DELETELOCALREF_RETURN();
962 #endif /* USDT2 */
963 JNI_END
964
965 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
966 JNIWrapper("IsSameObject");
967 #ifndef USDT2
968 DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);
969 #else /* USDT2 */
970 HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
971 #endif /* USDT2 */
972 oop a = JNIHandles::resolve(r1);
973 oop b = JNIHandles::resolve(r2);
974 jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
975 #ifndef USDT2
976 DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);
977 #else /* USDT2 */
978 HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
979 #endif /* USDT2 */
980 return ret;
981 JNI_END
982
983
984 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
985 JNIWrapper("NewLocalRef");
986 #ifndef USDT2
987 DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);
988 #else /* USDT2 */
989 HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
990 #endif /* USDT2 */
991 jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
992 #ifndef USDT2
993 DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);
994 #else /* USDT2 */
995 HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
996 #endif /* USDT2 */
997 return ret;
998 JNI_END
999
1000 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
1001 JNIWrapper("EnsureLocalCapacity");
1002 #ifndef USDT2
1003 DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);
1004 #else /* USDT2 */
1005 HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
1006 #endif /* USDT2 */
1007 jint ret;
1008 if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
1009 ret = JNI_OK;
1010 } else {
1011 ret = JNI_ERR;
1012 }
1013 #ifndef USDT2
1014 DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);
1015 #else /* USDT2 */
1016 HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(ret);
1017 #endif /* USDT2 */
1018 return ret;
1019 JNI_END
1020
1021 // Return the Handle Type
1022 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
1023 JNIWrapper("GetObjectRefType");
1024 #ifndef USDT2
1025 DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);
1026 #else /* USDT2 */
1027 HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(env, obj);
1028 #endif /* USDT2 */
1029 jobjectRefType ret;
1030 if (JNIHandles::is_local_handle(thread, obj) ||
1031 JNIHandles::is_frame_handle(thread, obj))
1032 ret = JNILocalRefType;
1033 else if (JNIHandles::is_global_handle(obj))
1034 ret = JNIGlobalRefType;
1035 else if (JNIHandles::is_weak_global_handle(obj))
1036 ret = JNIWeakGlobalRefType;
1037 else
1038 ret = JNIInvalidRefType;
1039 #ifndef USDT2
1040 DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);
1041 #else /* USDT2 */
1042 HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
1043 #endif /* USDT2 */
1044 return ret;
1045 JNI_END
1046
1047
1048 class JNI_ArgumentPusher : public SignatureIterator {
1049 protected:
1050 JavaCallArguments* _arguments;
1051
1052 virtual void get_bool () = 0;
1053 virtual void get_char () = 0;
1054 virtual void get_short () = 0;
1055 virtual void get_byte () = 0;
1056 virtual void get_int () = 0;
1057 virtual void get_long () = 0;
1058 virtual void get_float () = 0;
1059 virtual void get_double () = 0;
1060 virtual void get_object () = 0;
1061
1062 JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
1357 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
1358 k()->check_valid_for_instantiation(false, CHECK_NULL);
1359 InstanceKlass::cast(k())->initialize(CHECK_NULL);
1360 instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD);
1361 return ih;
1362 }
1363
1364 #ifndef USDT2
1365 DT_RETURN_MARK_DECL(AllocObject, jobject);
1366 #else /* USDT2 */
1367 DT_RETURN_MARK_DECL(AllocObject, jobject
1368 , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1369 #endif /* USDT2 */
1370
1371 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
1372 JNIWrapper("AllocObject");
1373
1374 #ifndef USDT2
1375 DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);
1376 #else /* USDT2 */
1377 HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
1378 #endif /* USDT2 */
1379 jobject ret = NULL;
1380 DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
1381
1382 instanceOop i = alloc_object(clazz, CHECK_NULL);
1383 ret = JNIHandles::make_local(env, i);
1384 return ret;
1385 JNI_END
1386
1387 #ifndef USDT2
1388 DT_RETURN_MARK_DECL(NewObjectA, jobject);
1389 #else /* USDT2 */
1390 DT_RETURN_MARK_DECL(NewObjectA, jobject
1391 , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
1392 #endif /* USDT2 */
1393
1394 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
1395 JNIWrapper("NewObjectA");
1396 #ifndef USDT2
1397 DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);
1398 #else /* USDT2 */
1399 HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
1400 #endif /* USDT2 */
1401 jobject obj = NULL;
1402 DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
1403
1404 instanceOop i = alloc_object(clazz, CHECK_NULL);
1405 obj = JNIHandles::make_local(env, i);
1406 JavaValue jvalue(T_VOID);
1407 JNI_ArgumentPusherArray ap(methodID, args);
1408 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1409 return obj;
1410 JNI_END
1411
1412 #ifndef USDT2
1413 DT_RETURN_MARK_DECL(NewObjectV, jobject);
1414 #else /* USDT2 */
1415 DT_RETURN_MARK_DECL(NewObjectV, jobject
1416 , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1417 #endif /* USDT2 */
1418
1419 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1420 JNIWrapper("NewObjectV");
1421 #ifndef USDT2
1422 DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);
1423 #else /* USDT2 */
1424 HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1425 #endif /* USDT2 */
1426 jobject obj = NULL;
1427 DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1428
1429 instanceOop i = alloc_object(clazz, CHECK_NULL);
1430 obj = JNIHandles::make_local(env, i);
1431 JavaValue jvalue(T_VOID);
1432 JNI_ArgumentPusherVaArg ap(methodID, args);
1433 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1434 return obj;
1435 JNI_END
1436
1437 #ifndef USDT2
1438 DT_RETURN_MARK_DECL(NewObject, jobject);
1439 #else /* USDT2 */
1440 DT_RETURN_MARK_DECL(NewObject, jobject
1441 , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1442 #endif /* USDT2 */
1443
1444 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1445 JNIWrapper("NewObject");
1446 #ifndef USDT2
1447 DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);
1448 #else /* USDT2 */
1449 HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1450 #endif /* USDT2 */
1451 jobject obj = NULL;
1452 DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1453
1454 instanceOop i = alloc_object(clazz, CHECK_NULL);
1455 obj = JNIHandles::make_local(env, i);
1456 va_list args;
1457 va_start(args, methodID);
1458 JavaValue jvalue(T_VOID);
1459 JNI_ArgumentPusherVaArg ap(methodID, args);
1460 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1461 va_end(args);
1462 return obj;
1463 JNI_END
1464
1465
1466 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1467 JNIWrapper("GetObjectClass");
1468 #ifndef USDT2
1469 DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);
1470 #else /* USDT2 */
1471 HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1472 #endif /* USDT2 */
1473 Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1474 jclass ret =
1475 (jclass) JNIHandles::make_local(env, k->java_mirror());
1476 #ifndef USDT2
1477 DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
1478 #else /* USDT2 */
1479 HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1480 #endif /* USDT2 */
1481 return ret;
1482 JNI_END
1483
1484 JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1485 JNIWrapper("IsInstanceOf");
1486 #ifndef USDT2
1487 DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);
1488 #else /* USDT2 */
1489 HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1490 #endif /* USDT2 */
1491 jboolean ret = JNI_TRUE;
1492 if (obj != NULL) {
1493 ret = JNI_FALSE;
1494 Klass* k = java_lang_Class::as_Klass(
1495 JNIHandles::resolve_non_null(clazz));
1496 if (k != NULL) {
1497 ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
1498 }
1499 }
1500 #ifndef USDT2
1501 DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);
1502 #else /* USDT2 */
1503 HOTSPOT_JNI_ISINSTANCEOF_RETURN(ret);
1504 #endif /* USDT2 */
1505 return ret;
1506 JNI_END
1507
1508
1509 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
1510 const char *sig, bool is_static, TRAPS) {
1511 // %%%% This code should probably just call into a method in the LinkResolver
1512 //
1513 // The class should have been loaded (we have an instance of the class
1514 // passed in) so the method and signature should already be in the symbol
1515 // table. If they're not there, the method doesn't exist.
1516 const char *name_to_probe = (name_str == NULL)
1517 ? vmSymbols::object_initializer_name()->as_C_string()
1518 : name_str;
1519 TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));
1520 TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));
1521
1522 if (name == NULL || signature == NULL) {
1523 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1547 }
1548 } else {
1549 m = klass->lookup_method(name, signature);
1550 if (m == NULL && klass->oop_is_instance()) {
1551 m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature);
1552 }
1553 }
1554 if (m == NULL || (m->is_static() != is_static)) {
1555 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1556 }
1557 return m->jmethod_id();
1558 }
1559
1560
1561 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
1562 const char *name, const char *sig))
1563 JNIWrapper("GetMethodID");
1564 #ifndef USDT2
1565 DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);
1566 #else /* USDT2 */
1567 HOTSPOT_JNI_GETMETHODID_ENTRY(env, clazz, (char *) name, (char *) sig);
1568 #endif /* USDT2 */
1569 jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
1570 #ifndef USDT2
1571 DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);
1572 #else /* USDT2 */
1573 HOTSPOT_JNI_GETMETHODID_RETURN((uintptr_t) ret);
1574 #endif /* USDT2 */
1575 return ret;
1576 JNI_END
1577
1578
1579 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
1580 const char *name, const char *sig))
1581 JNIWrapper("GetStaticMethodID");
1582 #ifndef USDT2
1583 DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);
1584 #else /* USDT2 */
1585 HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(env, (char *) clazz, (char *) name, (char *)sig);
1586 #endif /* USDT2 */
1587 jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
1588 #ifndef USDT2
1589 DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);
1590 #else /* USDT2 */
1591 HOTSPOT_JNI_GETSTATICMETHODID_RETURN((uintptr_t) ret);
1592 #endif /* USDT2 */
1593 return ret;
1594 JNI_END
1595
1596
1597
1598 //
1599 // Calling Methods
1600 //
1601
1602 #ifndef USDT2
1603 #define DEFINE_CALLMETHOD(ResultType, Result, Tag) \
1604 \
1605 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\
1606 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\
1607 DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\
1608 \
1609 JNI_ENTRY(ResultType, \
1610 jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
1611 JNIWrapper("Call" XSTR(Result) "Method"); \
1831 HOTSPOT_JNI_CALLLONGMETHODA_RETURN(_ret_ref))
1832 // Float and double probes don't return value because dtrace doesn't currently support it
1833 DEFINE_CALLMETHODA(jfloat, Float, T_FLOAT
1834 , HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1835 HOTSPOT_JNI_CALLFLOATMETHODA_RETURN())
1836 DEFINE_CALLMETHODA(jdouble, Double, T_DOUBLE
1837 , HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1838 HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN())
1839
1840 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
1841 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
1842 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
1843
1844 #endif /* USDT2 */
1845
1846 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
1847 JNIWrapper("CallVoidMethod");
1848 #ifndef USDT2
1849 DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);
1850 #else /* USDT2 */
1851 HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(env, obj, (uintptr_t) methodID);
1852 #endif /* USDT2 */
1853 DT_VOID_RETURN_MARK(CallVoidMethod);
1854
1855 va_list args;
1856 va_start(args, methodID);
1857 JavaValue jvalue(T_VOID);
1858 JNI_ArgumentPusherVaArg ap(methodID, args);
1859 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1860 va_end(args);
1861 JNI_END
1862
1863
1864 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
1865 JNIWrapper("CallVoidMethodV");
1866 #ifndef USDT2
1867 DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);
1868 #else /* USDT2 */
1869 HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(env, obj, (uintptr_t) methodID);
1870 #endif /* USDT2 */
1871 DT_VOID_RETURN_MARK(CallVoidMethodV);
1872
1873 JavaValue jvalue(T_VOID);
1874 JNI_ArgumentPusherVaArg ap(methodID, args);
1875 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1876 JNI_END
1877
1878
1879 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
1880 JNIWrapper("CallVoidMethodA");
1881 #ifndef USDT2
1882 DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);
1883 #else /* USDT2 */
1884 HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(env, obj, (uintptr_t) methodID);
1885 #endif /* USDT2 */
1886 DT_VOID_RETURN_MARK(CallVoidMethodA);
1887
1888 JavaValue jvalue(T_VOID);
1889 JNI_ArgumentPusherArray ap(methodID, args);
1890 jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1891 JNI_END
1892
1893
1894 #ifndef USDT2
1895 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \
1896 \
1897 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\
1898 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\
1899 DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\
1900 \
1901 JNI_ENTRY(ResultType, \
1902 jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
1903 JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
1904 \
2126 HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
2127 DEFINE_CALLNONVIRTUALMETHODA(jdouble, Double, T_DOUBLE
2128 , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2129 HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
2130
2131 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
2132 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
2133 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
2134 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
2135 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
2136 , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
2137 #endif /* USDT2 */
2138
2139 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
2140 JNIWrapper("CallNonvirtualVoidMethod");
2141
2142 #ifndef USDT2
2143 DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,
2144 env, obj, cls, methodID);
2145 #else /* USDT2 */
2146 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(env, obj, cls, (uintptr_t) methodID);
2147 #endif /* USDT2 */
2148 DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
2149
2150 va_list args;
2151 va_start(args, methodID);
2152 JavaValue jvalue(T_VOID);
2153 JNI_ArgumentPusherVaArg ap(methodID, args);
2154 jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
2155 va_end(args);
2156 JNI_END
2157
2158
2159 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
2160 JNIWrapper("CallNonvirtualVoidMethodV");
2161
2162 #ifndef USDT2
2163 DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,
2164 env, obj, cls, methodID);
2165 #else /* USDT2 */
2166 HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
2427 DEFINE_CALLSTATICMETHODA(jfloat, Float, T_FLOAT
2428 , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2429 HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
2430 DEFINE_CALLSTATICMETHODA(jdouble, Double, T_DOUBLE
2431 , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2432 HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
2433
2434 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
2435 , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
2436 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
2437 , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
2438 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
2439 , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
2440 #endif /* USDT2 */
2441
2442 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
2443 JNIWrapper("CallStaticVoidMethod");
2444 #ifndef USDT2
2445 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);
2446 #else /* USDT2 */
2447 HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(env, cls, (uintptr_t) methodID);
2448 #endif /* USDT2 */
2449 DT_VOID_RETURN_MARK(CallStaticVoidMethod);
2450
2451 va_list args;
2452 va_start(args, methodID);
2453 JavaValue jvalue(T_VOID);
2454 JNI_ArgumentPusherVaArg ap(methodID, args);
2455 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2456 va_end(args);
2457 JNI_END
2458
2459
2460 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
2461 JNIWrapper("CallStaticVoidMethodV");
2462 #ifndef USDT2
2463 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);
2464 #else /* USDT2 */
2465 HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(env, cls, (uintptr_t) methodID);
2466 #endif /* USDT2 */
2467 DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
2468
2469 JavaValue jvalue(T_VOID);
2470 JNI_ArgumentPusherVaArg ap(methodID, args);
2471 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2472 JNI_END
2473
2474
2475 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
2476 JNIWrapper("CallStaticVoidMethodA");
2477 #ifndef USDT2
2478 DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);
2479 #else /* USDT2 */
2480 HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(env, cls, (uintptr_t) methodID);
2481 #endif /* USDT2 */
2482 DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
2483
2484 JavaValue jvalue(T_VOID);
2485 JNI_ArgumentPusherArray ap(methodID, args);
2486 jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2487 JNI_END
2488
2489
2490 //
2491 // Accessing Fields
2492 //
2493
2494
2495 #ifndef USDT2
2496 DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
2497 #else /* USDT2 */
2498 DT_RETURN_MARK_DECL(GetFieldID, jfieldID
2499 , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
2500 #endif /* USDT2 */
2501
2502 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
2503 const char *name, const char *sig))
2504 JNIWrapper("GetFieldID");
2505 #ifndef USDT2
2506 DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);
2507 #else /* USDT2 */
2508 HOTSPOT_JNI_GETFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
2509 #endif /* USDT2 */
2510 jfieldID ret = 0;
2511 DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
2512
2513 // The class should have been loaded (we have an instance of the class
2514 // passed in) so the field and signature should already be in the symbol
2515 // table. If they're not there, the field doesn't exist.
2516 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2517 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2518 if (fieldname == NULL || signame == NULL) {
2519 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2520 }
2521 KlassHandle k(THREAD,
2522 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
2523 // Make sure class is initialized before handing id's out to fields
2524 k()->initialize(CHECK_NULL);
2525
2526 fieldDescriptor fd;
2527 if (!k()->oop_is_instance() ||
2528 !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
2529 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2530 }
2531
2532 // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2533 // It may also have hash bits for k, if VerifyJNIFields is turned on.
2534 ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
2535 return ret;
2536 JNI_END
2537
2538
2539 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2540 JNIWrapper("GetObjectField");
2541 #ifndef USDT2
2542 DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
2543 #else /* USDT2 */
2544 HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2545 #endif /* USDT2 */
2546 oop o = JNIHandles::resolve_non_null(obj);
2547 Klass* k = o->klass();
2548 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2549 // Keep JVMTI addition small and only check enabled flag here.
2550 // jni_GetField_probe() assumes that is okay to create handles.
2551 if (JvmtiExport::should_post_field_access()) {
2552 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2553 }
2554 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2555 #if INCLUDE_ALL_GCS
2556 // If G1 is enabled and we are accessing the value of the referent
2557 // field in a reference object then we need to register a non-null
2558 // referent with the SATB barrier.
2559 if (UseG1GC) {
2560 bool needs_barrier = false;
2561
2562 if (ret != NULL &&
2563 offset == java_lang_ref_Reference::referent_offset &&
2564 InstanceKlass::cast(k)->reference_type() != REF_NONE) {
2565 assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2566 needs_barrier = true;
2567 }
2568
2569 if (needs_barrier) {
2570 oop referent = JNIHandles::resolve(ret);
2571 G1SATBCardTableModRefBS::enqueue(referent);
2572 }
2573 }
2574 #endif // INCLUDE_ALL_GCS
2575 #ifndef USDT2
2576 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
2577 #else /* USDT2 */
2578 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2579 #endif /* USDT2 */
2580 return ret;
2581 JNI_END
2582
2583
2584 #ifndef USDT2
2585 #define DEFINE_GETFIELD(Return,Fieldname,Result) \
2586 \
2587 DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\
2588 \
2589 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2590 JNIWrapper("Get" XSTR(Result) "Field"); \
2591 \
2592 DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\
2593 Return ret = 0;\
2594 DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2595 \
2596 oop o = JNIHandles::resolve_non_null(obj); \
2597 Klass* k = o->klass(); \
2598 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
2683 return (address)jni_GetShortField;
2684 }
2685 address jni_GetIntField_addr() {
2686 return (address)jni_GetIntField;
2687 }
2688 address jni_GetLongField_addr() {
2689 return (address)jni_GetLongField;
2690 }
2691 address jni_GetFloatField_addr() {
2692 return (address)jni_GetFloatField;
2693 }
2694 address jni_GetDoubleField_addr() {
2695 return (address)jni_GetDoubleField;
2696 }
2697
2698 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2699 JNIWrapper("SetObjectField");
2700 #ifndef USDT2
2701 DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);
2702 #else /* USDT2 */
2703 HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2704 #endif /* USDT2 */
2705 oop o = JNIHandles::resolve_non_null(obj);
2706 Klass* k = o->klass();
2707 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2708 // Keep JVMTI addition small and only check enabled flag here.
2709 // jni_SetField_probe_nh() assumes that is not okay to create handles
2710 // and creates a ResetNoHandleMark.
2711 if (JvmtiExport::should_post_field_modification()) {
2712 jvalue field_value;
2713 field_value.l = value;
2714 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2715 }
2716 o->obj_field_put(offset, JNIHandles::resolve(value));
2717 #ifndef USDT2
2718 DTRACE_PROBE(hotspot_jni, SetObjectField__return);
2719 #else /* USDT2 */
2720 HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2721 #endif /* USDT2 */
2722 JNI_END
2723
2724 #ifndef USDT2
2725 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
2726 \
2727 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2728 JNIWrapper("Set" XSTR(Result) "Field"); \
2729 \
2730 FP_SELECT_##Result( \
2731 DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \
2732 DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \
2733 \
2734 oop o = JNIHandles::resolve_non_null(obj); \
2735 Klass* k = o->klass(); \
2736 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \
2737 /* Keep JVMTI addition small and only check enabled flag here. */ \
2738 /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2739 /* and creates a ResetNoHandleMark. */ \
2740 if (JvmtiExport::should_post_field_modification()) { \
2803 , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2804 HOTSPOT_JNI_SETFLOATFIELD_RETURN())
2805 DEFINE_SETFIELD(jdouble, double, Double, 'D', d
2806 , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2807 HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
2808 #endif /* USDT2 */
2809
2810 #ifndef USDT2
2811 DT_RETURN_MARK_DECL(ToReflectedField, jobject);
2812 #else /* USDT2 */
2813 DT_RETURN_MARK_DECL(ToReflectedField, jobject
2814 , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
2815 #endif /* USDT2 */
2816
2817 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
2818 JNIWrapper("ToReflectedField");
2819 #ifndef USDT2
2820 DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,
2821 env, cls, fieldID, isStatic);
2822 #else /* USDT2 */
2823 HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(env, cls, (uintptr_t) fieldID, isStatic);
2824 #endif /* USDT2 */
2825 jobject ret = NULL;
2826 DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
2827
2828 fieldDescriptor fd;
2829 bool found = false;
2830 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2831
2832 assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
2833
2834 if (isStatic) {
2835 // Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*.
2836 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2837 assert(id->is_static_field_id(), "invalid static field id");
2838 found = id->find_local_field(&fd);
2839 } else {
2840 // Non-static field. The fieldID is really the offset of the field within the instanceOop.
2841 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2842 found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
2843 }
2847 return ret;
2848 JNI_END
2849
2850
2851 //
2852 // Accessing Static Fields
2853 //
2854 #ifndef USDT2
2855 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
2856 #else /* USDT2 */
2857 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
2858 , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
2859 #endif /* USDT2 */
2860
2861 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
2862 const char *name, const char *sig))
2863 JNIWrapper("GetStaticFieldID");
2864 #ifndef USDT2
2865 DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);
2866 #else /* USDT2 */
2867 HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
2868 #endif /* USDT2 */
2869 jfieldID ret = NULL;
2870 DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
2871
2872 // The class should have been loaded (we have an instance of the class
2873 // passed in) so the field and signature should already be in the symbol
2874 // table. If they're not there, the field doesn't exist.
2875 TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2876 TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2877 if (fieldname == NULL || signame == NULL) {
2878 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2879 }
2880 KlassHandle k(THREAD,
2881 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
2882 // Make sure class is initialized before handing id's out to static fields
2883 k()->initialize(CHECK_NULL);
2884
2885 fieldDescriptor fd;
2886 if (!k()->oop_is_instance() ||
2887 !InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
2888 THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2889 }
2890
2891 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
2892 JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
2893 debug_only(id->set_is_static_field_id();)
2894
2895 debug_only(id->verify(fd.field_holder()));
2896
2897 ret = jfieldIDWorkaround::to_static_jfieldID(id);
2898 return ret;
2899 JNI_END
2900
2901
2902 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2903 JNIWrapper("GetStaticObjectField");
2904 #ifndef USDT2
2905 DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
2906 #else /* USDT2 */
2907 HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID);
2908 #endif /* USDT2 */
2909 #if INCLUDE_JNI_CHECK
2910 DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
2911 #endif // INCLUDE_JNI_CHECK
2912 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2913 assert(id->is_static_field_id(), "invalid static field id");
2914 // Keep JVMTI addition small and only check enabled flag here.
2915 // jni_GetField_probe() assumes that is okay to create handles.
2916 if (JvmtiExport::should_post_field_access()) {
2917 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
2918 }
2919 jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
2920 #ifndef USDT2
2921 DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
2922 #else /* USDT2 */
2923 HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(ret);
2924 #endif /* USDT2 */
2925 return ret;
2926 JNI_END
2927
2928 #ifndef USDT2
2929 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
2930 \
2931 DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\
2932 \
2933 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
2934 JNIWrapper("GetStatic" XSTR(Result) "Field"); \
2935 DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\
2936 Return ret = 0;\
2937 DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
2938 (const Return&)ret);\
2939 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
2940 assert(id->is_static_field_id(), "invalid static field id"); \
2941 /* Keep JVMTI addition small and only check enabled flag here. */ \
2942 /* jni_GetField_probe() assumes that is okay to create handles. */ \
2943 if (JvmtiExport::should_post_field_access()) { \
2988 DEFINE_GETSTATICFIELD(jchar, char, Char
2989 , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref) )
2990 DEFINE_GETSTATICFIELD(jshort, short, Short
2991 , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref) )
2992 DEFINE_GETSTATICFIELD(jint, int, Int
2993 , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref) )
2994 DEFINE_GETSTATICFIELD(jlong, long, Long
2995 , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref) )
2996 // Float and double probes don't return value because dtrace doesn't currently support it
2997 DEFINE_GETSTATICFIELD(jfloat, float, Float
2998 , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN() )
2999 DEFINE_GETSTATICFIELD(jdouble, double, Double
3000 , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN() )
3001 #endif /* USDT2 */
3002
3003 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
3004 JNIWrapper("SetStaticObjectField");
3005 #ifndef USDT2
3006 DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);
3007 #else /* USDT2 */
3008 HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value);
3009 #endif /* USDT2 */
3010 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
3011 assert(id->is_static_field_id(), "invalid static field id");
3012 // Keep JVMTI addition small and only check enabled flag here.
3013 // jni_SetField_probe() assumes that is okay to create handles.
3014 if (JvmtiExport::should_post_field_modification()) {
3015 jvalue field_value;
3016 field_value.l = value;
3017 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
3018 }
3019 id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
3020 #ifndef USDT2
3021 DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
3022 #else /* USDT2 */
3023 HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN();
3024 #endif /* USDT2 */
3025 JNI_END
3026
3027
3028 #ifndef USDT2
3029 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
3030 \
3031 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
3032 JNIWrapper("SetStatic" XSTR(Result) "Field"); \
3033 FP_SELECT_##Result( \
3034 DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \
3035 DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \
3036 \
3037 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
3038 assert(id->is_static_field_id(), "invalid static field id"); \
3039 /* Keep JVMTI addition small and only check enabled flag here. */ \
3040 /* jni_SetField_probe() assumes that is okay to create handles. */ \
3041 if (JvmtiExport::should_post_field_modification()) { \
3042 jvalue field_value; \
3043 field_value.unionType = value; \
3106 #endif /* USDT2 */
3107
3108 //
3109 // String Operations
3110 //
3111
3112 // Unicode Interface
3113
3114 #ifndef USDT2
3115 DT_RETURN_MARK_DECL(NewString, jstring);
3116 #else /* USDT2 */
3117 DT_RETURN_MARK_DECL(NewString, jstring
3118 , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
3119 #endif /* USDT2 */
3120
3121 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
3122 JNIWrapper("NewString");
3123 #ifndef USDT2
3124 DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);
3125 #else /* USDT2 */
3126 HOTSPOT_JNI_NEWSTRING_ENTRY(env, (uint16_t *) unicodeChars, len);
3127 #endif /* USDT2 */
3128 jstring ret = NULL;
3129 DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
3130 oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
3131 ret = (jstring) JNIHandles::make_local(env, string);
3132 return ret;
3133 JNI_END
3134
3135
3136 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
3137 JNIWrapper("GetStringLength");
3138 #ifndef USDT2
3139 DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);
3140 #else /* USDT2 */
3141 HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
3142 #endif /* USDT2 */
3143 jsize ret = 0;
3144 oop s = JNIHandles::resolve_non_null(string);
3145 if (java_lang_String::value(s) != NULL) {
3146 ret = java_lang_String::length(s);
3147 }
3148 #ifndef USDT2
3149 DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
3150 #else /* USDT2 */
3151 HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
3152 #endif /* USDT2 */
3153 return ret;
3154 JNI_END
3155
3156
3157 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
3158 JNIEnv *env, jstring string, jboolean *isCopy))
3159 JNIWrapper("GetStringChars");
3160 #ifndef USDT2
3161 DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);
3162 #else /* USDT2 */
3163 HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
3164 #endif /* USDT2 */
3165 jchar* buf = NULL;
3166 oop s = JNIHandles::resolve_non_null(string);
3167 typeArrayOop s_value = java_lang_String::value(s);
3168 if (s_value != NULL) {
3169 int s_len = java_lang_String::length(s);
3170 int s_offset = java_lang_String::offset(s);
3171 buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
3172 /* JNI Specification states return NULL on OOM */
3173 if (buf != NULL) {
3174 if (s_len > 0) {
3175 memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
3176 }
3177 buf[s_len] = 0;
3178 //%note jni_5
3179 if (isCopy != NULL) {
3180 *isCopy = JNI_TRUE;
3181 }
3182 }
3183 }
3184 #ifndef USDT2
3185 DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
3186 #else /* USDT2 */
3187 HOTSPOT_JNI_GETSTRINGCHARS_RETURN(buf);
3188 #endif /* USDT2 */
3189 return buf;
3190 JNI_END
3191
3192
3193 JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
3194 JNIWrapper("ReleaseStringChars");
3195 #ifndef USDT2
3196 DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);
3197 #else /* USDT2 */
3198 HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(env, str, (uint16_t *) chars);
3199 #endif /* USDT2 */
3200 //%note jni_6
3201 if (chars != NULL) {
3202 // Since String objects are supposed to be immutable, don't copy any
3203 // new data back. A bad user will have to go after the char array.
3204 FreeHeap((void*) chars);
3205 }
3206 #ifndef USDT2
3207 DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);
3208 #else /* USDT2 */
3209 HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN();
3210 #endif /* USDT2 */
3211 JNI_END
3212
3213
3214 // UTF Interface
3215
3216 #ifndef USDT2
3217 DT_RETURN_MARK_DECL(NewStringUTF, jstring);
3218 #else /* USDT2 */
3219 DT_RETURN_MARK_DECL(NewStringUTF, jstring
3220 , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
3221 #endif /* USDT2 */
3222
3223 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
3224 JNIWrapper("NewStringUTF");
3225 #ifndef USDT2
3226 DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);
3227 #else /* USDT2 */
3228 HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(env, (char *) bytes);
3229 #endif /* USDT2 */
3230 jstring ret;
3231 DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
3232
3233 oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
3234 ret = (jstring) JNIHandles::make_local(env, result);
3235 return ret;
3236 JNI_END
3237
3238
3239 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
3240 JNIWrapper("GetStringUTFLength");
3241 #ifndef USDT2
3242 DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);
3243 #else /* USDT2 */
3244 HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(env, string);
3245 #endif /* USDT2 */
3246 jsize ret = 0;
3247 oop java_string = JNIHandles::resolve_non_null(string);
3248 if (java_lang_String::value(java_string) != NULL) {
3249 ret = java_lang_String::utf8_length(java_string);
3250 }
3251 #ifndef USDT2
3252 DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
3253 #else /* USDT2 */
3254 HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(ret);
3255 #endif /* USDT2 */
3256 return ret;
3257 JNI_END
3258
3259
3260 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
3261 JNIWrapper("GetStringUTFChars");
3262 #ifndef USDT2
3263 DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);
3264 #else /* USDT2 */
3265 HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
3266 #endif /* USDT2 */
3267 char* result = NULL;
3268 oop java_string = JNIHandles::resolve_non_null(string);
3269 if (java_lang_String::value(java_string) != NULL) {
3270 size_t length = java_lang_String::utf8_length(java_string);
3271 /* JNI Specification states return NULL on OOM */
3272 result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
3273 if (result != NULL) {
3274 java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
3275 if (isCopy != NULL) {
3276 *isCopy = JNI_TRUE;
3277 }
3278 }
3279 }
3280 #ifndef USDT2
3281 DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
3282 #else /* USDT2 */
3283 HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(result);
3284 #endif /* USDT2 */
3285 return result;
3286 JNI_END
3287
3288
3289 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
3290 JNIWrapper("ReleaseStringUTFChars");
3291 #ifndef USDT2
3292 DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);
3293 #else /* USDT2 */
3294 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(env, str, (char *) chars);
3295 #endif /* USDT2 */
3296 if (chars != NULL) {
3297 FreeHeap((char*) chars);
3298 }
3299 #ifndef USDT2
3300 DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);
3301 #else /* USDT2 */
3302 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN();
3303 #endif /* USDT2 */
3304 JNI_END
3305
3306
3307 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
3308 JNIWrapper("GetArrayLength");
3309 #ifndef USDT2
3310 DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);
3311 #else /* USDT2 */
3312 HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array);
3313 #endif /* USDT2 */
3314 arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
3315 assert(a->is_array(), "must be array");
3316 jsize ret = a->length();
3317 #ifndef USDT2
3318 DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);
3319 #else /* USDT2 */
3320 HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret);
3321 #endif /* USDT2 */
3322 return ret;
3323 JNI_END
3324
3325
3326 //
3327 // Object Array Operations
3328 //
3329
3330 #ifndef USDT2
3331 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
3332 #else /* USDT2 */
3333 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
3334 , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
3335 #endif /* USDT2 */
3336
3337 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
3338 JNIWrapper("NewObjectArray");
3339 #ifndef USDT2
3340 DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);
3341 #else /* USDT2 */
3342 HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
3343 #endif /* USDT2 */
3344 jobjectArray ret = NULL;
3345 DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
3346 KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));
3347 Klass* ako = ek()->array_klass(CHECK_NULL);
3348 KlassHandle ak = KlassHandle(THREAD, ako);
3349 ObjArrayKlass::cast(ak())->initialize(CHECK_NULL);
3350 objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
3351 oop initial_value = JNIHandles::resolve(initialElement);
3352 if (initial_value != NULL) { // array already initialized with NULL
3353 for (int index = 0; index < length; index++) {
3354 result->obj_at_put(index, initial_value);
3355 }
3356 }
3357 ret = (jobjectArray) JNIHandles::make_local(env, result);
3358 return ret;
3359 JNI_END
3360
3361 #ifndef USDT2
3362 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
3363 #else /* USDT2 */
3364 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
3365 , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
3366 #endif /* USDT2 */
3367
3368 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
3369 JNIWrapper("GetObjectArrayElement");
3370 #ifndef USDT2
3371 DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);
3372 #else /* USDT2 */
3373 HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
3374 #endif /* USDT2 */
3375 jobject ret = NULL;
3376 DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
3377 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
3378 if (a->is_within_bounds(index)) {
3379 ret = JNIHandles::make_local(env, a->obj_at(index));
3380 return ret;
3381 } else {
3382 char buf[jintAsStringSize];
3383 sprintf(buf, "%d", index);
3384 THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
3385 }
3386 JNI_END
3387
3388 #ifndef USDT2
3389 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
3390 #else /* USDT2 */
3391 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
3392 , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
3393 #endif /* USDT2 */
3394
3395 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
3396 JNIWrapper("SetObjectArrayElement");
3397 #ifndef USDT2
3398 DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);
3399 #else /* USDT2 */
3400 HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
3401 #endif /* USDT2 */
3402 DT_VOID_RETURN_MARK(SetObjectArrayElement);
3403
3404 objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
3405 oop v = JNIHandles::resolve(value);
3406 if (a->is_within_bounds(index)) {
3407 if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
3408 a->obj_at_put(index, v);
3409 } else {
3410 THROW(vmSymbols::java_lang_ArrayStoreException());
3411 }
3412 } else {
3413 char buf[jintAsStringSize];
3414 sprintf(buf, "%d", index);
3415 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
3416 }
3417 JNI_END
3418
3419
3420 #ifndef USDT2
3932 method->method_holder()->external_name(),
3933 method->name()->as_C_string());
3934 }
3935 return true;
3936 }
3937
3938 #ifndef USDT2
3939 DT_RETURN_MARK_DECL(RegisterNatives, jint);
3940 #else /* USDT2 */
3941 DT_RETURN_MARK_DECL(RegisterNatives, jint
3942 , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
3943 #endif /* USDT2 */
3944
3945 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
3946 const JNINativeMethod *methods,
3947 jint nMethods))
3948 JNIWrapper("RegisterNatives");
3949 #ifndef USDT2
3950 DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);
3951 #else /* USDT2 */
3952 HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
3953 #endif /* USDT2 */
3954 jint ret = 0;
3955 DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
3956
3957 KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
3958
3959 for (int index = 0; index < nMethods; index++) {
3960 const char* meth_name = methods[index].name;
3961 const char* meth_sig = methods[index].signature;
3962 int meth_name_len = (int)strlen(meth_name);
3963
3964 // The class should have been loaded (we have an instance of the class
3965 // passed in) so the method and signature should already be in the symbol
3966 // table. If they're not there, the method doesn't exist.
3967 TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len);
3968 TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
3969
3970 if (name == NULL || signature == NULL) {
3971 ResourceMark rm;
3972 stringStream st;
3974 // Must return negative value on failure
3975 THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
3976 }
3977
3978 bool res = register_native(h_k, name, signature,
3979 (address) methods[index].fnPtr, THREAD);
3980 if (!res) {
3981 ret = -1;
3982 break;
3983 }
3984 }
3985 return ret;
3986 JNI_END
3987
3988
3989 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
3990 JNIWrapper("UnregisterNatives");
3991 #ifndef USDT2
3992 DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);
3993 #else /* USDT2 */
3994 HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(env, clazz);
3995 #endif /* USDT2 */
3996 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
3997 //%note jni_2
3998 if (k->oop_is_instance()) {
3999 for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
4000 Method* m = InstanceKlass::cast(k)->methods()->at(index);
4001 if (m->is_native()) {
4002 m->clear_native_function();
4003 m->set_signature_handler(NULL);
4004 }
4005 }
4006 }
4007 #ifndef USDT2
4008 DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);
4009 #else /* USDT2 */
4010 HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(0);
4011 #endif /* USDT2 */
4012 return 0;
4013 JNI_END
4014
4015 //
4016 // Monitor functions
4017 //
4018
4019 #ifndef USDT2
4020 DT_RETURN_MARK_DECL(MonitorEnter, jint);
4021 #else /* USDT2 */
4022 DT_RETURN_MARK_DECL(MonitorEnter, jint
4023 , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
4024 #endif /* USDT2 */
4025
4026 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
4027 #ifndef USDT2
4028 DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);
4029 #else /* USDT2 */
4030 HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
4031 #endif /* USDT2 */
4032 jint ret = JNI_ERR;
4033 DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
4034
4035 // If the object is null, we can't do anything with it
4036 if (jobj == NULL) {
4037 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
4038 }
4039
4040 Handle obj(thread, JNIHandles::resolve_non_null(jobj));
4041 ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
4042 ret = JNI_OK;
4043 return ret;
4044 JNI_END
4045
4046 #ifndef USDT2
4047 DT_RETURN_MARK_DECL(MonitorExit, jint);
4048 #else /* USDT2 */
4049 DT_RETURN_MARK_DECL(MonitorExit, jint
4050 , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
4051 #endif /* USDT2 */
4052
4053 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
4054 #ifndef USDT2
4055 DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);
4056 #else /* USDT2 */
4057 HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
4058 #endif /* USDT2 */
4059 jint ret = JNI_ERR;
4060 DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
4061
4062 // Don't do anything with a null object
4063 if (jobj == NULL) {
4064 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
4065 }
4066
4067 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
4068 ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
4069
4070 ret = JNI_OK;
4071 return ret;
4072 JNI_END
4073
4074 //
4075 // Extensions
4076 //
4077
4078 #ifndef USDT2
4079 DT_VOID_RETURN_MARK_DECL(GetStringRegion);
4080 #else /* USDT2 */
4081 DT_VOID_RETURN_MARK_DECL(GetStringRegion
4082 , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
4083 #endif /* USDT2 */
4084
4085 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
4086 JNIWrapper("GetStringRegion");
4087 #ifndef USDT2
4088 DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);
4089 #else /* USDT2 */
4090 HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
4091 #endif /* USDT2 */
4092 DT_VOID_RETURN_MARK(GetStringRegion);
4093 oop s = JNIHandles::resolve_non_null(string);
4094 int s_len = java_lang_String::length(s);
4095 if (start < 0 || len < 0 || start + len > s_len) {
4096 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4097 } else {
4098 if (len > 0) {
4099 int s_offset = java_lang_String::offset(s);
4100 typeArrayOop s_value = java_lang_String::value(s);
4101 memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
4102 }
4103 }
4104 JNI_END
4105
4106 #ifndef USDT2
4107 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
4108 #else /* USDT2 */
4109 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
4110 , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
4111 #endif /* USDT2 */
4112
4113 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
4114 JNIWrapper("GetStringUTFRegion");
4115 #ifndef USDT2
4116 DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);
4117 #else /* USDT2 */
4118 HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
4119 #endif /* USDT2 */
4120 DT_VOID_RETURN_MARK(GetStringUTFRegion);
4121 oop s = JNIHandles::resolve_non_null(string);
4122 int s_len = java_lang_String::length(s);
4123 if (start < 0 || len < 0 || start + len > s_len) {
4124 THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4125 } else {
4126 //%note jni_7
4127 if (len > 0) {
4128 ResourceMark rm(THREAD);
4129 char *utf_region = java_lang_String::as_utf8_string(s, start, len);
4130 int utf_len = (int)strlen(utf_region);
4131 memcpy(buf, utf_region, utf_len);
4132 buf[utf_len] = 0;
4133 } else {
4134 // JDK null-terminates the buffer even in len is zero
4135 if (buf != NULL) {
4136 buf[0] = 0;
4137 }
4138 }
4139 }
4140 JNI_END
4141
4142
4143 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
4144 JNIWrapper("GetPrimitiveArrayCritical");
4145 #ifndef USDT2
4146 DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
4147 #else /* USDT2 */
4148 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
4149 #endif /* USDT2 */
4150 GC_locker::lock_critical(thread);
4151 if (isCopy != NULL) {
4152 *isCopy = JNI_FALSE;
4153 }
4154 oop a = JNIHandles::resolve_non_null(array);
4155 assert(a->is_array(), "just checking");
4156 BasicType type;
4157 if (a->is_objArray()) {
4158 type = T_OBJECT;
4159 } else {
4160 type = TypeArrayKlass::cast(a->klass())->element_type();
4161 }
4162 void* ret = arrayOop(a)->base(type);
4163 #ifndef USDT2
4164 DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
4165 #else /* USDT2 */
4166 HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
4167 #endif /* USDT2 */
4168 return ret;
4169 JNI_END
4170
4171
4172 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
4173 JNIWrapper("ReleasePrimitiveArrayCritical");
4174 #ifndef USDT2
4175 DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
4176 #else /* USDT2 */
4177 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
4178 #endif /* USDT2 */
4179 // The array, carray and mode arguments are ignored
4180 GC_locker::unlock_critical(thread);
4181 #ifndef USDT2
4182 DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
4183 #else /* USDT2 */
4184 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
4185 #endif /* USDT2 */
4186 JNI_END
4187
4188
4189 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
4190 JNIWrapper("GetStringCritical");
4191 #ifndef USDT2
4192 DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
4193 #else /* USDT2 */
4194 HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
4195 #endif /* USDT2 */
4196 GC_locker::lock_critical(thread);
4197 if (isCopy != NULL) {
4198 *isCopy = JNI_FALSE;
4199 }
4200 oop s = JNIHandles::resolve_non_null(string);
4201 int s_len = java_lang_String::length(s);
4202 typeArrayOop s_value = java_lang_String::value(s);
4203 int s_offset = java_lang_String::offset(s);
4204 const jchar* ret;
4205 if (s_len > 0) {
4206 ret = s_value->char_at_addr(s_offset);
4207 } else {
4208 ret = (jchar*) s_value->base(T_CHAR);
4209 }
4210 #ifndef USDT2
4211 DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
4212 #else /* USDT2 */
4213 HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
4214 #endif /* USDT2 */
4215 return ret;
4216 JNI_END
4217
4218
4219 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
4220 JNIWrapper("ReleaseStringCritical");
4221 #ifndef USDT2
4222 DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
4223 #else /* USDT2 */
4224 HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
4225 #endif /* USDT2 */
4226 // The str and chars arguments are ignored
4227 GC_locker::unlock_critical(thread);
4228 #ifndef USDT2
4229 DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
4230 #else /* USDT2 */
4231 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
4232 #endif /* USDT2 */
4233 JNI_END
4234
4235
4236 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
4237 JNIWrapper("jni_NewWeakGlobalRef");
4238 #ifndef USDT2
4239 DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
4240 #else /* USDT2 */
4241 HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
4242 #endif /* USDT2 */
4243 Handle ref_handle(thread, JNIHandles::resolve(ref));
4244 jweak ret = JNIHandles::make_weak_global(ref_handle);
4245 #ifndef USDT2
4246 DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);
4247 #else /* USDT2 */
4248 HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
4249 #endif /* USDT2 */
4250 return ret;
4251 JNI_END
4252
4253 // Must be JNI_ENTRY (with HandleMark)
4254 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
4255 JNIWrapper("jni_DeleteWeakGlobalRef");
4256 #ifndef USDT2
4257 DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);
4258 #else /* USDT2 */
4259 HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
4260 #endif /* USDT2 */
4261 JNIHandles::destroy_weak_global(ref);
4262 #ifndef USDT2
4263 DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);
4264 #else /* USDT2 */
4265 HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
4266 #endif /* USDT2 */
4267 JNI_END
4268
4269
4270 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
4271 JNIWrapper("jni_ExceptionCheck");
4272 #ifndef USDT2
4273 DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);
4274 #else /* USDT2 */
4275 HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
4276 #endif /* USDT2 */
4277 jni_check_async_exceptions(thread);
4278 jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
4279 #ifndef USDT2
4280 DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);
4281 #else /* USDT2 */
4282 HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(ret);
4283 #endif /* USDT2 */
4284 return ret;
4285 JNI_END
4286
4287
4288 // Initialization state for three routines below relating to
4289 // java.nio.DirectBuffers
4290 static jint directBufferSupportInitializeStarted = 0;
4291 static volatile jint directBufferSupportInitializeEnded = 0;
4292 static volatile jint directBufferSupportInitializeFailed = 0;
4293 static jclass bufferClass = NULL;
4294 static jclass directBufferClass = NULL;
4295 static jclass directByteBufferClass = NULL;
4296 static jmethodID directByteBufferConstructor = NULL;
4297 static jfieldID directBufferAddressField = NULL;
4298 static jfieldID bufferCapacityField = NULL;
4299
4300 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
4301 Handle loader; // null (bootstrap) loader
4302 Handle protection_domain; // null protection domain
4358 // is not necessary. The following call to change the VM state is purposely
4359 // put inside the loop to avoid potential deadlock when multiple threads
4360 // try to call this method. See 6791815 for more details.
4361 ThreadInVMfromNative tivn(thread);
4362 os::yield_all();
4363 }
4364 }
4365
4366 return !directBufferSupportInitializeFailed;
4367 }
4368
4369 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
4370 {
4371 // thread_from_jni_environment() will block if VM is gone.
4372 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4373
4374 JNIWrapper("jni_NewDirectByteBuffer");
4375 #ifndef USDT2
4376 DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);
4377 #else /* USDT2 */
4378 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(env, address, capacity);
4379 #endif /* USDT2 */
4380
4381 if (!directBufferSupportInitializeEnded) {
4382 if (!initializeDirectBufferSupport(env, thread)) {
4383 #ifndef USDT2
4384 DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL);
4385 #else /* USDT2 */
4386 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(NULL);
4387 #endif /* USDT2 */
4388 return NULL;
4389 }
4390 }
4391
4392 // Being paranoid about accidental sign extension on address
4393 jlong addr = (jlong) ((uintptr_t) address);
4394 // NOTE that package-private DirectByteBuffer constructor currently
4395 // takes int capacity
4396 jint cap = (jint) capacity;
4397 jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
4398 #ifndef USDT2
4399 DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);
4400 #else /* USDT2 */
4401 HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(ret);
4402 #endif /* USDT2 */
4403 return ret;
4404 }
4405
4406 #ifndef USDT2
4407 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
4408 #else /* USDT2 */
4409 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
4410 , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
4411 #endif /* USDT2 */
4412
4413 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
4414 {
4415 // thread_from_jni_environment() will block if VM is gone.
4416 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4417
4418 JNIWrapper("jni_GetDirectBufferAddress");
4419 #ifndef USDT2
4420 DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);
4421 #else /* USDT2 */
4422 HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(env, buf);
4423 #endif /* USDT2 */
4424 void* ret = NULL;
4425 DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
4426
4427 if (!directBufferSupportInitializeEnded) {
4428 if (!initializeDirectBufferSupport(env, thread)) {
4429 return 0;
4430 }
4431 }
4432
4433 if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
4434 return 0;
4435 }
4436
4437 ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
4438 return ret;
4439 }
4440
4441 #ifndef USDT2
4442 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
4443 #else /* USDT2 */
4444 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
4445 , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
4446 #endif /* USDT2 */
4447
4448 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
4449 {
4450 // thread_from_jni_environment() will block if VM is gone.
4451 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4452
4453 JNIWrapper("jni_GetDirectBufferCapacity");
4454 #ifndef USDT2
4455 DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);
4456 #else /* USDT2 */
4457 HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(env, buf);
4458 #endif /* USDT2 */
4459 jlong ret = -1;
4460 DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
4461
4462 if (!directBufferSupportInitializeEnded) {
4463 if (!initializeDirectBufferSupport(env, thread)) {
4464 ret = 0;
4465 return ret;
4466 }
4467 }
4468
4469 if (buf == NULL) {
4470 return -1;
4471 }
4472
4473 if (!env->IsInstanceOf(buf, directBufferClass)) {
4474 return -1;
4475 }
4476
4477 // NOTE that capacity is currently an int in the implementation
4478 ret = env->GetIntField(buf, bufferCapacityField);
4479 return ret;
4480 }
4481
4482
4483 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
4484 JNIWrapper("GetVersion");
4485 #ifndef USDT2
4486 DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);
4487 #else /* USDT2 */
4488 HOTSPOT_JNI_GETVERSION_ENTRY(env);
4489 #endif /* USDT2 */
4490 #ifndef USDT2
4491 DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);
4492 #else /* USDT2 */
4493 HOTSPOT_JNI_GETVERSION_RETURN(CurrentVersion);
4494 #endif /* USDT2 */
4495 return CurrentVersion;
4496 JNI_END
4497
4498 extern struct JavaVM_ main_vm;
4499
4500 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
4501 JNIWrapper("jni_GetJavaVM");
4502 #ifndef USDT2
4503 DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);
4504 #else /* USDT2 */
4505 HOTSPOT_JNI_GETJAVAVM_ENTRY(env, (void **) vm);
4506 #endif /* USDT2 */
4507 *vm = (JavaVM *)(&main_vm);
4508 #ifndef USDT2
4509 DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);
4510 #else /* USDT2 */
4511 HOTSPOT_JNI_GETJAVAVM_RETURN(JNI_OK);
4512 #endif /* USDT2 */
4513 return JNI_OK;
4514 JNI_END
4515
4516 // Structure containing all jni functions
4517 struct JNINativeInterface_ jni_NativeInterface = {
4518 NULL,
4519 NULL,
4520 NULL,
4521
4522 NULL,
4523
4524 jni_GetVersion,
4525
4526 jni_DefineClass,
4527 jni_FindClass,
4528
4529 jni_FromReflectedMethod,
4530 jni_FromReflectedField,
4531
4882 // Indicate whether it is safe to recreate VM
4883 volatile jint safe_to_recreate_vm = 1;
4884 struct JavaVM_ main_vm = {&jni_InvokeInterface};
4885
4886
4887 #define JAVASTACKSIZE (400 * 1024) /* Default size of a thread java stack */
4888 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
4889
4890 #ifndef USDT2
4891 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);
4892 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);
4893 #else /* USDT2 */
4894 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
4895 , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
4896 #endif /* USDT2 */
4897
4898 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
4899 #ifndef USDT2
4900 HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_);
4901 #else /* USDT2 */
4902 HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(args_);
4903 #endif /* USDT2 */
4904 JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
4905 jint ret = JNI_ERR;
4906 DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
4907
4908 if (Threads::is_supported_jni_version(args->version)) {
4909 ret = JNI_OK;
4910 }
4911 // 1.1 style no longer supported in hotspot.
4912 // According the JNI spec, we should update args->version on return.
4913 // We also use the structure to communicate with launcher about default
4914 // stack size.
4915 if (args->version == JNI_VERSION_1_1) {
4916 args->version = JNI_VERSION_1_2;
4917 // javaStackSize is int in arguments structure
4918 assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");
4919 args->javaStackSize = (jint)(ThreadStackSize * K);
4920 }
4921 return ret;
4922 }
4975 tty->print_cr("All internal VM tests passed");
4976 }
4977 }
4978
4979 #undef run_unit_test
4980
4981 #endif
4982
4983 #ifndef USDT2
4984 HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
4985 DT_RETURN_MARK_DECL(CreateJavaVM, jint);
4986 #else /* USDT2 */
4987 DT_RETURN_MARK_DECL(CreateJavaVM, jint
4988 , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
4989 #endif /* USDT2 */
4990
4991 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
4992 #ifndef USDT2
4993 HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
4994 #else /* USDT2 */
4995 HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
4996 #endif /* USDT2 */
4997
4998 jint result = JNI_ERR;
4999 DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
5000
5001 // We're about to use Atomic::xchg for synchronization. Some Zero
5002 // platforms use the GCC builtin __sync_lock_test_and_set for this,
5003 // but __sync_lock_test_and_set is not guaranteed to do what we want
5004 // on all architectures. So we check it works before relying on it.
5005 #if defined(ZERO) && defined(ASSERT)
5006 {
5007 jint a = 0xcafebabe;
5008 jint b = Atomic::xchg(0xdeadbeef, &a);
5009 void *c = &a;
5010 void *d = Atomic::xchg_ptr(&b, &c);
5011 assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
5012 assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
5013 }
5014 #endif // ZERO && ASSERT
5015
5097 // control both compiler and architectural-based reordering.
5098 OrderAccess::release_store(&vm_created, 0);
5099 }
5100
5101 return result;
5102 }
5103
5104 #ifndef USDT2
5105 HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \
5106 JavaVM**, jsize, jsize*);
5107 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint);
5108 #endif /* !USDT2 */
5109
5110 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
5111 // See bug 4367188, the wrapper can sometimes cause VM crashes
5112 // JNIWrapper("GetCreatedJavaVMs");
5113 #ifndef USDT2
5114 HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \
5115 vm_buf, bufLen, numVMs);
5116 #else /* USDT2 */
5117 HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
5118 #endif /* USDT2 */
5119 if (vm_created) {
5120 if (numVMs != NULL) *numVMs = 1;
5121 if (bufLen > 0) *vm_buf = (JavaVM *)(&main_vm);
5122 } else {
5123 if (numVMs != NULL) *numVMs = 0;
5124 }
5125 #ifndef USDT2
5126 HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK);
5127 #else /* USDT2 */
5128 HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);
5129 #endif /* USDT2 */
5130 return JNI_OK;
5131 }
5132
5133 extern "C" {
5134
5135 #ifndef USDT2
5136 DT_RETURN_MARK_DECL(DestroyJavaVM, jint);
5137 #else /* USDT2 */
5138 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
5139 , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
5140 #endif /* USDT2 */
5141
5142 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
5143 #ifndef USDT2
5144 DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm);
5145 #else /* USDT2 */
5146 HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(vm);
5147 #endif /* USDT2 */
5148 jint res = JNI_ERR;
5149 DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
5150
5151 if (!vm_created) {
5152 res = JNI_ERR;
5153 return res;
5154 }
5155
5156 JNIWrapper("DestroyJavaVM");
5157 JNIEnv *env;
5158 JavaVMAttachArgs destroyargs;
5159 destroyargs.version = CurrentVersion;
5160 destroyargs.name = (char *)"DestroyJavaVM";
5161 destroyargs.group = NULL;
5162 res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
5163 if (res != JNI_OK) {
5164 return res;
5165 }
5166
5282 *(JNIEnv**)penv = thread->jni_environment();
5283
5284 // Now leaving the VM, so change thread_state. This is normally automatically taken care
5285 // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
5286 // using ThreadStateTransition::transition, we do a callback to the safepoint code if
5287 // needed.
5288
5289 ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
5290
5291 // Perform any platform dependent FPU setup
5292 os::setup_fpu();
5293
5294 return JNI_OK;
5295 }
5296
5297
5298 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
5299 #ifndef USDT2
5300 DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args);
5301 #else /* USDT2 */
5302 HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
5303 #endif /* USDT2 */
5304 if (!vm_created) {
5305 #ifndef USDT2
5306 DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR);
5307 #else /* USDT2 */
5308 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
5309 #endif /* USDT2 */
5310 return JNI_ERR;
5311 }
5312
5313 JNIWrapper("AttachCurrentThread");
5314 jint ret = attach_current_thread(vm, penv, _args, false);
5315 #ifndef USDT2
5316 DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret);
5317 #else /* USDT2 */
5318 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(ret);
5319 #endif /* USDT2 */
5320 return ret;
5321 }
5322
5323
5324 jint JNICALL jni_DetachCurrentThread(JavaVM *vm) {
5325 #ifndef USDT2
5326 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm);
5327 #else /* USDT2 */
5328 HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(vm);
5329 #endif /* USDT2 */
5330 VM_Exit::block_if_vm_exited();
5331
5332 JNIWrapper("DetachCurrentThread");
5333
5334 // If the thread has been deattacted the operations is a no-op
5335 if (ThreadLocalStorage::thread() == NULL) {
5336 #ifndef USDT2
5337 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
5338 #else /* USDT2 */
5339 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
5340 #endif /* USDT2 */
5341 return JNI_OK;
5342 }
5343
5344 JavaThread* thread = JavaThread::current();
5345 if (thread->has_last_Java_frame()) {
5346 #ifndef USDT2
5347 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR);
5348 #else /* USDT2 */
5349 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
5350 #endif /* USDT2 */
5351 // Can't detach a thread that's running java, that can't work.
5352 return JNI_ERR;
5353 }
5354
5355 // Safepoint support. Have to do call-back to safepoint code, if in the
5356 // middel of a safepoint operation
5357 ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
5358
5359 // XXX: Note that JavaThread::exit() call below removes the guards on the
5360 // stack pages set up via enable_stack_{red,yellow}_zone() calls
5361 // above in jni_AttachCurrentThread. Unfortunately, while the setting
5362 // of the guards is visible in jni_AttachCurrentThread above,
5363 // the removal of the guards is buried below in JavaThread::exit()
5364 // here. The abstraction should be more symmetrically either exposed
5365 // or hidden (e.g. it could probably be hidden in the same
5366 // (platform-dependent) methods where we do alternate stack
5367 // maintenance work?)
5368 thread->exit(false, JavaThread::jni_detach);
5369 delete thread;
5370
5371 #ifndef USDT2
5372 DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
5373 #else /* USDT2 */
5374 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
5375 #endif /* USDT2 */
5376 return JNI_OK;
5377 }
5378
5379 #ifndef USDT2
5380 DT_RETURN_MARK_DECL(GetEnv, jint);
5381 #else /* USDT2 */
5382 DT_RETURN_MARK_DECL(GetEnv, jint
5383 , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
5384 #endif /* USDT2 */
5385
5386 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
5387 #ifndef USDT2
5388 DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version);
5389 #else /* USDT2 */
5390 HOTSPOT_JNI_GETENV_ENTRY(vm, penv, version);
5391 #endif /* USDT2 */
5392 jint ret = JNI_ERR;
5393 DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
5394
5395 if (!vm_created) {
5396 *penv = NULL;
5397 ret = JNI_EDETACHED;
5398 return ret;
5399 }
5400
5401 if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
5402 return ret;
5403 }
5404
5405 #ifndef JVMPI_VERSION_1
5406 // need these in order to be polite about older agents
5407 #define JVMPI_VERSION_1 ((jint)0x10000001)
5408 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
5409 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
5410 #endif // !JVMPI_VERSION_1
5428 tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
5429 ret = JNI_EVERSION;
5430 return ret;
5431 } else {
5432 *penv = NULL;
5433 ret = JNI_EVERSION;
5434 return ret;
5435 }
5436 } else {
5437 *penv = NULL;
5438 ret = JNI_EDETACHED;
5439 return ret;
5440 }
5441 }
5442
5443
5444 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
5445 #ifndef USDT2
5446 DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args);
5447 #else /* USDT2 */
5448 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
5449 #endif /* USDT2 */
5450 if (!vm_created) {
5451 #ifndef USDT2
5452 DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR);
5453 #else /* USDT2 */
5454 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
5455 #endif /* USDT2 */
5456 return JNI_ERR;
5457 }
5458
5459 JNIWrapper("AttachCurrentThreadAsDaemon");
5460 jint ret = attach_current_thread(vm, penv, _args, true);
5461 #ifndef USDT2
5462 DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret);
5463 #else /* USDT2 */
5464 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(ret);
5465 #endif /* USDT2 */
5466 return ret;
5467 }
5468
5469
5470 } // End extern "C"
5471
5472 const struct JNIInvokeInterface_ jni_InvokeInterface = {
5473 NULL,
5474 NULL,
5475 NULL,
5476
5477 jni_DestroyJavaVM,
5478 jni_AttachCurrentThread,
5479 jni_DetachCurrentThread,
5480 jni_GetEnv,
5481 jni_AttachCurrentThreadAsDaemon
5482 };
|