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

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









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

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

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

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

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














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














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

















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

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

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










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

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











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

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









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


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



























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

   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/arguments.hpp"
  80 #include "runtime/atomic.hpp"
  81 #include "runtime/fieldDescriptor.inline.hpp"

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

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

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

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

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

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

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