< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page

  36 #include "classfile/modules.hpp"
  37 #include "classfile/symbolTable.hpp"
  38 #include "classfile/systemDictionary.hpp"
  39 #include "classfile/vmClasses.hpp"
  40 #include "classfile/vmSymbols.hpp"
  41 #include "compiler/compiler_globals.hpp"
  42 #include "gc/shared/collectedHeap.hpp"
  43 #include "gc/shared/stringdedup/stringDedup.hpp"
  44 #include "interpreter/linkResolver.hpp"
  45 #include "jni.h"
  46 #include "jvm.h"
  47 #include "logging/log.hpp"
  48 #include "memory/allocation.hpp"
  49 #include "memory/allocation.inline.hpp"
  50 #include "memory/oopFactory.hpp"
  51 #include "memory/resourceArea.hpp"
  52 #include "memory/universe.hpp"
  53 #include "nmt/memTracker.hpp"
  54 #include "oops/access.inline.hpp"
  55 #include "oops/arrayOop.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/atomic.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   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 424   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset);
 425   return ret;
 426 JNI_END
 427 
 428 
 429 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 430                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 431 
 432 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 433   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 434 
 435   jobject ret = nullptr;
 436   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 437 
 438   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 439   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 440   oop reflection_method;
 441   if (m->is_object_initializer()) {
 442     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 443   } else {
 444     // Note: Static initializers can theoretically be here, if JNI users manage
 445     // to get their jmethodID. Record them as plain methods.
 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 = nullptr;
 459   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 460 
 461   oop mirror = JNIHandles::resolve_non_null(sub);

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

 947   result->set_type(args->return_type());
 948 
 949   // Invoke the method. Result is returned as oop.
 950   JavaCalls::call(result, method, &java_args, CHECK);
 951 
 952   // Convert result
 953   if (is_reference_type(result->get_type())) {
 954     result->set_jobject(JNIHandles::make_local(THREAD, result->get_oop()));
 955   }
 956 }
 957 
 958 DT_RETURN_MARK_DECL(AllocObject, jobject
 959                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
 960 
 961 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
 962   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
 963 
 964   jobject ret = nullptr;
 965   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
 966 
 967   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);






 968   ret = JNIHandles::make_local(THREAD, i);
 969   return ret;
 970 JNI_END
 971 
 972 DT_RETURN_MARK_DECL(NewObjectA, jobject
 973                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
 974 
 975 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
 976   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
 977 
 978   jobject obj = nullptr;
 979   DT_RETURN_MARK(NewObjectA, jobject, (const jobject&)obj);
 980 
 981   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







 982   obj = JNIHandles::make_local(THREAD, i);
 983   JavaValue jvalue(T_VOID);
 984   JNI_ArgumentPusherArray ap(methodID, args);
 985   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);

 986   return obj;
 987 JNI_END
 988 
 989 
 990 DT_RETURN_MARK_DECL(NewObjectV, jobject
 991                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
 992 
 993 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
 994   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
 995 
 996   jobject obj = nullptr;
 997   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
 998 
 999   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







1000   obj = JNIHandles::make_local(THREAD, i);
1001   JavaValue jvalue(T_VOID);
1002   JNI_ArgumentPusherVaArg ap(methodID, args);
1003   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);

1004   return obj;
1005 JNI_END
1006 
1007 
1008 DT_RETURN_MARK_DECL(NewObject, jobject
1009                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1010 
1011 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1012   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1013 
1014   jobject obj = nullptr;
1015   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1016 
1017   instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);







1018   obj = JNIHandles::make_local(THREAD, i);
1019   va_list args;
1020   va_start(args, methodID);
1021   JavaValue jvalue(T_VOID);
1022   JNI_ArgumentPusherVaArg ap(methodID, args);
1023   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1024   va_end(args);

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

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

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













