< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

  34 #include "classfile/moduleEntry.hpp"
  35 #include "classfile/modules.hpp"
  36 #include "classfile/symbolTable.hpp"
  37 #include "classfile/systemDictionary.hpp"
  38 #include "classfile/vmClasses.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "compiler/compiler_globals.hpp"
  41 #include "gc/shared/collectedHeap.hpp"
  42 #include "gc/shared/stringdedup/stringDedup.hpp"
  43 #include "interpreter/linkResolver.hpp"
  44 #include "jni.h"
  45 #include "jvm.h"
  46 #include "logging/log.hpp"
  47 #include "memory/allocation.inline.hpp"
  48 #include "memory/oopFactory.hpp"
  49 #include "memory/resourceArea.hpp"
  50 #include "memory/universe.hpp"
  51 #include "nmt/memTracker.hpp"
  52 #include "oops/access.inline.hpp"
  53 #include "oops/arrayOop.hpp"


  54 #include "oops/instanceKlass.inline.hpp"
  55 #include "oops/instanceOop.hpp"
  56 #include "oops/klass.inline.hpp"
  57 #include "oops/markWord.hpp"
  58 #include "oops/method.hpp"
  59 #include "oops/objArrayKlass.hpp"
  60 #include "oops/objArrayOop.inline.hpp"
  61 #include "oops/oop.inline.hpp"
  62 #include "oops/symbol.hpp"
  63 #include "oops/typeArrayKlass.hpp"
  64 #include "oops/typeArrayOop.inline.hpp"
  65 #include "prims/jniCheck.hpp"
  66 #include "prims/jniExport.hpp"
  67 #include "prims/jniFastGetField.hpp"
  68 #include "prims/jvm_misc.hpp"
  69 #include "prims/jvmtiExport.hpp"
  70 #include "prims/jvmtiThreadState.hpp"
  71 #include "runtime/arguments.hpp"
  72 #include "runtime/atomicAccess.hpp"
  73 #include "runtime/fieldDescriptor.inline.hpp"

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

 421   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 422   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 423   return ret;
 424 JNI_END
 425 
 426 
 427 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 428                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 429 
 430 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 431   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 432 
 433   jobject ret = nullptr;
 434   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 435 
 436   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 437   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 438   oop reflection_method;
 439   if (m->is_object_initializer()) {
 440     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 441   } else {
 442     // Note: Static initializers can theoretically be here, if JNI users manage
 443     // to get their jmethodID. Record them as plain methods.
 444     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 445   }
 446   ret = JNIHandles::make_local(THREAD, reflection_method);
 447   return ret;
 448 JNI_END
 449 
 450 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 451                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 452 
 453 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 454   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 455 
 456   jclass obj = nullptr;
 457   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 458 
 459   oop mirror = JNIHandles::resolve_non_null(sub);

 778   }
 779 
 780   friend class SignatureIterator;  // so do_parameters_on can call do_type
 781   void do_type(BasicType type) {
 782     switch (type) {
 783     // these are coerced to int when using va_arg
 784     case T_BYTE:
 785     case T_CHAR:
 786     case T_SHORT:
 787     case T_INT:         push_int(va_arg(_ap, jint)); break;
 788     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 789 
 790     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 791 
 792     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 793     // float is coerced to double w/ va_arg
 794     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 795     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 796 
 797     case T_ARRAY:
 798     case T_OBJECT:      push_object(va_arg(_ap, jobject)); break;
 799     default:            ShouldNotReachHere();
 800     }
 801   }
 802 
 803  public:
 804   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 805       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 806     set_ap(rap);
 807   }
 808 
 809   ~JNI_ArgumentPusherVaArg() {
 810     va_end(_ap);
 811   }
 812 
 813   virtual void push_arguments_on(JavaCallArguments* arguments) {
 814     _arguments = arguments;
 815     do_parameters_on(this);
 816   }
 817 };
 818 

 945   result->set_type(args->return_type());
 946 
 947   // Invoke the method. Result is returned as oop.
 948   JavaCalls::call(result, method, &java_args, CHECK);
 949 
 950   // Convert result
 951   if (is_reference_type(result->get_type())) {
 952     result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
 953   }
 954 }
 955 
 956 DT_RETURN_MARK_DECL(AllocObject, jobject
 957                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 958 
 959 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 960   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 961 
 962   jobject ret = nullptr;
 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 = nullptr;
 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 = nullptr;
 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 = nullptr;
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 != nullptr) {

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 == nullptr || signame == nullptr) {
1757     ResourceMark rm;
1758     THROW_MSG_NULL(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_NULL(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(); \
1810   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1811   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1812   if (JvmtiExport::should_post_field_access()) { \
1813     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); \
1814   } \
1815   ret = o->Fieldname##_field(offset); \

1887     assert(found, "bad field offset");
1888     assert(!fd.is_static(), "static/instance mismatch");
1889     if (fd.is_final()) {
1890       ResourceMark rm(current);
1891       log_debug(jni)("%s mutated final instance field %s.%s", func_name, ik->external_name(), fd.name()->as_C_string());
1892     }
1893   }
1894 }
1895 
1896 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1897   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1898   oop o = JNIHandles::resolve_non_null(obj);
1899   Klass* k = o->klass();
1900   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1901   // Keep JVMTI addition small and only check enabled flag here.
1902   if (JvmtiExport::should_post_field_modification()) {
1903     jvalue field_value;
1904     field_value.l = value;
1905     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1906   }
1907   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));





















