< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




  41 #include "jfr/jfrEvents.hpp"
  42 #include "jfr/support/jfrThreadId.hpp"
  43 #include "logging/log.hpp"
  44 #include "memory/allocation.hpp"
  45 #include "memory/allocation.inline.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "memory/universe.hpp"
  49 #include "oops/access.inline.hpp"
  50 #include "oops/arrayOop.inline.hpp"
  51 #include "oops/instanceKlass.hpp"
  52 #include "oops/instanceOop.hpp"
  53 #include "oops/markOop.hpp"
  54 #include "oops/method.hpp"
  55 #include "oops/objArrayKlass.hpp"
  56 #include "oops/objArrayOop.inline.hpp"
  57 #include "oops/oop.inline.hpp"
  58 #include "oops/symbol.hpp"
  59 #include "oops/typeArrayKlass.hpp"
  60 #include "oops/typeArrayOop.inline.hpp"

  61 #include "prims/jniCheck.hpp"
  62 #include "prims/jniExport.hpp"
  63 #include "prims/jniFastGetField.hpp"
  64 #include "prims/jvm_misc.hpp"
  65 #include "prims/jvmtiExport.hpp"
  66 #include "prims/jvmtiThreadState.hpp"
  67 #include "runtime/atomic.hpp"
  68 #include "runtime/compilationPolicy.hpp"
  69 #include "runtime/fieldDescriptor.inline.hpp"
  70 #include "runtime/handles.inline.hpp"
  71 #include "runtime/interfaceSupport.inline.hpp"
  72 #include "runtime/java.hpp"
  73 #include "runtime/javaCalls.hpp"
  74 #include "runtime/jfieldIDWorkaround.hpp"
  75 #include "runtime/jniHandles.inline.hpp"
  76 #include "runtime/orderAccess.hpp"
  77 #include "runtime/reflection.hpp"
  78 #include "runtime/safepointVerifiers.hpp"
  79 #include "runtime/sharedRuntime.hpp"
  80 #include "runtime/signature.hpp"


 499   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 500   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 501   return ret;
 502 JNI_END
 503 
 504 
 505 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 506                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 507 
 508 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 509   JNIWrapper("ToReflectedMethod");
 510 
 511   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 512 
 513   jobject ret = NULL;
 514   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 515 
 516   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 517   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 518   oop reflection_method;
 519   if (m->is_initializer()) {
 520     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 521   } else {
 522     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 523   }
 524   ret = JNIHandles::make_local(env, reflection_method);
 525   return ret;
 526 JNI_END
 527 
 528 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 529                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 530 
 531 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 532   JNIWrapper("GetSuperclass");
 533 
 534   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 535 
 536   jclass obj = NULL;
 537   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 538 
 539   oop mirror = JNIHandles::resolve_non_null(sub);


 561 
 562 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 563   JNIWrapper("IsSubclassOf");
 564 
 565   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 566 
 567   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 568   oop super_mirror = JNIHandles::resolve_non_null(super);
 569   if (java_lang_Class::is_primitive(sub_mirror) ||
 570       java_lang_Class::is_primitive(super_mirror)) {
 571     jboolean ret = oopDesc::equals(sub_mirror, super_mirror);
 572 
 573     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 574     return ret;
 575   }
 576   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 577   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 578   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 579   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
 580                    JNI_TRUE : JNI_FALSE;
 581 








 582   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 583   return ret;
 584 JNI_END
 585 
 586 
 587 DT_RETURN_MARK_DECL(Throw, jint
 588                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 589 
 590 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 591   JNIWrapper("Throw");
 592 
 593   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 594 
 595   jint ret = JNI_OK;
 596   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 597 
 598   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 599   ShouldNotReachHere();
 600   return 0;  // Mute compiler.
 601 JNI_END


 853   }
 854 
 855   HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
 856   return ret;
 857 JNI_END
 858 
 859 
 860 class JNI_ArgumentPusher : public SignatureIterator {
 861  protected:
 862   JavaCallArguments*  _arguments;
 863 
 864   virtual void get_bool   () = 0;
 865   virtual void get_char   () = 0;
 866   virtual void get_short  () = 0;
 867   virtual void get_byte   () = 0;
 868   virtual void get_int    () = 0;
 869   virtual void get_long   () = 0;
 870   virtual void get_float  () = 0;
 871   virtual void get_double () = 0;
 872   virtual void get_object () = 0;

 873 
 874   JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
 875     this->_return_type = T_ILLEGAL;
 876     _arguments = NULL;
 877   }
 878 
 879  public:
 880   virtual void iterate( uint64_t fingerprint ) = 0;
 881 
 882   void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
 883 
 884   inline void do_bool()                     { if (!is_return_type()) get_bool();   }
 885   inline void do_char()                     { if (!is_return_type()) get_char();   }
 886   inline void do_short()                    { if (!is_return_type()) get_short();  }
 887   inline void do_byte()                     { if (!is_return_type()) get_byte();   }
 888   inline void do_int()                      { if (!is_return_type()) get_int();    }
 889   inline void do_long()                     { if (!is_return_type()) get_long();   }
 890   inline void do_float()                    { if (!is_return_type()) get_float();  }
 891   inline void do_double()                   { if (!is_return_type()) get_double(); }
 892   inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }

 893   inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
 894   inline void do_void()                     { }
 895 
 896   JavaCallArguments* arguments()     { return _arguments; }
 897   void push_receiver(Handle h)       { _arguments->push_oop(h); }
 898 };
 899 
 900 
 901 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
 902  protected:
 903   va_list _ap;
 904 
 905   inline void get_bool()   {
 906     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
 907     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
 908     // TemplateInterpreterGenerator::generate_result_handler_for and
 909     // SharedRuntime::generate_native_wrapper.
 910     jboolean b = va_arg(_ap, jint);
 911     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
 912   }
 913   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
 914   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
 915   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
 916   inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
 917 
 918   // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 919 
 920   inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
 921   inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
 922   inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
 923   inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }

 924 
 925   inline void set_ap(va_list rap) {
 926     va_copy(_ap, rap);
 927   }
 928 
 929  public:
 930   JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)
 931        : JNI_ArgumentPusher(signature) {
 932     set_ap(rap);
 933   }
 934   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 935       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
 936     set_ap(rap);
 937   }
 938 
 939   // Optimized path if we have the bitvector form of signature
 940   void iterate( uint64_t fingerprint ) {
 941     if (fingerprint == (uint64_t)CONST64(-1)) {
 942       SignatureIterator::iterate(); // Must be too many arguments
 943     } else {


 993  protected:
 994   const jvalue *_ap;
 995 
 996   inline void get_bool()   {
 997     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
 998     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
 999     // TemplateInterpreterGenerator::generate_result_handler_for and
1000     // SharedRuntime::generate_native_wrapper.
1001     jboolean b = (_ap++)->z;
1002     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
1003   }
1004   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
1005   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
1006   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
1007   inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
1008 
1009   inline void get_long()   { _arguments->push_long((_ap++)->j);  }
1010   inline void get_float()  { _arguments->push_float((_ap++)->f); }
1011   inline void get_double() { _arguments->push_double((_ap++)->d);}
1012   inline void get_object() { _arguments->push_jobject((_ap++)->l); }


1013 
1014   inline void set_ap(const jvalue *rap) { _ap = rap; }
1015 
1016  public:
1017   JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)
1018        : JNI_ArgumentPusher(signature) {
1019     set_ap(rap);
1020   }
1021   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
1022       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
1023     set_ap(rap);
1024   }
1025 
1026   // Optimized path if we have the bitvector form of signature
1027   void iterate( uint64_t fingerprint ) {
1028     if (fingerprint == (uint64_t)CONST64(-1)) {
1029       SignatureIterator::iterate(); // Must be too many arguments
1030     } else {
1031       _return_type = (BasicType)((fingerprint >> static_feature_size) &
1032                                   result_feature_mask);


1087   methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));
1088 
1089   // Create object to hold arguments for the JavaCall, and associate it with
1090   // the jni parser
1091   ResourceMark rm(THREAD);
1092   int number_of_parameters = method->size_of_parameters();
1093   JavaCallArguments java_args(number_of_parameters);
1094   args->set_java_argument_object(&java_args);
1095 
1096   assert(method->is_static(), "method should be static");
1097 
1098   // Fill out JavaCallArguments object
1099   args->iterate( Fingerprinter(method).fingerprint() );
1100   // Initialize result type
1101   result->set_type(args->get_ret_type());
1102 
1103   // Invoke the method. Result is returned as oop.
1104   JavaCalls::call(result, method, &java_args, CHECK);
1105 
1106   // Convert result
1107   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
1108     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1109   }
1110 }
1111 
1112 
1113 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1114   oop recv = JNIHandles::resolve(receiver);
1115   if (recv == NULL) {
1116     THROW(vmSymbols::java_lang_NullPointerException());
1117   }
1118   Handle h_recv(THREAD, recv);
1119 
1120   int number_of_parameters;
1121   Method* selected_method;
1122   {
1123     Method* m = Method::resolve_jmethod_id(method_id);
1124     number_of_parameters = m->size_of_parameters();
1125     Klass* holder = m->method_holder();
1126     if (call_type != JNI_VIRTUAL) {
1127         selected_method = m;


1150 
1151   // Create object to hold arguments for the JavaCall, and associate it with
1152   // the jni parser
1153   ResourceMark rm(THREAD);
1154   JavaCallArguments java_args(number_of_parameters);
1155   args->set_java_argument_object(&java_args);
1156 
1157   // handle arguments
1158   assert(!method->is_static(), "method %s should not be static", method->name_and_sig_as_C_string());
1159   args->push_receiver(h_recv); // Push jobject handle
1160 
1161   // Fill out JavaCallArguments object
1162   args->iterate( Fingerprinter(method).fingerprint() );
1163   // Initialize result type
1164   result->set_type(args->get_ret_type());
1165 
1166   // Invoke the method. Result is returned as oop.
1167   JavaCalls::call(result, method, &java_args, CHECK);
1168 
1169   // Convert result
1170   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
1171     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1172   }
1173 }
1174 
1175 
1176 static instanceOop alloc_object(jclass clazz, TRAPS) {
1177   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1178   if (k == NULL) {
1179     ResourceMark rm(THREAD);
1180     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1181   }
1182   k->check_valid_for_instantiation(false, CHECK_NULL);
1183   k->initialize(CHECK_NULL);
1184   instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD);
1185   return ih;
1186 }
1187 
1188 DT_RETURN_MARK_DECL(AllocObject, jobject
1189                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1190 




  41 #include "jfr/jfrEvents.hpp"
  42 #include "jfr/support/jfrThreadId.hpp"
  43 #include "logging/log.hpp"
  44 #include "memory/allocation.hpp"
  45 #include "memory/allocation.inline.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "memory/universe.hpp"
  49 #include "oops/access.inline.hpp"
  50 #include "oops/arrayOop.inline.hpp"
  51 #include "oops/instanceKlass.hpp"
  52 #include "oops/instanceOop.hpp"
  53 #include "oops/markOop.hpp"
  54 #include "oops/method.hpp"
  55 #include "oops/objArrayKlass.hpp"
  56 #include "oops/objArrayOop.inline.hpp"
  57 #include "oops/oop.inline.hpp"
  58 #include "oops/symbol.hpp"
  59 #include "oops/typeArrayKlass.hpp"
  60 #include "oops/typeArrayOop.inline.hpp"
  61 #include "oops/valueKlass.hpp"
  62 #include "prims/jniCheck.hpp"
  63 #include "prims/jniExport.hpp"
  64 #include "prims/jniFastGetField.hpp"
  65 #include "prims/jvm_misc.hpp"
  66 #include "prims/jvmtiExport.hpp"
  67 #include "prims/jvmtiThreadState.hpp"
  68 #include "runtime/atomic.hpp"
  69 #include "runtime/compilationPolicy.hpp"
  70 #include "runtime/fieldDescriptor.inline.hpp"
  71 #include "runtime/handles.inline.hpp"
  72 #include "runtime/interfaceSupport.inline.hpp"
  73 #include "runtime/java.hpp"
  74 #include "runtime/javaCalls.hpp"
  75 #include "runtime/jfieldIDWorkaround.hpp"
  76 #include "runtime/jniHandles.inline.hpp"
  77 #include "runtime/orderAccess.hpp"
  78 #include "runtime/reflection.hpp"
  79 #include "runtime/safepointVerifiers.hpp"
  80 #include "runtime/sharedRuntime.hpp"
  81 #include "runtime/signature.hpp"


 500   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 501   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 502   return ret;
 503 JNI_END
 504 
 505 
 506 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 507                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 508 
 509 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 510   JNIWrapper("ToReflectedMethod");
 511 
 512   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 513 
 514   jobject ret = NULL;
 515   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 516 
 517   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 518   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 519   oop reflection_method;
 520   if (m->is_object_constructor()) {
 521     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 522   } else {
 523     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 524   }
 525   ret = JNIHandles::make_local(env, reflection_method);
 526   return ret;
 527 JNI_END
 528 
 529 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 530                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 531 
 532 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 533   JNIWrapper("GetSuperclass");
 534 
 535   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 536 
 537   jclass obj = NULL;
 538   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 539 
 540   oop mirror = JNIHandles::resolve_non_null(sub);


 562 
 563 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 564   JNIWrapper("IsSubclassOf");
 565 
 566   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 567 
 568   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 569   oop super_mirror = JNIHandles::resolve_non_null(super);
 570   if (java_lang_Class::is_primitive(sub_mirror) ||
 571       java_lang_Class::is_primitive(super_mirror)) {
 572     jboolean ret = oopDesc::equals(sub_mirror, super_mirror);
 573 
 574     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 575     return ret;
 576   }
 577   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 578   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 579   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 580   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
 581                    JNI_TRUE : JNI_FALSE;
 582   if (sub_klass == super_klass && sub_klass->is_value()) {
 583     // for inline class, V <: V?
 584     ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(sub_klass));
 585     if (sub_mirror == super_mirror || (sub_mirror == vk->value_mirror() && super_mirror == vk->indirect_mirror())) {
 586       ret = JNI_TRUE;
 587     } else {
 588       ret = JNI_FALSE;
 589     }
 590   }
 591   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 592   return ret;
 593 JNI_END
 594 
 595 
 596 DT_RETURN_MARK_DECL(Throw, jint
 597                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 598 
 599 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 600   JNIWrapper("Throw");
 601 
 602   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 603 
 604   jint ret = JNI_OK;
 605   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 606 
 607   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 608   ShouldNotReachHere();
 609   return 0;  // Mute compiler.
 610 JNI_END


 862   }
 863 
 864   HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
 865   return ret;
 866 JNI_END
 867 
 868 
 869 class JNI_ArgumentPusher : public SignatureIterator {
 870  protected:
 871   JavaCallArguments*  _arguments;
 872 
 873   virtual void get_bool   () = 0;
 874   virtual void get_char   () = 0;
 875   virtual void get_short  () = 0;
 876   virtual void get_byte   () = 0;
 877   virtual void get_int    () = 0;
 878   virtual void get_long   () = 0;
 879   virtual void get_float  () = 0;
 880   virtual void get_double () = 0;
 881   virtual void get_object () = 0;
 882   virtual void get_valuetype() = 0;
 883 
 884   JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
 885     this->_return_type = T_ILLEGAL;
 886     _arguments = NULL;
 887   }
 888 
 889  public:
 890   virtual void iterate( uint64_t fingerprint ) = 0;
 891 
 892   void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
 893 
 894   inline void do_bool()                     { if (!is_return_type()) get_bool();   }
 895   inline void do_char()                     { if (!is_return_type()) get_char();   }
 896   inline void do_short()                    { if (!is_return_type()) get_short();  }
 897   inline void do_byte()                     { if (!is_return_type()) get_byte();   }
 898   inline void do_int()                      { if (!is_return_type()) get_int();    }
 899   inline void do_long()                     { if (!is_return_type()) get_long();   }
 900   inline void do_float()                    { if (!is_return_type()) get_float();  }
 901   inline void do_double()                   { if (!is_return_type()) get_double(); }
 902   inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }
 903   inline void do_valuetype(int begin, int end) { if (!is_return_type()) get_valuetype();  }
 904   inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
 905   inline void do_void()                     { }
 906 
 907   JavaCallArguments* arguments()     { return _arguments; }
 908   void push_receiver(Handle h)       { _arguments->push_oop(h); }
 909 };
 910 
 911 
 912 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
 913  protected:
 914   va_list _ap;
 915 
 916   inline void get_bool()   {
 917     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
 918     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
 919     // TemplateInterpreterGenerator::generate_result_handler_for and
 920     // SharedRuntime::generate_native_wrapper.
 921     jboolean b = va_arg(_ap, jint);
 922     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
 923   }
 924   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
 925   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
 926   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
 927   inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
 928 
 929   // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 930 
 931   inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
 932   inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
 933   inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
 934   inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }
 935   inline void get_valuetype() { _arguments->push_jobject(va_arg(_ap, jobject)); }
 936 
 937   inline void set_ap(va_list rap) {
 938     va_copy(_ap, rap);
 939   }
 940 
 941  public:
 942   JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)
 943        : JNI_ArgumentPusher(signature) {
 944     set_ap(rap);
 945   }
 946   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 947       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
 948     set_ap(rap);
 949   }
 950 
 951   // Optimized path if we have the bitvector form of signature
 952   void iterate( uint64_t fingerprint ) {
 953     if (fingerprint == (uint64_t)CONST64(-1)) {
 954       SignatureIterator::iterate(); // Must be too many arguments
 955     } else {


1005  protected:
1006   const jvalue *_ap;
1007 
1008   inline void get_bool()   {
1009     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
1010     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
1011     // TemplateInterpreterGenerator::generate_result_handler_for and
1012     // SharedRuntime::generate_native_wrapper.
1013     jboolean b = (_ap++)->z;
1014     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
1015   }
1016   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
1017   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
1018   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
1019   inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
1020 
1021   inline void get_long()   { _arguments->push_long((_ap++)->j);  }
1022   inline void get_float()  { _arguments->push_float((_ap++)->f); }
1023   inline void get_double() { _arguments->push_double((_ap++)->d);}
1024   inline void get_object() { _arguments->push_jobject((_ap++)->l); }
1025   // value types are implemented with oops too
1026   inline void get_valuetype() { _arguments->push_jobject((_ap++)->l); }
1027 
1028   inline void set_ap(const jvalue *rap) { _ap = rap; }
1029 
1030  public:
1031   JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)
1032        : JNI_ArgumentPusher(signature) {
1033     set_ap(rap);
1034   }
1035   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
1036       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
1037     set_ap(rap);
1038   }
1039 
1040   // Optimized path if we have the bitvector form of signature
1041   void iterate( uint64_t fingerprint ) {
1042     if (fingerprint == (uint64_t)CONST64(-1)) {
1043       SignatureIterator::iterate(); // Must be too many arguments
1044     } else {
1045       _return_type = (BasicType)((fingerprint >> static_feature_size) &
1046                                   result_feature_mask);


1101   methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));
1102 
1103   // Create object to hold arguments for the JavaCall, and associate it with
1104   // the jni parser
1105   ResourceMark rm(THREAD);
1106   int number_of_parameters = method->size_of_parameters();
1107   JavaCallArguments java_args(number_of_parameters);
1108   args->set_java_argument_object(&java_args);
1109 
1110   assert(method->is_static(), "method should be static");
1111 
1112   // Fill out JavaCallArguments object
1113   args->iterate( Fingerprinter(method).fingerprint() );
1114   // Initialize result type
1115   result->set_type(args->get_ret_type());
1116 
1117   // Invoke the method. Result is returned as oop.
1118   JavaCalls::call(result, method, &java_args, CHECK);
1119 
1120   // Convert result
1121   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY || result->get_type() == T_VALUETYPE) {
1122     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1123   }
1124 }
1125 
1126 
1127 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1128   oop recv = JNIHandles::resolve(receiver);
1129   if (recv == NULL) {
1130     THROW(vmSymbols::java_lang_NullPointerException());
1131   }
1132   Handle h_recv(THREAD, recv);
1133 
1134   int number_of_parameters;
1135   Method* selected_method;
1136   {
1137     Method* m = Method::resolve_jmethod_id(method_id);
1138     number_of_parameters = m->size_of_parameters();
1139     Klass* holder = m->method_holder();
1140     if (call_type != JNI_VIRTUAL) {
1141         selected_method = m;


1164 
1165   // Create object to hold arguments for the JavaCall, and associate it with
1166   // the jni parser
1167   ResourceMark rm(THREAD);
1168   JavaCallArguments java_args(number_of_parameters);
1169   args->set_java_argument_object(&java_args);
1170 
1171   // handle arguments
1172   assert(!method->is_static(), "method %s should not be static", method->name_and_sig_as_C_string());
1173   args->push_receiver(h_recv); // Push jobject handle
1174 
1175   // Fill out JavaCallArguments object
1176   args->iterate( Fingerprinter(method).fingerprint() );
1177   // Initialize result type
1178   result->set_type(args->get_ret_type());
1179 
1180   // Invoke the method. Result is returned as oop.
1181   JavaCalls::call(result, method, &java_args, CHECK);
1182 
1183   // Convert result
1184   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY || result->get_type() == T_VALUETYPE) {
1185     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1186   }
1187 }
1188 
1189 
1190 static instanceOop alloc_object(jclass clazz, TRAPS) {
1191   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1192   if (k == NULL) {
1193     ResourceMark rm(THREAD);
1194     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1195   }
1196   k->check_valid_for_instantiation(false, CHECK_NULL);
1197   k->initialize(CHECK_NULL);
1198   instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD);
1199   return ih;
1200 }
1201 
1202 DT_RETURN_MARK_DECL(AllocObject, jobject
1203                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1204 


< prev index next >