< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

   9  * published by the Free Software Foundation.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  *
  25  */
  26 
  27 #include "precompiled.hpp"
  28 #include "jni.h"

  29 #include "jvm.h"
  30 #include "ci/ciReplay.hpp"
  31 #include "classfile/altHashing.hpp"
  32 #include "classfile/classFileStream.hpp"
  33 #include "classfile/classLoader.hpp"
  34 #include "classfile/classLoadInfo.hpp"
  35 #include "classfile/javaClasses.hpp"
  36 #include "classfile/javaClasses.inline.hpp"
  37 #include "classfile/javaThreadStatus.hpp"
  38 #include "classfile/moduleEntry.hpp"
  39 #include "classfile/modules.hpp"
  40 #include "classfile/symbolTable.hpp"
  41 #include "classfile/systemDictionary.hpp"
  42 #include "classfile/vmClasses.hpp"
  43 #include "classfile/vmSymbols.hpp"
  44 #include "compiler/compiler_globals.hpp"
  45 #include "gc/shared/collectedHeap.hpp"
  46 #include "gc/shared/gcLocker.inline.hpp"
  47 #include "gc/shared/stringdedup/stringDedup.hpp"
  48 #include "interpreter/linkResolver.hpp"
  49 #include "jfr/jfrEvents.hpp"
  50 #include "jfr/support/jfrThreadId.hpp"
  51 #include "logging/log.hpp"
  52 #include "memory/allocation.hpp"
  53 #include "memory/allocation.inline.hpp"
  54 #include "memory/oopFactory.hpp"
  55 #include "memory/resourceArea.hpp"
  56 #include "memory/universe.hpp"
  57 #include "oops/access.inline.hpp"
  58 #include "oops/arrayOop.hpp"


  59 #include "oops/instanceKlass.inline.hpp"
  60 #include "oops/instanceOop.hpp"
  61 #include "oops/klass.inline.hpp"
  62 #include "oops/markWord.hpp"
  63 #include "oops/method.hpp"
  64 #include "oops/objArrayKlass.hpp"
  65 #include "oops/objArrayOop.inline.hpp"
  66 #include "oops/oop.inline.hpp"
  67 #include "oops/symbol.hpp"
  68 #include "oops/typeArrayKlass.hpp"
  69 #include "oops/typeArrayOop.inline.hpp"
  70 #include "prims/jniCheck.hpp"
  71 #include "prims/jniExport.hpp"
  72 #include "prims/jniFastGetField.hpp"
  73 #include "prims/jvm_misc.hpp"
  74 #include "prims/jvmtiExport.hpp"
  75 #include "prims/jvmtiThreadState.hpp"
  76 #include "runtime/atomic.hpp"
  77 #include "runtime/fieldDescriptor.inline.hpp"
  78 #include "runtime/handles.inline.hpp"

 405   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 406 
 407   // Make sure class is initialized before handing id's out to fields
 408   k1->initialize(CHECK_NULL);
 409 
 410   // First check if this is a static field
 411   if (modifiers & JVM_ACC_STATIC) {
 412     intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
 413     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 414     assert(id != NULL, "corrupt Field object");
 415     debug_only(id->set_is_static_field_id();)
 416     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 417     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 418     return ret;
 419   }
 420 
 421   // The slot is the index of the field description in the field-array
 422   // The jfieldID is the offset of the field within the object
 423   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 424   intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );

 425   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 426   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 427   return ret;
 428 JNI_END
 429 
 430 
 431 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 432                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 433 
 434 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 435   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 436 
 437   jobject ret = NULL;
 438   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 439 
 440   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 441   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 442   oop reflection_method;
 443   if (m->is_initializer()) {
 444     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 445   } else {
 446     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 447   }
 448   ret = JNIHandles::make_local(THREAD, reflection_method);
 449   return ret;
 450 JNI_END
 451 
 452 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 453                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 454 
 455 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 456   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 457 
 458   jclass obj = NULL;
 459   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 460 
 461   oop mirror = JNIHandles::resolve_non_null(sub);
 462   // primitive classes return NULL
 463   if (java_lang_Class::is_primitive(mirror)) return NULL;

 479          "java_super computation depends on interface, array, other super");
 480   obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(THREAD, super->java_mirror());
 481   return obj;
 482 JNI_END
 483 
 484 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 485   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 486 
 487   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 488   oop super_mirror = JNIHandles::resolve_non_null(super);
 489   if (java_lang_Class::is_primitive(sub_mirror) ||
 490       java_lang_Class::is_primitive(super_mirror)) {
 491     jboolean ret = (sub_mirror == super_mirror);
 492 
 493     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 494     return ret;
 495   }
 496   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 497   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 498   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 499   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
 500                    JNI_TRUE : JNI_FALSE;
 501 









 502   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 503   return ret;
 504 JNI_END
 505 
 506 
 507 DT_RETURN_MARK_DECL(Throw, jint
 508                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 509 
 510 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 511   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 512 
 513   jint ret = JNI_OK;
 514   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 515 
 516   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 517   ShouldNotReachHere();
 518   return 0;  // Mute compiler.
 519 JNI_END
 520 
 521 

 783   }
 784 
 785   friend class SignatureIterator;  // so do_parameters_on can call do_type
 786   void do_type(BasicType type) {
 787     switch (type) {
 788     // these are coerced to int when using va_arg
 789     case T_BYTE:
 790     case T_CHAR:
 791     case T_SHORT:
 792     case T_INT:         push_int(va_arg(_ap, jint)); break;
 793     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 794 
 795     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 796 
 797     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 798     // float is coerced to double w/ va_arg
 799     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 800     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 801 
 802     case T_ARRAY:
 803     case T_OBJECT:      push_object(va_arg(_ap, jobject)); break;

 804     default:            ShouldNotReachHere();
 805     }
 806   }
 807 
 808  public:
 809   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 810       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 811     set_ap(rap);
 812   }
 813 
 814   ~JNI_ArgumentPusherVaArg() {
 815     va_end(_ap);
 816   }
 817 
 818   virtual void push_arguments_on(JavaCallArguments* arguments) {
 819     _arguments = arguments;
 820     do_parameters_on(this);
 821   }
 822 };
 823 
 824 
 825 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
 826  protected:
 827   const jvalue *_ap;
 828 
 829   inline void set_ap(const jvalue *rap) { _ap = rap; }
 830 
 831   friend class SignatureIterator;  // so do_parameters_on can call do_type
 832   void do_type(BasicType type) {
 833     switch (type) {
 834     case T_CHAR:        push_int((_ap++)->c); break;
 835     case T_SHORT:       push_int((_ap++)->s); break;
 836     case T_BYTE:        push_int((_ap++)->b); break;
 837     case T_INT:         push_int((_ap++)->i); break;
 838     case T_BOOLEAN:     push_boolean((_ap++)->z); break;
 839     case T_LONG:        push_long((_ap++)->j); break;
 840     case T_FLOAT:       push_float((_ap++)->f); break;
 841     case T_DOUBLE:      push_double((_ap++)->d); break;
 842     case T_ARRAY:
 843     case T_OBJECT:      push_object((_ap++)->l); break;

 844     default:            ShouldNotReachHere();
 845     }
 846   }
 847 
 848  public:
 849   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
 850       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 851     set_ap(rap);
 852   }
 853 
 854   virtual void push_arguments_on(JavaCallArguments* arguments) {
 855     _arguments = arguments;
 856     do_parameters_on(this);
 857   }
 858 };
 859 
 860 
 861 enum JNICallType {
 862   JNI_STATIC,
 863   JNI_VIRTUAL,

 959 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 960   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 961 
 962   jobject ret = NULL;
 963   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 964 
 965   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 966   ret = JNIHandles::make_local(THREAD, i);
 967   return ret;
 968 JNI_END
 969 
 970 DT_RETURN_MARK_DECL(NewObjectA, jobject
 971                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 972 
 973 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 974   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 975 
 976   jobject obj = NULL;
 977   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 978 
 979   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 980   obj = JNIHandles::make_local(THREAD, i);
 981   JavaValue jvalue(T_VOID);
 982   JNI_ArgumentPusherArray ap(methodID, args);
 983   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);














 984   return obj;
 985 JNI_END
 986 
 987 
 988 DT_RETURN_MARK_DECL(NewObjectV, jobject
 989                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
 990 
 991 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
 992   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
 993 
 994   jobject obj = NULL;
 995   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
 996 
 997   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 998   obj = JNIHandles::make_local(THREAD, i);
 999   JavaValue jvalue(T_VOID);
1000   JNI_ArgumentPusherVaArg ap(methodID, args);
1001   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);














1002   return obj;
1003 JNI_END
1004 
1005 
1006 DT_RETURN_MARK_DECL(NewObject, jobject
1007                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1008 
1009 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1010   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1011 
1012   jobject obj = NULL;
1013   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1014 
1015   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
1016   obj = JNIHandles::make_local(THREAD, i);
1017   va_list args;
1018   va_start(args, methodID);
1019   JavaValue jvalue(T_VOID);
1020   JNI_ArgumentPusherVaArg ap(methodID, args);
1021   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1022   va_end(args);

















1023   return obj;
1024 JNI_END
1025 
1026 
1027 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1028   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1029 
1030   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1031   jclass ret =
1032     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1033 
1034   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1035   return ret;
1036 JNI_END
1037 
1038 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1039   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1040 
1041   jboolean ret = JNI_TRUE;
1042   if (obj != NULL) {

1753   // table.  If they're not there, the field doesn't exist.
1754   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1755   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1756   if (fieldname == NULL || signame == NULL) {
1757     ResourceMark rm;
1758     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1759   }
1760 
1761   // Make sure class is initialized before handing id's out to fields
1762   k->initialize(CHECK_NULL);
1763 
1764   fieldDescriptor fd;
1765   if (!k->is_instance_klass() ||
1766       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1767     ResourceMark rm;
1768     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1769   }
1770 
1771   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1772   // It may also have hash bits for k, if VerifyJNIFields is turned on.
1773   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset());
1774   return ret;
1775 JNI_END
1776 
1777 
1778 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1779   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1780   oop o = JNIHandles::resolve_non_null(obj);
1781   Klass* k = o->klass();
1782   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);

1783   // Keep JVMTI addition small and only check enabled flag here.
1784   // jni_GetField_probe() assumes that is okay to create handles.
1785   if (JvmtiExport::should_post_field_access()) {
1786     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1787   }
1788   oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1789   jobject ret = JNIHandles::make_local(THREAD, loaded_obj);










1790   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1791   return ret;
1792 JNI_END
1793 
1794 
1795 
1796 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1797   , EntryProbe, ReturnProbe) \
1798 \
1799   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1800   , ReturnProbe); \
1801 \
1802 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1803 \
1804   EntryProbe; \
1805   Return ret = 0;\
1806   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1807 \
1808   oop o = JNIHandles::resolve_non_null(obj); \
1809   Klass* k = o->klass(); \

