1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012 Red Hat, Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "jni.h"
  28 #include "jvm.h"
  29 #include "ci/ciReplay.hpp"
  30 #include "classfile/altHashing.hpp"
  31 #include "classfile/classFileStream.hpp"
  32 #include "classfile/classLoader.hpp"
  33 #include "classfile/javaClasses.hpp"
  34 #include "classfile/javaClasses.inline.hpp"
  35 #include "classfile/modules.hpp"
  36 #include "classfile/symbolTable.hpp"
  37 #include "classfile/systemDictionary.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "gc/shared/gcLocker.inline.hpp"
  40 #include "interpreter/linkResolver.hpp"
  41 #include "jfr/jfrEvents.hpp"
  42 #include "jfr/support/jfrThreadId.hpp"
  43 #include "logging/log.hpp"
  44 #include "memory/allocation.hpp"
  45 #include "memory/allocation.inline.hpp"
  46 #include "memory/oopFactory.hpp"
  47 #include "memory/resourceArea.hpp"
  48 #include "memory/universe.hpp"
  49 #include "oops/access.inline.hpp"
  50 #include "oops/arrayOop.inline.hpp"
  51 #include "oops/instanceKlass.hpp"
  52 #include "oops/instanceOop.hpp"
  53 #include "oops/markWord.hpp"
  54 #include "oops/method.hpp"
  55 #include "oops/objArrayKlass.hpp"
  56 #include "oops/objArrayOop.inline.hpp"
  57 #include "oops/oop.inline.hpp"
  58 #include "oops/symbol.hpp"
  59 #include "oops/typeArrayKlass.hpp"
  60 #include "oops/typeArrayOop.inline.hpp"
  61 #include "oops/valueArrayOop.inline.hpp"
  62 #include "oops/valueKlass.inline.hpp"
  63 #include "prims/jniCheck.hpp"
  64 #include "prims/jniExport.hpp"
  65 #include "prims/jniFastGetField.hpp"
  66 #include "prims/jvm_misc.hpp"
  67 #include "prims/jvmtiExport.hpp"
  68 #include "prims/jvmtiThreadState.hpp"
  69 #include "runtime/atomic.hpp"
  70 #include "runtime/fieldDescriptor.inline.hpp"
  71 #include "runtime/handles.inline.hpp"
  72 #include "runtime/interfaceSupport.inline.hpp"
  73 #include "runtime/java.hpp"
  74 #include "runtime/javaCalls.hpp"
  75 #include "runtime/jfieldIDWorkaround.hpp"
  76 #include "runtime/jniHandles.inline.hpp"
  77 #include "runtime/reflection.hpp"
  78 #include "runtime/safepointVerifiers.hpp"
  79 #include "runtime/sharedRuntime.hpp"
  80 #include "runtime/signature.hpp"
  81 #include "runtime/thread.inline.hpp"
  82 #include "runtime/vmOperations.hpp"
  83 #include "services/memTracker.hpp"
  84 #include "services/runtimeService.hpp"
  85 #include "utilities/defaultStream.hpp"
  86 #include "utilities/dtrace.hpp"
  87 #include "utilities/events.hpp"
  88 #include "utilities/histogram.hpp"
  89 #include "utilities/macros.hpp"
  90 #include "utilities/vmError.hpp"
  91 #if INCLUDE_JVMCI
  92 #include "jvmci/jvmciCompiler.hpp"
  93 #endif
  94 
  95 static jint CurrentVersion = JNI_VERSION_10;
  96 
  97 #ifdef _WIN32
  98 extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
  99 #endif
 100 
 101 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
 102 // '-return' probe regardless of the return path is taken out of the function.
 103 // Methods that have multiple return paths use this to avoid having to
 104 // instrument each return path.  Methods that use CHECK or THROW must use this
 105 // since those macros can cause an immedate uninstrumented return.
 106 //
 107 // In order to get the return value, a reference to the variable containing
 108 // the return value must be passed to the contructor of the object, and
 109 // the return value must be set before return (since the mark object has
 110 // a reference to it).
 111 //
 112 // Example:
 113 // DT_RETURN_MARK_DECL(SomeFunc, int);
 114 // JNI_ENTRY(int, SomeFunc, ...)
 115 //   int return_value = 0;
 116 //   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
 117 //   foo(CHECK_0)
 118 //   return_value = 5;
 119 //   return return_value;
 120 // JNI_END
 121 #define DT_RETURN_MARK_DECL(name, type, probe)                             \
 122   DTRACE_ONLY(                                                             \
 123     class DTraceReturnProbeMark_##name {                                   \
 124      public:                                                               \
 125       const type& _ret_ref;                                                \
 126       DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
 127       ~DTraceReturnProbeMark_##name() {                                    \
 128         probe;                                                             \
 129       }                                                                    \
 130     }                                                                      \
 131   )
 132 // Void functions are simpler since there's no return value
 133 #define DT_VOID_RETURN_MARK_DECL(name, probe)                              \
 134   DTRACE_ONLY(                                                             \
 135     class DTraceReturnProbeMark_##name {                                   \
 136      public:                                                               \
 137       ~DTraceReturnProbeMark_##name() {                                    \
 138         probe;                                                             \
 139       }                                                                    \
 140     }                                                                      \
 141   )
 142 
 143 // Place these macros in the function to mark the return.  Non-void
 144 // functions need the type and address of the return value.
 145 #define DT_RETURN_MARK(name, type, ref) \
 146   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
 147 #define DT_VOID_RETURN_MARK(name) \
 148   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
 149 
 150 
 151 // Use these to select distinct code for floating-point vs. non-floating point
 152 // situations.  Used from within common macros where we need slightly
 153 // different behavior for Float/Double
 154 #define FP_SELECT_Boolean(intcode, fpcode) intcode
 155 #define FP_SELECT_Byte(intcode, fpcode)    intcode
 156 #define FP_SELECT_Char(intcode, fpcode)    intcode
 157 #define FP_SELECT_Short(intcode, fpcode)   intcode
 158 #define FP_SELECT_Object(intcode, fpcode)  intcode
 159 #define FP_SELECT_Int(intcode, fpcode)     intcode
 160 #define FP_SELECT_Long(intcode, fpcode)    intcode
 161 #define FP_SELECT_Float(intcode, fpcode)   fpcode
 162 #define FP_SELECT_Double(intcode, fpcode)  fpcode
 163 #define FP_SELECT(TypeName, intcode, fpcode) \
 164   FP_SELECT_##TypeName(intcode, fpcode)
 165 
 166 // Choose DT_RETURN_MARK macros  based on the type: float/double -> void
 167 // (dtrace doesn't do FP yet)
 168 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
 169   FP_SELECT(TypeName, \
 170     DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
 171 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
 172   FP_SELECT(TypeName, \
 173     DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
 174 
 175 
 176 // out-of-line helpers for class jfieldIDWorkaround:
 177 
 178 bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
 179   if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
 180     uintptr_t as_uint = (uintptr_t) id;
 181     intptr_t offset = raw_instance_offset(id);
 182     if (is_checked_jfieldID(id)) {
 183       if (!klass_hash_ok(k, id)) {
 184         return false;
 185       }
 186     }
 187     return InstanceKlass::cast(k)->contains_field_offset(offset);
 188   } else {
 189     JNIid* result = (JNIid*) id;
 190 #ifdef ASSERT
 191     return result != NULL && result->is_static_field_id();
 192 #else
 193     return result != NULL;
 194 #endif
 195   }
 196 }
 197 
 198 
 199 intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
 200   if (offset <= small_offset_mask) {
 201     Klass* field_klass = k;
 202     Klass* super_klass = field_klass->super();
 203     // With compressed oops the most super class with nonstatic fields would
 204     // be the owner of fields embedded in the header.
 205     while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
 206            InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
 207       field_klass = super_klass;   // super contains the field also
 208       super_klass = field_klass->super();
 209     }
 210     debug_only(NoSafepointVerifier nosafepoint;)
 211     uintptr_t klass_hash = field_klass->identity_hash();
 212     return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
 213   } else {
 214 #if 0
 215     #ifndef PRODUCT
 216     {
 217       ResourceMark rm;
 218       warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
 219     }
 220     #endif
 221 #endif
 222     return 0;
 223   }
 224 }
 225 
 226 bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
 227   uintptr_t as_uint = (uintptr_t) id;
 228   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 229   do {
 230     debug_only(NoSafepointVerifier nosafepoint;)
 231     // Could use a non-blocking query for identity_hash here...
 232     if ((k->identity_hash() & klass_mask) == klass_hash)
 233       return true;
 234     k = k->super();
 235   } while (k != NULL);
 236   return false;
 237 }
 238 
 239 void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
 240   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
 241   uintptr_t as_uint = (uintptr_t) id;
 242   intptr_t offset = raw_instance_offset(id);
 243   if (VerifyJNIFields) {
 244     if (is_checked_jfieldID(id)) {
 245       guarantee(klass_hash_ok(k, id),
 246     "Bug in native code: jfieldID class must match object");
 247     } else {
 248 #if 0
 249       #ifndef PRODUCT
 250       if (Verbose) {
 251   ResourceMark rm;
 252   warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
 253       }
 254       #endif
 255 #endif
 256     }
 257   }
 258   guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
 259       "Bug in native code: jfieldID offset must address interior of object");
 260 }
 261 
 262 // Wrapper to trace JNI functions
 263 
 264 #ifdef ASSERT
 265   Histogram* JNIHistogram;
 266   static volatile int JNIHistogram_lock = 0;
 267 
 268   class JNIHistogramElement : public HistogramElement {
 269     public:
 270      JNIHistogramElement(const char* name);
 271   };
 272 
 273   JNIHistogramElement::JNIHistogramElement(const char* elementName) {
 274     _name = elementName;
 275     uintx count = 0;
 276 
 277     while (Atomic::cmpxchg(&JNIHistogram_lock, 0, 1) != 0) {
 278       while (Atomic::load_acquire(&JNIHistogram_lock) != 0) {
 279         count +=1;
 280         if ( (WarnOnStalledSpinLock > 0)
 281           && (count % WarnOnStalledSpinLock == 0)) {
 282           warning("JNIHistogram_lock seems to be stalled");
 283         }
 284       }
 285      }
 286 
 287 
 288     if(JNIHistogram == NULL)
 289       JNIHistogram = new Histogram("JNI Call Counts",100);
 290 
 291     JNIHistogram->add_element(this);
 292     Atomic::dec(&JNIHistogram_lock);
 293   }
 294 
 295   #define JNICountWrapper(arg)                                     \
 296      static JNIHistogramElement* e = new JNIHistogramElement(arg); \
 297       /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \
 298      if (e != NULL) e->increment_count()
 299   #define JNIWrapper(arg) JNICountWrapper(arg);
 300 #else
 301   #define JNIWrapper(arg)
 302 #endif
 303 
 304 
 305 // Implementation of JNI entries
 306 
 307 DT_RETURN_MARK_DECL(DefineClass, jclass
 308                     , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
 309 
 310 JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
 311                                   const jbyte *buf, jsize bufLen))
 312   JNIWrapper("DefineClass");
 313 
 314   HOTSPOT_JNI_DEFINECLASS_ENTRY(
 315     env, (char*) name, loaderRef, (char*) buf, bufLen);
 316 
 317   jclass cls = NULL;
 318   DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
 319 
 320   TempNewSymbol class_name = NULL;
 321   // Since exceptions can be thrown, class initialization can take place
 322   // if name is NULL no check for class name in .class stream has to be made.
 323   if (name != NULL) {
 324     const int str_len = (int)strlen(name);
 325     if (str_len > Symbol::max_length()) {
 326       // It's impossible to create this class;  the name cannot fit
 327       // into the constant pool.
 328       Exceptions::fthrow(THREAD_AND_LOCATION,
 329                          vmSymbols::java_lang_NoClassDefFoundError(),
 330                          "Class name exceeds maximum length of %d: %s",
 331                          Symbol::max_length(),
 332                          name);
 333       return 0;
 334     }
 335     class_name = SymbolTable::new_symbol(name);
 336   }
 337   ResourceMark rm(THREAD);
 338   ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
 339   Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
 340 
 341   if (UsePerfData && !class_loader.is_null()) {
 342     // check whether the current caller thread holds the lock or not.
 343     // If not, increment the corresponding counter
 344     if (ObjectSynchronizer::
 345         query_lock_ownership((JavaThread*)THREAD, class_loader) !=
 346         ObjectSynchronizer::owner_self) {
 347       ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
 348     }
 349   }
 350   Klass* k = SystemDictionary::resolve_from_stream(class_name,
 351                                                    class_loader,
 352                                                    Handle(),
 353                                                    &st,
 354                                                    CHECK_NULL);
 355 
 356   if (log_is_enabled(Debug, class, resolve) && k != NULL) {
 357     trace_class_resolution(k);
 358   }
 359 
 360   cls = (jclass)JNIHandles::make_local(
 361     env, k->java_mirror());
 362   return cls;
 363 JNI_END
 364 
 365 
 366 
 367 DT_RETURN_MARK_DECL(FindClass, jclass
 368                     , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
 369 
 370 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
 371   JNIWrapper("FindClass");
 372 
 373   HOTSPOT_JNI_FINDCLASS_ENTRY(env, (char *)name);
 374 
 375   jclass result = NULL;
 376   DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
 377 
 378   // Sanity check the name:  it cannot be null or larger than the maximum size
 379   // name we can fit in the constant pool.
 380   if (name == NULL) {
 381     THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), "No class name given");
 382   }
 383   if ((int)strlen(name) > Symbol::max_length()) {
 384     Exceptions::fthrow(THREAD_AND_LOCATION,
 385                        vmSymbols::java_lang_NoClassDefFoundError(),
 386                        "Class name exceeds maximum length of %d: %s",
 387                        Symbol::max_length(),
 388                        name);
 389     return 0;
 390   }
 391 
 392   //%note jni_3
 393   Handle protection_domain;
 394   // Find calling class
 395   Klass* k = thread->security_get_caller_class(0);
 396   // default to the system loader when no context
 397   Handle loader(THREAD, SystemDictionary::java_system_loader());
 398   if (k != NULL) {
 399     // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
 400     // in the correct class context.
 401     if (k->class_loader() == NULL &&
 402         k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
 403       JavaValue result(T_OBJECT);
 404       JavaCalls::call_static(&result, k,
 405                              vmSymbols::getFromClass_name(),
 406                              vmSymbols::void_class_signature(),
 407                              CHECK_NULL);
 408       // When invoked from JNI_OnLoad, NativeLibrary::getFromClass returns
 409       // a non-NULL Class object.  When invoked from JNI_OnUnload,
 410       // it will return NULL to indicate no context.
 411       oop mirror = (oop) result.get_jobject();
 412       if (mirror != NULL) {
 413         Klass* fromClass = java_lang_Class::as_Klass(mirror);
 414         loader = Handle(THREAD, fromClass->class_loader());
 415         protection_domain = Handle(THREAD, fromClass->protection_domain());
 416       }
 417     } else {
 418       loader = Handle(THREAD, k->class_loader());
 419     }
 420   }
 421 
 422   TempNewSymbol sym = SymbolTable::new_symbol(name);
 423   result = find_class_from_class_loader(env, sym, true, loader,
 424                                         protection_domain, true, thread);
 425 
 426   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
 427     trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
 428   }
 429 
 430   return result;
 431 JNI_END
 432 
 433 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
 434                     , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
 435 
 436 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
 437   JNIWrapper("FromReflectedMethod");
 438 
 439   HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(env, method);
 440 
 441   jmethodID ret = NULL;
 442   DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
 443 
 444   // method is a handle to a java.lang.reflect.Method object
 445   oop reflected  = JNIHandles::resolve_non_null(method);
 446   oop mirror     = NULL;
 447   int slot       = 0;
 448 
 449   if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
 450     mirror = java_lang_reflect_Constructor::clazz(reflected);
 451     slot   = java_lang_reflect_Constructor::slot(reflected);
 452   } else {
 453     assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
 454     mirror = java_lang_reflect_Method::clazz(reflected);
 455     slot   = java_lang_reflect_Method::slot(reflected);
 456   }
 457   Klass* k1 = java_lang_Class::as_Klass(mirror);
 458 
 459   // Make sure class is initialized before handing id's out to methods
 460   k1->initialize(CHECK_NULL);
 461   Method* m = InstanceKlass::cast(k1)->method_with_idnum(slot);
 462   ret = m==NULL? NULL : m->jmethod_id();  // return NULL if reflected method deleted
 463   return ret;
 464 JNI_END
 465 
 466 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
 467                     , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
 468 
 469 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
 470   JNIWrapper("FromReflectedField");
 471 
 472   HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(env, field);
 473 
 474   jfieldID ret = NULL;
 475   DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
 476 
 477   // field is a handle to a java.lang.reflect.Field object
 478   oop reflected   = JNIHandles::resolve_non_null(field);
 479   oop mirror      = java_lang_reflect_Field::clazz(reflected);
 480   Klass* k1       = java_lang_Class::as_Klass(mirror);
 481   int slot        = java_lang_reflect_Field::slot(reflected);
 482   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 483 
 484   // Make sure class is initialized before handing id's out to fields
 485   k1->initialize(CHECK_NULL);
 486 
 487   // First check if this is a static field
 488   if (modifiers & JVM_ACC_STATIC) {
 489     intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
 490     JNIid* id = InstanceKlass::cast(k1)->jni_id_for(offset);
 491     assert(id != NULL, "corrupt Field object");
 492     debug_only(id->set_is_static_field_id();)
 493     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
 494     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 495     return ret;
 496   }
 497 
 498   // The slot is the index of the field description in the field-array
 499   // The jfieldID is the offset of the field within the object
 500   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 501   intptr_t offset = InstanceKlass::cast(k1)->field_offset( slot );
 502   bool is_flattened = InstanceKlass::cast(k1)->field_is_flattened(slot);
 503   assert(InstanceKlass::cast(k1)->contains_field_offset(offset), "stay within object");
 504   ret = jfieldIDWorkaround::to_instance_jfieldID(k1, offset, is_flattened);
 505   return ret;
 506 JNI_END
 507 
 508 
 509 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 510                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 511 
 512 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 513   JNIWrapper("ToReflectedMethod");
 514 
 515   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(env, cls, (uintptr_t) method_id, isStatic);
 516 
 517   jobject ret = NULL;
 518   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 519 
 520   methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
 521   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 522   oop reflection_method;
 523   if (m->is_object_constructor()) {
 524     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 525   } else {
 526     reflection_method = Reflection::new_method(m, false, CHECK_NULL);
 527   }
 528   ret = JNIHandles::make_local(env, reflection_method);
 529   return ret;
 530 JNI_END
 531 
 532 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 533                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 534 
 535 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 536   JNIWrapper("GetSuperclass");
 537 
 538   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(env, sub);
 539 
 540   jclass obj = NULL;
 541   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 542 
 543   oop mirror = JNIHandles::resolve_non_null(sub);
 544   // primitive classes return NULL
 545   if (java_lang_Class::is_primitive(mirror)) return NULL;
 546 
 547   // Rules of Class.getSuperClass as implemented by KLass::java_super:
 548   // arrays return Object
 549   // interfaces return NULL
 550   // proper classes return Klass::super()
 551   Klass* k = java_lang_Class::as_Klass(mirror);
 552   if (k->is_interface()) return NULL;
 553 
 554   // return mirror for superclass
 555   Klass* super = k->java_super();
 556   // super2 is the value computed by the compiler's getSuperClass intrinsic:
 557   debug_only(Klass* super2 = ( k->is_array_klass()
 558                                  ? SystemDictionary::Object_klass()
 559                                  : k->super() ) );
 560   assert(super == super2,
 561          "java_super computation depends on interface, array, other super");
 562   obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
 563   return obj;
 564 JNI_END
 565 
 566 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 567   JNIWrapper("IsSubclassOf");
 568 
 569   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
 570 
 571   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 572   oop super_mirror = JNIHandles::resolve_non_null(super);
 573   if (java_lang_Class::is_primitive(sub_mirror) ||
 574       java_lang_Class::is_primitive(super_mirror)) {
 575     jboolean ret = (sub_mirror == super_mirror);
 576 
 577     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 578     return ret;
 579   }
 580   Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
 581   Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
 582   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 583   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
 584                    JNI_TRUE : JNI_FALSE;
 585   if (sub_klass == super_klass && sub_klass->is_value()) {
 586     // for inline class, V <: V?
 587     ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(sub_klass));
 588     if (sub_mirror == super_mirror || (sub_mirror == vk->value_mirror() && super_mirror == vk->indirect_mirror())) {
 589       ret = JNI_TRUE;
 590     } else {
 591       ret = JNI_FALSE;
 592     }
 593   }
 594   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
 595   return ret;
 596 JNI_END
 597 
 598 
 599 DT_RETURN_MARK_DECL(Throw, jint
 600                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 601 
 602 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 603   JNIWrapper("Throw");
 604 
 605   HOTSPOT_JNI_THROW_ENTRY(env, obj);
 606 
 607   jint ret = JNI_OK;
 608   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 609 
 610   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 611   ShouldNotReachHere();
 612   return 0;  // Mute compiler.
 613 JNI_END
 614 
 615 
 616 DT_RETURN_MARK_DECL(ThrowNew, jint
 617                     , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
 618 
 619 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
 620   JNIWrapper("ThrowNew");
 621 
 622   HOTSPOT_JNI_THROWNEW_ENTRY(env, clazz, (char *) message);
 623 
 624   jint ret = JNI_OK;
 625   DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
 626 
 627   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
 628   Symbol*  name = k->name();
 629   Handle class_loader (THREAD,  k->class_loader());
 630   Handle protection_domain (THREAD, k->protection_domain());
 631   THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
 632   ShouldNotReachHere();
 633   return 0;  // Mute compiler.
 634 JNI_END
 635 
 636 
 637 // JNI functions only transform a pending async exception to a synchronous
 638 // exception in ExceptionOccurred and ExceptionCheck calls, since
 639 // delivering an async exception in other places won't change the native
 640 // code's control flow and would be harmful when native code further calls
 641 // JNI functions with a pending exception. Async exception is also checked
 642 // during the call, so ExceptionOccurred/ExceptionCheck won't return
 643 // false but deliver the async exception at the very end during
 644 // state transition.
 645 
 646 static void jni_check_async_exceptions(JavaThread *thread) {
 647   assert(thread == Thread::current(), "must be itself");
 648   thread->check_and_handle_async_exceptions();
 649 }
 650 
 651 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
 652   JNIWrapper("ExceptionOccurred");
 653 
 654   HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(env);
 655 
 656   jni_check_async_exceptions(thread);
 657   oop exception = thread->pending_exception();
 658   jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
 659 
 660   HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(ret);
 661   return ret;
 662 JNI_END
 663 
 664 
 665 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
 666   JNIWrapper("ExceptionDescribe");
 667 
 668   HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(env);
 669 
 670   if (thread->has_pending_exception()) {
 671     Handle ex(thread, thread->pending_exception());
 672     thread->clear_pending_exception();
 673     if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {
 674       // Don't print anything if we are being killed.
 675     } else {
 676       jio_fprintf(defaultStream::error_stream(), "Exception ");
 677       if (thread != NULL && thread->threadObj() != NULL) {
 678         ResourceMark rm(THREAD);
 679         jio_fprintf(defaultStream::error_stream(),
 680         "in thread \"%s\" ", thread->get_thread_name());
 681       }
 682       if (ex->is_a(SystemDictionary::Throwable_klass())) {
 683         JavaValue result(T_VOID);
 684         JavaCalls::call_virtual(&result,
 685                                 ex,
 686                                 SystemDictionary::Throwable_klass(),
 687                                 vmSymbols::printStackTrace_name(),
 688                                 vmSymbols::void_method_signature(),
 689                                 THREAD);
 690         // If an exception is thrown in the call it gets thrown away. Not much
 691         // we can do with it. The native code that calls this, does not check
 692         // for the exception - hence, it might still be in the thread when DestroyVM gets
 693         // called, potentially causing a few asserts to trigger - since no pending exception
 694         // is expected.
 695         CLEAR_PENDING_EXCEPTION;
 696       } else {
 697         ResourceMark rm(THREAD);
 698         jio_fprintf(defaultStream::error_stream(),
 699         ". Uncaught exception of type %s.",
 700         ex->klass()->external_name());
 701       }
 702     }
 703   }
 704 
 705   HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN();
 706 JNI_END
 707 
 708 
 709 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionClear(JNIEnv *env))
 710   JNIWrapper("ExceptionClear");
 711 
 712   HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(env);
 713 
 714   // The jni code might be using this API to clear java thrown exception.
 715   // So just mark jvmti thread exception state as exception caught.
 716   JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
 717   if (state != NULL && state->is_exception_detected()) {
 718     state->set_exception_caught();
 719   }
 720   thread->clear_pending_exception();
 721 
 722   HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN();
 723 JNI_END
 724 
 725 
 726 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
 727   JNIWrapper("FatalError");
 728 
 729   HOTSPOT_JNI_FATALERROR_ENTRY(env, (char *) msg);
 730 
 731   tty->print_cr("FATAL ERROR in native method: %s", msg);
 732   thread->print_stack();
 733   os::abort(); // Dump core and abort
 734 JNI_END
 735 
 736 
 737 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
 738   JNIWrapper("PushLocalFrame");
 739 
 740   HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(env, capacity);
 741 
 742   //%note jni_11
 743   if (capacity < 0 ||
 744       ((MaxJNILocalCapacity > 0) && (capacity > MaxJNILocalCapacity))) {
 745     HOTSPOT_JNI_PUSHLOCALFRAME_RETURN((uint32_t)JNI_ERR);
 746     return JNI_ERR;
 747   }
 748   JNIHandleBlock* old_handles = thread->active_handles();
 749   JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
 750   assert(new_handles != NULL, "should not be NULL");
 751   new_handles->set_pop_frame_link(old_handles);
 752   thread->set_active_handles(new_handles);
 753   jint ret = JNI_OK;
 754   HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(ret);
 755   return ret;
 756 JNI_END
 757 
 758 
 759 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
 760   JNIWrapper("PopLocalFrame");
 761 
 762   HOTSPOT_JNI_POPLOCALFRAME_ENTRY(env, result);
 763 
 764   //%note jni_11
 765   Handle result_handle(thread, JNIHandles::resolve(result));
 766   JNIHandleBlock* old_handles = thread->active_handles();
 767   JNIHandleBlock* new_handles = old_handles->pop_frame_link();
 768   if (new_handles != NULL) {
 769     // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
 770     // This way code will still work if PopLocalFrame is called without a corresponding
 771     // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
 772     // the release_block call will release the blocks.
 773     thread->set_active_handles(new_handles);
 774     old_handles->set_pop_frame_link(NULL);              // clear link we won't release new_handles below
 775     JNIHandleBlock::release_block(old_handles, thread); // may block
 776     result = JNIHandles::make_local(thread, result_handle());
 777   }
 778   HOTSPOT_JNI_POPLOCALFRAME_RETURN(result);
 779   return result;
 780 JNI_END
 781 
 782 
 783 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
 784   JNIWrapper("NewGlobalRef");
 785 
 786   HOTSPOT_JNI_NEWGLOBALREF_ENTRY(env, ref);
 787 
 788   Handle ref_handle(thread, JNIHandles::resolve(ref));
 789   jobject ret = JNIHandles::make_global(ref_handle);
 790 
 791   HOTSPOT_JNI_NEWGLOBALREF_RETURN(ret);
 792   return ret;
 793 JNI_END
 794 
 795 // Must be JNI_ENTRY (with HandleMark)
 796 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
 797   JNIWrapper("DeleteGlobalRef");
 798 
 799   HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(env, ref);
 800 
 801   JNIHandles::destroy_global(ref);
 802 
 803   HOTSPOT_JNI_DELETEGLOBALREF_RETURN();
 804 JNI_END
 805 
 806 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
 807   JNIWrapper("DeleteLocalRef");
 808 
 809   HOTSPOT_JNI_DELETELOCALREF_ENTRY(env, obj);
 810 
 811   JNIHandles::destroy_local(obj);
 812 
 813   HOTSPOT_JNI_DELETELOCALREF_RETURN();
 814 JNI_END
 815 
 816 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
 817   JNIWrapper("IsSameObject");
 818 
 819   HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2);
 820 
 821   jboolean ret = JNIHandles::is_same_object(r1, r2) ? JNI_TRUE : JNI_FALSE;
 822 
 823   HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret);
 824   return ret;
 825 JNI_END
 826 
 827 
 828 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
 829   JNIWrapper("NewLocalRef");
 830 
 831   HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
 832 
 833   jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
 834 
 835   HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
 836   return ret;
 837 JNI_END
 838 
 839 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
 840   JNIWrapper("EnsureLocalCapacity");
 841 
 842   HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
 843 
 844   jint ret;
 845   if (capacity >= 0 &&
 846       ((MaxJNILocalCapacity <= 0) || (capacity <= MaxJNILocalCapacity))) {
 847     ret = JNI_OK;
 848   } else {
 849     ret = JNI_ERR;
 850   }
 851 
 852   HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(ret);
 853   return ret;
 854 JNI_END
 855 
 856 // Return the Handle Type
 857 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
 858   JNIWrapper("GetObjectRefType");
 859 
 860   HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(env, obj);
 861 
 862   jobjectRefType ret = JNIInvalidRefType;
 863   if (obj != NULL) {
 864     ret = JNIHandles::handle_type(thread, obj);
 865   }
 866 
 867   HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
 868   return ret;
 869 JNI_END
 870 
 871 
 872 class JNI_ArgumentPusher : public SignatureIterator {
 873  protected:
 874   JavaCallArguments*  _arguments;
 875 
 876   virtual void get_bool   () = 0;
 877   virtual void get_char   () = 0;
 878   virtual void get_short  () = 0;
 879   virtual void get_byte   () = 0;
 880   virtual void get_int    () = 0;
 881   virtual void get_long   () = 0;
 882   virtual void get_float  () = 0;
 883   virtual void get_double () = 0;
 884   virtual void get_object () = 0;
 885   virtual void get_valuetype() = 0;
 886 
 887   JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
 888     this->_return_type = T_ILLEGAL;
 889     _arguments = NULL;
 890   }
 891 
 892  public:
 893   virtual void iterate( uint64_t fingerprint ) = 0;
 894 
 895   void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
 896 
 897   inline void do_bool()                     { if (!is_return_type()) get_bool();   }
 898   inline void do_char()                     { if (!is_return_type()) get_char();   }
 899   inline void do_short()                    { if (!is_return_type()) get_short();  }
 900   inline void do_byte()                     { if (!is_return_type()) get_byte();   }
 901   inline void do_int()                      { if (!is_return_type()) get_int();    }
 902   inline void do_long()                     { if (!is_return_type()) get_long();   }
 903   inline void do_float()                    { if (!is_return_type()) get_float();  }
 904   inline void do_double()                   { if (!is_return_type()) get_double(); }
 905   inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }
 906   inline void do_valuetype(int begin, int end) { if (!is_return_type()) get_valuetype();  }
 907   inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
 908   inline void do_void()                     { }
 909 
 910   JavaCallArguments* arguments()     { return _arguments; }
 911   void push_receiver(Handle h)       { _arguments->push_oop(h); }
 912 };
 913 
 914 
 915 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
 916  protected:
 917   va_list _ap;
 918 
 919   inline void get_bool()   {
 920     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
 921     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
 922     // TemplateInterpreterGenerator::generate_result_handler_for and
 923     // SharedRuntime::generate_native_wrapper.
 924     jboolean b = va_arg(_ap, jint);
 925     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
 926   }
 927   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
 928   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
 929   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
 930   inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
 931 
 932   // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
 933 
 934   inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
 935   inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
 936   inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
 937   inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }
 938   inline void get_valuetype() { _arguments->push_jobject(va_arg(_ap, jobject)); }
 939 
 940   inline void set_ap(va_list rap) {
 941     va_copy(_ap, rap);
 942   }
 943 
 944  public:
 945   JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)
 946        : JNI_ArgumentPusher(signature) {
 947     set_ap(rap);
 948   }
 949   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
 950       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
 951     set_ap(rap);
 952   }
 953 
 954   // Optimized path if we have the bitvector form of signature
 955   void iterate( uint64_t fingerprint ) {
 956     if (fingerprint == (uint64_t)CONST64(-1)) {
 957       SignatureIterator::iterate(); // Must be too many arguments
 958     } else {
 959       _return_type = (BasicType)((fingerprint >> static_feature_size) &
 960                                   result_feature_mask);
 961 
 962       assert(fingerprint, "Fingerprint should not be 0");
 963       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
 964       while ( 1 ) {
 965         switch ( fingerprint & parameter_feature_mask ) {
 966           case bool_parm:
 967             get_bool();
 968             break;
 969           case char_parm:
 970             get_char();
 971             break;
 972           case short_parm:
 973             get_short();
 974             break;
 975           case byte_parm:
 976             get_byte();
 977             break;
 978           case int_parm:
 979             get_int();
 980             break;
 981           case obj_parm:
 982             get_object();
 983             break;
 984           case long_parm:
 985             get_long();
 986             break;
 987           case float_parm:
 988             get_float();
 989             break;
 990           case double_parm:
 991             get_double();
 992             break;
 993           case done_parm:
 994             return;
 995             break;
 996           default:
 997             ShouldNotReachHere();
 998             break;
 999         }
1000         fingerprint >>= parameter_feature_size;
1001       }
1002     }
1003   }
1004 };
1005 
1006 
1007 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
1008  protected:
1009   const jvalue *_ap;
1010 
1011   inline void get_bool()   {
1012     // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and
1013     // 0 to JNI_FALSE.  Boolean return values from native are normalized the same in
1014     // TemplateInterpreterGenerator::generate_result_handler_for and
1015     // SharedRuntime::generate_native_wrapper.
1016     jboolean b = (_ap++)->z;
1017     _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));
1018   }
1019   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
1020   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
1021   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
1022   inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
1023 
1024   inline void get_long()   { _arguments->push_long((_ap++)->j);  }
1025   inline void get_float()  { _arguments->push_float((_ap++)->f); }
1026   inline void get_double() { _arguments->push_double((_ap++)->d);}
1027   inline void get_object() { _arguments->push_jobject((_ap++)->l); }
1028   // value types are implemented with oops too
1029   inline void get_valuetype() { _arguments->push_jobject((_ap++)->l); }
1030 
1031   inline void set_ap(const jvalue *rap) { _ap = rap; }
1032 
1033  public:
1034   JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)
1035        : JNI_ArgumentPusher(signature) {
1036     set_ap(rap);
1037   }
1038   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
1039       : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
1040     set_ap(rap);
1041   }
1042 
1043   // Optimized path if we have the bitvector form of signature
1044   void iterate( uint64_t fingerprint ) {
1045     if (fingerprint == (uint64_t)CONST64(-1)) {
1046       SignatureIterator::iterate(); // Must be too many arguments
1047     } else {
1048       _return_type = (BasicType)((fingerprint >> static_feature_size) &
1049                                   result_feature_mask);
1050       assert(fingerprint, "Fingerprint should not be 0");
1051       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
1052       while ( 1 ) {
1053         switch ( fingerprint & parameter_feature_mask ) {
1054           case bool_parm:
1055             get_bool();
1056             break;
1057           case char_parm:
1058             get_char();
1059             break;
1060           case short_parm:
1061             get_short();
1062             break;
1063           case byte_parm:
1064             get_byte();
1065             break;
1066           case int_parm:
1067             get_int();
1068             break;
1069           case obj_parm:
1070             get_object();
1071             break;
1072           case long_parm:
1073             get_long();
1074             break;
1075           case float_parm:
1076             get_float();
1077             break;
1078           case double_parm:
1079             get_double();
1080             break;
1081           case done_parm:
1082             return;
1083             break;
1084           default:
1085             ShouldNotReachHere();
1086             break;
1087         }
1088         fingerprint >>= parameter_feature_size;
1089       }
1090     }
1091   }
1092 };
1093 
1094 
1095 enum JNICallType {
1096   JNI_STATIC,
1097   JNI_VIRTUAL,
1098   JNI_NONVIRTUAL
1099 };
1100 
1101 
1102 
1103 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1104   methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));
1105 
1106   // Create object to hold arguments for the JavaCall, and associate it with
1107   // the jni parser
1108   ResourceMark rm(THREAD);
1109   int number_of_parameters = method->size_of_parameters();
1110   JavaCallArguments java_args(number_of_parameters);
1111   args->set_java_argument_object(&java_args);
1112 
1113   assert(method->is_static(), "method should be static");
1114 
1115   // Fill out JavaCallArguments object
1116   args->iterate( Fingerprinter(method).fingerprint() );
1117   // Initialize result type
1118   result->set_type(args->get_ret_type());
1119 
1120   // Invoke the method. Result is returned as oop.
1121   JavaCalls::call(result, method, &java_args, CHECK);
1122 
1123   // Convert result
1124   if (is_reference_type(result->get_type())) {
1125     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1126   }
1127 }
1128 
1129 
1130 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1131   oop recv = JNIHandles::resolve(receiver);
1132   if (recv == NULL) {
1133     THROW(vmSymbols::java_lang_NullPointerException());
1134   }
1135   Handle h_recv(THREAD, recv);
1136 
1137   int number_of_parameters;
1138   Method* selected_method;
1139   {
1140     Method* m = Method::resolve_jmethod_id(method_id);
1141     number_of_parameters = m->size_of_parameters();
1142     Klass* holder = m->method_holder();
1143     if (call_type != JNI_VIRTUAL) {
1144         selected_method = m;
1145     } else if (!m->has_itable_index()) {
1146       // non-interface call -- for that little speed boost, don't handlize
1147       debug_only(NoSafepointVerifier nosafepoint;)
1148       // jni_GetMethodID makes sure class is linked and initialized
1149       // so m should have a valid vtable index.
1150       assert(m->valid_vtable_index(), "no valid vtable index");
1151       int vtbl_index = m->vtable_index();
1152       if (vtbl_index != Method::nonvirtual_vtable_index) {
1153         selected_method = h_recv->klass()->method_at_vtable(vtbl_index);
1154       } else {
1155         // final method
1156         selected_method = m;
1157       }
1158     } else {
1159       // interface call
1160       int itbl_index = m->itable_index();
1161       Klass* k = h_recv->klass();
1162       selected_method = InstanceKlass::cast(k)->method_at_itable(holder, itbl_index, CHECK);
1163     }
1164   }
1165 
1166   methodHandle method(THREAD, selected_method);
1167 
1168   // Create object to hold arguments for the JavaCall, and associate it with
1169   // the jni parser
1170   ResourceMark rm(THREAD);
1171   JavaCallArguments java_args(number_of_parameters);
1172   args->set_java_argument_object(&java_args);
1173 
1174   // handle arguments
1175   assert(!method->is_static(), "method %s should not be static", method->name_and_sig_as_C_string());
1176   args->push_receiver(h_recv); // Push jobject handle
1177 
1178   // Fill out JavaCallArguments object
1179   args->iterate( Fingerprinter(method).fingerprint() );
1180   // Initialize result type
1181   result->set_type(args->get_ret_type());
1182 
1183   // Invoke the method. Result is returned as oop.
1184   JavaCalls::call(result, method, &java_args, CHECK);
1185 
1186   // Convert result
1187   if (is_reference_type(result->get_type())) {
1188     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1189   }
1190 }
1191 
1192 
1193 static instanceOop alloc_object(jclass clazz, TRAPS) {
1194   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1195   if (k == NULL) {
1196     ResourceMark rm(THREAD);
1197     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1198   }
1199   k->check_valid_for_instantiation(false, CHECK_NULL);
1200   k->initialize(CHECK_NULL);
1201   instanceOop ih = InstanceKlass::cast(k)->allocate_instance(THREAD);
1202   return ih;
1203 }
1204 
1205 DT_RETURN_MARK_DECL(AllocObject, jobject
1206                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1207 
1208 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
1209   JNIWrapper("AllocObject");
1210 
1211   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(env, clazz);
1212 
1213   jobject ret = NULL;
1214   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
1215 
1216   instanceOop i = alloc_object(clazz, CHECK_NULL);
1217   ret = JNIHandles::make_local(env, i);
1218   return ret;
1219 JNI_END
1220 
1221 DT_RETURN_MARK_DECL(NewObjectA, jobject
1222                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
1223 
1224 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
1225   JNIWrapper("NewObjectA");
1226 
1227   HOTSPOT_JNI_NEWOBJECTA_ENTRY(env, clazz, (uintptr_t) methodID);
1228 
1229   jobject obj = NULL;
1230   DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
1231 
1232   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1233   if (k == NULL) {
1234     ResourceMark rm(THREAD);
1235     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1236   }
1237 
1238   if (!k->is_value()) {
1239     instanceOop i = alloc_object(clazz, CHECK_NULL);
1240     obj = JNIHandles::make_local(env, i);
1241     JavaValue jvalue(T_VOID);
1242     JNI_ArgumentPusherArray ap(methodID, args);
1243     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1244   } else {
1245     JavaValue jvalue(T_VALUETYPE);
1246     JNI_ArgumentPusherArray ap(methodID, args);
1247     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1248     obj = jvalue.get_jobject();
1249   }
1250   return obj;
1251   JNI_END
1252 
1253 
1254 DT_RETURN_MARK_DECL(NewObjectV, jobject
1255                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1256 
1257 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1258   JNIWrapper("NewObjectV");
1259 
1260   HOTSPOT_JNI_NEWOBJECTV_ENTRY(env, clazz, (uintptr_t) methodID);
1261 
1262   jobject obj = NULL;
1263   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1264 
1265   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1266   if (k == NULL) {
1267     ResourceMark rm(THREAD);
1268     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1269   }
1270 
1271   if (!k->is_value()) {
1272     instanceOop i = alloc_object(clazz, CHECK_NULL);
1273     obj = JNIHandles::make_local(env, i);
1274     JavaValue jvalue(T_VOID);
1275     JNI_ArgumentPusherVaArg ap(methodID, args);
1276     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1277   } else {
1278     JavaValue jvalue(T_VALUETYPE);
1279     JNI_ArgumentPusherVaArg ap(methodID, args);
1280     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1281     obj = jvalue.get_jobject();
1282   }
1283   return obj;
1284 JNI_END
1285 
1286 
1287 DT_RETURN_MARK_DECL(NewObject, jobject
1288                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1289 
1290 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1291   JNIWrapper("NewObject");
1292 
1293   HOTSPOT_JNI_NEWOBJECT_ENTRY(env, clazz, (uintptr_t) methodID);
1294 
1295   jobject obj = NULL;
1296   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1297 
1298   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1299   if (k == NULL) {
1300     ResourceMark rm(THREAD);
1301     THROW_(vmSymbols::java_lang_InstantiationException(), NULL);
1302   }
1303 
1304   if (!k->is_value()) {
1305     instanceOop i = alloc_object(clazz, CHECK_NULL);
1306     obj = JNIHandles::make_local(env, i);
1307     va_list args;
1308     va_start(args, methodID);
1309     JavaValue jvalue(T_VOID);
1310     JNI_ArgumentPusherVaArg ap(methodID, args);
1311     jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1312     va_end(args);
1313   } else {
1314     va_list args;
1315     va_start(args, methodID);
1316     JavaValue jvalue(T_VALUETYPE);
1317     JNI_ArgumentPusherVaArg ap(methodID, args);
1318     jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_NULL);
1319     va_end(args);
1320     obj = jvalue.get_jobject();
1321   }
1322   return obj;
1323 JNI_END
1324 
1325 
1326 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1327   JNIWrapper("GetObjectClass");
1328 
1329   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(env, obj);
1330 
1331   Klass* k = JNIHandles::resolve_non_null(obj)->klass();
1332   jclass ret =
1333     (jclass) JNIHandles::make_local(env, k->java_mirror());
1334 
1335   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
1336   return ret;
1337 JNI_END
1338 
1339 JNI_ENTRY_NO_PRESERVE(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1340   JNIWrapper("IsInstanceOf");
1341 
1342   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
1343 
1344   jboolean ret = JNI_TRUE;
1345   if (obj != NULL) {
1346     ret = JNI_FALSE;
1347     Klass* k = java_lang_Class::as_Klass(
1348       JNIHandles::resolve_non_null(clazz));
1349     if (k != NULL) {
1350       ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
1351     }
1352   }
1353 
1354   HOTSPOT_JNI_ISINSTANCEOF_RETURN(ret);
1355   return ret;
1356 JNI_END
1357 
1358 
1359 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
1360                                const char *sig, bool is_static, TRAPS) {
1361   // %%%% This code should probably just call into a method in the LinkResolver
1362   //
1363   // The class should have been loaded (we have an instance of the class
1364   // passed in) so the method and signature should already be in the symbol
1365   // table.  If they're not there, the method doesn't exist.
1366   const char *name_to_probe = (name_str == NULL)
1367                         ? vmSymbols::object_initializer_name()->as_C_string()
1368                         : name_str;
1369   TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));
1370   TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));
1371 
1372   if (name == NULL || signature == NULL) {
1373     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1374   }
1375 
1376   Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1377 
1378   // Throw a NoSuchMethodError exception if we have an instance of a
1379   // primitive java.lang.Class
1380   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
1381     ResourceMark rm;
1382     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
1383   }
1384 
1385   // Make sure class is linked and initialized before handing id's out to
1386   // Method*s.
1387   klass->initialize(CHECK_NULL);
1388 
1389   Method* m;
1390   if (name == vmSymbols::object_initializer_name() ||
1391       name == vmSymbols::class_initializer_name()) {
1392     // Never search superclasses for constructors
1393     if (klass->is_instance_klass()) {
1394       m = InstanceKlass::cast(klass)->find_method(name, signature);
1395     } else {
1396       m = NULL;
1397     }
1398   } else {
1399     m = klass->lookup_method(name, signature);
1400     if (m == NULL &&  klass->is_instance_klass()) {
1401       m = InstanceKlass::cast(klass)->lookup_method_in_ordered_interfaces(name, signature);
1402     }
1403   }
1404   if (m == NULL || (m->is_static() != is_static)) {
1405     ResourceMark rm;
1406     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
1407   }
1408   return m->jmethod_id();
1409 }
1410 
1411 
1412 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
1413           const char *name, const char *sig))
1414   JNIWrapper("GetMethodID");
1415   HOTSPOT_JNI_GETMETHODID_ENTRY(env, clazz, (char *) name, (char *) sig);
1416   jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
1417   HOTSPOT_JNI_GETMETHODID_RETURN((uintptr_t) ret);
1418   return ret;
1419 JNI_END
1420 
1421 
1422 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
1423           const char *name, const char *sig))
1424   JNIWrapper("GetStaticMethodID");
1425   HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(env, (char *) clazz, (char *) name, (char *)sig);
1426   jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
1427   HOTSPOT_JNI_GETSTATICMETHODID_RETURN((uintptr_t) ret);
1428   return ret;
1429 JNI_END
1430 
1431 
1432 
1433 //
1434 // Calling Methods
1435 //
1436 
1437 
1438 #define DEFINE_CALLMETHOD(ResultType, Result, Tag \
1439                           , EntryProbe, ReturnProbe)    \
1440 \
1441   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \
1442                           , ReturnProbe);                          \
1443 \
1444 JNI_ENTRY(ResultType, \
1445           jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
1446   JNIWrapper("Call" XSTR(Result) "Method"); \
1447 \
1448   EntryProbe; \
1449   ResultType ret = 0;\
1450   DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
1451                      (const ResultType&)ret);\
1452 \
1453   va_list args; \
1454   va_start(args, methodID); \
1455   JavaValue jvalue(Tag); \
1456   JNI_ArgumentPusherVaArg ap(methodID, args); \
1457   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1458   va_end(args); \
1459   ret = jvalue.get_##ResultType(); \
1460   return ret;\
1461 JNI_END
1462 
1463 // the runtime type of subword integral basic types is integer
1464 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
1465                   , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1466                   HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1467 DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE
1468                   , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1469                   HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1470 DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR
1471                   , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1472                   HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1473 DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT
1474                   , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1475                   HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1476 
1477 DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT
1478                   , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1479                   HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1480 DEFINE_CALLMETHOD(jint,     Int,     T_INT,
1481                   HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1482                   HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1483 DEFINE_CALLMETHOD(jlong,    Long,    T_LONG
1484                   , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1485                   HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
1486 // Float and double probes don't return value because dtrace doesn't currently support it
1487 DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT
1488                   , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1489                   HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1490 DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE
1491                   , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1492                   HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1493 
1494 #define DEFINE_CALLMETHODV(ResultType, Result, Tag \
1495                           , EntryProbe, ReturnProbe)    \
1496 \
1497   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \
1498                           , ReturnProbe);                          \
1499 \
1500 JNI_ENTRY(ResultType, \
1501           jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
1502   JNIWrapper("Call" XSTR(Result) "MethodV"); \
1503 \
1504   EntryProbe;\
1505   ResultType ret = 0;\
1506   DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
1507                      (const ResultType&)ret);\
1508 \
1509   JavaValue jvalue(Tag); \
1510   JNI_ArgumentPusherVaArg ap(methodID, args); \
1511   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1512   ret = jvalue.get_##ResultType(); \
1513   return ret;\
1514 JNI_END
1515 
1516 // the runtime type of subword integral basic types is integer
1517 DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
1518                   , HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1519                   HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN(_ret_ref))
1520 DEFINE_CALLMETHODV(jbyte,    Byte,    T_BYTE
1521                   , HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1522                   HOTSPOT_JNI_CALLBYTEMETHODV_RETURN(_ret_ref))
1523 DEFINE_CALLMETHODV(jchar,    Char,    T_CHAR
1524                   , HOTSPOT_JNI_CALLCHARMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1525                   HOTSPOT_JNI_CALLCHARMETHODV_RETURN(_ret_ref))
1526 DEFINE_CALLMETHODV(jshort,   Short,   T_SHORT
1527                   , HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1528                   HOTSPOT_JNI_CALLSHORTMETHODV_RETURN(_ret_ref))
1529 
1530 DEFINE_CALLMETHODV(jobject,  Object,  T_OBJECT
1531                   , HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1532                   HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN(_ret_ref))
1533 DEFINE_CALLMETHODV(jint,     Int,     T_INT,
1534                   HOTSPOT_JNI_CALLINTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1535                   HOTSPOT_JNI_CALLINTMETHODV_RETURN(_ret_ref))
1536 DEFINE_CALLMETHODV(jlong,    Long,    T_LONG
1537                   , HOTSPOT_JNI_CALLLONGMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1538                   HOTSPOT_JNI_CALLLONGMETHODV_RETURN(_ret_ref))
1539 // Float and double probes don't return value because dtrace doesn't currently support it
1540 DEFINE_CALLMETHODV(jfloat,   Float,   T_FLOAT
1541                   , HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1542                   HOTSPOT_JNI_CALLFLOATMETHODV_RETURN())
1543 DEFINE_CALLMETHODV(jdouble,  Double,  T_DOUBLE
1544                   , HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),
1545                   HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN())
1546 
1547 #define DEFINE_CALLMETHODA(ResultType, Result, Tag \
1548                           , EntryProbe, ReturnProbe)    \
1549 \
1550   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \
1551                           , ReturnProbe);                          \
1552 \
1553 JNI_ENTRY(ResultType, \
1554           jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
1555   JNIWrapper("Call" XSTR(Result) "MethodA"); \
1556   EntryProbe; \
1557   ResultType ret = 0;\
1558   DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
1559                      (const ResultType&)ret);\
1560 \
1561   JavaValue jvalue(Tag); \
1562   JNI_ArgumentPusherArray ap(methodID, args); \
1563   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1564   ret = jvalue.get_##ResultType(); \
1565   return ret;\
1566 JNI_END
1567 
1568 // the runtime type of subword integral basic types is integer
1569 DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
1570                   , HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1571                   HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN(_ret_ref))
1572 DEFINE_CALLMETHODA(jbyte,    Byte,    T_BYTE
1573                   , HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1574                   HOTSPOT_JNI_CALLBYTEMETHODA_RETURN(_ret_ref))
1575 DEFINE_CALLMETHODA(jchar,    Char,    T_CHAR
1576                   , HOTSPOT_JNI_CALLCHARMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1577                   HOTSPOT_JNI_CALLCHARMETHODA_RETURN(_ret_ref))
1578 DEFINE_CALLMETHODA(jshort,   Short,   T_SHORT
1579                   , HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1580                   HOTSPOT_JNI_CALLSHORTMETHODA_RETURN(_ret_ref))
1581 
1582 DEFINE_CALLMETHODA(jobject,  Object,  T_OBJECT
1583                   , HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1584                   HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN(_ret_ref))
1585 DEFINE_CALLMETHODA(jint,     Int,     T_INT,
1586                   HOTSPOT_JNI_CALLINTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1587                   HOTSPOT_JNI_CALLINTMETHODA_RETURN(_ret_ref))
1588 DEFINE_CALLMETHODA(jlong,    Long,    T_LONG
1589                   , HOTSPOT_JNI_CALLLONGMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1590                   HOTSPOT_JNI_CALLLONGMETHODA_RETURN(_ret_ref))
1591 // Float and double probes don't return value because dtrace doesn't currently support it
1592 DEFINE_CALLMETHODA(jfloat,   Float,   T_FLOAT
1593                   , HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1594                   HOTSPOT_JNI_CALLFLOATMETHODA_RETURN())
1595 DEFINE_CALLMETHODA(jdouble,  Double,  T_DOUBLE
1596                   , HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),
1597                   HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN())
1598 
1599 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
1600 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
1601 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
1602 
1603 
1604 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
1605   JNIWrapper("CallVoidMethod");
1606   HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(env, obj, (uintptr_t) methodID);
1607   DT_VOID_RETURN_MARK(CallVoidMethod);
1608 
1609   va_list args;
1610   va_start(args, methodID);
1611   JavaValue jvalue(T_VOID);
1612   JNI_ArgumentPusherVaArg ap(methodID, args);
1613   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1614   va_end(args);
1615 JNI_END
1616 
1617 
1618 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
1619   JNIWrapper("CallVoidMethodV");
1620   HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(env, obj, (uintptr_t) methodID);
1621   DT_VOID_RETURN_MARK(CallVoidMethodV);
1622 
1623   JavaValue jvalue(T_VOID);
1624   JNI_ArgumentPusherVaArg ap(methodID, args);
1625   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1626 JNI_END
1627 
1628 
1629 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
1630   JNIWrapper("CallVoidMethodA");
1631   HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(env, obj, (uintptr_t) methodID);
1632   DT_VOID_RETURN_MARK(CallVoidMethodA);
1633 
1634   JavaValue jvalue(T_VOID);
1635   JNI_ArgumentPusherArray ap(methodID, args);
1636   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1637 JNI_END
1638 
1639 
1640 
1641 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \
1642                                     , EntryProbe, ReturnProbe)      \
1643 \
1644   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \
1645                           , ReturnProbe);\
1646 \
1647 JNI_ENTRY(ResultType, \
1648           jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
1649   JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
1650 \
1651   EntryProbe;\
1652   ResultType ret;\
1653   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
1654                      (const ResultType&)ret);\
1655 \
1656   va_list args; \
1657   va_start(args, methodID); \
1658   JavaValue jvalue(Tag); \
1659   JNI_ArgumentPusherVaArg ap(methodID, args); \
1660   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1661   va_end(args); \
1662   ret = jvalue.get_##ResultType(); \
1663   return ret;\
1664 JNI_END
1665 
1666 // the runtime type of subword integral basic types is integer
1667 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
1668                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1669                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
1670 DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE
1671                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1672                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
1673 DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR
1674                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1675                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
1676 DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT
1677                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1678                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
1679 
1680 DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT
1681                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1682                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
1683 DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT
1684                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1685                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
1686 DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG
1687                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1688 // Float and double probes don't return value because dtrace doesn't currently support it
1689                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))
1690 DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT
1691                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1692                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
1693 DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE
1694                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
1695                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())
1696 
1697 #define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \
1698                                     , EntryProbe, ReturnProbe)      \
1699 \
1700   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \
1701                           , ReturnProbe);\
1702 \
1703 JNI_ENTRY(ResultType, \
1704           jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
1705   JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \
1706 \
1707   EntryProbe;\
1708   ResultType ret;\
1709   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
1710                      (const ResultType&)ret);\
1711 \
1712   JavaValue jvalue(Tag); \
1713   JNI_ArgumentPusherVaArg ap(methodID, args); \
1714   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1715   ret = jvalue.get_##ResultType(); \
1716   return ret;\
1717 JNI_END
1718 
1719 // the runtime type of subword integral basic types is integer
1720 DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
1721                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1722                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
1723 DEFINE_CALLNONVIRTUALMETHODV(jbyte,    Byte,    T_BYTE
1724                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1725                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
1726 DEFINE_CALLNONVIRTUALMETHODV(jchar,    Char,    T_CHAR
1727                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1728                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
1729 DEFINE_CALLNONVIRTUALMETHODV(jshort,   Short,   T_SHORT
1730                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1731                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
1732 
1733 DEFINE_CALLNONVIRTUALMETHODV(jobject,  Object,  T_OBJECT
1734                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1735                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
1736 DEFINE_CALLNONVIRTUALMETHODV(jint,     Int,     T_INT
1737                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1738                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
1739 DEFINE_CALLNONVIRTUALMETHODV(jlong,    Long,    T_LONG
1740                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1741 // Float and double probes don't return value because dtrace doesn't currently support it
1742                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))
1743 DEFINE_CALLNONVIRTUALMETHODV(jfloat,   Float,   T_FLOAT
1744                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1745                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
1746 DEFINE_CALLNONVIRTUALMETHODV(jdouble,  Double,  T_DOUBLE
1747                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
1748                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())
1749 
1750 #define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \
1751                                     , EntryProbe, ReturnProbe)      \
1752 \
1753   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \
1754                           , ReturnProbe);\
1755 \
1756 JNI_ENTRY(ResultType, \
1757           jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
1758   JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
1759 \
1760   EntryProbe;\
1761   ResultType ret;\
1762   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
1763                      (const ResultType&)ret);\
1764 \
1765   JavaValue jvalue(Tag); \
1766   JNI_ArgumentPusherArray ap(methodID, args); \
1767   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1768   ret = jvalue.get_##ResultType(); \
1769   return ret;\
1770 JNI_END
1771 
1772 // the runtime type of subword integral basic types is integer
1773 DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
1774                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1775                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
1776 DEFINE_CALLNONVIRTUALMETHODA(jbyte,    Byte,    T_BYTE
1777                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1778                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
1779 DEFINE_CALLNONVIRTUALMETHODA(jchar,    Char,    T_CHAR
1780                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1781                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
1782 DEFINE_CALLNONVIRTUALMETHODA(jshort,   Short,   T_SHORT
1783                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1784                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
1785 
1786 DEFINE_CALLNONVIRTUALMETHODA(jobject,  Object,  T_OBJECT
1787                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1788                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
1789 DEFINE_CALLNONVIRTUALMETHODA(jint,     Int,     T_INT
1790                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1791                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
1792 DEFINE_CALLNONVIRTUALMETHODA(jlong,    Long,    T_LONG
1793                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1794 // Float and double probes don't return value because dtrace doesn't currently support it
1795                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))
1796 DEFINE_CALLNONVIRTUALMETHODA(jfloat,   Float,   T_FLOAT
1797                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1798                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
1799 DEFINE_CALLNONVIRTUALMETHODA(jdouble,  Double,  T_DOUBLE
1800                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
1801                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
1802 
1803 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
1804                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
1805 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
1806                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
1807 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
1808                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
1809 
1810 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
1811   JNIWrapper("CallNonvirtualVoidMethod");
1812 
1813   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(env, obj, cls, (uintptr_t) methodID);
1814   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
1815 
1816   va_list args;
1817   va_start(args, methodID);
1818   JavaValue jvalue(T_VOID);
1819   JNI_ArgumentPusherVaArg ap(methodID, args);
1820   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1821   va_end(args);
1822 JNI_END
1823 
1824 
1825 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
1826   JNIWrapper("CallNonvirtualVoidMethodV");
1827 
1828   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
1829                env, obj, cls, (uintptr_t) methodID);
1830   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
1831 
1832   JavaValue jvalue(T_VOID);
1833   JNI_ArgumentPusherVaArg ap(methodID, args);
1834   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1835 JNI_END
1836 
1837 
1838 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
1839   JNIWrapper("CallNonvirtualVoidMethodA");
1840   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(
1841                 env, obj, cls, (uintptr_t) methodID);
1842   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
1843   JavaValue jvalue(T_VOID);
1844   JNI_ArgumentPusherArray ap(methodID, args);
1845   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
1846 JNI_END
1847 
1848 
1849 
1850 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \
1851                                 , EntryProbe, ResultProbe) \
1852 \
1853   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \
1854                           , ResultProbe);                               \
1855 \
1856 JNI_ENTRY(ResultType, \
1857           jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
1858   JNIWrapper("CallStatic" XSTR(Result) "Method"); \
1859 \
1860   EntryProbe; \
1861   ResultType ret = 0;\
1862   DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
1863                      (const ResultType&)ret);\
1864 \
1865   va_list args; \
1866   va_start(args, methodID); \
1867   JavaValue jvalue(Tag); \
1868   JNI_ArgumentPusherVaArg ap(methodID, args); \
1869   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1870   va_end(args); \
1871   ret = jvalue.get_##ResultType(); \
1872   return ret;\
1873 JNI_END
1874 
1875 // the runtime type of subword integral basic types is integer
1876 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
1877                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1878                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
1879 DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE
1880                         , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1881                         HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
1882 DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR
1883                         , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1884                         HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
1885 DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT
1886                         , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1887                         HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
1888 
1889 DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT
1890                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1891                         HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
1892 DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT
1893                         , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1894                         HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
1895 DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG
1896                         , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1897                         HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));
1898 // Float and double probes don't return value because dtrace doesn't currently support it
1899 DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT
1900                         , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1901                         HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
1902 DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE
1903                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
1904                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());
1905 
1906 #define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \
1907                                 , EntryProbe, ResultProbe) \
1908 \
1909   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \
1910                           , ResultProbe);                               \
1911 \
1912 JNI_ENTRY(ResultType, \
1913           jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
1914   JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
1915 \
1916   EntryProbe; \
1917   ResultType ret = 0;\
1918   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
1919                      (const ResultType&)ret);\
1920 \
1921   JavaValue jvalue(Tag); \
1922   JNI_ArgumentPusherVaArg ap(methodID, args); \
1923   /* Make sure class is initialized before trying to invoke its method */ \
1924   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); \
1925   k->initialize(CHECK_0); \
1926   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1927   va_end(args); \
1928   ret = jvalue.get_##ResultType(); \
1929   return ret;\
1930 JNI_END
1931 
1932 // the runtime type of subword integral basic types is integer
1933 DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
1934                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1935                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
1936 DEFINE_CALLSTATICMETHODV(jbyte,    Byte,    T_BYTE
1937                         , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1938                         HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
1939 DEFINE_CALLSTATICMETHODV(jchar,    Char,    T_CHAR
1940                         , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1941                         HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
1942 DEFINE_CALLSTATICMETHODV(jshort,   Short,   T_SHORT
1943                         , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1944                         HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
1945 
1946 DEFINE_CALLSTATICMETHODV(jobject,  Object,  T_OBJECT
1947                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1948                         HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
1949 DEFINE_CALLSTATICMETHODV(jint,     Int,     T_INT
1950                         , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1951                         HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
1952 DEFINE_CALLSTATICMETHODV(jlong,    Long,    T_LONG
1953                         , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1954                         HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));
1955 // Float and double probes don't return value because dtrace doesn't currently support it
1956 DEFINE_CALLSTATICMETHODV(jfloat,   Float,   T_FLOAT
1957                         , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1958                         HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
1959 DEFINE_CALLSTATICMETHODV(jdouble,  Double,  T_DOUBLE
1960                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
1961                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());
1962 
1963 #define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \
1964                                 , EntryProbe, ResultProbe) \
1965 \
1966   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \
1967                           , ResultProbe);                               \
1968 \
1969 JNI_ENTRY(ResultType, \
1970           jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
1971   JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
1972 \
1973   EntryProbe; \
1974   ResultType ret = 0;\
1975   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
1976                      (const ResultType&)ret);\
1977 \
1978   JavaValue jvalue(Tag); \
1979   JNI_ArgumentPusherArray ap(methodID, args); \
1980   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
1981   ret = jvalue.get_##ResultType(); \
1982   return ret;\
1983 JNI_END
1984 
1985 // the runtime type of subword integral basic types is integer
1986 DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
1987                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1988                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
1989 DEFINE_CALLSTATICMETHODA(jbyte,    Byte,    T_BYTE
1990                         , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1991                         HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
1992 DEFINE_CALLSTATICMETHODA(jchar,    Char,    T_CHAR
1993                         , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1994                         HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
1995 DEFINE_CALLSTATICMETHODA(jshort,   Short,   T_SHORT
1996                         , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
1997                         HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
1998 
1999 DEFINE_CALLSTATICMETHODA(jobject,  Object,  T_OBJECT
2000                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2001                         HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
2002 DEFINE_CALLSTATICMETHODA(jint,     Int,     T_INT
2003                         , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2004                         HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
2005 DEFINE_CALLSTATICMETHODA(jlong,    Long,    T_LONG
2006                         , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2007                         HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));
2008 // Float and double probes don't return value because dtrace doesn't currently support it
2009 DEFINE_CALLSTATICMETHODA(jfloat,   Float,   T_FLOAT
2010                         , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2011                         HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
2012 DEFINE_CALLSTATICMETHODA(jdouble,  Double,  T_DOUBLE
2013                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2014                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
2015 
2016 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
2017                          , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
2018 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
2019                          , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
2020 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
2021                          , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
2022 
2023 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
2024   JNIWrapper("CallStaticVoidMethod");
2025   HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(env, cls, (uintptr_t) methodID);
2026   DT_VOID_RETURN_MARK(CallStaticVoidMethod);
2027 
2028   va_list args;
2029   va_start(args, methodID);
2030   JavaValue jvalue(T_VOID);
2031   JNI_ArgumentPusherVaArg ap(methodID, args);
2032   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2033   va_end(args);
2034 JNI_END
2035 
2036 
2037 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
2038   JNIWrapper("CallStaticVoidMethodV");
2039   HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(env, cls, (uintptr_t) methodID);
2040   DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
2041 
2042   JavaValue jvalue(T_VOID);
2043   JNI_ArgumentPusherVaArg ap(methodID, args);
2044   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2045 JNI_END
2046 
2047 
2048 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
2049   JNIWrapper("CallStaticVoidMethodA");
2050   HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(env, cls, (uintptr_t) methodID);
2051   DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
2052 
2053   JavaValue jvalue(T_VOID);
2054   JNI_ArgumentPusherArray ap(methodID, args);
2055   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2056 JNI_END
2057 
2058 
2059 //
2060 // Accessing Fields
2061 //
2062 
2063 
2064 DT_RETURN_MARK_DECL(GetFieldID, jfieldID
2065                     , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
2066 
2067 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
2068           const char *name, const char *sig))
2069   JNIWrapper("GetFieldID");
2070   HOTSPOT_JNI_GETFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
2071   jfieldID ret = 0;
2072   DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
2073 
2074   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
2075 
2076   // The class should have been loaded (we have an instance of the class
2077   // passed in) so the field and signature should already be in the symbol
2078   // table.  If they're not there, the field doesn't exist.
2079   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2080   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2081   if (fieldname == NULL || signame == NULL) {
2082     ResourceMark rm;
2083     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2084   }
2085 
2086   // Make sure class is initialized before handing id's out to fields
2087   k->initialize(CHECK_NULL);
2088 
2089   fieldDescriptor fd;
2090   if (!k->is_instance_klass() ||
2091       !InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
2092     ResourceMark rm;
2093     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
2094   }
2095 
2096   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2097   // It may also have hash bits for k, if VerifyJNIFields is turned on.
2098   ret = jfieldIDWorkaround::to_instance_jfieldID(k, fd.offset(), fd.is_flattened());
2099   return ret;
2100 JNI_END
2101 
2102 
2103 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2104   JNIWrapper("GetObjectField");
2105   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID);
2106   oop o = JNIHandles::resolve_non_null(obj);
2107   Klass* k = o->klass();
2108   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2109   oop res = NULL;
2110   // Keep JVMTI addition small and only check enabled flag here.
2111   // jni_GetField_probe() assumes that is okay to create handles.
2112   if (JvmtiExport::should_post_field_access()) {
2113     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2114   }
2115   if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
2116     res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
2117   } else {
2118     assert(k->is_instance_klass(), "Only instance can have flattened fields");
2119     InstanceKlass* ik = InstanceKlass::cast(k);
2120     fieldDescriptor fd;
2121     ik->find_field_from_offset(offset, false, &fd);  // performance bottleneck
2122     InstanceKlass* holder = fd.field_holder();
2123     ValueKlass* field_vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
2124     res = field_vklass->read_flattened_field(o, ik->field_offset(fd.index()), CHECK_NULL);
2125   }
2126   jobject ret = JNIHandles::make_local(env, res);
2127   HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
2128   return ret;
2129 JNI_END
2130 
2131 
2132 
2133 #define DEFINE_GETFIELD(Return,Fieldname,Result \
2134   , EntryProbe, ReturnProbe) \
2135 \
2136   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
2137   , ReturnProbe); \
2138 \
2139 JNI_ENTRY_NO_PRESERVE(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2140   JNIWrapper("Get" XSTR(Result) "Field"); \
2141 \
2142   EntryProbe; \
2143   Return ret = 0;\
2144   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2145 \
2146   oop o = JNIHandles::resolve_non_null(obj); \
2147   Klass* k = o->klass(); \
2148   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2149   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2150   /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
2151   /* and creates a ResetNoHandleMark.                                   */ \
2152   if (JvmtiExport::should_post_field_access()) { \
2153     o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
2154   } \
2155   ret = o->Fieldname##_field(offset); \
2156   return ret; \
2157 JNI_END
2158 
2159 DEFINE_GETFIELD(jboolean, bool,   Boolean
2160                 , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2161                 HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
2162 DEFINE_GETFIELD(jbyte,    byte,   Byte
2163                 , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2164                 HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
2165 DEFINE_GETFIELD(jchar,    char,   Char
2166                 , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2167                 HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
2168 DEFINE_GETFIELD(jshort,   short,  Short
2169                 , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2170                 HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
2171 DEFINE_GETFIELD(jint,     int,    Int
2172                 , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2173                 HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
2174 DEFINE_GETFIELD(jlong,    long,   Long
2175                 , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2176                 HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))
2177 // Float and double probes don't return value because dtrace doesn't currently support it
2178 DEFINE_GETFIELD(jfloat,   float,  Float
2179                 , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2180                 HOTSPOT_JNI_GETFLOATFIELD_RETURN())
2181 DEFINE_GETFIELD(jdouble,  double, Double
2182                 , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2183                 HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
2184 
2185 address jni_GetBooleanField_addr() {
2186   return (address)jni_GetBooleanField;
2187 }
2188 address jni_GetByteField_addr() {
2189   return (address)jni_GetByteField;
2190 }
2191 address jni_GetCharField_addr() {
2192   return (address)jni_GetCharField;
2193 }
2194 address jni_GetShortField_addr() {
2195   return (address)jni_GetShortField;
2196 }
2197 address jni_GetIntField_addr() {
2198   return (address)jni_GetIntField;
2199 }
2200 address jni_GetLongField_addr() {
2201   return (address)jni_GetLongField;
2202 }
2203 address jni_GetFloatField_addr() {
2204   return (address)jni_GetFloatField;
2205 }
2206 address jni_GetDoubleField_addr() {
2207   return (address)jni_GetDoubleField;
2208 }
2209 
2210 JNI_ENTRY_NO_PRESERVE(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2211   JNIWrapper("SetObjectField");
2212   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value);
2213   oop o = JNIHandles::resolve_non_null(obj);
2214   Klass* k = o->klass();
2215   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2216   // Keep JVMTI addition small and only check enabled flag here.
2217   // jni_SetField_probe_nh() assumes that is not okay to create handles
2218   // and creates a ResetNoHandleMark.
2219   if (JvmtiExport::should_post_field_modification()) {
2220     jvalue field_value;
2221     field_value.l = value;
2222     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
2223   }
2224   if (!jfieldIDWorkaround::is_flattened_field(fieldID)) {
2225     HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(o, offset, JNIHandles::resolve(value));
2226   } else {
2227     assert(k->is_instance_klass(), "Only instances can have flattened fields");
2228     InstanceKlass* ik = InstanceKlass::cast(k);
2229     fieldDescriptor fd;
2230     ik->find_field_from_offset(offset, false, &fd);
2231     InstanceKlass* holder = fd.field_holder();
2232     ValueKlass* vklass = ValueKlass::cast(holder->get_value_field_klass(fd.index()));
2233     oop v = JNIHandles::resolve_non_null(value);
2234     vklass->write_flattened_field(o, offset, v, CHECK);
2235   }
2236   HOTSPOT_JNI_SETOBJECTFIELD_RETURN();
2237 JNI_END
2238 
2239 
2240 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2241                         , EntryProbe, ReturnProbe) \
2242 \
2243 JNI_ENTRY_NO_PRESERVE(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2244   JNIWrapper("Set" XSTR(Result) "Field"); \
2245 \
2246   EntryProbe; \
2247 \
2248   oop o = JNIHandles::resolve_non_null(obj); \
2249   Klass* k = o->klass(); \
2250   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2251   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2252   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2253   /* and creates a ResetNoHandleMark.                                   */ \
2254   if (JvmtiExport::should_post_field_modification()) { \
2255     jvalue field_value; \
2256     field_value.unionType = value; \
2257     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2258   } \
2259   if (SigType == JVM_SIGNATURE_BOOLEAN) { value = ((jboolean)value) & 1; } \
2260   o->Fieldname##_field_put(offset, value); \
2261   ReturnProbe; \
2262 JNI_END
2263 
2264 DEFINE_SETFIELD(jboolean, bool,   Boolean, JVM_SIGNATURE_BOOLEAN, z
2265                 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2266                 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2267 DEFINE_SETFIELD(jbyte,    byte,   Byte,    JVM_SIGNATURE_BYTE, b
2268                 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2269                 HOTSPOT_JNI_SETBYTEFIELD_RETURN())
2270 DEFINE_SETFIELD(jchar,    char,   Char,    JVM_SIGNATURE_CHAR, c
2271                 , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2272                 HOTSPOT_JNI_SETCHARFIELD_RETURN())
2273 DEFINE_SETFIELD(jshort,   short,  Short,   JVM_SIGNATURE_SHORT, s
2274                 , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2275                 HOTSPOT_JNI_SETSHORTFIELD_RETURN())
2276 DEFINE_SETFIELD(jint,     int,    Int,     JVM_SIGNATURE_INT, i
2277                 , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2278                 HOTSPOT_JNI_SETINTFIELD_RETURN())
2279 DEFINE_SETFIELD(jlong,    long,   Long,    JVM_SIGNATURE_LONG, j
2280                 , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2281                 HOTSPOT_JNI_SETLONGFIELD_RETURN())
2282 // Float and double probes don't return value because dtrace doesn't currently support it
2283 DEFINE_SETFIELD(jfloat,   float,  Float,   JVM_SIGNATURE_FLOAT, f
2284                 , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2285                 HOTSPOT_JNI_SETFLOATFIELD_RETURN())
2286 DEFINE_SETFIELD(jdouble,  double, Double,  JVM_SIGNATURE_DOUBLE, d
2287                 , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2288                 HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
2289 
2290 DT_RETURN_MARK_DECL(ToReflectedField, jobject
2291                     , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
2292 
2293 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
2294   JNIWrapper("ToReflectedField");
2295   HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(env, cls, (uintptr_t) fieldID, isStatic);
2296   jobject ret = NULL;
2297   DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
2298 
2299   fieldDescriptor fd;
2300   bool found = false;
2301   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2302 
2303   assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
2304 
2305   if (isStatic) {
2306     // Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*.
2307     JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2308     assert(id->is_static_field_id(), "invalid static field id");
2309     found = id->find_local_field(&fd);
2310   } else {
2311     // Non-static field. The fieldID is really the offset of the field within the instanceOop.
2312     int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2313     found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
2314   }
2315   assert(found, "bad fieldID passed into jni_ToReflectedField");
2316   oop reflected = Reflection::new_field(&fd, CHECK_NULL);
2317   ret = JNIHandles::make_local(env, reflected);
2318   return ret;
2319 JNI_END
2320 
2321 
2322 //
2323 // Accessing Static Fields
2324 //
2325 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
2326                     , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
2327 
2328 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
2329           const char *name, const char *sig))
2330   JNIWrapper("GetStaticFieldID");
2331   HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig);
2332   jfieldID ret = NULL;
2333   DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
2334 
2335   // The class should have been loaded (we have an instance of the class
2336   // passed in) so the field and signature should already be in the symbol
2337   // table.  If they're not there, the field doesn't exist.
2338   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2339   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2340   if (fieldname == NULL || signame == NULL) {
2341     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2342   }
2343   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
2344   // Make sure class is initialized before handing id's out to static fields
2345   k->initialize(CHECK_NULL);
2346 
2347   fieldDescriptor fd;
2348   if (!k->is_instance_klass() ||
2349       !InstanceKlass::cast(k)->find_field(fieldname, signame, true, &fd)) {
2350     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2351   }
2352 
2353   // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
2354   JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
2355   debug_only(id->set_is_static_field_id();)
2356 
2357   debug_only(id->verify(fd.field_holder()));
2358 
2359   ret = jfieldIDWorkaround::to_static_jfieldID(id);
2360   return ret;
2361 JNI_END
2362 
2363 
2364 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2365   JNIWrapper("GetStaticObjectField");
2366   HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID);
2367 #if INCLUDE_JNI_CHECK
2368   DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
2369 #endif // INCLUDE_JNI_CHECK
2370   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2371   assert(id->is_static_field_id(), "invalid static field id");
2372   // Keep JVMTI addition small and only check enabled flag here.
2373   // jni_GetField_probe() assumes that is okay to create handles.
2374   if (JvmtiExport::should_post_field_access()) {
2375     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
2376   }
2377   jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
2378   HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(ret);
2379   return ret;
2380 JNI_END
2381 
2382 
2383 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \
2384                               , EntryProbe, ReturnProbe) \
2385 \
2386   DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \
2387                           , ReturnProbe);                                          \
2388 \
2389 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
2390   JNIWrapper("GetStatic" XSTR(Result) "Field"); \
2391   EntryProbe; \
2392   Return ret = 0;\
2393   DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
2394                      (const Return&)ret);\
2395   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
2396   assert(id->is_static_field_id(), "invalid static field id"); \
2397   /* Keep JVMTI addition small and only check enabled flag here. */ \
2398   /* jni_GetField_probe() assumes that is okay to create handles. */ \
2399   if (JvmtiExport::should_post_field_access()) { \
2400     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
2401   } \
2402   ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
2403   return ret;\
2404 JNI_END
2405 
2406 DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean
2407                       , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
2408 DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte
2409                       , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref)   )
2410 DEFINE_GETSTATICFIELD(jchar,    char,   Char
2411                       , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref)   )
2412 DEFINE_GETSTATICFIELD(jshort,   short,  Short
2413                       , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref)  )
2414 DEFINE_GETSTATICFIELD(jint,     int,    Int
2415                       , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),     HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref)    )
2416 DEFINE_GETSTATICFIELD(jlong,    long,   Long
2417                       , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref)   )
2418 // Float and double probes don't return value because dtrace doesn't currently support it
2419 DEFINE_GETSTATICFIELD(jfloat,   float,  Float
2420                       , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN()          )
2421 DEFINE_GETSTATICFIELD(jdouble,  double, Double
2422                       , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),  HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN()         )
2423 
2424 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
2425   JNIWrapper("SetStaticObjectField");
2426  HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value);
2427   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2428   assert(id->is_static_field_id(), "invalid static field id");
2429   // Keep JVMTI addition small and only check enabled flag here.
2430   // jni_SetField_probe() assumes that is okay to create handles.
2431   if (JvmtiExport::should_post_field_modification()) {
2432     jvalue field_value;
2433     field_value.l = value;
2434     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, JVM_SIGNATURE_CLASS, (jvalue *)&field_value);
2435   }
2436   id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
2437   HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN();
2438 JNI_END
2439 
2440 
2441 
2442 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
2443                               , EntryProbe, ReturnProbe) \
2444 \
2445 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
2446   JNIWrapper("SetStatic" XSTR(Result) "Field"); \
2447   EntryProbe; \
2448 \
2449   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
2450   assert(id->is_static_field_id(), "invalid static field id"); \
2451   /* Keep JVMTI addition small and only check enabled flag here. */ \
2452   /* jni_SetField_probe() assumes that is okay to create handles. */ \
2453   if (JvmtiExport::should_post_field_modification()) { \
2454     jvalue field_value; \
2455     field_value.unionType = value; \
2456     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
2457   } \
2458   if (SigType == JVM_SIGNATURE_BOOLEAN) { value = ((jboolean)value) & 1; } \
2459   id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
2460   ReturnProbe;\
2461 JNI_END
2462 
2463 DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, JVM_SIGNATURE_BOOLEAN, z
2464                       , HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
2465                       HOTSPOT_JNI_SETSTATICBOOLEANFIELD_RETURN())
2466 DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    JVM_SIGNATURE_BYTE, b
2467                       , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2468                       HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
2469 DEFINE_SETSTATICFIELD(jchar,    char,   Char,    JVM_SIGNATURE_CHAR, c
2470                       , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2471                       HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
2472 DEFINE_SETSTATICFIELD(jshort,   short,  Short,   JVM_SIGNATURE_SHORT, s
2473                       , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2474                       HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
2475 DEFINE_SETSTATICFIELD(jint,     int,    Int,     JVM_SIGNATURE_INT, i
2476                       , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2477                       HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
2478 DEFINE_SETSTATICFIELD(jlong,    long,   Long,    JVM_SIGNATURE_LONG, j
2479                       , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
2480                       HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())
2481 // Float and double probes don't return value because dtrace doesn't currently support it
2482 DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   JVM_SIGNATURE_FLOAT, f
2483                       , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
2484                       HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
2485 DEFINE_SETSTATICFIELD(jdouble,  double, Double,  JVM_SIGNATURE_DOUBLE, d
2486                       , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
2487                       HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())
2488 
2489 //
2490 // String Operations
2491 //
2492 
2493 // Unicode Interface
2494 
2495 DT_RETURN_MARK_DECL(NewString, jstring
2496                     , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
2497 
2498 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
2499   JNIWrapper("NewString");
2500  HOTSPOT_JNI_NEWSTRING_ENTRY(env, (uint16_t *) unicodeChars, len);
2501   jstring ret = NULL;
2502   DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
2503   oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
2504   ret = (jstring) JNIHandles::make_local(env, string);
2505   return ret;
2506 JNI_END
2507 
2508 
2509 JNI_ENTRY_NO_PRESERVE(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
2510   JNIWrapper("GetStringLength");
2511   HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
2512   jsize ret = 0;
2513   oop s = JNIHandles::resolve_non_null(string);
2514   ret = java_lang_String::length(s);
2515  HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
2516   return ret;
2517 JNI_END
2518 
2519 
2520 JNI_ENTRY_NO_PRESERVE(const jchar*, jni_GetStringChars(
2521   JNIEnv *env, jstring string, jboolean *isCopy))
2522   JNIWrapper("GetStringChars");
2523  HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2524   jchar* buf = NULL;
2525   oop s = JNIHandles::resolve_non_null(string);
2526   typeArrayOop s_value = java_lang_String::value(s);
2527   if (s_value != NULL) {
2528     int s_len = java_lang_String::length(s, s_value);
2529     bool is_latin1 = java_lang_String::is_latin1(s);
2530     buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
2531     /* JNI Specification states return NULL on OOM */
2532     if (buf != NULL) {
2533       if (s_len > 0) {
2534         if (!is_latin1) {
2535           ArrayAccess<>::arraycopy_to_native(s_value, (size_t) typeArrayOopDesc::element_offset<jchar>(0),
2536                                              buf, s_len);
2537         } else {
2538           for (int i = 0; i < s_len; i++) {
2539             buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
2540           }
2541         }
2542       }
2543       buf[s_len] = 0;
2544       //%note jni_5
2545       if (isCopy != NULL) {
2546         *isCopy = JNI_TRUE;
2547       }
2548     }
2549   }
2550   HOTSPOT_JNI_GETSTRINGCHARS_RETURN(buf);
2551   return buf;
2552 JNI_END
2553 
2554 
2555 JNI_ENTRY_NO_PRESERVE(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
2556   JNIWrapper("ReleaseStringChars");
2557   HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(env, str, (uint16_t *) chars);
2558   //%note jni_6
2559   if (chars != NULL) {
2560     // Since String objects are supposed to be immutable, don't copy any
2561     // new data back.  A bad user will have to go after the char array.
2562     FreeHeap((void*) chars);
2563   }
2564   HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN();
2565 JNI_END
2566 
2567 
2568 // UTF Interface
2569 
2570 DT_RETURN_MARK_DECL(NewStringUTF, jstring
2571                     , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
2572 
2573 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
2574   JNIWrapper("NewStringUTF");
2575   HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(env, (char *) bytes);
2576   jstring ret;
2577   DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
2578 
2579   oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
2580   ret = (jstring) JNIHandles::make_local(env, result);
2581   return ret;
2582 JNI_END
2583 
2584 
2585 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
2586   JNIWrapper("GetStringUTFLength");
2587  HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(env, string);
2588   oop java_string = JNIHandles::resolve_non_null(string);
2589   jsize ret = java_lang_String::utf8_length(java_string);
2590   HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(ret);
2591   return ret;
2592 JNI_END
2593 
2594 
2595 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
2596   JNIWrapper("GetStringUTFChars");
2597  HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
2598   char* result = NULL;
2599   oop java_string = JNIHandles::resolve_non_null(string);
2600   typeArrayOop s_value = java_lang_String::value(java_string);
2601   if (s_value != NULL) {
2602     size_t length = java_lang_String::utf8_length(java_string, s_value);
2603     /* JNI Specification states return NULL on OOM */
2604     result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
2605     if (result != NULL) {
2606       java_lang_String::as_utf8_string(java_string, s_value, result, (int) length + 1);
2607       if (isCopy != NULL) {
2608         *isCopy = JNI_TRUE;
2609       }
2610     }
2611   }
2612  HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(result);
2613   return result;
2614 JNI_END
2615 
2616 
2617 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
2618   JNIWrapper("ReleaseStringUTFChars");
2619  HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(env, str, (char *) chars);
2620   if (chars != NULL) {
2621     FreeHeap((char*) chars);
2622   }
2623 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN();
2624 JNI_END
2625 
2626 
2627 JNI_ENTRY_NO_PRESERVE(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
2628   JNIWrapper("GetArrayLength");
2629  HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array);
2630   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
2631   assert(a->is_array(), "must be array");
2632   jsize ret = a->length();
2633  HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret);
2634   return ret;
2635 JNI_END
2636 
2637 
2638 //
2639 // Object Array Operations
2640 //
2641 
2642 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
2643                     , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
2644 
2645 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
2646   JNIWrapper("NewObjectArray");
2647  HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(env, length, elementClass, initialElement);
2648   jobjectArray ret = NULL;
2649   DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
2650   Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass));
2651   Klass* ak = ek->array_klass(CHECK_NULL);
2652   ObjArrayKlass::cast(ak)->initialize(CHECK_NULL);
2653   objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL);
2654   oop initial_value = JNIHandles::resolve(initialElement);
2655   if (initial_value != NULL) {  // array already initialized with NULL
2656     for (int index = 0; index < length; index++) {
2657       result->obj_at_put(index, initial_value);
2658     }
2659   }
2660   ret = (jobjectArray) JNIHandles::make_local(env, result);
2661   return ret;
2662 JNI_END
2663 
2664 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
2665                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
2666 
2667 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
2668   JNIWrapper("GetObjectArrayElement");
2669  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(env, array, index);
2670   jobject ret = NULL;
2671   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
2672   oop res = NULL;
2673   arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2674   if (arr->is_within_bounds(index)) {
2675     if (arr->is_valueArray()) {
2676       valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
2677       arrayHandle ah(THREAD, a);
2678       valueArrayHandle vah(thread, a);
2679       res = valueArrayOopDesc::value_alloc_copy_from_index(vah, index, CHECK_NULL);
2680       assert(res != NULL, "Must be set in one of two paths above");
2681     } else {
2682       assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2683       objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2684       res = a->obj_at(index);
2685     }
2686   } else {
2687     ResourceMark rm(THREAD);
2688     stringStream ss;
2689     ss.print("Index %d out of bounds for length %d", index,arr->length());
2690     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2691   }
2692   ret = JNIHandles::make_local(env, res);
2693   return ret;
2694 JNI_END
2695 
2696 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
2697                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
2698 
2699 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
2700   JNIWrapper("SetObjectArrayElement");
2701   HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(env, array, index, value);
2702   DT_VOID_RETURN_MARK(SetObjectArrayElement);
2703 
2704    bool oob = false;
2705    int length = -1;
2706    oop res = NULL;
2707    arrayOop arr((arrayOop)JNIHandles::resolve_non_null(array));
2708    if (arr->is_within_bounds(index)) {
2709      if (arr->is_valueArray()) {
2710        valueArrayOop a = valueArrayOop(JNIHandles::resolve_non_null(array));
2711        oop v = JNIHandles::resolve(value);
2712        ValueArrayKlass* vaklass = ValueArrayKlass::cast(a->klass());
2713        ValueKlass* element_vklass = vaklass->element_klass();
2714        if (v != NULL && v->is_a(element_vklass)) {
2715          a->value_copy_to_index(v, index);
2716        } else {
2717          ResourceMark rm(THREAD);
2718          stringStream ss;
2719          Klass *kl = ValueArrayKlass::cast(a->klass());
2720          ss.print("type mismatch: can not store %s to %s[%d]",
2721              v->klass()->external_name(),
2722              kl->external_name(),
2723              index);
2724          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2725            ss.print("[]");
2726          }
2727          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2728        }
2729      } else {
2730        assert(arr->is_objArray(), "If not a valueArray. must be an objArray");
2731        objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
2732        oop v = JNIHandles::resolve(value);
2733        if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
2734          a->obj_at_put(index, v);
2735        } else {
2736          ResourceMark rm(THREAD);
2737          stringStream ss;
2738          Klass *bottom_kl = ObjArrayKlass::cast(a->klass())->bottom_klass();
2739          ss.print("type mismatch: can not store %s to %s[%d]",
2740              v->klass()->external_name(),
2741              bottom_kl->is_typeArray_klass() ? type2name_tab[ArrayKlass::cast(bottom_kl)->element_type()] : bottom_kl->external_name(),
2742                  index);
2743          for (int dims = ArrayKlass::cast(a->klass())->dimension(); dims > 1; --dims) {
2744            ss.print("[]");
2745          }
2746          THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
2747        }
2748      }
2749    } else {
2750      ResourceMark rm(THREAD);
2751      stringStream ss;
2752      ss.print("Index %d out of bounds for length %d", index, arr->length());
2753      THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2754    }
2755 JNI_END
2756 
2757 
2758 
2759 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
2760                               ,EntryProbe,ReturnProbe)  \
2761 \
2762   DT_RETURN_MARK_DECL(New##Result##Array, Return \
2763                       , ReturnProbe); \
2764 \
2765 JNI_ENTRY(Return, \
2766           jni_New##Result##Array(JNIEnv *env, jsize len)) \
2767   JNIWrapper("New" XSTR(Result) "Array"); \
2768   EntryProbe; \
2769   Return ret = NULL;\
2770   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
2771 \
2772   oop obj= oopFactory::Allocator(len, CHECK_0); \
2773   ret = (Return) JNIHandles::make_local(env, obj); \
2774   return ret;\
2775 JNI_END
2776 
2777 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean,
2778                       HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
2779                       HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
2780 DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte,
2781                       HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
2782                       HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
2783 DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short,
2784                       HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
2785                       HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
2786 DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char,
2787                       HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
2788                       HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
2789 DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int,
2790                       HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
2791                       HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
2792 DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long,
2793                       HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
2794                       HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
2795 DEFINE_NEWSCALARARRAY(jfloatArray,   new_floatArray,  Float,
2796                       HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
2797                       HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
2798 DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double,
2799                       HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),
2800                       HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))
2801 
2802 // Return an address which will fault if the caller writes to it.
2803 
2804 static char* get_bad_address() {
2805   static char* bad_address = NULL;
2806   if (bad_address == NULL) {
2807     size_t size = os::vm_allocation_granularity();
2808     bad_address = os::reserve_memory(size);
2809     if (bad_address != NULL) {
2810       os::protect_memory(bad_address, size, os::MEM_PROT_READ,
2811                          /*is_committed*/false);
2812       MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);
2813     }
2814   }
2815   return bad_address;
2816 }
2817 
2818 
2819 
2820 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
2821                                       , EntryProbe, ReturnProbe) \
2822 \
2823 JNI_ENTRY_NO_PRESERVE(ElementType*, \
2824           jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
2825   JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
2826   EntryProbe; \
2827   /* allocate an chunk of memory in c land */ \
2828   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2829   ElementType* result; \
2830   int len = a->length(); \
2831   if (len == 0) { \
2832     if (isCopy != NULL) { \
2833       *isCopy = JNI_FALSE; \
2834     } \
2835     /* Empty array: legal but useless, can't return NULL. \
2836      * Return a pointer to something useless. \
2837      * Avoid asserts in typeArrayOop. */ \
2838     result = (ElementType*)get_bad_address(); \
2839   } else { \
2840     /* JNI Specification states return NULL on OOM */                    \
2841     result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
2842     if (result != NULL) {                                                \
2843       /* copy the array to the c chunk */                                \
2844       ArrayAccess<>::arraycopy_to_native(a, typeArrayOopDesc::element_offset<ElementType>(0), \
2845                                          result, len);                   \
2846       if (isCopy) {                                                      \
2847         *isCopy = JNI_TRUE;                                              \
2848       }                                                                  \
2849     }                                                                    \
2850   } \
2851   ReturnProbe; \
2852   return result; \
2853 JNI_END
2854 
2855 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2856                               , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2857                               HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
2858 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
2859                               , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2860                               HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
2861 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
2862                               , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
2863                               HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))
2864 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
2865                               , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
2866                               HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
2867 DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
2868                               , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2869                               HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
2870 DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
2871                               , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2872                               HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
2873 // Float and double probes don't return value because dtrace doesn't currently support it
2874 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
2875                               , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2876                               HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
2877 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
2878                               , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
2879                               HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
2880 
2881 
2882 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
2883                                           , EntryProbe, ReturnProbe);\
2884 \
2885 JNI_ENTRY_NO_PRESERVE(void, \
2886           jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
2887                                              ElementType *buf, jint mode)) \
2888   JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
2889   EntryProbe; \
2890   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2891   int len = a->length(); \
2892   if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
2893     if ((mode == 0) || (mode == JNI_COMMIT)) { \
2894       ArrayAccess<>::arraycopy_from_native(buf, a, typeArrayOopDesc::element_offset<ElementType>(0), len); \
2895     } \
2896     if ((mode == 0) || (mode == JNI_ABORT)) { \
2897       FreeHeap(buf); \
2898     } \
2899   } \
2900   ReturnProbe; \
2901 JNI_END
2902 
2903 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
2904                                   , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2905                                   HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
2906 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
2907                                   , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
2908                                   HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
2909 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
2910                                   ,  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2911                                   HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
2912 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
2913                                   ,  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
2914                                   HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
2915 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
2916                                   , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
2917                                   HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
2918 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
2919                                   , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
2920                                   HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
2921 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
2922                                   , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
2923                                   HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
2924 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
2925                                   , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
2926                                   HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
2927 
2928 static void check_bounds(jsize start, jsize copy_len, jsize array_len, TRAPS) {
2929   ResourceMark rm(THREAD);
2930   if (copy_len < 0) {
2931     stringStream ss;
2932     ss.print("Length %d is negative", copy_len);
2933     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2934   } else if (start < 0 || (start > array_len - copy_len)) {
2935     stringStream ss;
2936     ss.print("Array region %d.." INT64_FORMAT " out of bounds for length %d",
2937              start, (int64_t)start+(int64_t)copy_len, array_len);
2938     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
2939   }
2940 }
2941 
2942 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2943                                     , EntryProbe, ReturnProbe); \
2944   DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
2945                            , ReturnProbe); \
2946 \
2947 JNI_ENTRY(void, \
2948 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2949              jsize len, ElementType *buf)) \
2950   JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
2951   EntryProbe; \
2952   DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
2953   typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2954   check_bounds(start, len, src->length(), CHECK); \
2955   if (len > 0) {    \
2956     ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
2957   } \
2958 JNI_END
2959 
2960 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
2961                             , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2962                             HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
2963 DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte
2964                             ,  HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
2965                             HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
2966 DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short
2967                             , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
2968                             HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
2969 DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char
2970                             ,  HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
2971                             HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
2972 DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int
2973                             , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
2974                             HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
2975 DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long
2976                             ,  HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
2977                             HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
2978 DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float
2979                             , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
2980                             HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
2981 DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double
2982                             , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
2983                             HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
2984 
2985 
2986 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
2987                                     , EntryProbe, ReturnProbe); \
2988   DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
2989                            ,ReturnProbe);           \
2990 \
2991 JNI_ENTRY(void, \
2992 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
2993              jsize len, const ElementType *buf)) \
2994   JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
2995   EntryProbe; \
2996   DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
2997   typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
2998   check_bounds(start, len, dst->length(), CHECK); \
2999   if (len > 0) { \
3000     ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
3001   } \
3002 JNI_END
3003 
3004 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
3005                             , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
3006                             HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
3007 DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte
3008                             , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
3009                             HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
3010 DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short
3011                             , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3012                             HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
3013 DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char
3014                             , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3015                             HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
3016 DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int
3017                             , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
3018                             HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
3019 DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long
3020                             , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3021                             HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
3022 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
3023                             , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3024                             HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
3025 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double
3026                             , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
3027                             HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
3028 
3029 
3030 DT_RETURN_MARK_DECL(RegisterNatives, jint
3031                     , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
3032 
3033 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
3034                                     const JNINativeMethod *methods,
3035                                     jint nMethods))
3036   JNIWrapper("RegisterNatives");
3037   HOTSPOT_JNI_REGISTERNATIVES_ENTRY(env, clazz, (void *) methods, nMethods);
3038   jint ret = 0;
3039   DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
3040 
3041   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
3042 
3043   for (int index = 0; index < nMethods; index++) {
3044     const char* meth_name = methods[index].name;
3045     const char* meth_sig = methods[index].signature;
3046     int meth_name_len = (int)strlen(meth_name);
3047 
3048     // The class should have been loaded (we have an instance of the class
3049     // passed in) so the method and signature should already be in the symbol
3050     // table.  If they're not there, the method doesn't exist.
3051     TempNewSymbol  name = SymbolTable::probe(meth_name, meth_name_len);
3052     TempNewSymbol  signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
3053 
3054     if (name == NULL || signature == NULL) {
3055       ResourceMark rm;
3056       stringStream st;
3057       st.print("Method %s.%s%s not found", k->external_name(), meth_name, meth_sig);
3058       // Must return negative value on failure
3059       THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
3060     }
3061 
3062     bool res = Method::register_native(k, name, signature,
3063                                        (address) methods[index].fnPtr, THREAD);
3064     if (!res) {
3065       ret = -1;
3066       break;
3067     }
3068   }
3069   return ret;
3070 JNI_END
3071 
3072 
3073 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
3074   JNIWrapper("UnregisterNatives");
3075  HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(env, clazz);
3076   Klass* k   = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
3077   //%note jni_2
3078   if (k->is_instance_klass()) {
3079     for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
3080       Method* m = InstanceKlass::cast(k)->methods()->at(index);
3081       if (m->is_native()) {
3082         m->clear_native_function();
3083         m->set_signature_handler(NULL);
3084       }
3085     }
3086   }
3087  HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(0);
3088   return 0;
3089 JNI_END
3090 
3091 //
3092 // Monitor functions
3093 //
3094 
3095 DT_RETURN_MARK_DECL(MonitorEnter, jint
3096                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
3097 
3098 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
3099  HOTSPOT_JNI_MONITORENTER_ENTRY(env, jobj);
3100   jint ret = JNI_ERR;
3101   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
3102 
3103   // If the object is null, we can't do anything with it
3104   if (jobj == NULL) {
3105     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3106   }
3107 
3108   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
3109   ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
3110   ret = JNI_OK;
3111   return ret;
3112 JNI_END
3113 
3114 DT_RETURN_MARK_DECL(MonitorExit, jint
3115                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
3116 
3117 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
3118  HOTSPOT_JNI_MONITOREXIT_ENTRY(env, jobj);
3119   jint ret = JNI_ERR;
3120   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
3121 
3122   // Don't do anything with a null object
3123   if (jobj == NULL) {
3124     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
3125   }
3126 
3127   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
3128   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
3129 
3130   ret = JNI_OK;
3131   return ret;
3132 JNI_END
3133 
3134 //
3135 // Extensions
3136 //
3137 
3138 DT_VOID_RETURN_MARK_DECL(GetStringRegion
3139                          , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
3140 
3141 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
3142   JNIWrapper("GetStringRegion");
3143  HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
3144   DT_VOID_RETURN_MARK(GetStringRegion);
3145   oop s = JNIHandles::resolve_non_null(string);
3146   typeArrayOop s_value = java_lang_String::value(s);
3147   int s_len = java_lang_String::length(s, s_value);
3148   if (start < 0 || len < 0 || start > s_len - len) {
3149     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3150   } else {
3151     if (len > 0) {
3152       bool is_latin1 = java_lang_String::is_latin1(s);
3153       if (!is_latin1) {
3154         ArrayAccess<>::arraycopy_to_native(s_value, typeArrayOopDesc::element_offset<jchar>(start),
3155                                            buf, len);
3156       } else {
3157         for (int i = 0; i < len; i++) {
3158           buf[i] = ((jchar) s_value->byte_at(i + start)) & 0xff;
3159         }
3160       }
3161     }
3162   }
3163 JNI_END
3164 
3165 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
3166                          , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
3167 
3168 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
3169   JNIWrapper("GetStringUTFRegion");
3170  HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
3171   DT_VOID_RETURN_MARK(GetStringUTFRegion);
3172   oop s = JNIHandles::resolve_non_null(string);
3173   typeArrayOop s_value = java_lang_String::value(s);
3174   int s_len = java_lang_String::length(s, s_value);
3175   if (start < 0 || len < 0 || start > s_len - len) {
3176     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
3177   } else {
3178     //%note jni_7
3179     if (len > 0) {
3180       // Assume the buffer is large enough as the JNI spec. does not require user error checking
3181       java_lang_String::as_utf8_string(s, s_value, start, len, buf, INT_MAX);
3182       // as_utf8_string null-terminates the result string
3183     } else {
3184       // JDK null-terminates the buffer even in len is zero
3185       if (buf != NULL) {
3186         buf[0] = 0;
3187       }
3188     }
3189   }
3190 JNI_END
3191 
3192 static oop lock_gc_or_pin_object(JavaThread* thread, jobject obj) {
3193   if (Universe::heap()->supports_object_pinning()) {
3194     const oop o = JNIHandles::resolve_non_null(obj);
3195     return Universe::heap()->pin_object(thread, o);
3196   } else {
3197     GCLocker::lock_critical(thread);
3198     return JNIHandles::resolve_non_null(obj);
3199   }
3200 }
3201 
3202 static void unlock_gc_or_unpin_object(JavaThread* thread, jobject obj) {
3203   if (Universe::heap()->supports_object_pinning()) {
3204     const oop o = JNIHandles::resolve_non_null(obj);
3205     return Universe::heap()->unpin_object(thread, o);
3206   } else {
3207     GCLocker::unlock_critical(thread);
3208   }
3209 }
3210 
3211 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
3212   JNIWrapper("GetPrimitiveArrayCritical");
3213  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(env, array, (uintptr_t *) isCopy);
3214   if (isCopy != NULL) {
3215     *isCopy = JNI_FALSE;
3216   }
3217   oop a = lock_gc_or_pin_object(thread, array);
3218   assert(a->is_array(), "just checking");
3219   BasicType type;
3220   if (a->is_objArray()) {
3221     type = T_OBJECT;
3222   } else {
3223     type = TypeArrayKlass::cast(a->klass())->element_type();
3224   }
3225   void* ret = arrayOop(a)->base(type);
3226  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(ret);
3227   return ret;
3228 JNI_END
3229 
3230 
3231 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
3232   JNIWrapper("ReleasePrimitiveArrayCritical");
3233   HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(env, array, carray, mode);
3234   unlock_gc_or_unpin_object(thread, array);
3235 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN();
3236 JNI_END
3237 
3238 
3239 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
3240   JNIWrapper("GetStringCritical");
3241   HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
3242   oop s = lock_gc_or_pin_object(thread, string);
3243   typeArrayOop s_value = java_lang_String::value(s);
3244   bool is_latin1 = java_lang_String::is_latin1(s);
3245   if (isCopy != NULL) {
3246     *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE;
3247   }
3248   jchar* ret;
3249   if (!is_latin1) {
3250     ret = (jchar*) s_value->base(T_CHAR);
3251   } else {
3252     // Inflate latin1 encoded string to UTF16
3253     int s_len = java_lang_String::length(s, s_value);
3254     ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
3255     /* JNI Specification states return NULL on OOM */
3256     if (ret != NULL) {
3257       for (int i = 0; i < s_len; i++) {
3258         ret[i] = ((jchar) s_value->byte_at(i)) & 0xff;
3259       }
3260       ret[s_len] = 0;
3261     }
3262   }
3263  HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
3264   return ret;
3265 JNI_END
3266 
3267 
3268 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
3269   JNIWrapper("ReleaseStringCritical");
3270   HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
3271   // The str and chars arguments are ignored for UTF16 strings
3272   oop s = JNIHandles::resolve_non_null(str);
3273   bool is_latin1 = java_lang_String::is_latin1(s);
3274   if (is_latin1) {
3275     // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
3276     // This assumes that ReleaseStringCritical bookends GetStringCritical.
3277     FREE_C_HEAP_ARRAY(jchar, chars);
3278   }
3279   unlock_gc_or_unpin_object(thread, str);
3280 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
3281 JNI_END
3282 
3283 
3284 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
3285   JNIWrapper("jni_NewWeakGlobalRef");
3286  HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
3287   Handle ref_handle(thread, JNIHandles::resolve(ref));
3288   jweak ret = JNIHandles::make_weak_global(ref_handle);
3289  HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
3290   return ret;
3291 JNI_END
3292 
3293 // Must be JNI_ENTRY (with HandleMark)
3294 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
3295   JNIWrapper("jni_DeleteWeakGlobalRef");
3296   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(env, ref);
3297   JNIHandles::destroy_weak_global(ref);
3298   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN();
3299 JNI_END
3300 
3301 
3302 JNI_ENTRY_NO_PRESERVE(jboolean, jni_ExceptionCheck(JNIEnv *env))
3303   JNIWrapper("jni_ExceptionCheck");
3304  HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(env);
3305   jni_check_async_exceptions(thread);
3306   jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
3307  HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(ret);
3308   return ret;
3309 JNI_END
3310 
3311 
3312 // Initialization state for three routines below relating to
3313 // java.nio.DirectBuffers
3314 static          int directBufferSupportInitializeStarted = 0;
3315 static volatile int directBufferSupportInitializeEnded   = 0;
3316 static volatile int directBufferSupportInitializeFailed  = 0;
3317 static jclass    bufferClass                 = NULL;
3318 static jclass    directBufferClass           = NULL;
3319 static jclass    directByteBufferClass       = NULL;
3320 static jmethodID directByteBufferConstructor = NULL;
3321 static jfieldID  directBufferAddressField    = NULL;
3322 static jfieldID  bufferCapacityField         = NULL;
3323 
3324 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
3325   Handle loader;            // null (bootstrap) loader
3326   Handle protection_domain; // null protection domain
3327 
3328   TempNewSymbol sym = SymbolTable::new_symbol(name);
3329   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
3330 
3331   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
3332     trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
3333   }
3334   return result;
3335 }
3336 
3337 // These lookups are done with the NULL (bootstrap) ClassLoader to
3338 // circumvent any security checks that would be done by jni_FindClass.
3339 JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))
3340 {
3341   if ((bufferClass           = lookupOne(env, "java/nio/Buffer", thread))           == NULL) { return false; }
3342   if ((directBufferClass     = lookupOne(env, "sun/nio/ch/DirectBuffer", thread))   == NULL) { return false; }
3343   if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }
3344   return true;
3345 }
3346 JNI_END
3347 
3348 
3349 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
3350   if (directBufferSupportInitializeFailed) {
3351     return false;
3352   }
3353 
3354   if (Atomic::cmpxchg(&directBufferSupportInitializeStarted, 0, 1) == 0) {
3355     if (!lookupDirectBufferClasses(env)) {
3356       directBufferSupportInitializeFailed = 1;
3357       return false;
3358     }
3359 
3360     // Make global references for these
3361     bufferClass           = (jclass) env->NewGlobalRef(bufferClass);
3362     directBufferClass     = (jclass) env->NewGlobalRef(directBufferClass);
3363     directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
3364 
3365     // Get needed field and method IDs
3366     directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
3367     if (env->ExceptionCheck()) {
3368       env->ExceptionClear();
3369       directBufferSupportInitializeFailed = 1;
3370       return false;
3371     }
3372     directBufferAddressField    = env->GetFieldID(bufferClass, "address", "J");
3373     if (env->ExceptionCheck()) {
3374       env->ExceptionClear();
3375       directBufferSupportInitializeFailed = 1;
3376       return false;
3377     }
3378     bufferCapacityField         = env->GetFieldID(bufferClass, "capacity", "I");
3379     if (env->ExceptionCheck()) {
3380       env->ExceptionClear();
3381       directBufferSupportInitializeFailed = 1;
3382       return false;
3383     }
3384 
3385     if ((directByteBufferConstructor == NULL) ||
3386         (directBufferAddressField    == NULL) ||
3387         (bufferCapacityField         == NULL)) {
3388       directBufferSupportInitializeFailed = 1;
3389       return false;
3390     }
3391 
3392     directBufferSupportInitializeEnded = 1;
3393   } else {
3394     while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
3395       os::naked_yield();
3396     }
3397   }
3398 
3399   return !directBufferSupportInitializeFailed;
3400 }
3401 
3402 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
3403 {
3404   // thread_from_jni_environment() will block if VM is gone.
3405   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3406 
3407   JNIWrapper("jni_NewDirectByteBuffer");
3408  HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(env, address, capacity);
3409 
3410   if (!directBufferSupportInitializeEnded) {
3411     if (!initializeDirectBufferSupport(env, thread)) {
3412       HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(NULL);
3413       return NULL;
3414     }
3415   }
3416 
3417   // Being paranoid about accidental sign extension on address
3418   jlong addr = (jlong) ((uintptr_t) address);
3419   // NOTE that package-private DirectByteBuffer constructor currently
3420   // takes int capacity
3421   jint  cap  = (jint)  capacity;
3422   jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
3423   HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(ret);
3424   return ret;
3425 }
3426 
3427 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
3428                     , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
3429 
3430 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3431 {
3432   // thread_from_jni_environment() will block if VM is gone.
3433   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3434 
3435   JNIWrapper("jni_GetDirectBufferAddress");
3436   HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(env, buf);
3437   void* ret = NULL;
3438   DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
3439 
3440   if (!directBufferSupportInitializeEnded) {
3441     if (!initializeDirectBufferSupport(env, thread)) {
3442       return 0;
3443     }
3444   }
3445 
3446   if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
3447     return 0;
3448   }
3449 
3450   ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
3451   return ret;
3452 }
3453 
3454 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
3455                     , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
3456 
3457 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
3458 {
3459   // thread_from_jni_environment() will block if VM is gone.
3460   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
3461 
3462   JNIWrapper("jni_GetDirectBufferCapacity");
3463   HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(env, buf);
3464   jlong ret = -1;
3465   DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
3466 
3467   if (!directBufferSupportInitializeEnded) {
3468     if (!initializeDirectBufferSupport(env, thread)) {
3469       ret = 0;
3470       return ret;
3471     }
3472   }
3473 
3474   if (buf == NULL) {
3475     return -1;
3476   }
3477 
3478   if (!env->IsInstanceOf(buf, directBufferClass)) {
3479     return -1;
3480   }
3481 
3482   // NOTE that capacity is currently an int in the implementation
3483   ret = env->GetIntField(buf, bufferCapacityField);
3484   return ret;
3485 }
3486 
3487 
3488 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
3489   JNIWrapper("GetVersion");
3490   HOTSPOT_JNI_GETVERSION_ENTRY(env);
3491   HOTSPOT_JNI_GETVERSION_RETURN(CurrentVersion);
3492   return CurrentVersion;
3493 JNI_END
3494 
3495 extern struct JavaVM_ main_vm;
3496 
3497 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
3498   JNIWrapper("jni_GetJavaVM");
3499   HOTSPOT_JNI_GETJAVAVM_ENTRY(env, (void **) vm);
3500   *vm  = (JavaVM *)(&main_vm);
3501   HOTSPOT_JNI_GETJAVAVM_RETURN(JNI_OK);
3502   return JNI_OK;
3503 JNI_END
3504 
3505 
3506 JNI_ENTRY(jobject, jni_GetModule(JNIEnv* env, jclass clazz))
3507   JNIWrapper("GetModule");
3508   return Modules::get_module(clazz, THREAD);
3509 JNI_END
3510 
3511 
3512 JNI_ENTRY(void*, jni_GetFlattenedArrayElements(JNIEnv* env, jarray array, jboolean* isCopy))
3513   JNIWrapper("jni_GetFlattenedArrayElements");
3514   if (isCopy != NULL) {
3515     *isCopy = JNI_FALSE;
3516   }
3517   arrayOop ar = arrayOop(JNIHandles::resolve_non_null(array));
3518   if (!ar->is_array()) {
3519     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not an array");
3520   }
3521   if (!ar->is_valueArray()) {
3522     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not a flattened array");
3523   }
3524   ValueArrayKlass* vak = ValueArrayKlass::cast(ar->klass());
3525   if (vak->contains_oops()) {
3526     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Flattened array contains oops");
3527   }
3528   oop a = lock_gc_or_pin_object(thread, array);
3529   valueArrayOop vap = valueArrayOop(a);
3530   void* ret = vap->value_at_addr(0, vak->layout_helper());
3531   return ret;
3532 JNI_END
3533 
3534 JNI_ENTRY(void, jni_ReleaseFlattenedArrayElements(JNIEnv* env, jarray array, void* elem, jint mode))
3535   JNIWrapper("jni_ReleaseFlattenedArrayElements");
3536   unlock_gc_or_unpin_object(thread, array);
3537 JNI_END
3538 
3539 JNI_ENTRY(jsize, jni_GetFlattenedArrayElementSize(JNIEnv* env, jarray array)) {
3540   JNIWrapper("jni_GetFlattenedElementSize");
3541   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
3542   if (!a->is_array()) {
3543     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Not an array");
3544   }
3545   if (!a->is_valueArray()) {
3546     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Not a flattened array");
3547   }
3548   ValueArrayKlass* vak = ValueArrayKlass::cast(a->klass());
3549   jsize ret = vak->element_byte_size();
3550   return ret;
3551 }
3552 JNI_END
3553 
3554 JNI_ENTRY(jclass, jni_GetFlattenedArrayElementClass(JNIEnv* env, jarray array))
3555   JNIWrapper("jni_GetArrayElementClass");
3556   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
3557   if (!a->is_array()) {
3558     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not an array");
3559   }
3560   if (!a->is_valueArray()) {
3561     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "Not a flattened array");
3562   }
3563   ValueArrayKlass* vak = ValueArrayKlass::cast(a->klass());
3564   ValueKlass* vk = vak->element_klass();
3565   return (jclass) JNIHandles::make_local(vk->java_mirror());
3566 JNI_END
3567 
3568 JNI_ENTRY(jsize, jni_GetFieldOffsetInFlattenedLayout(JNIEnv* env, jclass clazz, const char *name, const char *signature, jboolean* isFlattened))
3569   JNIWrapper("jni_GetFieldOffsetInFlattenedLayout");
3570 
3571   oop mirror = JNIHandles::resolve_non_null(clazz);
3572   Klass* k = java_lang_Class::as_Klass(mirror);
3573   if (!k->is_value()) {
3574     ResourceMark rm;
3575         THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("%s has not flattened layout", k->external_name()));
3576   }
3577   ValueKlass* vk = ValueKlass::cast(k);
3578 
3579   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
3580   TempNewSymbol signame = SymbolTable::probe(signature, (int)strlen(signature));
3581   if (fieldname == NULL || signame == NULL) {
3582     ResourceMark rm;
3583     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", vk->external_name(), name, signature));
3584   }
3585 
3586   assert(vk->is_initialized(), "If a flattened array has been created, the element klass must have been initialized");
3587 
3588   fieldDescriptor fd;
3589   if (!vk->is_instance_klass() ||
3590       !InstanceKlass::cast(vk)->find_field(fieldname, signame, false, &fd)) {
3591     ResourceMark rm;
3592     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", vk->external_name(), name, signature));
3593   }
3594 
3595   int offset = fd.offset() - vk->first_field_offset();
3596   if (isFlattened != NULL) {
3597     *isFlattened = fd.is_flattened();
3598   }
3599   return (jsize)offset;
3600 JNI_END
3601 
3602 // Structure containing all jni functions
3603 struct JNINativeInterface_ jni_NativeInterface = {
3604     NULL,
3605     NULL,
3606     NULL,
3607 
3608     NULL,
3609 
3610     jni_GetVersion,
3611 
3612     jni_DefineClass,
3613     jni_FindClass,
3614 
3615     jni_FromReflectedMethod,
3616     jni_FromReflectedField,
3617 
3618     jni_ToReflectedMethod,
3619 
3620     jni_GetSuperclass,
3621     jni_IsAssignableFrom,
3622 
3623     jni_ToReflectedField,
3624 
3625     jni_Throw,
3626     jni_ThrowNew,
3627     jni_ExceptionOccurred,
3628     jni_ExceptionDescribe,
3629     jni_ExceptionClear,
3630     jni_FatalError,
3631 
3632     jni_PushLocalFrame,
3633     jni_PopLocalFrame,
3634 
3635     jni_NewGlobalRef,
3636     jni_DeleteGlobalRef,
3637     jni_DeleteLocalRef,
3638     jni_IsSameObject,
3639 
3640     jni_NewLocalRef,
3641     jni_EnsureLocalCapacity,
3642 
3643     jni_AllocObject,
3644     jni_NewObject,
3645     jni_NewObjectV,
3646     jni_NewObjectA,
3647 
3648     jni_GetObjectClass,
3649     jni_IsInstanceOf,
3650 
3651     jni_GetMethodID,
3652 
3653     jni_CallObjectMethod,
3654     jni_CallObjectMethodV,
3655     jni_CallObjectMethodA,
3656     jni_CallBooleanMethod,
3657     jni_CallBooleanMethodV,
3658     jni_CallBooleanMethodA,
3659     jni_CallByteMethod,
3660     jni_CallByteMethodV,
3661     jni_CallByteMethodA,
3662     jni_CallCharMethod,
3663     jni_CallCharMethodV,
3664     jni_CallCharMethodA,
3665     jni_CallShortMethod,
3666     jni_CallShortMethodV,
3667     jni_CallShortMethodA,
3668     jni_CallIntMethod,
3669     jni_CallIntMethodV,
3670     jni_CallIntMethodA,
3671     jni_CallLongMethod,
3672     jni_CallLongMethodV,
3673     jni_CallLongMethodA,
3674     jni_CallFloatMethod,
3675     jni_CallFloatMethodV,
3676     jni_CallFloatMethodA,
3677     jni_CallDoubleMethod,
3678     jni_CallDoubleMethodV,
3679     jni_CallDoubleMethodA,
3680     jni_CallVoidMethod,
3681     jni_CallVoidMethodV,
3682     jni_CallVoidMethodA,
3683 
3684     jni_CallNonvirtualObjectMethod,
3685     jni_CallNonvirtualObjectMethodV,
3686     jni_CallNonvirtualObjectMethodA,
3687     jni_CallNonvirtualBooleanMethod,
3688     jni_CallNonvirtualBooleanMethodV,
3689     jni_CallNonvirtualBooleanMethodA,
3690     jni_CallNonvirtualByteMethod,
3691     jni_CallNonvirtualByteMethodV,
3692     jni_CallNonvirtualByteMethodA,
3693     jni_CallNonvirtualCharMethod,
3694     jni_CallNonvirtualCharMethodV,
3695     jni_CallNonvirtualCharMethodA,
3696     jni_CallNonvirtualShortMethod,
3697     jni_CallNonvirtualShortMethodV,
3698     jni_CallNonvirtualShortMethodA,
3699     jni_CallNonvirtualIntMethod,
3700     jni_CallNonvirtualIntMethodV,
3701     jni_CallNonvirtualIntMethodA,
3702     jni_CallNonvirtualLongMethod,
3703     jni_CallNonvirtualLongMethodV,
3704     jni_CallNonvirtualLongMethodA,
3705     jni_CallNonvirtualFloatMethod,
3706     jni_CallNonvirtualFloatMethodV,
3707     jni_CallNonvirtualFloatMethodA,
3708     jni_CallNonvirtualDoubleMethod,
3709     jni_CallNonvirtualDoubleMethodV,
3710     jni_CallNonvirtualDoubleMethodA,
3711     jni_CallNonvirtualVoidMethod,
3712     jni_CallNonvirtualVoidMethodV,
3713     jni_CallNonvirtualVoidMethodA,
3714 
3715     jni_GetFieldID,
3716 
3717     jni_GetObjectField,
3718     jni_GetBooleanField,
3719     jni_GetByteField,
3720     jni_GetCharField,
3721     jni_GetShortField,
3722     jni_GetIntField,
3723     jni_GetLongField,
3724     jni_GetFloatField,
3725     jni_GetDoubleField,
3726 
3727     jni_SetObjectField,
3728     jni_SetBooleanField,
3729     jni_SetByteField,
3730     jni_SetCharField,
3731     jni_SetShortField,
3732     jni_SetIntField,
3733     jni_SetLongField,
3734     jni_SetFloatField,
3735     jni_SetDoubleField,
3736 
3737     jni_GetStaticMethodID,
3738 
3739     jni_CallStaticObjectMethod,
3740     jni_CallStaticObjectMethodV,
3741     jni_CallStaticObjectMethodA,
3742     jni_CallStaticBooleanMethod,
3743     jni_CallStaticBooleanMethodV,
3744     jni_CallStaticBooleanMethodA,
3745     jni_CallStaticByteMethod,
3746     jni_CallStaticByteMethodV,
3747     jni_CallStaticByteMethodA,
3748     jni_CallStaticCharMethod,
3749     jni_CallStaticCharMethodV,
3750     jni_CallStaticCharMethodA,
3751     jni_CallStaticShortMethod,
3752     jni_CallStaticShortMethodV,
3753     jni_CallStaticShortMethodA,
3754     jni_CallStaticIntMethod,
3755     jni_CallStaticIntMethodV,
3756     jni_CallStaticIntMethodA,
3757     jni_CallStaticLongMethod,
3758     jni_CallStaticLongMethodV,
3759     jni_CallStaticLongMethodA,
3760     jni_CallStaticFloatMethod,
3761     jni_CallStaticFloatMethodV,
3762     jni_CallStaticFloatMethodA,
3763     jni_CallStaticDoubleMethod,
3764     jni_CallStaticDoubleMethodV,
3765     jni_CallStaticDoubleMethodA,
3766     jni_CallStaticVoidMethod,
3767     jni_CallStaticVoidMethodV,
3768     jni_CallStaticVoidMethodA,
3769 
3770     jni_GetStaticFieldID,
3771 
3772     jni_GetStaticObjectField,
3773     jni_GetStaticBooleanField,
3774     jni_GetStaticByteField,
3775     jni_GetStaticCharField,
3776     jni_GetStaticShortField,
3777     jni_GetStaticIntField,
3778     jni_GetStaticLongField,
3779     jni_GetStaticFloatField,
3780     jni_GetStaticDoubleField,
3781 
3782     jni_SetStaticObjectField,
3783     jni_SetStaticBooleanField,
3784     jni_SetStaticByteField,
3785     jni_SetStaticCharField,
3786     jni_SetStaticShortField,
3787     jni_SetStaticIntField,
3788     jni_SetStaticLongField,
3789     jni_SetStaticFloatField,
3790     jni_SetStaticDoubleField,
3791 
3792     jni_NewString,
3793     jni_GetStringLength,
3794     jni_GetStringChars,
3795     jni_ReleaseStringChars,
3796 
3797     jni_NewStringUTF,
3798     jni_GetStringUTFLength,
3799     jni_GetStringUTFChars,
3800     jni_ReleaseStringUTFChars,
3801 
3802     jni_GetArrayLength,
3803 
3804     jni_NewObjectArray,
3805     jni_GetObjectArrayElement,
3806     jni_SetObjectArrayElement,
3807 
3808     jni_NewBooleanArray,
3809     jni_NewByteArray,
3810     jni_NewCharArray,
3811     jni_NewShortArray,
3812     jni_NewIntArray,
3813     jni_NewLongArray,
3814     jni_NewFloatArray,
3815     jni_NewDoubleArray,
3816 
3817     jni_GetBooleanArrayElements,
3818     jni_GetByteArrayElements,
3819     jni_GetCharArrayElements,
3820     jni_GetShortArrayElements,
3821     jni_GetIntArrayElements,
3822     jni_GetLongArrayElements,
3823     jni_GetFloatArrayElements,
3824     jni_GetDoubleArrayElements,
3825 
3826     jni_ReleaseBooleanArrayElements,
3827     jni_ReleaseByteArrayElements,
3828     jni_ReleaseCharArrayElements,
3829     jni_ReleaseShortArrayElements,
3830     jni_ReleaseIntArrayElements,
3831     jni_ReleaseLongArrayElements,
3832     jni_ReleaseFloatArrayElements,
3833     jni_ReleaseDoubleArrayElements,
3834 
3835     jni_GetBooleanArrayRegion,
3836     jni_GetByteArrayRegion,
3837     jni_GetCharArrayRegion,
3838     jni_GetShortArrayRegion,
3839     jni_GetIntArrayRegion,
3840     jni_GetLongArrayRegion,
3841     jni_GetFloatArrayRegion,
3842     jni_GetDoubleArrayRegion,
3843 
3844     jni_SetBooleanArrayRegion,
3845     jni_SetByteArrayRegion,
3846     jni_SetCharArrayRegion,
3847     jni_SetShortArrayRegion,
3848     jni_SetIntArrayRegion,
3849     jni_SetLongArrayRegion,
3850     jni_SetFloatArrayRegion,
3851     jni_SetDoubleArrayRegion,
3852 
3853     jni_RegisterNatives,
3854     jni_UnregisterNatives,
3855 
3856     jni_MonitorEnter,
3857     jni_MonitorExit,
3858 
3859     jni_GetJavaVM,
3860 
3861     jni_GetStringRegion,
3862     jni_GetStringUTFRegion,
3863 
3864     jni_GetPrimitiveArrayCritical,
3865     jni_ReleasePrimitiveArrayCritical,
3866 
3867     jni_GetStringCritical,
3868     jni_ReleaseStringCritical,
3869 
3870     jni_NewWeakGlobalRef,
3871     jni_DeleteWeakGlobalRef,
3872 
3873     jni_ExceptionCheck,
3874 
3875     jni_NewDirectByteBuffer,
3876     jni_GetDirectBufferAddress,
3877     jni_GetDirectBufferCapacity,
3878 
3879     // New 1_6 features
3880 
3881     jni_GetObjectRefType,
3882 
3883     // Module features
3884 
3885     jni_GetModule,
3886 
3887     // Flattened arrays features
3888 
3889     jni_GetFlattenedArrayElements,
3890     jni_ReleaseFlattenedArrayElements,
3891     jni_GetFlattenedArrayElementClass,
3892     jni_GetFlattenedArrayElementSize,
3893     jni_GetFieldOffsetInFlattenedLayout
3894 };
3895 
3896 
3897 // For jvmti use to modify jni function table.
3898 // Java threads in native contiues to run until it is transitioned
3899 // to VM at safepoint. Before the transition or before it is blocked
3900 // for safepoint it may access jni function table. VM could crash if
3901 // any java thread access the jni function table in the middle of memcpy.
3902 // To avoid this each function pointers are copied automically.
3903 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3904   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3905   intptr_t *a = (intptr_t *) jni_functions();
3906   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3907   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3908     Atomic::store(a++, *b++);
3909   }
3910 }
3911 
3912 void quicken_jni_functions() {
3913   // Replace Get<Primitive>Field with fast versions
3914   if (UseFastJNIAccessors && !VerifyJNIFields && !CountJNICalls && !CheckJNICalls) {
3915     address func;
3916     func = JNI_FastGetField::generate_fast_get_boolean_field();
3917     if (func != (address)-1) {
3918       jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
3919     }
3920     func = JNI_FastGetField::generate_fast_get_byte_field();
3921     if (func != (address)-1) {
3922       jni_NativeInterface.GetByteField = (GetByteField_t)func;
3923     }
3924     func = JNI_FastGetField::generate_fast_get_char_field();
3925     if (func != (address)-1) {
3926       jni_NativeInterface.GetCharField = (GetCharField_t)func;
3927     }
3928     func = JNI_FastGetField::generate_fast_get_short_field();
3929     if (func != (address)-1) {
3930       jni_NativeInterface.GetShortField = (GetShortField_t)func;
3931     }
3932     func = JNI_FastGetField::generate_fast_get_int_field();
3933     if (func != (address)-1) {
3934       jni_NativeInterface.GetIntField = (GetIntField_t)func;
3935     }
3936     func = JNI_FastGetField::generate_fast_get_long_field();
3937     if (func != (address)-1) {
3938       jni_NativeInterface.GetLongField = (GetLongField_t)func;
3939     }
3940     func = JNI_FastGetField::generate_fast_get_float_field();
3941     if (func != (address)-1) {
3942       jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
3943     }
3944     func = JNI_FastGetField::generate_fast_get_double_field();
3945     if (func != (address)-1) {
3946       jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
3947     }
3948   }
3949 }
3950 
3951 // Returns the function structure
3952 struct JNINativeInterface_* jni_functions() {
3953 #if INCLUDE_JNI_CHECK
3954   if (CheckJNICalls) return jni_functions_check();
3955 #endif // INCLUDE_JNI_CHECK
3956   return &jni_NativeInterface;
3957 }
3958 
3959 // Returns the function structure
3960 struct JNINativeInterface_* jni_functions_nocheck() {
3961   return &jni_NativeInterface;
3962 }
3963 
3964 static void post_thread_start_event(const JavaThread* jt) {
3965   assert(jt != NULL, "invariant");
3966   EventThreadStart event;
3967   if (event.should_commit()) {
3968     event.set_thread(JFR_THREAD_ID(jt));
3969     event.commit();
3970   }
3971 }
3972 
3973 // Invocation API
3974 
3975 
3976 // Forward declaration
3977 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
3978 
3979 // Global invocation API vars
3980 volatile int vm_created = 0;
3981 // Indicate whether it is safe to recreate VM
3982 volatile int safe_to_recreate_vm = 1;
3983 struct JavaVM_ main_vm = {&jni_InvokeInterface};
3984 
3985 
3986 #define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
3987 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
3988 
3989 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
3990                     , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
3991 
3992 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
3993   HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(args_);
3994   JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
3995   jint ret = JNI_ERR;
3996   DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
3997 
3998   if (Threads::is_supported_jni_version(args->version)) {
3999     ret = JNI_OK;
4000   }
4001   // 1.1 style no longer supported in hotspot.
4002   // According the JNI spec, we should update args->version on return.
4003   // We also use the structure to communicate with launcher about default
4004   // stack size.
4005   if (args->version == JNI_VERSION_1_1) {
4006     args->version = JNI_VERSION_1_2;
4007     // javaStackSize is int in arguments structure
4008     assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");
4009     args->javaStackSize = (jint)(ThreadStackSize * K);
4010   }
4011   return ret;
4012 }
4013 
4014 DT_RETURN_MARK_DECL(CreateJavaVM, jint
4015                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
4016 
4017 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
4018   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
4019 
4020   jint result = JNI_ERR;
4021   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
4022 
4023   // We're about to use Atomic::xchg for synchronization.  Some Zero
4024   // platforms use the GCC builtin __sync_lock_test_and_set for this,
4025   // but __sync_lock_test_and_set is not guaranteed to do what we want
4026   // on all architectures.  So we check it works before relying on it.
4027 #if defined(ZERO) && defined(ASSERT)
4028   {
4029     jint a = 0xcafebabe;
4030     jint b = Atomic::xchg(&a, (jint) 0xdeadbeef);
4031     void *c = &a;
4032     void *d = Atomic::xchg(&c, &b);
4033     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
4034     assert(c == &b && d == &a, "Atomic::xchg() works");
4035   }
4036 #endif // ZERO && ASSERT
4037 
4038   // At the moment it's only possible to have one Java VM,
4039   // since some of the runtime state is in global variables.
4040 
4041   // We cannot use our mutex locks here, since they only work on
4042   // Threads. We do an atomic compare and exchange to ensure only
4043   // one thread can call this method at a time
4044 
4045   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
4046   // the add/dec implementations are dependent on whether we are running
4047   // on a multiprocessor Atomic::xchg does not have this problem.
4048   if (Atomic::xchg(&vm_created, 1) == 1) {
4049     return JNI_EEXIST;   // already created, or create attempt in progress
4050   }
4051   if (Atomic::xchg(&safe_to_recreate_vm, 0) == 0) {
4052     return JNI_ERR;  // someone tried and failed and retry not allowed.
4053   }
4054 
4055   assert(vm_created == 1, "vm_created is true during the creation");
4056 
4057   /**
4058    * Certain errors during initialization are recoverable and do not
4059    * prevent this method from being called again at a later time
4060    * (perhaps with different arguments).  However, at a certain
4061    * point during initialization if an error occurs we cannot allow
4062    * this function to be called again (or it will crash).  In those
4063    * situations, the 'canTryAgain' flag is set to false, which atomically
4064    * sets safe_to_recreate_vm to 1, such that any new call to
4065    * JNI_CreateJavaVM will immediately fail using the above logic.
4066    */
4067   bool can_try_again = true;
4068 
4069   result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
4070   if (result == JNI_OK) {
4071     JavaThread *thread = JavaThread::current();
4072     assert(!thread->has_pending_exception(), "should have returned not OK");
4073     /* thread is thread_in_vm here */
4074     *vm = (JavaVM *)(&main_vm);
4075     *(JNIEnv**)penv = thread->jni_environment();
4076 
4077 #if INCLUDE_JVMCI
4078     if (EnableJVMCI) {
4079       if (UseJVMCICompiler) {
4080         // JVMCI is initialized on a CompilerThread
4081         if (BootstrapJVMCI) {
4082           JavaThread* THREAD = thread;
4083           JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH);
4084           compiler->bootstrap(THREAD);
4085           if (HAS_PENDING_EXCEPTION) {
4086             HandleMark hm;
4087             vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
4088           }
4089         }
4090       }
4091     }
4092 #endif
4093 
4094     // Notify JVMTI
4095     if (JvmtiExport::should_post_thread_life()) {
4096        JvmtiExport::post_thread_start(thread);
4097     }
4098 
4099     post_thread_start_event(thread);
4100 
4101 #ifndef PRODUCT
4102     if (ReplayCompiles) ciReplay::replay(thread);
4103 
4104     // Some platforms (like Win*) need a wrapper around these test
4105     // functions in order to properly handle error conditions.
4106     VMError::test_error_handler();
4107 #endif
4108 
4109     // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
4110     ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
4111   } else {
4112     // If create_vm exits because of a pending exception, exit with that
4113     // exception.  In the future when we figure out how to reclaim memory,
4114     // we may be able to exit with JNI_ERR and allow the calling application
4115     // to continue.
4116     if (Universe::is_fully_initialized()) {
4117       // otherwise no pending exception possible - VM will already have aborted
4118       JavaThread* THREAD = JavaThread::current();
4119       if (HAS_PENDING_EXCEPTION) {
4120         HandleMark hm;
4121         vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
4122       }
4123     }
4124 
4125     if (can_try_again) {
4126       // reset safe_to_recreate_vm to 1 so that retrial would be possible
4127       safe_to_recreate_vm = 1;
4128     }
4129 
4130     // Creation failed. We must reset vm_created
4131     *vm = 0;
4132     *(JNIEnv**)penv = 0;
4133     // reset vm_created last to avoid race condition. Use OrderAccess to
4134     // control both compiler and architectural-based reordering.
4135     Atomic::release_store(&vm_created, 0);
4136   }
4137 
4138   // Flush stdout and stderr before exit.
4139   fflush(stdout);
4140   fflush(stderr);
4141 
4142   return result;
4143 
4144 }
4145 
4146 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
4147   jint result = JNI_ERR;
4148   // On Windows, let CreateJavaVM run with SEH protection
4149 #ifdef _WIN32
4150   __try {
4151 #endif
4152     result = JNI_CreateJavaVM_inner(vm, penv, args);
4153 #ifdef _WIN32
4154   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4155     // Nothing to do.
4156   }
4157 #endif
4158   return result;
4159 }
4160 
4161 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
4162   // See bug 4367188, the wrapper can sometimes cause VM crashes
4163   // JNIWrapper("GetCreatedJavaVMs");
4164 
4165   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
4166 
4167   if (vm_created == 1) {
4168     if (numVMs != NULL) *numVMs = 1;
4169     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
4170   } else {
4171     if (numVMs != NULL) *numVMs = 0;
4172   }
4173   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(JNI_OK);
4174   return JNI_OK;
4175 }
4176 
4177 extern "C" {
4178 
4179 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
4180                     , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
4181 
4182 static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
4183   HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(vm);
4184   jint res = JNI_ERR;
4185   DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
4186 
4187   if (vm_created == 0) {
4188     res = JNI_ERR;
4189     return res;
4190   }
4191 
4192   JNIWrapper("DestroyJavaVM");
4193   JNIEnv *env;
4194   JavaVMAttachArgs destroyargs;
4195   destroyargs.version = CurrentVersion;
4196   destroyargs.name = (char *)"DestroyJavaVM";
4197   destroyargs.group = NULL;
4198   res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
4199   if (res != JNI_OK) {
4200     return res;
4201   }
4202 
4203   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
4204   JavaThread* thread = JavaThread::current();
4205   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
4206   if (Threads::destroy_vm()) {
4207     // Should not change thread state, VM is gone
4208     vm_created = 0;
4209     res = JNI_OK;
4210     return res;
4211   } else {
4212     ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
4213     res = JNI_ERR;
4214     return res;
4215   }
4216 }
4217 
4218 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
4219   jint result = JNI_ERR;
4220   // On Windows, we need SEH protection
4221 #ifdef _WIN32
4222   __try {
4223 #endif
4224     result = jni_DestroyJavaVM_inner(vm);
4225 #ifdef _WIN32
4226   } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
4227     // Nothing to do.
4228   }
4229 #endif
4230   return result;
4231 }
4232 
4233 static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {
4234   JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;
4235 
4236   // Check below commented out from JDK1.2fcs as well
4237   /*
4238   if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {
4239     return JNI_EVERSION;
4240   }
4241   */
4242 
4243   Thread* t = Thread::current_or_null();
4244   if (t != NULL) {
4245     // If the thread has been attached this operation is a no-op
4246     *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
4247     return JNI_OK;
4248   }
4249 
4250   // Create a thread and mark it as attaching so it will be skipped by the
4251   // ThreadsListEnumerator - see CR 6404306
4252   JavaThread* thread = new JavaThread(true);
4253 
4254   // Set correct safepoint info. The thread is going to call into Java when
4255   // initializing the Java level thread object. Hence, the correct state must
4256   // be set in order for the Safepoint code to deal with it correctly.
4257   thread->set_thread_state(_thread_in_vm);
4258   thread->record_stack_base_and_size();
4259   thread->register_thread_stack_with_NMT();
4260   thread->initialize_thread_current();
4261 
4262   if (!os::create_attached_thread(thread)) {
4263     thread->smr_delete();
4264     return JNI_ERR;
4265   }
4266   // Enable stack overflow checks
4267   thread->create_stack_guard_pages();
4268 
4269   thread->initialize_tlab();
4270 
4271   thread->cache_global_variables();
4272 
4273   // This thread will not do a safepoint check, since it has
4274   // not been added to the Thread list yet.
4275   { MutexLocker ml(Threads_lock);
4276     // This must be inside this lock in order to get FullGCALot to work properly, i.e., to
4277     // avoid this thread trying to do a GC before it is added to the thread-list
4278     thread->set_active_handles(JNIHandleBlock::allocate_block());
4279     Threads::add(thread, daemon);
4280   }
4281   // Create thread group and name info from attach arguments
4282   oop group = NULL;
4283   char* thread_name = NULL;
4284   if (args != NULL && Threads::is_supported_jni_version(args->version)) {
4285     group = JNIHandles::resolve(args->group);
4286     thread_name = args->name; // may be NULL
4287   }
4288   if (group == NULL) group = Universe::main_thread_group();
4289 
4290   // Create Java level thread object and attach it to this thread
4291   bool attach_failed = false;
4292   {
4293     EXCEPTION_MARK;
4294     HandleMark hm(THREAD);
4295     Handle thread_group(THREAD, group);
4296     thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD);
4297     if (HAS_PENDING_EXCEPTION) {
4298       CLEAR_PENDING_EXCEPTION;
4299       // cleanup outside the handle mark.
4300       attach_failed = true;
4301     }
4302   }
4303 
4304   if (attach_failed) {
4305     // Added missing cleanup
4306     thread->cleanup_failed_attach_current_thread(daemon);
4307     return JNI_ERR;
4308   }
4309 
4310   // mark the thread as no longer attaching
4311   // this uses a fence to push the change through so we don't have
4312   // to regrab the threads_lock
4313   thread->set_done_attaching_via_jni();
4314 
4315   // Set java thread status.
4316   java_lang_Thread::set_thread_status(thread->threadObj(),
4317               java_lang_Thread::RUNNABLE);
4318 
4319   // Notify the debugger
4320   if (JvmtiExport::should_post_thread_life()) {
4321     JvmtiExport::post_thread_start(thread);
4322   }
4323 
4324   post_thread_start_event(thread);
4325 
4326   *(JNIEnv**)penv = thread->jni_environment();
4327 
4328   // Now leaving the VM, so change thread_state. This is normally automatically taken care
4329   // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
4330   // using ThreadStateTransition::transition, we do a callback to the safepoint code if
4331   // needed.
4332 
4333   ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
4334 
4335   // Perform any platform dependent FPU setup
4336   os::setup_fpu();
4337 
4338   return JNI_OK;
4339 }
4340 
4341 
4342 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
4343   HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
4344   if (vm_created == 0) {
4345   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4346     return JNI_ERR;
4347   }
4348 
4349   JNIWrapper("AttachCurrentThread");
4350   jint ret = attach_current_thread(vm, penv, _args, false);
4351   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(ret);
4352   return ret;
4353 }
4354 
4355 
4356 jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
4357   HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(vm);
4358 
4359   JNIWrapper("DetachCurrentThread");
4360 
4361   // If the thread has already been detached the operation is a no-op
4362   if (Thread::current_or_null() == NULL) {
4363     HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4364     return JNI_OK;
4365   }
4366 
4367   VM_Exit::block_if_vm_exited();
4368 
4369   JavaThread* thread = JavaThread::current();
4370   if (thread->has_last_Java_frame()) {
4371     HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
4372     // Can't detach a thread that's running java, that can't work.
4373     return JNI_ERR;
4374   }
4375 
4376   // Safepoint support. Have to do call-back to safepoint code, if in the
4377   // middle of a safepoint operation
4378   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
4379 
4380   // XXX: Note that JavaThread::exit() call below removes the guards on the
4381   // stack pages set up via enable_stack_{red,yellow}_zone() calls
4382   // above in jni_AttachCurrentThread. Unfortunately, while the setting
4383   // of the guards is visible in jni_AttachCurrentThread above,
4384   // the removal of the guards is buried below in JavaThread::exit()
4385   // here. The abstraction should be more symmetrically either exposed
4386   // or hidden (e.g. it could probably be hidden in the same
4387   // (platform-dependent) methods where we do alternate stack
4388   // maintenance work?)
4389   thread->exit(false, JavaThread::jni_detach);
4390   thread->smr_delete();
4391 
4392   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
4393   return JNI_OK;
4394 }
4395 
4396 DT_RETURN_MARK_DECL(GetEnv, jint
4397                     , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
4398 
4399 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
4400   HOTSPOT_JNI_GETENV_ENTRY(vm, penv, version);
4401   jint ret = JNI_ERR;
4402   DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
4403 
4404   if (vm_created == 0) {
4405     *penv = NULL;
4406     ret = JNI_EDETACHED;
4407     return ret;
4408   }
4409 
4410   if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
4411     return ret;
4412   }
4413 
4414 #ifndef JVMPI_VERSION_1
4415 // need these in order to be polite about older agents
4416 #define JVMPI_VERSION_1   ((jint)0x10000001)
4417 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
4418 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
4419 #endif // !JVMPI_VERSION_1
4420 
4421   Thread* thread = Thread::current_or_null();
4422   if (thread != NULL && thread->is_Java_thread()) {
4423     if (Threads::is_supported_jni_version_including_1_1(version)) {
4424       *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
4425       ret = JNI_OK;
4426       return ret;
4427 
4428     } else if (version == JVMPI_VERSION_1 ||
4429                version == JVMPI_VERSION_1_1 ||
4430                version == JVMPI_VERSION_1_2) {
4431       tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported.");
4432       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4433       ret = JNI_EVERSION;
4434       return ret;
4435     } else if (JvmtiExport::is_jvmdi_version(version)) {
4436       tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
4437       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
4438       ret = JNI_EVERSION;
4439       return ret;
4440     } else {
4441       *penv = NULL;
4442       ret = JNI_EVERSION;
4443       return ret;
4444     }
4445   } else {
4446     *penv = NULL;
4447     ret = JNI_EDETACHED;
4448     return ret;
4449   }
4450 }
4451 
4452 
4453 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
4454   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
4455   if (vm_created == 0) {
4456   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
4457     return JNI_ERR;
4458   }
4459 
4460   JNIWrapper("AttachCurrentThreadAsDaemon");
4461   jint ret = attach_current_thread(vm, penv, _args, true);
4462   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(ret);
4463   return ret;
4464 }
4465 
4466 
4467 } // End extern "C"
4468 
4469 const struct JNIInvokeInterface_ jni_InvokeInterface = {
4470     NULL,
4471     NULL,
4472     NULL,
4473 
4474     jni_DestroyJavaVM,
4475     jni_AttachCurrentThread,
4476     jni_DetachCurrentThread,
4477     jni_GetEnv,
4478     jni_AttachCurrentThreadAsDaemon
4479 };