1908   log_debug_if_final_instance_field(thread, "SetObjectField", InstanceKlass::cast(k), offset);
1909   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1910 JNI_END
1911 
1912 // TODO: make this a template
1913 
1914 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1915                         , EntryProbe, ReturnProbe) \
1916 \
1917 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1918 \
1919   EntryProbe; \
1920 \
1921   oop o = JNIHandles::resolve_non_null(obj); \
1922   Klass* k = o->klass(); \
1923   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1924   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1925   if (JvmtiExport::should_post_field_modification()) { \
1926     jvalue field_value; \
1927     field_value.unionType = value; \

2320 
2321   oop initial_value = JNIHandles::resolve(initialElement);
2322   if (initial_value != nullptr) {  // array already initialized with null
2323     for (int index = 0; index < length; index++) {
2324       result->obj_at_put(index, initial_value);
2325     }
2326   }
2327   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2328   return ret;
2329 JNI_END
2330 
2331 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2332                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2333 
2334 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2335  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2336   jobject ret = nullptr;
2337   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2338   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2339   if (a->is_within_bounds(index)) {
2340     ret = JNIHandles::make_local(THREAD, a->obj_at(index));


2341     return ret;
2342   } else {
2343     ResourceMark rm(THREAD);
2344     stringStream ss;
2345     ss.print("Index %d out of bounds for length %d", index, a->length());
2346     THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2347   }
2348 JNI_END
2349 
2350 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2351                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2352 
2353 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2354  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2355   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2356 
2357   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2358   oop v = JNIHandles::resolve(value);
2359   if (a->is_within_bounds(index)) {
2360     if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2361       a->obj_at_put(index, v);

2362     } else {
2363       ResourceMark rm(THREAD);
2364       stringStream ss;
2365       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2366       ss.print("type mismatch: can not store %s to %s[%d]",
2367                v->klass()->external_name(),
2368                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2369                index);
2370       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2371         ss.print("[]");
2372       }
2373       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2374     }
2375   } else {
2376     ResourceMark rm(THREAD);
2377     stringStream ss;
2378     ss.print("Index %d out of bounds for length %d", index, a->length());
2379     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2380   }
2381 JNI_END
2382 
2383 
2384 
2385 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2386                               ,EntryProbe,ReturnProbe)  \
2387 \
2388   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2389                       , ReturnProbe); \
2390 \
2391 JNI_ENTRY(Return, \
2392           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2393   EntryProbe; \
2394   Return ret = nullptr;\
2395   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2396 \
2397   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2398   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2399   return ret;\
2400 JNI_END

2736 JNI_END
2737 
2738 //
2739 // Monitor functions
2740 //
2741 
2742 DT_RETURN_MARK_DECL(MonitorEnter, jint
2743                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2744 
2745 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2746  HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2747   jint ret = JNI_ERR;
2748   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2749 
2750   // If the object is null, we can't do anything with it
2751   if (jobj == nullptr) {
2752     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2753   }
2754 
2755   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2756   ObjectSynchronizer::jni_enter(obj, thread);
2757   return JNI_OK;
2758 JNI_END
2759 
2760 DT_RETURN_MARK_DECL(MonitorExit, jint
2761                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2762 
2763 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2764  HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2765   jint ret = JNI_ERR;
2766   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2767 
2768   // Don't do anything with a null object
2769   if (jobj == nullptr) {
2770     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2771   }
2772 
2773   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2774   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2775   return JNI_OK;
2776 JNI_END

  34 #include "classfile/moduleEntry.hpp"
  35 #include "classfile/modules.hpp"
  36 #include "classfile/symbolTable.hpp"
  37 #include "classfile/systemDictionary.hpp"
  38 #include "classfile/vmClasses.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "compiler/compiler_globals.hpp"
  41 #include "gc/shared/collectedHeap.hpp"
  42 #include "gc/shared/stringdedup/stringDedup.hpp"
  43 #include "interpreter/linkResolver.hpp"
  44 #include "jni.h"
  45 #include "jvm.h"
  46 #include "logging/log.hpp"
  47 #include "memory/allocation.inline.hpp"
  48 #include "memory/oopFactory.hpp"
  49 #include "memory/resourceArea.hpp"
  50 #include "memory/universe.hpp"
  51 #include "nmt/memTracker.hpp"
  52 #include "oops/access.inline.hpp"
  53 #include "oops/arrayOop.hpp"
  54 #include "oops/flatArrayOop.inline.hpp"
  55 #include "oops/inlineKlass.inline.hpp"
  56 #include "oops/instanceKlass.inline.hpp"
  57 #include "oops/instanceOop.hpp"
  58 #include "oops/klass.inline.hpp"
  59 #include "oops/markWord.hpp"
  60 #include "oops/method.hpp"
  61 #include "oops/objArrayKlass.hpp"
  62 #include "oops/objArrayOop.inline.hpp"
  63 #include "oops/oop.inline.hpp"
  64 #include "oops/symbol.hpp"
  65 #include "oops/typeArrayKlass.hpp"
  66 #include "oops/typeArrayOop.inline.hpp"
  67 #include "prims/jniCheck.hpp"
  68 #include "prims/jniExport.hpp"
  69 #include "prims/jniFastGetField.hpp"
  70 #include "prims/jvm_misc.hpp"
  71 #include "prims/jvmtiExport.hpp"
  72 #include "prims/jvmtiThreadState.hpp"
  73 #include "runtime/arguments.hpp"
  74 #include "runtime/atomicAccess.hpp"
  75 #include "runtime/fieldDescriptor.inline.hpp"

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

 781   }
 782 
 783   friend class SignatureIterator;  // so do_parameters_on can call do_type
 784   void do_type(BasicType type) {
 785     switch (type) {
 786     // these are coerced to int when using va_arg
 787     case T_BYTE:
 788     case T_CHAR:
 789     case T_SHORT:
 790     case T_INT:         push_int(va_arg(_ap, jint)); break;
 791     case T_BOOLEAN:     push_boolean((jboolean) va_arg(_ap, jint)); break;
 792 
 793     // each of these paths is exercised by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 794 
 795     case T_LONG:        push_long(va_arg(_ap, jlong)); break;
 796     // float is coerced to double w/ va_arg
 797     case T_FLOAT:       push_float((jfloat) va_arg(_ap, jdouble)); break;
 798     case T_DOUBLE:      push_double(va_arg(_ap, jdouble)); break;
 799 
 800     case T_ARRAY:
 801     case T_OBJECT: push_object(va_arg(_ap, jobject)); break;
 802     default:            ShouldNotReachHere();
 803     }
 804   }
 805 
 806  public:
 807   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 808       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)) {
 809     set_ap(rap);
 810   }
 811 
 812   ~JNI_ArgumentPusherVaArg() {
 813     va_end(_ap);
 814   }
 815 
 816   virtual void push_arguments_on(JavaCallArguments* arguments) {
 817     _arguments = arguments;
 818     do_parameters_on(this);
 819   }
 820 };
 821 

 948   result->set_type(args->return_type());
 949 
 950   // Invoke the method. Result is returned as oop.
 951   JavaCalls::call(result, method, &java_args, CHECK);
 952 
 953   // Convert result
 954   if (is_reference_type(result->get_type())) {
 955     result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
 956   }
 957 }
 958 
 959 DT_RETURN_MARK_DECL(AllocObject, jobject
 960                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 961 
 962 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 963   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 964 
 965   jobject ret = nullptr;
 966   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 967 
 968   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 969   Klass* k = java_lang_Class::as_Klass(clazzoop);
 970   if (k == nullptr || k->is_inline_klass()) {
 971     ResourceMark rm(THREAD);
 972     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
 973   }
 974   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
 975   ret = JNIHandles::make_local(THREAD, i);
 976   return ret;
 977 JNI_END
 978 
 979 DT_RETURN_MARK_DECL(NewObjectA, jobject
 980                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 981 
 982 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 983   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 984 
 985   jobject obj = nullptr;
 986   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 987 
 988   oop clazzoop = JNIHandles::resolve_non_null(clazz);
 989   Klass* k = java_lang_Class::as_Klass(clazzoop);
 990   if (k == nullptr) {
 991     ResourceMark rm(THREAD);
 992     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
 993   }
 994 
 995   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
 996   obj = JNIHandles::make_local(THREAD, i);
 997   JavaValue jvalue(T_VOID);
 998   JNI_ArgumentPusherArray ap(methodID, args);
 999   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1000 
1001   return obj;
1002   JNI_END
1003 
1004 
1005 DT_RETURN_MARK_DECL(NewObjectV, jobject
1006                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1007 
1008 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1009   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1010 
1011   jobject obj = nullptr;
1012   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1013 
1014   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1015   Klass* k = java_lang_Class::as_Klass(clazzoop);
1016   if (k == nullptr) {
1017     ResourceMark rm(THREAD);
1018     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1019   }
1020 
1021   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1022   obj = JNIHandles::make_local(THREAD, i);
1023   JavaValue jvalue(T_VOID);
1024   JNI_ArgumentPusherVaArg ap(methodID, args);
1025   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1026 
1027   return obj;
1028 JNI_END
1029 
1030 
1031 DT_RETURN_MARK_DECL(NewObject, jobject
1032                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1033 
1034 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1035   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1036 
1037   jobject obj = nullptr;
1038   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1039 
1040   oop clazzoop = JNIHandles::resolve_non_null(clazz);
1041   Klass* k = java_lang_Class::as_Klass(clazzoop);
1042   if (k == nullptr) {
1043     ResourceMark rm(THREAD);
1044     THROW_(vmSymbols::java_lang_InstantiationException(), nullptr);
1045   }
1046 
1047   instanceOop i = InstanceKlass::allocate_instance(clazzoop, CHECK_NULL);
1048   obj = JNIHandles::make_local(THREAD, i);
1049   va_list args;
1050   va_start(args, methodID);
1051   JavaValue jvalue(T_VOID);
1052   JNI_ArgumentPusherVaArg ap(methodID, args);
1053   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1054   va_end(args);
1055 
1056   return obj;
1057 JNI_END
1058 
1059 
1060 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1061   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1062 
1063   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1064   jclass ret =
1065     (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
1066 
1067   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1068   return ret;
1069 JNI_END
1070 
1071 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1072   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1073 
1074   jboolean ret = JNI_TRUE;
1075   if (obj != nullptr) {

1786   // table.  If they're not there, the field doesn't exist.
1787   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
1788   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
1789   if (fieldname == nullptr || signame == nullptr) {
1790     ResourceMark rm;
1791     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1792   }
1793 
1794   // Make sure class is initialized before handing id's out to fields
1795   k->initialize(CHECK_NULL);
1796 
1797   fieldDescriptor fd;
1798   if (!k->is_instance_klass() ||
1799       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
1800     ResourceMark rm;
1801     THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
1802   }
1803 
1804   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
1805   // It may also have hash bits for k, if VerifyJNIFields is turned on.
1806   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flat());
1807   return ret;
1808 JNI_END
1809 
1810 
1811 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
1812   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
1813   oop o = JNIHandles::resolve_non_null(obj);
1814   Klass* k = o->klass();
1815   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1816   oop res = nullptr;
1817   // Keep JVMTI addition small and only check enabled flag here.
1818   // jni_GetField_probe() assumes that is okay to create handles.
1819   if (JvmtiExport::should_post_field_access()) {
1820     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1821   }
1822   if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1823     res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
1824   } else {
1825     assert(k->is_instance_klass(), "Only instance can have flat fields");
1826     InstanceKlass* ik = InstanceKlass::cast(k);
1827     fieldDescriptor fd;
1828     bool found = ik->find_field_from_offset(offset, false, &fd);  // performance bottleneck
1829     assert(found, "Field not found");
1830     InstanceKlass* holder = fd.field_holder();
1831     assert(holder->field_is_flat(fd.index()), "Must be");
1832     InlineLayoutInfo* li = holder->inline_layout_info_adr(fd.index());
1833     InlineKlass* field_vklass = li->klass();
1834     res = field_vklass->read_payload_from_addr(o, ik->field_offset(fd.index()), li->kind(), CHECK_NULL);
1835   }
1836   jobject ret = JNIHandles::make_local(THREAD, res);
1837   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1838   return ret;
1839 JNI_END
1840 


1841 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1842   , EntryProbe, ReturnProbe) \
1843 \
1844   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1845   , ReturnProbe); \
1846 \
1847 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1848 \
1849   EntryProbe; \
1850   Return ret = 0;\
1851   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1852 \
1853   oop o = JNIHandles::resolve_non_null(obj); \
1854   Klass* k = o->klass(); \
1855   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1856   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1857   if (JvmtiExport::should_post_field_access()) { \
1858     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); \
1859   } \
1860   ret = o->Fieldname##_field(offset); \

1932     assert(found, "bad field offset");
1933     assert(!fd.is_static(), "static/instance mismatch");
1934     if (fd.is_final()) {
1935       ResourceMark rm(current);
1936       log_debug(jni)("%s mutated final instance field %s.%s", func_name, ik->external_name(), fd.name()->as_C_string());
1937     }
1938   }
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_flat_jfieldID(fieldID)) {
1953     oop v = JNIHandles::resolve(value);
1954     if (v == nullptr) {
1955       InstanceKlass *ik = InstanceKlass::cast(k);
1956       fieldDescriptor fd;
1957       ik->find_field_from_offset(offset, false, &fd);
1958       if (fd.is_null_free_inline_type()) {
1959         THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Cannot store null in a null-restricted field");
1960       }
1961     }
1962     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, v);
1963   } else {
1964     assert(k->is_instance_klass(), "Only instances can have flat fields");
1965     InstanceKlass* ik = InstanceKlass::cast(k);
1966     fieldDescriptor fd;
1967     ik->find_field_from_offset(offset, false, &fd);
1968     InstanceKlass* holder = fd.field_holder();
1969     InlineLayoutInfo* li = holder->inline_layout_info_adr(fd.index());
1970     InlineKlass* vklass = li->klass();
1971     oop v = JNIHandles::resolve(value);
1972     vklass->write_value_to_addr(v, ((char*)(oopDesc*)o) + offset, li->kind(), true, CHECK);
1973   }
1974   log_debug_if_final_instance_field(thread, "SetObjectField", InstanceKlass::cast(k), offset);
1975   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1976 JNI_END
1977 
1978 // TODO: make this a template
1979 
1980 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1981                         , EntryProbe, ReturnProbe) \
1982 \
1983 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1984 \
1985   EntryProbe; \
1986 \
1987   oop o = JNIHandles::resolve_non_null(obj); \
1988   Klass* k = o->klass(); \
1989   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1990   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1991   if (JvmtiExport::should_post_field_modification()) { \
1992     jvalue field_value; \
1993     field_value.unionType = value; \

2386 
2387   oop initial_value = JNIHandles::resolve(initialElement);
2388   if (initial_value != nullptr) {  // array already initialized with null
2389     for (int index = 0; index < length; index++) {
2390       result->obj_at_put(index, initial_value);
2391     }
2392   }
2393   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2394   return ret;
2395 JNI_END
2396 
2397 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2398                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2399 
2400 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2401  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2402   jobject ret = nullptr;
2403   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2404   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2405   if (a->is_within_bounds(index)) {
2406     oop res = a->obj_at(index, CHECK_NULL);
2407     assert(res != nullptr || !a->is_null_free_array(), "Invalid value");
2408     ret = JNIHandles::make_local(THREAD, res);
2409     return ret;
2410   } else {
2411     ResourceMark rm(THREAD);
2412     stringStream ss;
2413     ss.print("Index %d out of bounds for length %d", index, a->length());
2414     THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2415   }
2416 JNI_END
2417 
2418 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2419                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2420 
2421 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2422  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2423   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2424 
2425    objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2426    oop v = JNIHandles::resolve(value);
2427    if (a->is_within_bounds(index)) {
2428     Klass* ek = a->is_flatArray() ? FlatArrayKlass::cast(a->klass())->element_klass() : RefArrayKlass::cast(a->klass())->element_klass();
2429     if (v == nullptr || v->is_a(ek)) {
2430       a->obj_at_put(index, v, CHECK);
2431     } else {
2432       ResourceMark rm(THREAD);
2433       stringStream ss;
2434       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2435       ss.print("type mismatch: can not store %s to %s[%d]",
2436                v->klass()->external_name(),
2437                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2438                index);
2439       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2440         ss.print("[]");
2441       }
2442       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2443     }
2444    } else {
2445      ResourceMark rm(THREAD);
2446      stringStream ss;
2447      ss.print("Index %d out of bounds for length %d", index, a->length());
2448      THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2449    }
2450 JNI_END
2451 
2452 
2453 
2454 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2455                               ,EntryProbe,ReturnProbe)  \
2456 \
2457   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2458                       , ReturnProbe); \
2459 \
2460 JNI_ENTRY(Return, \
2461           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2462   EntryProbe; \
2463   Return ret = nullptr;\
2464   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2465 \
2466   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2467   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2468   return ret;\
2469 JNI_END

2805 JNI_END
2806 
2807 //
2808 // Monitor functions
2809 //
2810 
2811 DT_RETURN_MARK_DECL(MonitorEnter, jint
2812                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2813 
2814 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2815  HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2816   jint ret = JNI_ERR;
2817   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2818 
2819   // If the object is null, we can't do anything with it
2820   if (jobj == nullptr) {
2821     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2822   }
2823 
2824   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2825   ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
2826   return JNI_OK;
2827 JNI_END
2828 
2829 DT_RETURN_MARK_DECL(MonitorExit, jint
2830                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2831 
2832 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2833  HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2834   jint ret = JNI_ERR;
2835   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2836 
2837   // Don't do anything with a null object
2838   if (jobj == nullptr) {
2839     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2840   }
2841 
2842   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2843   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2844   return JNI_OK;
2845 JNI_END
< prev index next >