1861   return (address)jni_GetLongField;
1862 }
1863 address jni_GetFloatField_addr() {
1864   return (address)jni_GetFloatField;
1865 }
1866 address jni_GetDoubleField_addr() {
1867   return (address)jni_GetDoubleField;
1868 }
1869 
1870 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1871   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1872   oop o = JNIHandles::resolve_non_null(obj);
1873   Klass* k = o->klass();
1874   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1875   // Keep JVMTI addition small and only check enabled flag here.
1876   if (JvmtiExport::should_post_field_modification()) {
1877     jvalue field_value;
1878     field_value.l = value;
1879     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1880   }
1881   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));











1882   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1883 JNI_END
1884 
1885 
1886 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1887                         , EntryProbe, ReturnProbe) \
1888 \
1889 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1890 \
1891   EntryProbe; \
1892 \
1893   oop o = JNIHandles::resolve_non_null(obj); \
1894   Klass* k = o->klass(); \
1895   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1896   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1897   if (JvmtiExport::should_post_field_modification()) { \
1898     jvalue field_value; \
1899     field_value.unionType = value; \
1900     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
1901   } \

2278   Klass* ak = ek->array_klass(CHECK_NULL);
2279   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2280   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2281   oop initial_value = JNIHandles::resolve(initialElement);
2282   if (initial_value != NULL) {  // array already initialized with NULL
2283     for (int index = 0; index < length; index++) {
2284       result->obj_at_put(index, initial_value);
2285     }
2286   }
2287   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2288   return ret;
2289 JNI_END
2290 
2291 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2292                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2293 
2294 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2295  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2296   jobject ret = NULL;
2297   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2298   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2299   if (a->is_within_bounds(index)) {
2300     ret = JNIHandles::make_local(THREAD, a->obj_at(index));
2301     return ret;









2302   } else {
2303     ResourceMark rm(THREAD);
2304     stringStream ss;
2305     ss.print("Index %d out of bounds for length %d", index, a->length());
2306     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2307   }