1792   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
1793   return ret;
1794 JNI_END
1795 
1796 
1797 
1798 #define DEFINE_GETFIELD(Return,Fieldname,Result \
1799   , EntryProbe, ReturnProbe) \
1800 \
1801   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
1802   , ReturnProbe); \
1803 \
1804 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
1805 \
1806   EntryProbe; \
1807   Return ret = 0;\
1808   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
1809 \
1810   oop o = JNIHandles::resolve_non_null(obj); \
1811   Klass* k = o->klass(); \
1812   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1813   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1814   if (JvmtiExport::should_post_field_access()) { \
1815     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); \
1816   } \
1817   ret = o->Fieldname##_field(offset); \

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





















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

2292 
2293   oop initial_value = JNIHandles::resolve(initialElement);
2294   if (initial_value != nullptr) {  // array already initialized with null
2295     for (int index = 0; index < length; index++) {
2296       result->obj_at_put(index, initial_value);
2297     }
2298   }
2299   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2300   return ret;
2301 JNI_END
2302 
2303 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2304                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2305 
2306 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2307  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2308   jobject ret = nullptr;
2309   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2310   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2311   if (a->is_within_bounds(index)) {
2312     ret = JNIHandles::make_local(THREAD, a->obj_at(index));


2313     return ret;
2314   } else {
2315     ResourceMark rm(THREAD);
2316     stringStream ss;
2317     ss.print("Index %d out of bounds for length %d", index, a->length());
2318     THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2319   }
2320 JNI_END
2321 
2322 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2323                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2324 
2325 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2326  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2327   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2328 
2329   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2330   oop v = JNIHandles::resolve(value);
2331   if (a->is_within_bounds(index)) {
2332     if (v == nullptr || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2333       a->obj_at_put(index, v);

2334     } else {
2335       ResourceMark rm(THREAD);
2336       stringStream ss;
2337       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2338       ss.print("type mismatch: can not store %s to %s[%d]",
2339                v->klass()->external_name(),
2340                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2341                index);
2342       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2343         ss.print("[]");
2344       }
2345       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2346     }
2347   } else {
2348     ResourceMark rm(THREAD);
2349     stringStream ss;
2350     ss.print("Index %d out of bounds for length %d", index, a->length());
2351     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2352   }
2353 JNI_END
2354 
2355 
2356 
2357 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2358                               ,EntryProbe,ReturnProbe)  \
2359 \
2360   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2361                       , ReturnProbe); \
2362 \
2363 JNI_ENTRY(Return, \
2364           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2365   EntryProbe; \
2366   Return ret = nullptr;\
2367   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2368 \
2369   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2370   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2371   return ret;\
2372 JNI_END

2708 JNI_END
2709 
2710 //
2711 // Monitor functions
2712 //
2713 
2714 DT_RETURN_MARK_DECL(MonitorEnter, jint
2715                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2716 
2717 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2718  HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2719   jint ret = JNI_ERR;
2720   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2721 
2722   // If the object is null, we can't do anything with it
2723   if (jobj == nullptr) {
2724     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2725   }
2726 
2727   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2728   ObjectSynchronizer::jni_enter(obj, thread);
2729   return JNI_OK;
2730 JNI_END
2731 
2732 DT_RETURN_MARK_DECL(MonitorExit, jint
2733                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2734 
2735 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2736  HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2737   jint ret = JNI_ERR;
2738   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2739 
2740   // Don't do anything with a null object
2741   if (jobj == nullptr) {
2742     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2743   }
2744 
2745   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2746   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2747   return JNI_OK;
2748 JNI_END

  36 #include "classfile/modules.hpp"
  37 #include "classfile/symbolTable.hpp"
  38 #include "classfile/systemDictionary.hpp"
  39 #include "classfile/vmClasses.hpp"
  40 #include "classfile/vmSymbols.hpp"
  41 #include "compiler/compiler_globals.hpp"
  42 #include "gc/shared/collectedHeap.hpp"
  43 #include "gc/shared/stringdedup/stringDedup.hpp"
  44 #include "interpreter/linkResolver.hpp"
  45 #include "jni.h"
  46 #include "jvm.h"
  47 #include "logging/log.hpp"
  48 #include "memory/allocation.hpp"
  49 #include "memory/allocation.inline.hpp"
  50 #include "memory/oopFactory.hpp"
  51 #include "memory/resourceArea.hpp"
  52 #include "memory/universe.hpp"
  53 #include "nmt/memTracker.hpp"
  54 #include "oops/access.inline.hpp"
  55 #include "oops/arrayOop.hpp"
  56 #include "oops/flatArrayOop.inline.hpp"
  57 #include "oops/inlineKlass.inline.hpp"
  58 #include "oops/instanceKlass.inline.hpp"
  59 #include "oops/instanceOop.hpp"
  60 #include "oops/klass.inline.hpp"
  61 #include "oops/markWord.hpp"
  62 #include "oops/method.hpp"
  63 #include "oops/objArrayKlass.hpp"
  64 #include "oops/objArrayOop.inline.hpp"
  65 #include "oops/oop.inline.hpp"
  66 #include "oops/symbol.hpp"
  67 #include "oops/typeArrayKlass.hpp"
  68 #include "oops/typeArrayOop.inline.hpp"
  69 #include "prims/jniCheck.hpp"
  70 #include "prims/jniExport.hpp"
  71 #include "prims/jniFastGetField.hpp"
  72 #include "prims/jvm_misc.hpp"
  73 #include "prims/jvmtiExport.hpp"
  74 #include "prims/jvmtiThreadState.hpp"
  75 #include "runtime/arguments.hpp"
  76 #include "runtime/atomic.hpp"
  77 #include "runtime/fieldDescriptor.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     int offset = InstanceKlass::cast(k1)->field_offset( slot );
 413     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 414     assert(id != nullptr, "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   int offset = InstanceKlass::cast(k1)->field_offset( slot );
 425   bool is_flat = InstanceKlass::cast(k1)->field_is_flat(slot);
 426   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 427   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flat);
 428   return ret;
 429 JNI_END
 430 
 431 
 432 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 433                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 434 
 435 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 436   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 437 
 438   jobject ret = nullptr;
 439   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 440 
 441   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 442   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 443   oop reflection_method;
 444   if (m->is_object_constructor()) {
 445     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 446   } else {
 447     // Note: Static initializers can theoretically be here, if JNI users manage
 448     // to get their jmethodID. Record them as plain methods.
 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 = nullptr;
 462   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 463 
 464   oop mirror = JNIHandles::resolve_non_null(sub);

 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 

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

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


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

1908   return (address)jni_GetLongField;
1909 }
1910 address jni_GetFloatField_addr() {
1911   return (address)jni_GetFloatField;
1912 }
1913 address jni_GetDoubleField_addr() {
1914   return (address)jni_GetDoubleField;
1915 }
1916 
1917 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
1918   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
1919   oop o = JNIHandles::resolve_non_null(obj);
1920   Klass* k = o->klass();
1921   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
1922   // Keep JVMTI addition small and only check enabled flag here.
1923   if (JvmtiExport::should_post_field_modification()) {
1924     jvalue field_value;
1925     field_value.l = value;
1926     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
1927   }
1928   if (!jfieldIDWorkaround::is_flat_jfieldID(fieldID)) {
1929     oop v = JNIHandles::resolve(value);
1930     if (v == nullptr) {
1931       InstanceKlass *ik = InstanceKlass::cast(k);
1932       fieldDescriptor fd;
1933       ik->find_field_from_offset(offset, false, &fd);
1934       if (fd.is_null_free_inline_type()) {
1935         THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Cannot store null in a null-restricted field");
1936       }
1937     }
1938     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, v);
1939   } else {
1940     assert(k->is_instance_klass(), "Only instances can have flat fields");
1941     InstanceKlass* ik = InstanceKlass::cast(k);
1942     fieldDescriptor fd;
1943     ik->find_field_from_offset(offset, false, &fd);
1944     InstanceKlass* holder = fd.field_holder();
1945     InlineLayoutInfo* li = holder->inline_layout_info_adr(fd.index());
1946     InlineKlass* vklass = li->klass();
1947     oop v = JNIHandles::resolve(value);
1948     vklass->write_value_to_addr(v, ((char*)(oopDesc*)o) + offset, li->kind(), true, CHECK);
1949   }
1950   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
1951 JNI_END
1952 
1953 // TODO: make this a template
1954 
1955 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
1956                         , EntryProbe, ReturnProbe) \
1957 \
1958 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
1959 \
1960   EntryProbe; \
1961 \
1962   oop o = JNIHandles::resolve_non_null(obj); \
1963   Klass* k = o->klass(); \
1964   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
1965   /* Keep JVMTI addition small and only check enabled flag here.       */ \
1966   if (JvmtiExport::should_post_field_modification()) { \
1967     jvalue field_value; \
1968     field_value.unionType = value; \
1969     o = JvmtiExport::jni_SetField_probe(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \

2358 
2359   oop initial_value = JNIHandles::resolve(initialElement);
2360   if (initial_value != nullptr) {  // array already initialized with null
2361     for (int index = 0; index < length; index++) {
2362       result->obj_at_put(index, initial_value);
2363     }
2364   }
2365   ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
2366   return ret;
2367 JNI_END
2368 
2369 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2370                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2371 
2372 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2373  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2374   jobject ret = nullptr;
2375   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2376   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2377   if (a->is_within_bounds(index)) {
2378     oop res = a->obj_at(index, CHECK_NULL);
2379     assert(res != nullptr || !a->is_null_free_array(), "Invalid value");
2380     ret = JNIHandles::make_local(THREAD, res);
2381     return ret;
2382   } else {
2383     ResourceMark rm(THREAD);
2384     stringStream ss;
2385     ss.print("Index %d out of bounds for length %d", index, a->length());
2386     THROW_MSG_NULL(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2387   }
2388 JNI_END
2389 
2390 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2391                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2392 
2393 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2394  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2395   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2396 
2397    objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2398    oop v = JNIHandles::resolve(value);
2399    if (a->is_within_bounds(index)) {
2400     Klass* ek = a->is_flatArray() ? FlatArrayKlass::cast(a->klass())->element_klass() : RefArrayKlass::cast(a->klass())->element_klass();
2401     if (v == nullptr || v->is_a(ek)) {
2402       a->obj_at_put(index, v, CHECK);
2403     } else {
2404       ResourceMark rm(THREAD);
2405       stringStream ss;
2406       Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2407       ss.print("type mismatch: can not store %s to %s[%d]",
2408                v->klass()->external_name(),
2409                bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2410                index);
2411       for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2412         ss.print("[]");
2413       }
2414       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2415     }
2416    } else {
2417      ResourceMark rm(THREAD);
2418      stringStream ss;
2419      ss.print("Index %d out of bounds for length %d", index, a->length());
2420      THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2421    }
2422 JNI_END
2423 
2424 
2425 
2426 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2427                               ,EntryProbe,ReturnProbe)  \
2428 \
2429   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2430                       , ReturnProbe); \
2431 \
2432 JNI_ENTRY(Return, \
2433           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2434   EntryProbe; \
2435   Return ret = nullptr;\
2436   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2437 \
2438   oop obj= oopFactory::Allocator(len, CHECK_NULL); \
2439   ret = (Return) JNIHandles::make_local(THREAD, obj); \
2440   return ret;\
2441 JNI_END

2777 JNI_END
2778 
2779 //
2780 // Monitor functions
2781 //
2782 
2783 DT_RETURN_MARK_DECL(MonitorEnter, jint
2784                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
2785 
2786 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
2787  HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
2788   jint ret = JNI_ERR;
2789   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
2790 
2791   // If the object is null, we can't do anything with it
2792   if (jobj == nullptr) {
2793     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2794   }
2795 
2796   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
2797   ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
2798   return JNI_OK;
2799 JNI_END
2800 
2801 DT_RETURN_MARK_DECL(MonitorExit, jint
2802                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
2803 
2804 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
2805  HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
2806   jint ret = JNI_ERR;
2807   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
2808 
2809   // Don't do anything with a null object
2810   if (jobj == nullptr) {
2811     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
2812   }
2813 
2814   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
2815   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
2816   return JNI_OK;
2817 JNI_END
< prev index next >