2308 JNI_END
2309 
2310 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2311                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2312 
2313 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2314  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2315   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2316 
2317   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2318   oop v = JNIHandles::resolve(value);
2319   if (a->is_within_bounds(index)) {
2320     if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2321       a->obj_at_put(index, v);
2322     } else {
2323       ResourceMark rm(THREAD);
2324       stringStream ss;
2325       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2326       ss.print("type mismatch: can not store %s to %s[%d]",
2327                v->klass()->external_name(),
2328                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2329                index);
2330       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2331         ss.print("[]");
2332       }
2333       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2334     }
2335   } else {
2336     ResourceMark rm(THREAD);
2337     stringStream ss;
2338     ss.print("Index %d out of bounds for length %d", index, a->length());
2339     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2340   }



























2341 JNI_END
2342 
2343 
2344 
2345 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2346                               ,EntryProbe,ReturnProbe)  \
2347 \
2348   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2349                       , ReturnProbe); \
2350 \
2351 JNI_ENTRY(Return, \
2352           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2353   EntryProbe; \
2354   Return ret = NULL;\
2355   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2356 \
2357   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2358   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2359   return ret;\
2360 JNI_END

3116 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
3117   HOTSPOT_JNI_GETVERSION_ENTRY(env);
3118   HOTSPOT_JNI_GETVERSION_RETURN(CurrentVersion);
3119   return CurrentVersion;
3120 JNI_END
3121 
3122 extern struct JavaVM_ main_vm;
3123 
3124 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
3125   HOTSPOT_JNI_GETJAVAVM_ENTRY(env, (void **) vm);
3126   *vm  = (JavaVM *)(&main_vm);
3127   HOTSPOT_JNI_GETJAVAVM_RETURN(JNI_OK);
3128   return JNI_OK;
3129 JNI_END
3130 
3131 
3132 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3133   return Modules::get_module(clazz, THREAD);
3134 JNI_END
3135 
3136 
3137 // Structure containing all jni functions
3138 struct JNINativeInterface_ jni_NativeInterface = {
3139     NULL,
3140     NULL,
3141     NULL,
3142 
3143     NULL,
3144 
3145     jni_GetVersion,
3146 
3147     jni_DefineClass,
3148     jni_FindClass,
3149 
3150     jni_FromReflectedMethod,
3151     jni_FromReflectedField,
3152 
3153     jni_ToReflectedMethod,
3154 
3155     jni_GetSuperclass,
3156     jni_IsAssignableFrom,

3400     jni_ReleasePrimitiveArrayCritical,
3401 
3402     jni_GetStringCritical,
3403     jni_ReleaseStringCritical,
3404 
3405     jni_NewWeakGlobalRef,
3406     jni_DeleteWeakGlobalRef,
3407 
3408     jni_ExceptionCheck,
3409 
3410     jni_NewDirectByteBuffer,
3411     jni_GetDirectBufferAddress,
3412     jni_GetDirectBufferCapacity,
3413 
3414     // New 1_6 features
3415 
3416     jni_GetObjectRefType,
3417 
3418     // Module features
3419 
3420     jni_GetModule

3421 };
3422 
3423 
3424 // For jvmti use to modify jni function table.
3425 // Java threads in native contiues to run until it is transitioned
3426 // to VM at safepoint. Before the transition or before it is blocked
3427 // for safepoint it may access jni function table. VM could crash if
3428 // any java thread access the jni function table in the middle of memcpy.
3429 // To avoid this each function pointers are copied automically.
3430 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3431   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3432   intptr_t *a = (intptr_t *) jni_functions();
3433   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3434   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3435     Atomic::store(a++, *b++);
3436   }
3437 }
3438 
3439 void quicken_jni_functions() {
3440   // Replace Get<Primitive>Field with fast versions

   9  * published by the Free Software Foundation.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  *
  25  */
  26 
  27 #include "precompiled.hpp"
  28 #include "jni.h"
  29 #include "jni.h"
  30 #include "jvm.h"
  31 #include "ci/ciReplay.hpp"
  32 #include "classfile/altHashing.hpp"
  33 #include "classfile/classFileStream.hpp"
  34 #include "classfile/classLoader.hpp"
  35 #include "classfile/classLoadInfo.hpp"
  36 #include "classfile/javaClasses.hpp"
  37 #include "classfile/javaClasses.inline.hpp"
  38 #include "classfile/javaThreadStatus.hpp"
  39 #include "classfile/moduleEntry.hpp"
  40 #include "classfile/modules.hpp"
  41 #include "classfile/symbolTable.hpp"
  42 #include "classfile/systemDictionary.hpp"
  43 #include "classfile/vmClasses.hpp"
  44 #include "classfile/vmSymbols.hpp"
  45 #include "compiler/compiler_globals.hpp"
  46 #include "gc/shared/collectedHeap.hpp"
  47 #include "gc/shared/gcLocker.inline.hpp"
  48 #include "gc/shared/stringdedup/stringDedup.hpp"
  49 #include "interpreter/linkResolver.hpp"
  50 #include "jfr/jfrEvents.hpp"
  51 #include "jfr/support/jfrThreadId.hpp"
  52 #include "logging/log.hpp"
  53 #include "memory/allocation.hpp"
  54 #include "memory/allocation.inline.hpp"
  55 #include "memory/oopFactory.hpp"
  56 #include "memory/resourceArea.hpp"
  57 #include "memory/universe.hpp"
  58 #include "oops/access.inline.hpp"
  59 #include "oops/arrayOop.hpp"
  60 #include "oops/flatArrayOop.inline.hpp"
  61 #include "oops/inlineKlass.inline.hpp"
  62 #include "oops/instanceKlass.inline.hpp"
  63 #include "oops/instanceOop.hpp"
  64 #include "oops/klass.inline.hpp"
  65 #include "oops/markWord.hpp"
  66 #include "oops/method.hpp"
  67 #include "oops/objArrayKlass.hpp"
  68 #include "oops/objArrayOop.inline.hpp"
  69 #include "oops/oop.inline.hpp"
  70 #include "oops/symbol.hpp"
  71 #include "oops/typeArrayKlass.hpp"
  72 #include "oops/typeArrayOop.inline.hpp"
  73 #include "prims/jniCheck.hpp"
  74 #include "prims/jniExport.hpp"
  75 #include "prims/jniFastGetField.hpp"
  76 #include "prims/jvm_misc.hpp"
  77 #include "prims/jvmtiExport.hpp"
  78 #include "prims/jvmtiThreadState.hpp"
  79 #include "runtime/atomic.hpp"
  80 #include "runtime/fieldDescriptor.inline.hpp"
  81 #include "runtime/handles.inline.hpp"

 408   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 409 
 410   // Make sure class is initialized before handing id's out to fields
 411   k1->initialize(CHECK_NULL);
 412 
 413   // First check if this is a static field
 414   if (modifiers & JVM_ACC_STATIC) {
 415     intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
 416     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 417     assert(id != NULL, "corrupt Field object");
 418     debug_only(id->set_is_static_field_id();)
 419     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 420     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 421     return ret;
 422   }
 423 
 424   // The slot is the index of the field description in the field-array
 425   // The jfieldID is the offset of the field within the object
 426   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 427   intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
 428   bool is_inlined = InstanceKlass::cast(k1)->field_is_inlined(slot);
 429   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 430   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_inlined);
 431   return ret;
 432 JNI_END
 433 
 434 
 435 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 436                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 437 
 438 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 439   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 440 
 441   jobject ret = NULL;
 442   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 443 
 444   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 445   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 446   oop reflection_method;
 447   if (m->is_object_constructor() || m->is_static_init_factory()) {
 448     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 449   } else {
 450     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 451   }
 452   ret = JNIHandles::make_local(THREAD, reflection_method);
 453   return ret;
 454 JNI_END
 455 
 456 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 457                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 458 
 459 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 460   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 461 
 462   jclass obj = NULL;
 463   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 464 
 465   oop mirror = JNIHandles::resolve_non_null(sub);
 466   // primitive classes return NULL
 467   if (java_lang_Class::is_primitive(mirror)) return NULL;

 483          "java_super computation depends on interface, array, other super");
 484   obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(THREAD, super->java_mirror());
 485   return obj;
 486 JNI_END
 487 
 488 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 489   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 490 
 491   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 492   oop super_mirror = JNIHandles::resolve_non_null(super);
 493   if (java_lang_Class::is_primitive(sub_mirror) ||
 494       java_lang_Class::is_primitive(super_mirror)) {
 495     jboolean ret = (sub_mirror == super_mirror);
 496 
 497     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 498     return ret;
 499   }
 500   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 501   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 502   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 503   jboolean ret;
 504   if (sub_klass == super_klass && sub_klass->is_inline_klass()) {
 505     // val type is a subtype of ref type
 506     InlineKlass* ik = InlineKlass::cast(sub_klass);
 507     if (sub_mirror == super_mirror || (ik->val_mirror() == sub_mirror && ik->ref_mirror() == super_mirror)) {
 508       ret = JNI_TRUE;
 509     } else {
 510       ret = JNI_FALSE;
 511     }
 512   } else {
 513     ret = sub_klass->is_subtype_of(super_klass) ? JNI_TRUE : JNI_FALSE;
 514   }
 515   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 516   return ret;
 517 JNI_END
 518 
 519 
 520 DT_RETURN_MARK_DECL(Throw, jint
 521                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 522 
 523 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 524   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 525 
 526   jint ret = JNI_OK;
 527   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 528 
 529   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 530   ShouldNotReachHere();
 531   return 0;  // Mute compiler.
 532 JNI_END
 533 
 534 

 796   }
 797 
 798   friend class SignatureIterator;  // so do_parameters_on can call do_type
 799   void do_type(BasicType type) {
 800     switch (type) {
 801     // these are coerced to int when using va_arg
 802     case T_BYTE:
 803     case T_CHAR:
 804     case T_SHORT:
 805     case T_INT:         push_int(va_arg(_ap, jint)); break;
 806     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 807 
 808     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 809 
 810     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 811     // float is coerced to double w/ va_arg
 812     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 813     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 814 
 815     case T_ARRAY:
 816     case T_OBJECT:
 817     case T_PRIMITIVE_OBJECT: push_object(va_arg(_ap, jobject)); break;
 818     default:            ShouldNotReachHere();
 819     }
 820   }
 821 
 822  public:
 823   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 824       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 825     set_ap(rap);
 826   }
 827 
 828   ~JNI_ArgumentPusherVaArg() {
 829     va_end(_ap);
 830   }
 831 
 832   virtual void push_arguments_on(JavaCallArguments* arguments) {
 833     _arguments = arguments;
 834     do_parameters_on(this);
 835   }
 836 };
 837 
 838 
 839 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
 840  protected:
 841   const jvalue *_ap;
 842 
 843   inline void set_ap(const jvalue *rap) { _ap = rap; }
 844 
 845   friend class SignatureIterator;  // so do_parameters_on can call do_type
 846   void do_type(BasicType type) {
 847     switch (type) {
 848     case T_CHAR:        push_int((_ap++)->c); break;
 849     case T_SHORT:       push_int((_ap++)->s); break;
 850     case T_BYTE:        push_int((_ap++)->b); break;
 851     case T_INT:         push_int((_ap++)->i); break;
 852     case T_BOOLEAN:     push_boolean((_ap++)->z); break;
 853     case T_LONG:        push_long((_ap++)->j); break;
 854     case T_FLOAT:       push_float((_ap++)->f); break;
 855     case T_DOUBLE:      push_double((_ap++)->d); break;
 856     case T_ARRAY:
 857     case T_OBJECT:
 858     case T_PRIMITIVE_OBJECT: push_object((_ap++)->l); break;
 859     default:            ShouldNotReachHere();
 860     }
 861   }
 862 
 863  public:
 864   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
 865       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 866     set_ap(rap);
 867   }
 868 
 869   virtual void push_arguments_on(JavaCallArguments* arguments) {
 870     _arguments = arguments;
 871     do_parameters_on(this);
 872   }
 873 };
 874 
 875 
 876 enum JNICallType {
 877   JNI_STATIC,
 878   JNI_VIRTUAL,

 974 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 975   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 976 
 977   jobject ret = NULL;
 978   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 979 
 980   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
 981   ret = JNIHandles::make_local(THREAD, i);
 982   return ret;
 983 JNI_END
 984 
 985 DT_RETURN_MARK_DECL(NewObjectA, jobject
 986                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 987 
 988 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 989   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 990 
 991   jobject obj = NULL;
 992   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 993 
 994   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 995   Klass* k = java_lang_Class::as_Klass(clazzoop);
 996   if (k == NULL) {
 997     ResourceMark rm(THREAD);
 998     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
 999   }
1000 
1001   if (!k->is_inline_klass()) {
1002     instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1003     obj = JNIHandles::make_local(THREAD, i);
1004     JavaValue jvalue(T_VOID);
1005     JNI_ArgumentPusherArray ap(methodID, args);
1006     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1007   } else {
1008     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1009     JNI_ArgumentPusherArray ap(methodID, args);
1010     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1011     obj = jvalue.get_jobject();
1012   }
1013   return obj;
1014   JNI_END
1015 
1016 
1017 DT_RETURN_MARK_DECL(NewObjectV, jobject
1018                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1019 
1020 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1021   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1022 
1023   jobject obj = NULL;
1024   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1025 
1026   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1027   Klass* k = java_lang_Class::as_Klass(clazzoop);
1028   if (k == NULL) {
1029     ResourceMark rm(THREAD);
1030     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1031   }
1032 
1033   if (!k->is_inline_klass()) {
1034     instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1035     obj = JNIHandles::make_local(THREAD, i);
1036     JavaValue jvalue(T_VOID);
1037     JNI_ArgumentPusherVaArg ap(methodID, args);
1038     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1039   } else {
1040     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1041     JNI_ArgumentPusherVaArg ap(methodID, args);
1042     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1043     obj = jvalue.get_jobject();
1044   }
1045   return obj;
1046 JNI_END
1047 
1048 
1049 DT_RETURN_MARK_DECL(NewObject, jobject
1050                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1051 
1052 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1053   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1054 
1055   jobject obj = NULL;
1056   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1057 
1058   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1059   Klass* k = java_lang_Class::as_Klass(clazzoop);
1060   if (k == NULL) {
1061     ResourceMark rm(THREAD);
1062     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1063   }
1064 
1065   if (!k->is_inline_klass()) {
1066     instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1067     obj = JNIHandles::make_local(THREAD, i);
1068     va_list args;
1069     va_start(args, methodID);
1070     JavaValue jvalue(T_VOID);
1071     JNI_ArgumentPusherVaArg ap(methodID, args);
1072     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1073     va_end(args);
1074   } else {
1075     va_list args;
1076     va_start(args, methodID);
1077     JavaValue jvalue(T_PRIMITIVE_OBJECT);
1078     JNI_ArgumentPusherVaArg ap(methodID, args);
1079     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1080     va_end(args);
1081     obj = jvalue.get_jobject();
1082   }
1083   return obj;
1084 JNI_END
1085 
1086 
1087 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1088   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1089 
1090   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1091   jclass ret =
1092     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1093 
1094   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1095   return ret;
1096 JNI_END
1097 
1098 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1099   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1100 
1101   jboolean ret = JNI_TRUE;
1102   if (obj != NULL) {

1813   // table.  If they're not there, the field doesn't exist.
1814   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1815   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1816   if (fieldname == NULL || signame == NULL) {
1817     ResourceMark rm;
1818     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1819   }
1820 
1821   // Make sure class is initialized before handing id's out to fields
1822   k->initialize(CHECK_NULL);
1823 
1824   fieldDescriptor fd;
1825   if (!k->is_instance_klass() ||
1826       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1827     ResourceMark rm;
1828     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1829   }
1830 
1831   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1832   // It may also have hash bits for k, if VerifyJNIFields is turned on.
1833   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_inlined());
1834   return ret;
1835 JNI_END
1836 
1837 
1838 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1839   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1840   oop o = JNIHandles::resolve_non_null(obj);
1841   Klass* k = o->klass();
1842   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1843   oop res = NULL;
1844   // Keep JVMTI addition small and only check enabled flag here.
1845   // jni_GetField_probe() assumes that is okay to create handles.
1846   if (JvmtiExport::should_post_field_access()) {
1847     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1848   }
1849   if (!jfieldIDWorkaround::is_inlined_jfieldID(fieldID)) {
1850     res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1851   } else {
1852     assert(k->is_instance_klass(), "Only instance can have inlined fields");
1853     InstanceKlass* ik = InstanceKlass::cast(k);
1854     fieldDescriptor fd;
1855     ik->find_field_from_offset(offset, false, &fd);  // performance bottleneck
1856     InstanceKlass* holder = fd.field_holder();
1857     InlineKlass* field_vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1858     res = field_vklass->read_inlined_field(o, ik->field_offset(fd.index()), CHECK_NULL);
1859   }
1860   jobject ret = JNIHandles::make_local(THREAD, res);
1861   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1862   return ret;
1863 JNI_END
1864 
1865 
1866 
1867 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1868   , EntryProbe, ReturnProbe) \
1869 \
1870   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1871   , ReturnProbe); \
1872 \
1873 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1874 \
1875   EntryProbe; \
1876   Return ret = 0;\
1877   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1878 \
1879   oop o = JNIHandles::resolve_non_null(obj); \
1880   Klass* k = o->klass(); \

1932   return (address)jni_GetLongField;
1933 }
1934 address jni_GetFloatField_addr() {
1935   return (address)jni_GetFloatField;
1936 }
1937 address jni_GetDoubleField_addr() {
1938   return (address)jni_GetDoubleField;
1939 }
1940 
1941 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1942   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1943   oop o = JNIHandles::resolve_non_null(obj);
1944   Klass* k = o->klass();
1945   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1946   // Keep JVMTI addition small and only check enabled flag here.
1947   if (JvmtiExport::should_post_field_modification()) {
1948     jvalue field_value;
1949     field_value.l = value;
1950     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1951   }
1952   if (!jfieldIDWorkaround::is_inlined_jfieldID(fieldID)) {
1953     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
1954   } else {
1955     assert(k->is_instance_klass(), "Only instances can have inlined fields");
1956     InstanceKlass* ik = InstanceKlass::cast(k);
1957     fieldDescriptor fd;
1958     ik->find_field_from_offset(offset, false, &fd);
1959     InstanceKlass* holder = fd.field_holder();
1960     InlineKlass* vklass = InlineKlass::cast(holder->get_inline_type_field_klass(fd.index()));
1961     oop v = JNIHandles::resolve_non_null(value);
1962     vklass->write_inlined_field(o, offset, v, CHECK);
1963   }
1964   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1965 JNI_END
1966 
1967 
1968 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1969                         , EntryProbe, ReturnProbe) \
1970 \
1971 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1972 \
1973   EntryProbe; \
1974 \
1975   oop o = JNIHandles::resolve_non_null(obj); \
1976   Klass* k = o->klass(); \
1977   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1978   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1979   if (JvmtiExport::should_post_field_modification()) { \
1980     jvalue field_value; \
1981     field_value.unionType = value; \
1982     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
1983   } \

2360   Klass* ak = ek->array_klass(CHECK_NULL);
2361   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2362   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2363   oop initial_value = JNIHandles::resolve(initialElement);
2364   if (initial_value != NULL) {  // array already initialized with NULL
2365     for (int index = 0; index < length; index++) {
2366       result->obj_at_put(index, initial_value);
2367     }
2368   }
2369   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2370   return ret;
2371 JNI_END
2372 
2373 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2374                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2375 
2376 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2377  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2378   jobject ret = NULL;
2379   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2380   oop res = NULL;
2381   arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2382   if (arr->is_within_bounds(index)) {
2383     if (arr->is_flatArray()) {
2384       flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2385       flatArrayHandle vah(thread, a);
2386       res = flatArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
2387       assert(res != NULL, "Must be set in one of two paths above");
2388     } else {
2389       assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2390       objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2391       res = a->obj_at(index);
2392     }
2393   } else {
2394     ResourceMark rm(THREAD);
2395     stringStream ss;
2396     ss.print("Index %d out of bounds for length %d", index,arr->length());
2397     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2398   }
2399   ret = JNIHandles::make_local(THREAD, res);
2400   return ret;
2401 JNI_END
2402 
2403 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2404                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2405 
2406 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2407  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2408   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2409 
2410    bool oob = false;
2411    int length = -1;
2412    oop res = NULL;
2413    arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2414    if (arr->is_within_bounds(index)) {
2415      if (arr->is_flatArray()) {
2416        flatArrayOop a = flatArrayOop(JNIHandles::resolve_non_null(array));
2417        oop v = JNIHandles::resolve(value);
2418        FlatArrayKlass* vaklass = FlatArrayKlass::cast(a->klass());
2419        InlineKlass* element_vklass = vaklass->element_klass();
2420        if (v != NULL && v->is_a(element_vklass)) {
2421          a->value_copy_to_index(v, index);
2422        } else {
2423          ResourceMark rm(THREAD);
2424          stringStream ss;
2425          Klass *kl = FlatArrayKlass::cast(a->klass());
2426          ss.print("type mismatch: can not store %s to %s[%d]",
2427              v->klass()->external_name(),
2428              kl->external_name(),
2429              index);
2430          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2431            ss.print("[]");
2432          }
2433          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2434        }
2435      } else {
2436        assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2437        objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2438        oop v = JNIHandles::resolve(value);
2439        if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2440          a->obj_at_put(index, v);
2441        } else {
2442          ResourceMark rm(THREAD);
2443          stringStream ss;
2444          Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2445          ss.print("type mismatch: can not store %s to %s[%d]",
2446              v->klass()->external_name(),
2447              bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2448                  index);
2449          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2450            ss.print("[]");
2451          }
2452          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2453        }
2454      }
2455    } else {
2456      ResourceMark rm(THREAD);
2457      stringStream ss;
2458      ss.print("Index %d out of bounds for length %d", index, arr->length());
2459      THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2460    }
2461 JNI_END
2462 
2463 
2464 
2465 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2466                               ,EntryProbe,ReturnProbe)  \
2467 \
2468   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2469                       , ReturnProbe); \
2470 \
2471 JNI_ENTRY(Return, \
2472           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2473   EntryProbe; \
2474   Return ret = NULL;\
2475   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2476 \
2477   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2478   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2479   return ret;\
2480 JNI_END

3236 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
3237   HOTSPOT_JNI_GETVERSION_ENTRY(env);
3238   HOTSPOT_JNI_GETVERSION_RETURN(CurrentVersion);
3239   return CurrentVersion;
3240 JNI_END
3241 
3242 extern struct JavaVM_ main_vm;
3243 
3244 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
3245   HOTSPOT_JNI_GETJAVAVM_ENTRY(env, (void **) vm);
3246   *vm  = (JavaVM *)(&main_vm);
3247   HOTSPOT_JNI_GETJAVAVM_RETURN(JNI_OK);
3248   return JNI_OK;
3249 JNI_END
3250 
3251 
3252 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3253   return Modules::get_module(clazz, THREAD);
3254 JNI_END
3255 

3256 // Structure containing all jni functions
3257 struct JNINativeInterface_ jni_NativeInterface = {
3258     NULL,
3259     NULL,
3260     NULL,
3261 
3262     NULL,
3263 
3264     jni_GetVersion,
3265 
3266     jni_DefineClass,
3267     jni_FindClass,
3268 
3269     jni_FromReflectedMethod,
3270     jni_FromReflectedField,
3271 
3272     jni_ToReflectedMethod,
3273 
3274     jni_GetSuperclass,
3275     jni_IsAssignableFrom,

3519     jni_ReleasePrimitiveArrayCritical,
3520 
3521     jni_GetStringCritical,
3522     jni_ReleaseStringCritical,
3523 
3524     jni_NewWeakGlobalRef,
3525     jni_DeleteWeakGlobalRef,
3526 
3527     jni_ExceptionCheck,
3528 
3529     jni_NewDirectByteBuffer,
3530     jni_GetDirectBufferAddress,
3531     jni_GetDirectBufferCapacity,
3532 
3533     // New 1_6 features
3534 
3535     jni_GetObjectRefType,
3536 
3537     // Module features
3538 
3539     jni_GetModule,
3540 
3541 };
3542 
3543 
3544 // For jvmti use to modify jni function table.
3545 // Java threads in native contiues to run until it is transitioned
3546 // to VM at safepoint. Before the transition or before it is blocked
3547 // for safepoint it may access jni function table. VM could crash if
3548 // any java thread access the jni function table in the middle of memcpy.
3549 // To avoid this each function pointers are copied automically.
3550 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3551   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3552   intptr_t *a = (intptr_t *) jni_functions();
3553   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3554   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3555     Atomic::store(a++, *b++);
3556   }
3557 }
3558 
3559 void quicken_jni_functions() {
3560   // Replace Get<Primitive>Field with fast versions
< prev index next >