sssssss66


JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
  JVMWrapper("JVM_Sleep");
  if (millis < 0) {
    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
  }
  if (Thread::is_interrupted (THREAD, true) && !HAS_PENDING_EXCEPTION) {
    THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
  }
  JavaThreadSleepState jtss(thread);
#ifndef USDT2
  HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis);
#else /* USDT2 */
  HOTSPOT_THREAD_SLEEP_BEGIN(
                             millis);
#endif /* USDT2 */
  EventThreadSleep event;
  if (millis == 0) {
    if (ConvertSleepToYield) {
      os::yield();
    } else {
      ThreadState old_state = thread->osthread()->get_state();
      thread->osthread()->set_state(SLEEPING);
      os::sleep(thread, MinSleepInterval, false);
      thread->osthread()->set_state(old_state);
    }
  } else {
    ThreadState old_state = thread->osthread()->get_state();
    thread->osthread()->set_state(SLEEPING);
    if (os::sleep(thread, millis, true) == OS_INTRPT) {
      if (!HAS_PENDING_EXCEPTION) {
        if (event.should_commit()) {
          post_thread_sleep_event(&event, millis);
        }
#ifndef USDT2
        HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
#else /* USDT2 */
        HOTSPOT_THREAD_SLEEP_END(
                                 1);
#endif /* USDT2 */
        THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted");
      }
    }
    thread->osthread()->set_state(old_state);
  }
  if (event.should_commit()) {
    post_thread_sleep_event(&event, millis);
  }
#ifndef USDT2
  HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
#else /* USDT2 */
  HOTSPOT_THREAD_SLEEP_END(
                           0);
#endif /* USDT2 */
JVM_END
JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
  JVMWrapper("JVM_CurrentThread");
  oop jthread = thread->threadObj();
  assert (thread != NULL, "no current thread!");
  return JNIHandles::make_local(env, jthread);
JVM_END
JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_CountStackFrames");
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  bool throw_illegal_thread_state = false;
  int count = 0;
  {
    MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
    JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
    if (thr == NULL) {
    } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {
      throw_illegal_thread_state = true;
    } else {
      for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {
        if (!vfst.method()->is_native()) count++;
       }
    }
  }
  if (throw_illegal_thread_state) {
    THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
                "this thread is not suspended");
  }
  return count;
JVM_END
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_Interrupt");
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
  if (thr != NULL) {
    Thread::interrupt(thr);
  }
JVM_END
JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
  JVMWrapper("JVM_IsInterrupted");
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
  if (thr == NULL) {
    return JNI_FALSE;
  } else {
    return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
  }
JVM_END
JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
  JVMWrapper("JVM_HoldsLock");
  assert(THREAD->is_Java_thread(), "sanity check");
  if (obj == NULL) {
    THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
  }
  Handle h_obj(THREAD, JNIHandles::resolve(obj));
  return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj);
JVM_END
JVM_ENTRY(void, JVM_DumpAllStacks(JNIEnv* env, jclass))
  JVMWrapper("JVM_DumpAllStacks");
  VM_PrintThreads op;
  VMThread::execute(&op);
  if (JvmtiExport::should_post_data_dump()) {
    JvmtiExport::post_data_dump();
  }
JVM_END
JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))
  JVMWrapper("JVM_SetNativeThreadName");
  ResourceMark rm(THREAD);
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  JavaThread* thr = java_lang_Thread::thread(java_thread);
  if (Thread::current() == thr && !thr->has_attached_via_jni()) {
    const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
    os::set_native_thread_name(thread_name);
  }
JVM_END
static bool is_trusted_frame(JavaThread* jthread, vframeStream* vfst) {
  assert(jthread->is_Java_thread(), "must be a Java thread");
  if (jthread->privileged_stack_top() == NULL) return false;
  if (jthread->privileged_stack_top()->frame_id() == vfst->frame_id()) {
    oop loader = jthread->privileged_stack_top()->class_loader();
    if (loader == NULL) return true;
    bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
    if (trusted) return true;
  }
  return false;
}
JVM_ENTRY(jclass, JVM_CurrentLoadedClass(JNIEnv *env))
  JVMWrapper("JVM_CurrentLoadedClass");
  ResourceMark rm(THREAD);
  for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
    bool trusted = is_trusted_frame(thread, &vfst);
    if (trusted) return NULL;
    Method* m = vfst.method();
    if (!m->is_native()) {
      InstanceKlass* holder = m->method_holder();
      oop loader = holder->class_loader();
      if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
        return (jclass) JNIHandles::make_local(env, holder->java_mirror());
      }
    }
  }
  return NULL;
JVM_END
JVM_ENTRY(jobject, JVM_CurrentClassLoader(JNIEnv *env))
  JVMWrapper("JVM_CurrentClassLoader");
  ResourceMark rm(THREAD);
  for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
    bool trusted = is_trusted_frame(thread, &vfst);
    if (trusted) return NULL;
    Method* m = vfst.method();
    if (!m->is_native()) {
      InstanceKlass* holder = m->method_holder();
      assert(holder->is_klass(), "just checking");
      oop loader = holder->class_loader();
      if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
        return JNIHandles::make_local(env, loader);
      }
    }
  }
  return NULL;
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))
  JVMWrapper("JVM_GetClassContext");
  ResourceMark rm(THREAD);
  JvmtiVMObjectAllocEventCollector oam;
  vframeStream vfst(thread);
  if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) {
    Method* m = vfst.method();
    if (!(m->method_holder() == SystemDictionary::SecurityManager_klass() &&
          m->name()          == vmSymbols::getClassContext_name() &&
          m->signature()     == vmSymbols::void_class_array_signature())) {
      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");
    }
  }
  GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>();
  for (; !vfst.at_end(); vfst.security_next()) {
    Method* m = vfst.method();
    if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {
      Klass* holder = m->method_holder();
      assert(holder->is_klass(), "just checking");
      klass_array->append(holder);
    }
  }
  objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL);
  for (int i = 0; i < klass_array->length(); i++) {
    result->obj_at_put(i, klass_array->at(i)->java_mirror());
  }
  return (jobjectArray) JNIHandles::make_local(env, result);
JVM_END
JVM_ENTRY(jint, JVM_ClassDepth(JNIEnv *env, jstring name))
  JVMWrapper("JVM_ClassDepth");
  ResourceMark rm(THREAD);
  Handle h_name (THREAD, JNIHandles::resolve_non_null(name));
  Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0);
  const char* str = java_lang_String::as_utf8_string(class_name_str());
  TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str));
  if (class_name_sym == NULL) {
    return -1;
  }
  int depth = 0;
  for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
    if (!vfst.method()->is_native()) {
      InstanceKlass* holder = vfst.method()->method_holder();
      assert(holder->is_klass(), "just checking");
      if (holder->name() == class_name_sym) {
        return depth;
      }
      depth++;
    }
  }
  return -1;
JVM_END
JVM_ENTRY(jint, JVM_ClassLoaderDepth(JNIEnv *env))
  JVMWrapper("JVM_ClassLoaderDepth");
  ResourceMark rm(THREAD);
  int depth = 0;
  for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
    bool trusted = is_trusted_frame(thread, &vfst);
    if (trusted) return -1;
    Method* m = vfst.method();
    if (!m->is_native()) {
      InstanceKlass* holder = m->method_holder();
      assert(holder->is_klass(), "just checking");
      oop loader = holder->class_loader();
      if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
        return depth;
      }
      depth++;
    }
  }
  return -1;
JVM_END
JVM_ENTRY(jstring, JVM_GetSystemPackage(JNIEnv *env, jstring name))
  JVMWrapper("JVM_GetSystemPackage");
  ResourceMark rm(THREAD);
  JvmtiVMObjectAllocEventCollector oam;
  char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
  oop result = ClassLoader::get_system_package(str, CHECK_NULL);
  return (jstring) JNIHandles::make_local(result);
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetSystemPackages(JNIEnv *env))
  JVMWrapper("JVM_GetSystemPackages");
  JvmtiVMObjectAllocEventCollector oam;
  objArrayOop result = ClassLoader::get_system_packages(CHECK_NULL);
  return (jobjectArray) JNIHandles::make_local(result);
JVM_END
bool force_verify_field_access(Klass* current_class, Klass* field_class, AccessFlags access, bool classloader_only) {
  if (current_class == NULL) {
    return true;
  }
  if ((current_class == field_class) || access.is_public()) {
    return true;
  }
  if (access.is_protected()) {
    if (current_class->is_subclass_of(field_class)) {
      return true;
    }
  }
  return (!access.is_private() && InstanceKlass::cast(current_class)->is_same_class_package(field_class));
}
JVM_ENTRY(jobject, JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass))
  JVMWrapper("JVM_AllocateNewObject");
  JvmtiVMObjectAllocEventCollector oam;
  oop curr_mirror = JNIHandles::resolve_non_null(currClass);
  oop init_mirror = JNIHandles::resolve_non_null(initClass);
  if (java_lang_Class::is_primitive(curr_mirror) || java_lang_Class::is_primitive(init_mirror)) {
    ResourceMark rm(THREAD);
    THROW_0(vmSymbols::java_lang_InvalidClassException());
  }
  if (java_lang_Class::as_Klass(curr_mirror)->oop_is_array() ||
      java_lang_Class::as_Klass(init_mirror)->oop_is_array()) {
    ResourceMark rm(THREAD);
    THROW_0(vmSymbols::java_lang_InvalidClassException());
  }
  instanceKlassHandle curr_klass (THREAD, java_lang_Class::as_Klass(curr_mirror));
  instanceKlassHandle init_klass (THREAD, java_lang_Class::as_Klass(init_mirror));
  assert(curr_klass->is_subclass_of(init_klass()), "just checking");
  curr_klass->check_valid_for_instantiation(false, CHECK_NULL);
  curr_klass->initialize(CHECK_NULL);
 methodHandle m (THREAD,
                 init_klass->find_method(vmSymbols::object_initializer_name(),
                                         vmSymbols::void_method_signature()));
  if (m.is_null()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
                Method::name_and_sig_as_C_string(init_klass(),
                                          vmSymbols::object_initializer_name(),
                                          vmSymbols::void_method_signature()));
  }
  if (curr_klass ==  init_klass && !m->is_public()) {
    THROW_0(vmSymbols::java_lang_IllegalAccessException());
  }
  if (!force_verify_field_access(curr_klass(), init_klass(), m->access_flags(), false)) {
    THROW_0(vmSymbols::java_lang_IllegalAccessException());
  }
  Handle obj = curr_klass->allocate_instance_handle(CHECK_NULL);
  JavaCalls::call_default_constructor(thread, m, obj, CHECK_NULL);
  return JNIHandles::make_local(obj());
JVM_END
JVM_ENTRY(jobject, JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length))
  JVMWrapper("JVM_AllocateNewArray");
  JvmtiVMObjectAllocEventCollector oam;
  oop mirror = JNIHandles::resolve_non_null(currClass);
  if (java_lang_Class::is_primitive(mirror)) {
    THROW_0(vmSymbols::java_lang_InvalidClassException());
  }
  Klass* k = java_lang_Class::as_Klass(mirror);
  oop result;
  if (k->oop_is_typeArray()) {
    result = TypeArrayKlass::cast(k)->allocate(length, CHECK_NULL);
  } else if (k->oop_is_objArray()) {
    ObjArrayKlass* oak = ObjArrayKlass::cast(k);
    oak->initialize(CHECK_NULL); // make sure class is initialized (matches Classic VM behavior)
    result = oak->allocate(length, CHECK_NULL);
  } else {
    THROW_0(vmSymbols::java_lang_InvalidClassException());
  }
  return JNIHandles::make_local(env, result);
JVM_END
JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))
  for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
    vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
    oop loader = vfst.method()->method_holder()->class_loader();
    if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) {
      return JNIHandles::make_local(env, loader);
    }
  }
  return NULL;
JVM_END
JVM_ENTRY(jclass, JVM_LoadClass0(JNIEnv *env, jobject receiver,
                                 jclass currClass, jstring currClassName))
  JVMWrapper("JVM_LoadClass0");
  ResourceMark rm(THREAD);
  Handle classname (THREAD, JNIHandles::resolve_non_null(currClassName));
  Handle string = java_lang_String::internalize_classname(classname, CHECK_NULL);
  const char* str = java_lang_String::as_utf8_string(string());
  if (str == NULL || (int)strlen(str) > Symbol::max_length()) {
    THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), str);
  }
  TempNewSymbol name = SymbolTable::new_symbol(str, CHECK_NULL);
  Handle curr_klass (THREAD, JNIHandles::resolve(currClass));
  oop loader = NULL;
  oop protection_domain = NULL;
  if (curr_klass.is_null()) {
    for (vframeStream vfst(thread);
         !vfst.at_end() && loader == NULL;
         vfst.next()) {
      if (!vfst.method()->is_native()) {
        InstanceKlass* holder = vfst.method()->method_holder();
        loader             = holder->class_loader();
        protection_domain  = holder->protection_domain();
      }
    }
  } else {
    Klass* curr_klass_oop = java_lang_Class::as_Klass(curr_klass());
    loader            = InstanceKlass::cast(curr_klass_oop)->class_loader();
    protection_domain = InstanceKlass::cast(curr_klass_oop)->protection_domain();
  }
  Handle h_loader(THREAD, loader);
  Handle h_prot  (THREAD, protection_domain);
  jclass result =  find_class_from_class_loader(env, name, true, h_loader, h_prot,
                                                false, thread);
  if (TraceClassResolution && result != NULL) {
    trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
  }
  return result;
JVM_END
static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_only, TRAPS) {
  if (arr == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }
  oop a = JNIHandles::resolve_non_null(arr);
  if (!a->is_array() || (type_array_only && !a->is_typeArray())) {
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array");
  }
  return arrayOop(a);
}
JVM_ENTRY(jint, JVM_GetArrayLength(JNIEnv *env, jobject arr))
  JVMWrapper("JVM_GetArrayLength");
  arrayOop a = check_array(env, arr, false, CHECK_0);
  return a->length();
JVM_END
JVM_ENTRY(jobject, JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index))
  JVMWrapper("JVM_Array_Get");
  JvmtiVMObjectAllocEventCollector oam;
  arrayOop a = check_array(env, arr, false, CHECK_NULL);
  jvalue value;
  BasicType type = Reflection::array_get(&value, a, index, CHECK_NULL);
  oop box = Reflection::box(&value, type, CHECK_NULL);
  return JNIHandles::make_local(env, box);
JVM_END
JVM_ENTRY(jvalue, JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode))
  JVMWrapper("JVM_GetPrimitiveArrayElement");
  jvalue value;
  value.i = 0; // to initialize value before getting used in CHECK
  arrayOop a = check_array(env, arr, true, CHECK_(value));
  assert(a->is_typeArray(), "just checking");
  BasicType type = Reflection::array_get(&value, a, index, CHECK_(value));
  BasicType wide_type = (BasicType) wCode;
  if (type != wide_type) {
    Reflection::widen(&value, type, wide_type, CHECK_(value));
  }
  return value;
JVM_END
JVM_ENTRY(void, JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val))
  JVMWrapper("JVM_SetArrayElement");
  arrayOop a = check_array(env, arr, false, CHECK);
  oop box = JNIHandles::resolve(val);
  jvalue value;
  value.i = 0; // to initialize value before getting used in CHECK
  BasicType value_type;
  if (a->is_objArray()) {
    value_type = Reflection::unbox_for_regular_object(box, &value);
  } else {
    value_type = Reflection::unbox_for_primitive(box, &value, CHECK);
  }
  Reflection::array_set(&value, a, index, value_type, CHECK);
JVM_END
JVM_ENTRY(void, JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode))
  JVMWrapper("JVM_SetPrimitiveArrayElement");
  arrayOop a = check_array(env, arr, true, CHECK);
  assert(a->is_typeArray(), "just checking");
  BasicType value_type = (BasicType) vCode;
  Reflection::array_set(&v, a, index, value_type, CHECK);
JVM_END
JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length))
  JVMWrapper("JVM_NewArray");
  JvmtiVMObjectAllocEventCollector oam;
  oop element_mirror = JNIHandles::resolve(eltClass);
  oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL);
  return JNIHandles::make_local(env, result);
JVM_END
JVM_ENTRY(jobject, JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim))
  JVMWrapper("JVM_NewMultiArray");
  JvmtiVMObjectAllocEventCollector oam;
  arrayOop dim_array = check_array(env, dim, true, CHECK_NULL);
  oop element_mirror = JNIHandles::resolve(eltClass);
  assert(dim_array->is_typeArray(), "just checking");
  oop result = Reflection::reflect_new_multi_array(element_mirror, typeArrayOop(dim_array), CHECK_NULL);
  return JNIHandles::make_local(env, result);
JVM_END
JVM_LEAF(jint, JVM_InitializeSocketLibrary())
  JVMWrapper("JVM_InitializeSocketLibrary");
  return 0;
JVM_END
JVM_LEAF(jint, JVM_Socket(jint domain, jint type, jint protocol))
  JVMWrapper("JVM_Socket");
  return os::socket(domain, type, protocol);
JVM_END
JVM_LEAF(jint, JVM_SocketClose(jint fd))
  JVMWrapper2("JVM_SocketClose (0x%x)", fd);
  return os::socket_close(fd);
JVM_END
JVM_LEAF(jint, JVM_SocketShutdown(jint fd, jint howto))
  JVMWrapper2("JVM_SocketShutdown (0x%x)", fd);
  return os::socket_shutdown(fd, howto);
JVM_END
JVM_LEAF(jint, JVM_Recv(jint fd, char *buf, jint nBytes, jint flags))
  JVMWrapper2("JVM_Recv (0x%x)", fd);
  return os::recv(fd, buf, (size_t)nBytes, (uint)flags);
JVM_END
JVM_LEAF(jint, JVM_Send(jint fd, char *buf, jint nBytes, jint flags))
  JVMWrapper2("JVM_Send (0x%x)", fd);
  return os::send(fd, buf, (size_t)nBytes, (uint)flags);
JVM_END
JVM_LEAF(jint, JVM_Timeout(int fd, long timeout))
  JVMWrapper2("JVM_Timeout (0x%x)", fd);
  return os::timeout(fd, timeout);
JVM_END
JVM_LEAF(jint, JVM_Listen(jint fd, jint count))
  JVMWrapper2("JVM_Listen (0x%x)", fd);
  return os::listen(fd, count);
JVM_END
JVM_LEAF(jint, JVM_Connect(jint fd, struct sockaddr *him, jint len))
  JVMWrapper2("JVM_Connect (0x%x)", fd);
  return os::connect(fd, him, (socklen_t)len);
JVM_END
JVM_LEAF(jint, JVM_Bind(jint fd, struct sockaddr *him, jint len))
  JVMWrapper2("JVM_Bind (0x%x)", fd);
  return os::bind(fd, him, (socklen_t)len);
JVM_END
JVM_LEAF(jint, JVM_Accept(jint fd, struct sockaddr *him, jint *len))
  JVMWrapper2("JVM_Accept (0x%x)", fd);
  socklen_t socklen = (socklen_t)(*len);
  jint result = os::accept(fd, him, &socklen);
  return result;
JVM_END
JVM_LEAF(jint, JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen))
  JVMWrapper2("JVM_RecvFrom (0x%x)", fd);
  socklen_t socklen = (socklen_t)(*fromlen);
  jint result = os::recvfrom(fd, buf, (size_t)nBytes, (uint)flags, from, &socklen);
  return result;
JVM_END
JVM_LEAF(jint, JVM_GetSockName(jint fd, struct sockaddr *him, int *len))
  JVMWrapper2("JVM_GetSockName (0x%x)", fd);
  socklen_t socklen = (socklen_t)(*len);
  jint result = os::get_sock_name(fd, him, &socklen);
  return result;
JVM_END
JVM_LEAF(jint, JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen))
  JVMWrapper2("JVM_SendTo (0x%x)", fd);
  return os::sendto(fd, buf, (size_t)len, (uint)flags, to, (socklen_t)tolen);
JVM_END
JVM_LEAF(jint, JVM_SocketAvailable(jint fd, jint *pbytes))
  JVMWrapper2("JVM_SocketAvailable (0x%x)", fd);
  return os::socket_available(fd, pbytes);
JVM_END
JVM_LEAF(jint, JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen))
  JVMWrapper2("JVM_GetSockOpt (0x%x)", fd);
  socklen_t socklen = (socklen_t)(*optlen);
  jint result = os::get_sock_opt(fd, level, optname, optval, &socklen);
  return result;
JVM_END
JVM_LEAF(jint, JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen))
  JVMWrapper2("JVM_GetSockOpt (0x%x)", fd);
  return os::set_sock_opt(fd, level, optname, optval, (socklen_t)optlen);
JVM_END
JVM_LEAF(int, JVM_GetHostName(char* name, int namelen))
  JVMWrapper("JVM_GetHostName");
  return os::get_host_name(name, namelen);
JVM_END
JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name))
  JVMWrapper2("JVM_LoadLibrary (%s)", name);
  char ebuf[1024];
  void *load_result;
  {
    ThreadToNativeFromVM ttnfvm(thread);
    load_result = os::dll_load(name, ebuf, sizeof ebuf);
  }
  if (load_result == NULL) {
    char msg[1024];
    jio_snprintf(msg, sizeof msg, "%s: %s", name, ebuf);
    Handle h_exception =
      Exceptions::new_exception(thread,
                                vmSymbols::java_lang_UnsatisfiedLinkError(),
                                msg, Exceptions::unsafe_to_utf8);
    THROW_HANDLE_0(h_exception);
  }
  return load_result;
JVM_END
JVM_LEAF(void, JVM_UnloadLibrary(void* handle))
  JVMWrapper("JVM_UnloadLibrary");
  os::dll_unload(handle);
JVM_END
JVM_LEAF(void*, JVM_FindLibraryEntry(void* handle, const char* name))
  JVMWrapper2("JVM_FindLibraryEntry (%s)", name);
  return os::dll_lookup(handle, name);
JVM_END
JVM_LEAF(jboolean, JVM_IsNaN(jdouble a))
  JVMWrapper("JVM_IsNaN");
  return g_isnan(a);
JVM_END
JVM_LEAF(jboolean, JVM_IsSupportedJNIVersion(jint version))
  JVMWrapper2("JVM_IsSupportedJNIVersion (%d)", version);
  return Threads::is_supported_jni_version_including_1_1(version);
JVM_END
JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))
  JVMWrapper("JVM_InternString");
  JvmtiVMObjectAllocEventCollector oam;
  if (str == NULL) return NULL;
  oop string = JNIHandles::resolve_non_null(str);
  oop result = StringTable::intern(string, CHECK_NULL);
  return (jstring) JNIHandles::make_local(env, result);
JVM_END
JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) {
  VM_Exit::block_if_vm_exited();
  JVMWrapper("JVM_RawMonitorCreate");
  return new Mutex(Mutex::native, "JVM_RawMonitorCreate");
}
JNIEXPORT void JNICALL  JVM_RawMonitorDestroy(void *mon) {
  VM_Exit::block_if_vm_exited();
  JVMWrapper("JVM_RawMonitorDestroy");
  delete ((Mutex*) mon);
}
JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {
  VM_Exit::block_if_vm_exited();
  JVMWrapper("JVM_RawMonitorEnter");
  ((Mutex*) mon)->jvm_raw_lock();
  return 0;
}
JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
  VM_Exit::block_if_vm_exited();
  JVMWrapper("JVM_RawMonitorExit");
  ((Mutex*) mon)->jvm_raw_unlock();
}
typedef jfloat  (JNICALL *IntBitsToFloatFn  )(JNIEnv* env, jclass cb, jint    value);
typedef jdouble (JNICALL *LongBitsToDoubleFn)(JNIEnv* env, jclass cb, jlong   value);
typedef jint    (JNICALL *FloatToIntBitsFn  )(JNIEnv* env, jclass cb, jfloat  value);
typedef jlong   (JNICALL *DoubleToLongBitsFn)(JNIEnv* env, jclass cb, jdouble value);
static IntBitsToFloatFn   int_bits_to_float_fn   = NULL;
static LongBitsToDoubleFn long_bits_to_double_fn = NULL;
static FloatToIntBitsFn   float_to_int_bits_fn   = NULL;
static DoubleToLongBitsFn double_to_long_bits_fn = NULL;
void initialize_converter_functions() {
  if (JDK_Version::is_gte_jdk14x_version()) {
    return;
  }
  assert(
    int_bits_to_float_fn   == NULL &&
    long_bits_to_double_fn == NULL &&
    float_to_int_bits_fn   == NULL &&
    double_to_long_bits_fn == NULL ,
    "initialization done twice"
  );
  int_bits_to_float_fn   = CAST_TO_FN_PTR(IntBitsToFloatFn  , NativeLookup::base_library_lookup("java/lang/Float" , "intBitsToFloat"  , "(I)F"));
  long_bits_to_double_fn = CAST_TO_FN_PTR(LongBitsToDoubleFn, NativeLookup::base_library_lookup("java/lang/Double", "longBitsToDouble", "(J)D"));
  float_to_int_bits_fn   = CAST_TO_FN_PTR(FloatToIntBitsFn  , NativeLookup::base_library_lookup("java/lang/Float" , "floatToIntBits"  , "(F)I"));
  double_to_long_bits_fn = CAST_TO_FN_PTR(DoubleToLongBitsFn, NativeLookup::base_library_lookup("java/lang/Double", "doubleToLongBits", "(D)J"));
  assert(
    int_bits_to_float_fn   != NULL &&
    long_bits_to_double_fn != NULL &&
    float_to_int_bits_fn   != NULL &&
    double_to_long_bits_fn != NULL ,
    "initialization failed"
  );
}
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
                                    Handle loader, Handle protection_domain,
                                    jboolean throwError, TRAPS) {
  Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
  KlassHandle klass_handle(THREAD, klass);
  if (init && klass_handle->oop_is_instance()) {
    klass_handle->initialize(CHECK_NULL);
  }
  return (jclass) JNIHandles::make_local(env, klass_handle->java_mirror());
}
#ifndef PRODUCT
extern "C" {
  JNIEXPORT jboolean JNICALL JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get);
  JNIEXPORT jboolean JNICALL JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get);
  JNIEXPORT void JNICALL JVM_VMBreakPoint(JNIEnv *env, jobject obj);
}
JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get))
  JVMWrapper("JVM_AccessBoolVMFlag");
  return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, Flag::INTERNAL);
JVM_END
JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get))
  JVMWrapper("JVM_AccessVMIntFlag");
  intx v;
  jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, Flag::INTERNAL);
  return result;
JVM_END
JVM_ENTRY(void, JVM_VMBreakPoint(JNIEnv *env, jobject obj))
  JVMWrapper("JVM_VMBreakPoint");
  oop the_obj = JNIHandles::resolve(obj);
  BREAKPOINT;
JVM_END
#endif
JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))
  JVMWrapper("JVM_InvokeMethod");
  Handle method_handle;
  if (thread->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) {
    method_handle = Handle(THREAD, JNIHandles::resolve(method));
    Handle receiver(THREAD, JNIHandles::resolve(obj));
    objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
    oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);
    jobject res = JNIHandles::make_local(env, result);
    if (JvmtiExport::should_post_vm_object_alloc()) {
      oop ret_type = java_lang_reflect_Method::return_type(method_handle());
      assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");
      if (java_lang_Class::is_primitive(ret_type)) {
        JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
      }
    }
    return res;
  } else {
    THROW_0(vmSymbols::java_lang_StackOverflowError());
  }
JVM_END
JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0))
  JVMWrapper("JVM_NewInstanceFromConstructor");
  oop constructor_mirror = JNIHandles::resolve(c);
  objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
  oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL);
  jobject res = JNIHandles::make_local(env, result);
  if (JvmtiExport::should_post_vm_object_alloc()) {
    JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
  }
  return res;
JVM_END
JVM_LEAF(jboolean, JVM_SupportsCX8())
  JVMWrapper("JVM_SupportsCX8");
  return VM_Version::supports_cx8();
JVM_END
JVM_ENTRY(jboolean, JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal))
  JVMWrapper("JVM_CX8Field");
  jlong res;
  oop             o       = JNIHandles::resolve(obj);
  intptr_t        fldOffs = jfieldIDWorkaround::from_instance_jfieldID(o->klass(), fid);
  volatile jlong* addr    = (volatile jlong*)((address)o + fldOffs);
  assert(VM_Version::supports_cx8(), "cx8 not supported");
  res = Atomic::cmpxchg(newVal, addr, oldVal);
  return res == oldVal;
JVM_END
JVM_ENTRY(jint, JVM_DTraceGetVersion(JNIEnv* env))
  JVMWrapper("JVM_DTraceGetVersion");
  return (jint)JVM_TRACING_DTRACE_VERSION;
JVM_END
JVM_ENTRY(jlong,JVM_DTraceActivate(
    JNIEnv* env, jint version, jstring module_name, jint providers_count,
    JVM_DTraceProvider* providers))
  JVMWrapper("JVM_DTraceActivate");
  return DTraceJSDT::activate(
    version, module_name, providers_count, providers, THREAD);
JVM_END
JVM_ENTRY(jboolean,JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method))
  JVMWrapper("JVM_DTraceIsProbeEnabled");
  return DTraceJSDT::is_probe_enabled(method);
JVM_END
JVM_ENTRY(void,JVM_DTraceDispose(JNIEnv* env, jlong handle))
  JVMWrapper("JVM_DTraceDispose");
  DTraceJSDT::dispose(handle);
JVM_END
JVM_ENTRY(jboolean,JVM_DTraceIsSupported(JNIEnv* env))
  JVMWrapper("JVM_DTraceIsSupported");
  return DTraceJSDT::is_supported();
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetAllThreads(JNIEnv *env, jclass dummy))
  ResourceMark rm(THREAD);
  ThreadsListEnumerator tle(THREAD, false, false);
  JvmtiVMObjectAllocEventCollector oam;
  int num_threads = tle.num_threads();
  objArrayOop r = oopFactory::new_objArray(SystemDictionary::Thread_klass(), num_threads, CHECK_NULL);
  objArrayHandle threads_ah(THREAD, r);
  for (int i = 0; i < num_threads; i++) {
    Handle h = tle.get_threadObj(i);
    threads_ah->obj_at_put(i, h());
  }
  return (jobjectArray) JNIHandles::make_local(env, threads_ah());
JVM_END
JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads))
  JVMWrapper("JVM_DumpThreads");
  JvmtiVMObjectAllocEventCollector oam;
  if (threads == NULL) {
    THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  }
  objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(threads));
  objArrayHandle ah(THREAD, a);
  int num_threads = ah->length();
  if (num_threads == 0) {
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);
  }
  Klass* k = ObjArrayKlass::cast(ah->klass())->element_klass();
  if (k != SystemDictionary::Thread_klass()) {
    THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0);
  }
  ResourceMark rm(THREAD);
  GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
  for (int i = 0; i < num_threads; i++) {
    oop thread_obj = ah->obj_at(i);
    instanceHandle h(THREAD, (instanceOop) thread_obj);
    thread_handle_array->append(h);
  }
  Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);
  return (jobjectArray)JNIHandles::make_local(env, stacktraces());
JVM_END
JVM_ENTRY_NO_ENV(void*, JVM_GetManagement(jint version))
  return Management::get_jmm_interface(version);
JVM_END
JVM_ENTRY(jobject, JVM_InitAgentProperties(JNIEnv *env, jobject properties))
  JVMWrapper("JVM_InitAgentProperties");
  ResourceMark rm;
  Handle props(THREAD, JNIHandles::resolve_non_null(properties));
  PUTPROP(props, "sun.java.command", Arguments::java_command());
  PUTPROP(props, "sun.jvm.flags", Arguments::jvm_flags());
  PUTPROP(props, "sun.jvm.args", Arguments::jvm_args());
  return properties;
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass))
{
  JVMWrapper("JVM_GetEnclosingMethodInfo");
  JvmtiVMObjectAllocEventCollector oam;
  if (ofClass == NULL) {
    return NULL;
  }
  Handle mirror(THREAD, JNIHandles::resolve_non_null(ofClass));
  if (java_lang_Class::is_primitive(mirror())) {
    return NULL;
  }
  Klass* k = java_lang_Class::as_Klass(mirror());
  if (!k->oop_is_instance()) {
    return NULL;
  }
  instanceKlassHandle ik_h(THREAD, k);
  int encl_method_class_idx = ik_h->enclosing_method_class_index();
  if (encl_method_class_idx == 0) {
    return NULL;
  }
  objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::Object_klass(), 3, CHECK_NULL);
  objArrayHandle dest(THREAD, dest_o);
  Klass* enc_k = ik_h->constants()->klass_at(encl_method_class_idx, CHECK_NULL);
  dest->obj_at_put(0, enc_k->java_mirror());
  int encl_method_method_idx = ik_h->enclosing_method_method_index();
  if (encl_method_method_idx != 0) {
    Symbol* sym = ik_h->constants()->symbol_at(
                        extract_low_short_from_int(
                          ik_h->constants()->name_and_type_at(encl_method_method_idx)));
    Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
    dest->obj_at_put(1, str());
    sym = ik_h->constants()->symbol_at(
              extract_high_short_from_int(
                ik_h->constants()->name_and_type_at(encl_method_method_idx)));
    str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
    dest->obj_at_put(2, str());
  }
  return (jobjectArray) JNIHandles::make_local(dest());
}
JVM_END
JVM_ENTRY(jintArray, JVM_GetThreadStateValues(JNIEnv* env,
                                              jint javaThreadState))
{
  typeArrayHandle values_h;
  switch (javaThreadState) {
    case JAVA_THREAD_STATE_NEW : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::NEW);
      break;
    }
    case JAVA_THREAD_STATE_RUNNABLE : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::RUNNABLE);
      break;
    }
    case JAVA_THREAD_STATE_BLOCKED : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER);
      break;
    }
    case JAVA_THREAD_STATE_WAITING : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 2, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::IN_OBJECT_WAIT);
      values_h->int_at_put(1, java_lang_Thread::PARKED);
      break;
    }
    case JAVA_THREAD_STATE_TIMED_WAITING : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 3, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::SLEEPING);
      values_h->int_at_put(1, java_lang_Thread::IN_OBJECT_WAIT_TIMED);
      values_h->int_at_put(2, java_lang_Thread::PARKED_TIMED);
      break;
    }
    case JAVA_THREAD_STATE_TERMINATED : {
      typeArrayOop r = oopFactory::new_typeArray(T_INT, 1, CHECK_NULL);
      values_h = typeArrayHandle(THREAD, r);
      values_h->int_at_put(0, java_lang_Thread::TERMINATED);
      break;
    }
    default:
      return NULL;
  }
  return (jintArray) JNIHandles::make_local(env, values_h());
}
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetThreadStateNames(JNIEnv* env,
                                                jint javaThreadState,
                                                jintArray values))
{
  ResourceMark rm;
  if (values == NULL) {
    THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  }
  typeArrayOop v = typeArrayOop(JNIHandles::resolve_non_null(values));
  typeArrayHandle values_h(THREAD, v);
  objArrayHandle names_h;
  switch (javaThreadState) {
    case JAVA_THREAD_STATE_NEW : {
      assert(values_h->length() == 1 &&
               values_h->int_at(0) == java_lang_Thread::NEW,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               1, /* only 1 substate */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name = java_lang_String::create_from_str("NEW", CHECK_NULL);
      names_h->obj_at_put(0, name());
      break;
    }
    case JAVA_THREAD_STATE_RUNNABLE : {
      assert(values_h->length() == 1 &&
               values_h->int_at(0) == java_lang_Thread::RUNNABLE,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               1, /* only 1 substate */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name = java_lang_String::create_from_str("RUNNABLE", CHECK_NULL);
      names_h->obj_at_put(0, name());
      break;
    }
    case JAVA_THREAD_STATE_BLOCKED : {
      assert(values_h->length() == 1 &&
               values_h->int_at(0) == java_lang_Thread::BLOCKED_ON_MONITOR_ENTER,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               1, /* only 1 substate */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name = java_lang_String::create_from_str("BLOCKED", CHECK_NULL);
      names_h->obj_at_put(0, name());
      break;
    }
    case JAVA_THREAD_STATE_WAITING : {
      assert(values_h->length() == 2 &&
               values_h->int_at(0) == java_lang_Thread::IN_OBJECT_WAIT &&
               values_h->int_at(1) == java_lang_Thread::PARKED,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               2, /* number of substates */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name0 = java_lang_String::create_from_str("WAITING.OBJECT_WAIT",
                                                       CHECK_NULL);
      Handle name1 = java_lang_String::create_from_str("WAITING.PARKED",
                                                       CHECK_NULL);
      names_h->obj_at_put(0, name0());
      names_h->obj_at_put(1, name1());
      break;
    }
    case JAVA_THREAD_STATE_TIMED_WAITING : {
      assert(values_h->length() == 3 &&
               values_h->int_at(0) == java_lang_Thread::SLEEPING &&
               values_h->int_at(1) == java_lang_Thread::IN_OBJECT_WAIT_TIMED &&
               values_h->int_at(2) == java_lang_Thread::PARKED_TIMED,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               3, /* number of substates */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name0 = java_lang_String::create_from_str("TIMED_WAITING.SLEEPING",
                                                       CHECK_NULL);
      Handle name1 = java_lang_String::create_from_str("TIMED_WAITING.OBJECT_WAIT",
                                                       CHECK_NULL);
      Handle name2 = java_lang_String::create_from_str("TIMED_WAITING.PARKED",
                                                       CHECK_NULL);
      names_h->obj_at_put(0, name0());
      names_h->obj_at_put(1, name1());
      names_h->obj_at_put(2, name2());
      break;
    }
    case JAVA_THREAD_STATE_TERMINATED : {
      assert(values_h->length() == 1 &&
               values_h->int_at(0) == java_lang_Thread::TERMINATED,
             "Invalid threadStatus value");
      objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
                                               1, /* only 1 substate */
                                               CHECK_NULL);
      names_h = objArrayHandle(THREAD, r);
      Handle name = java_lang_String::create_from_str("TERMINATED", CHECK_NULL);
      names_h->obj_at_put(0, name());
      break;
    }
    default:
      return NULL;
  }
  return (jobjectArray) JNIHandles::make_local(env, names_h());
}
JVM_END
JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))
{
  memset(info, 0, info_size);
  info->jvm_version = Abstract_VM_Version::jvm_version();
  info->update_version = 0;          /* 0 in HotSpot Express VM */
  info->special_update_version = 0;  /* 0 in HotSpot Express VM */
  info->is_attachable = AttachListener::is_attach_supported();
}
JVM_END
C:\hotspot-69087d08d473\src\share\vm/prims/jvm.h
#ifndef SHARE_VM_PRIMS_JVM_H
#define SHARE_VM_PRIMS_JVM_H
#include "prims/jni.h"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "jvm_solaris.h"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "jvm_windows.h"
#endif
#ifdef TARGET_OS_FAMILY_aix
# include "jvm_aix.h"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "jvm_bsd.h"
#endif
#ifndef _JAVASOFT_JVM_H_
#define _JAVASOFT_JVM_H_
#ifdef __cplusplus
extern "C" {
#endif
#define JVM_INTERFACE_VERSION 4
JNIEXPORT jobjectArray JNICALL
JVM_GetMethodParameters(JNIEnv *env, jobject method);
JNIEXPORT jint JNICALL
JVM_GetInterfaceVersion(void);
 PART 1: Functions for Native Libraries
JNIEXPORT jint JNICALL
JVM_IHashCode(JNIEnv *env, jobject obj);
JNIEXPORT void JNICALL
JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms);
JNIEXPORT void JNICALL
JVM_MonitorNotify(JNIEnv *env, jobject obj);
JNIEXPORT void JNICALL
JVM_MonitorNotifyAll(JNIEnv *env, jobject obj);
JNIEXPORT jobject JNICALL
JVM_Clone(JNIEnv *env, jobject obj);
JNIEXPORT jstring JNICALL
JVM_InternString(JNIEnv *env, jstring str);
JNIEXPORT jlong JNICALL
JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);
JNIEXPORT jlong JNICALL
JVM_NanoTime(JNIEnv *env, jclass ignored);
JNIEXPORT void JNICALL
JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
              jobject dst, jint dst_pos, jint length);
JNIEXPORT jobject JNICALL
JVM_InitProperties(JNIEnv *env, jobject p);
JNIEXPORT void JNICALL
JVM_OnExit(void (*func)(void));
JNIEXPORT void JNICALL
JVM_CopySwapMemory(JNIEnv *env, jobject srcObj, jlong srcOffset,
                   jobject dstObj, jlong dstOffset, jlong size,
                   jlong elemSize);
JNIEXPORT void JNICALL
JVM_Exit(jint code);
JNIEXPORT void JNICALL
JVM_BeforeHalt();
JNIEXPORT void JNICALL
JVM_Halt(jint code);
JNIEXPORT void JNICALL
JVM_GC(void);
JNIEXPORT jlong JNICALL
JVM_MaxObjectInspectionAge(void);
JNIEXPORT void JNICALL
JVM_TraceInstructions(jboolean on);
JNIEXPORT void JNICALL
JVM_TraceMethodCalls(jboolean on);
JNIEXPORT jlong JNICALL
JVM_TotalMemory(void);
JNIEXPORT jlong JNICALL
JVM_FreeMemory(void);
JNIEXPORT jlong JNICALL
JVM_MaxMemory(void);
JNIEXPORT jint JNICALL
JVM_ActiveProcessorCount(void);
JNIEXPORT jboolean JNICALL
JVM_IsUseContainerSupport(void);
JNIEXPORT void * JNICALL
JVM_LoadLibrary(const char *name);
JNIEXPORT void JNICALL
JVM_UnloadLibrary(void * handle);
JNIEXPORT void * JNICALL
JVM_FindLibraryEntry(void *handle, const char *name);
JNIEXPORT jboolean JNICALL
JVM_IsSupportedJNIVersion(jint version);
JNIEXPORT jboolean JNICALL
JVM_IsNaN(jdouble d);
JNIEXPORT void JNICALL
JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
JNIEXPORT jint JNICALL
JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
JNIEXPORT jobject JNICALL
JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
JNIEXPORT void JNICALL
JVM_InitializeCompiler (JNIEnv *env, jclass compCls);
JNIEXPORT jboolean JNICALL
JVM_IsSilentCompiler(JNIEnv *env, jclass compCls);
JNIEXPORT jboolean JNICALL
JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls);
JNIEXPORT jboolean JNICALL
JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname);
JNIEXPORT jobject JNICALL
JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg);
JNIEXPORT void JNICALL
JVM_EnableCompiler(JNIEnv *env, jclass compCls);
JNIEXPORT void JNICALL
JVM_DisableCompiler(JNIEnv *env, jclass compCls);
JNIEXPORT void JNICALL
JVM_StartThread(JNIEnv *env, jobject thread);
JNIEXPORT void JNICALL
JVM_StopThread(JNIEnv *env, jobject thread, jobject exception);
JNIEXPORT jboolean JNICALL
JVM_IsThreadAlive(JNIEnv *env, jobject thread);
JNIEXPORT void JNICALL
JVM_SuspendThread(JNIEnv *env, jobject thread);
JNIEXPORT void JNICALL
JVM_ResumeThread(JNIEnv *env, jobject thread);
JNIEXPORT void JNICALL
JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio);
JNIEXPORT void JNICALL
JVM_Yield(JNIEnv *env, jclass threadClass);
JNIEXPORT void JNICALL
JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis);
JNIEXPORT jobject JNICALL
JVM_CurrentThread(JNIEnv *env, jclass threadClass);
JNIEXPORT jint JNICALL
JVM_CountStackFrames(JNIEnv *env, jobject thread);
JNIEXPORT void JNICALL
JVM_Interrupt(JNIEnv *env, jobject thread);
JNIEXPORT jboolean JNICALL
JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted);
JNIEXPORT jboolean JNICALL
JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj);
JNIEXPORT void JNICALL
JVM_DumpAllStacks(JNIEnv *env, jclass unused);
JNIEXPORT jobjectArray JNICALL
JVM_GetAllThreads(JNIEnv *env, jclass dummy);
JNIEXPORT void JNICALL
JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name);
JNIEXPORT jobjectArray JNICALL
JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
JNIEXPORT jclass JNICALL
JVM_CurrentLoadedClass(JNIEnv *env);
JNIEXPORT jobject JNICALL
JVM_CurrentClassLoader(JNIEnv *env);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassContext(JNIEnv *env);
JNIEXPORT jint JNICALL
JVM_ClassDepth(JNIEnv *env, jstring name);
JNIEXPORT jint JNICALL
JVM_ClassLoaderDepth(JNIEnv *env);
JNIEXPORT jstring JNICALL
JVM_GetSystemPackage(JNIEnv *env, jstring name);
JNIEXPORT jobjectArray JNICALL
JVM_GetSystemPackages(JNIEnv *env);
JNIEXPORT jobject JNICALL
JVM_AllocateNewObject(JNIEnv *env, jobject obj, jclass currClass,
                      jclass initClass);
JNIEXPORT jobject JNICALL
JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass,
                     jint length);
JNIEXPORT jobject JNICALL
JVM_LatestUserDefinedLoader(JNIEnv *env);
JNIEXPORT jclass JNICALL
JVM_LoadClass0(JNIEnv *env, jobject obj, jclass currClass,
               jstring currClassName);
JNIEXPORT jint JNICALL
JVM_GetArrayLength(JNIEnv *env, jobject arr);
JNIEXPORT jobject JNICALL
JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index);
JNIEXPORT jvalue JNICALL
JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode);
JNIEXPORT void JNICALL
JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val);
JNIEXPORT void JNICALL
JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v,
                             unsigned char vCode);
JNIEXPORT jobject JNICALL
JVM_NewArray(JNIEnv *env, jclass eltClass, jint length);
JNIEXPORT jobject JNICALL
JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
#define JVM_CALLER_DEPTH -1
JNIEXPORT jclass JNICALL
JVM_GetCallerClass(JNIEnv *env, int n);
JNIEXPORT jclass JNICALL
JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
JNIEXPORT void JNICALL
JVM_ResolveClass(JNIEnv *env, jclass cls);
JNIEXPORT jclass JNICALL
JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
                             jobject loader, jboolean throwError);
JNIEXPORT jclass JNICALL
JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
JNIEXPORT jclass JNICALL
JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
                        jobject loader, jclass caller);
JNIEXPORT jclass JNICALL
JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init,
                             jclass from);
JNIEXPORT jclass JNICALL
JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name);
JNIEXPORT jclass JNICALL
JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
                jsize len, jobject pd);
JNIEXPORT jclass JNICALL
JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
                          const jbyte *buf, jsize len, jobject pd,
                          const char *source);
JNIEXPORT jclass JNICALL
JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,
                              jobject loader, const jbyte *buf,
                              jsize len, jobject pd, const char *source,
                              jboolean verify);
JNIEXPORT jstring JNICALL
JVM_GetClassName(JNIEnv *env, jclass cls);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
JNIEXPORT jobject JNICALL
JVM_GetClassLoader(JNIEnv *env, jclass cls);
JNIEXPORT jboolean JNICALL
JVM_IsInterface(JNIEnv *env, jclass cls);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassSigners(JNIEnv *env, jclass cls);
JNIEXPORT void JNICALL
JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers);
JNIEXPORT jobject JNICALL
JVM_GetProtectionDomain(JNIEnv *env, jclass cls);
JNIEXPORT jboolean JNICALL
JVM_IsArrayClass(JNIEnv *env, jclass cls);
JNIEXPORT jboolean JNICALL
JVM_IsPrimitiveClass(JNIEnv *env, jclass cls);
JNIEXPORT jclass JNICALL
JVM_GetComponentType(JNIEnv *env, jclass cls);
JNIEXPORT jint JNICALL
JVM_GetClassModifiers(JNIEnv *env, jclass cls);
JNIEXPORT jobjectArray JNICALL
JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass);
JNIEXPORT jclass JNICALL
JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass);
JNIEXPORT jstring JNICALL
JVM_GetClassSignature(JNIEnv *env, jclass cls);
JNIEXPORT jbyteArray JNICALL
JVM_GetClassAnnotations(JNIEnv *env, jclass cls);
JNIEXPORT jbyteArray JNICALL
JVM_GetFieldAnnotations(JNIEnv *env, jobject field);
JNIEXPORT jbyteArray JNICALL
JVM_GetMethodAnnotations(JNIEnv *env, jobject method);
JNIEXPORT jbyteArray JNICALL
JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method);
JNIEXPORT jbyteArray JNICALL
JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method);
JNIEXPORT jbyteArray JNICALL
JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
JNIEXPORT jbyteArray JNICALL
JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field);
JNIEXPORT jbyteArray JNICALL
JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly);
JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
   This returns the access flags for the class as specified in the
   class file rather than searching the InnerClasses attribute (if
   present) to find the source-level access flags. Only the values of
   the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
   valid. */
JNIEXPORT jint JNICALL
JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
JNIEXPORT jobject JNICALL
JVM_GetClassConstantPool(JNIEnv *env, jclass cls);
JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize
(JNIEnv *env, jobject obj, jobject unused);
JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At
(JNIEnv *env, jobject obj, jobject unused, jint index);
JNIEXPORT jobject JNICALL
JVM_DoPrivileged(JNIEnv *env, jclass cls,
                 jobject action, jobject context, jboolean wrapException);
JNIEXPORT jobject JNICALL
JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
JNIEXPORT jobject JNICALL
JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
JNIEXPORT void * JNICALL
JVM_RegisterSignal(jint sig, void *handler);
JNIEXPORT jboolean JNICALL
JVM_RaiseSignal(jint sig);
JNIEXPORT jint JNICALL
JVM_FindSignal(const char *name);
JNIEXPORT jboolean JNICALL
JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls);
JNIEXPORT jobject JNICALL
JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused);
JNIEXPORT jboolean JNICALL
JVM_SupportsCX8(void);
JNIEXPORT jboolean JNICALL
JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fldID, jlong oldVal, jlong newVal);
#define JVM_TRACING_DTRACE_VERSION 1
typedef struct {
    jmethodID method;
    jstring   function;
    jstring   name;
    void*     reserved[4];     // for future use
} JVM_DTraceProbe;
typedef struct {
    jint nameStability;
    jint dataStability;
    jint dependencyClass;
} JVM_DTraceInterfaceAttributes;
typedef struct {
    jstring                       name;
    JVM_DTraceProbe*              probes;
    jint                          probe_count;
    JVM_DTraceInterfaceAttributes providerAttributes;
    JVM_DTraceInterfaceAttributes moduleAttributes;
    JVM_DTraceInterfaceAttributes functionAttributes;
    JVM_DTraceInterfaceAttributes nameAttributes;
    JVM_DTraceInterfaceAttributes argsAttributes;
    void*                         reserved[4]; // for future use
} JVM_DTraceProvider;
JNIEXPORT jint JNICALL
JVM_DTraceGetVersion(JNIEnv* env);
JNIEXPORT jlong JNICALL
JVM_DTraceActivate(JNIEnv* env, jint version, jstring module_name,
  jint providers_count, JVM_DTraceProvider* providers);
JNIEXPORT jboolean JNICALL
JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method);
JNIEXPORT void JNICALL
JVM_DTraceDispose(JNIEnv* env, jlong handle);
JNIEXPORT jboolean JNICALL
JVM_DTraceIsSupported(JNIEnv* env);
 PART 2: Support for the Verifier and Class File Format Checker
JNIEXPORT const char * JNICALL
JVM_GetClassNameUTF(JNIEnv *env, jclass cb);
JNIEXPORT void JNICALL
JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types);
JNIEXPORT jint JNICALL
JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb);
JNIEXPORT jint JNICALL
JVM_GetClassFieldsCount(JNIEnv *env, jclass cb);
JNIEXPORT jint JNICALL
JVM_GetClassMethodsCount(JNIEnv *env, jclass cb);
JNIEXPORT void JNICALL
JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index,
                                unsigned short *exceptions);
JNIEXPORT jint JNICALL
JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index);
JNIEXPORT void JNICALL
JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index,
                        unsigned char *code);
JNIEXPORT jint JNICALL
JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index);
typedef struct {
    jint start_pc;
    jint end_pc;
    jint handler_pc;
    jint catchType;
} JVM_ExceptionTableEntryType;
JNIEXPORT void JNICALL
JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index,
                                   jint entry_index,
                                   JVM_ExceptionTableEntryType *entry);
JNIEXPORT jint JNICALL
JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index);
JNIEXPORT jint JNICALL
JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index);
JNIEXPORT jint JNICALL
JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index);
JNIEXPORT jint JNICALL
JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index);
JNIEXPORT jint JNICALL
JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index);
JNIEXPORT jint JNICALL
JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index);
JNIEXPORT jboolean JNICALL
JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
JNIEXPORT jboolean JNICALL
JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index);
JNIEXPORT const char * JNICALL
JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT const char * JNICALL
JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index);
JNIEXPORT jint JNICALL
JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
JNIEXPORT jint JNICALL
JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
JNIEXPORT void JNICALL
JVM_ReleaseUTF(const char *utf);
JNIEXPORT jboolean JNICALL
JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2);
#define JVM_ACC_PUBLIC        0x0001  /* visible to everyone */
#define JVM_ACC_PRIVATE       0x0002  /* visible only to the defining class */
#define JVM_ACC_PROTECTED     0x0004  /* visible to subclasses */
#define JVM_ACC_STATIC        0x0008  /* instance variable is static */
#define JVM_ACC_FINAL         0x0010  /* no further subclassing, overriding */
#define JVM_ACC_SYNCHRONIZED  0x0020  /* wrap method call in monitor lock */
#define JVM_ACC_SUPER         0x0020  /* funky handling of invokespecial */
#define JVM_ACC_VOLATILE      0x0040  /* can not cache in registers */
#define JVM_ACC_BRIDGE        0x0040  /* bridge method generated by compiler */
#define JVM_ACC_TRANSIENT     0x0080  /* not persistent */
#define JVM_ACC_VARARGS       0x0080  /* method declared with variable number of args */
#define JVM_ACC_NATIVE        0x0100  /* implemented in C */
#define JVM_ACC_INTERFACE     0x0200  /* class is an interface */
#define JVM_ACC_ABSTRACT      0x0400  /* no definition provided */
#define JVM_ACC_STRICT        0x0800  /* strict floating point */
#define JVM_ACC_SYNTHETIC     0x1000  /* compiler-generated class, method or field */
#define JVM_ACC_ANNOTATION    0x2000  /* annotation type */
#define JVM_ACC_ENUM          0x4000  /* field is declared as element of enum */
#define JVM_ACC_PUBLIC_BIT        0
#define JVM_ACC_PRIVATE_BIT       1
#define JVM_ACC_PROTECTED_BIT     2
#define JVM_ACC_STATIC_BIT        3
#define JVM_ACC_FINAL_BIT         4
#define JVM_ACC_SYNCHRONIZED_BIT  5
#define JVM_ACC_SUPER_BIT         5
#define JVM_ACC_VOLATILE_BIT      6
#define JVM_ACC_BRIDGE_BIT        6
#define JVM_ACC_TRANSIENT_BIT     7
#define JVM_ACC_VARARGS_BIT       7
#define JVM_ACC_NATIVE_BIT        8
#define JVM_ACC_INTERFACE_BIT     9
#define JVM_ACC_ABSTRACT_BIT      10
#define JVM_ACC_STRICT_BIT        11
#define JVM_ACC_SYNTHETIC_BIT     12
#define JVM_ACC_ANNOTATION_BIT    13
#define JVM_ACC_ENUM_BIT          14
enum {
    JVM_CONSTANT_Utf8 = 1,
    JVM_CONSTANT_Unicode,               /* unused */
    JVM_CONSTANT_Integer,
    JVM_CONSTANT_Float,
    JVM_CONSTANT_Long,
    JVM_CONSTANT_Double,
    JVM_CONSTANT_Class,
    JVM_CONSTANT_String,
    JVM_CONSTANT_Fieldref,
    JVM_CONSTANT_Methodref,
    JVM_CONSTANT_InterfaceMethodref,
    JVM_CONSTANT_NameAndType,
    JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
    JVM_CONSTANT_MethodType             = 16,  // JSR 292
    JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
    JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
};
enum {
    JVM_REF_getField                = 1,
    JVM_REF_getStatic               = 2,
    JVM_REF_putField                = 3,
    JVM_REF_putStatic               = 4,
    JVM_REF_invokeVirtual           = 5,
    JVM_REF_invokeStatic            = 6,
    JVM_REF_invokeSpecial           = 7,
    JVM_REF_newInvokeSpecial        = 8,
    JVM_REF_invokeInterface         = 9
};
#define JVM_T_BOOLEAN 4
#define JVM_T_CHAR    5
#define JVM_T_FLOAT   6
#define JVM_T_DOUBLE  7
#define JVM_T_BYTE    8
#define JVM_T_SHORT   9
#define JVM_T_INT    10
#define JVM_T_LONG   11
#define JVM_SIGNATURE_ARRAY             '['
#define JVM_SIGNATURE_BYTE              'B'
#define JVM_SIGNATURE_CHAR              'C'
#define JVM_SIGNATURE_CLASS             'L'
#define JVM_SIGNATURE_ENDCLASS          ';'
#define JVM_SIGNATURE_ENUM              'E'
#define JVM_SIGNATURE_FLOAT             'F'
#define JVM_SIGNATURE_DOUBLE            'D'
#define JVM_SIGNATURE_FUNC              '('
#define JVM_SIGNATURE_ENDFUNC           ')'
#define JVM_SIGNATURE_INT               'I'
#define JVM_SIGNATURE_LONG              'J'
#define JVM_SIGNATURE_SHORT             'S'
#define JVM_SIGNATURE_VOID              'V'
#define JVM_SIGNATURE_BOOLEAN           'Z'
typedef jboolean (*verifier_fn_t)(JNIEnv *env,
                                  jclass cb,
                                  char * msg_buf,
                                  jint buf_len);
typedef struct {
    unsigned long code;    /* byte code */
    unsigned long excs;    /* exceptions */
    unsigned long etab;    /* catch table */
    unsigned long lnum;    /* line number */
    unsigned long lvar;    /* local vars */
} method_size_info;
typedef struct {
    unsigned int constants;    /* constant pool */
    unsigned int fields;
    unsigned int methods;
    unsigned int interfaces;
    unsigned int fields2;      /* number of static 2-word fields */
    unsigned int innerclasses; /* # of records in InnerClasses attr */
    method_size_info clinit;   /* memory used in clinit */
    method_size_info main;     /* used everywhere else */
} class_size_info;
typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
typedef jint (*check_format_fn_t)(char *class_name,
                                  unsigned char *data,
                                  unsigned int data_size,
                                  class_size_info *class_size,
                                  char *message_buffer,
                                  jint buffer_length,
                                  jboolean measure_only,
                                  jboolean check_relaxed);
#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
                                        JVM_ACC_FINAL | \
                                        JVM_ACC_SUPER | \
                                        JVM_ACC_INTERFACE | \
                                        JVM_ACC_ABSTRACT | \
                                        JVM_ACC_ANNOTATION | \
                                        JVM_ACC_ENUM | \
                                        JVM_ACC_SYNTHETIC)
#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \
                                        JVM_ACC_PRIVATE | \
                                        JVM_ACC_PROTECTED | \
                                        JVM_ACC_STATIC | \
                                        JVM_ACC_FINAL | \
                                        JVM_ACC_VOLATILE | \
                                        JVM_ACC_TRANSIENT | \
                                        JVM_ACC_ENUM | \
                                        JVM_ACC_SYNTHETIC)
#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \
                                         JVM_ACC_PRIVATE | \
                                         JVM_ACC_PROTECTED | \
                                         JVM_ACC_STATIC | \
                                         JVM_ACC_FINAL | \
                                         JVM_ACC_SYNCHRONIZED | \
                                         JVM_ACC_BRIDGE | \
                                         JVM_ACC_VARARGS | \
                                         JVM_ACC_NATIVE | \
                                         JVM_ACC_ABSTRACT | \
                                         JVM_ACC_STRICT | \
                                         JVM_ACC_SYNTHETIC)
typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len);
 PART 3: I/O and Network Support
#define JVM_IO_ERR  (-1)
#define JVM_IO_INTR (-2)
JNIEXPORT jint JNICALL
JVM_GetLastErrorString(char *buf, int len);
JNIEXPORT char * JNICALL
JVM_NativePath(char *);
#define JVM_EEXIST       -100
JNIEXPORT jint JNICALL
JVM_Open(const char *fname, jint flags, jint mode);
JNIEXPORT jint JNICALL
JVM_Close(jint fd);
JNIEXPORT jint JNICALL
JVM_Read(jint fd, char *buf, jint nbytes);
JNIEXPORT jint JNICALL
JVM_Write(jint fd, char *buf, jint nbytes);
JNIEXPORT jint JNICALL
JVM_Available(jint fd, jlong *pbytes);
JNIEXPORT jlong JNICALL
JVM_Lseek(jint fd, jlong offset, jint whence);
JNIEXPORT jint JNICALL
JVM_SetLength(jint fd, jlong length);
JNIEXPORT jint JNICALL
JVM_Sync(jint fd);
JNIEXPORT jint JNICALL
JVM_InitializeSocketLibrary(void);
struct sockaddr;
JNIEXPORT jint JNICALL
JVM_Socket(jint domain, jint type, jint protocol);
JNIEXPORT jint JNICALL
JVM_SocketClose(jint fd);
JNIEXPORT jint JNICALL
JVM_SocketShutdown(jint fd, jint howto);
JNIEXPORT jint JNICALL
JVM_Recv(jint fd, char *buf, jint nBytes, jint flags);
JNIEXPORT jint JNICALL
JVM_Send(jint fd, char *buf, jint nBytes, jint flags);
JNIEXPORT jint JNICALL
JVM_Timeout(int fd, long timeout);
JNIEXPORT jint JNICALL
JVM_Listen(jint fd, jint count);
JNIEXPORT jint JNICALL
JVM_Connect(jint fd, struct sockaddr *him, jint len);
JNIEXPORT jint JNICALL
JVM_Bind(jint fd, struct sockaddr *him, jint len);
JNIEXPORT jint JNICALL
JVM_Accept(jint fd, struct sockaddr *him, jint *len);
JNIEXPORT jint JNICALL
JVM_RecvFrom(jint fd, char *buf, int nBytes,
                  int flags, struct sockaddr *from, int *fromlen);
JNIEXPORT jint JNICALL
JVM_SendTo(jint fd, char *buf, int len,
                int flags, struct sockaddr *to, int tolen);
JNIEXPORT jint JNICALL
JVM_SocketAvailable(jint fd, jint *result);
JNIEXPORT jint JNICALL
JVM_GetSockName(jint fd, struct sockaddr *him, int *len);
JNIEXPORT jint JNICALL
JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen);
JNIEXPORT jint JNICALL
JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen);
JNIEXPORT int JNICALL
JVM_GetHostName(char* name, int namelen);
JNIEXPORT int
jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
JNIEXPORT int
jio_snprintf(char *str, size_t count, const char *fmt, ...);
JNIEXPORT int
jio_fprintf(FILE *, const char *fmt, ...);
JNIEXPORT int
jio_vfprintf(FILE *, const char *fmt, va_list args);
JNIEXPORT void * JNICALL
JVM_RawMonitorCreate(void);
JNIEXPORT void JNICALL
JVM_RawMonitorDestroy(void *mon);
JNIEXPORT jint JNICALL
JVM_RawMonitorEnter(void *mon);
JNIEXPORT void JNICALL
JVM_RawMonitorExit(void *mon);
JNIEXPORT jobject JNICALL
JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0);
JNIEXPORT jobject JNICALL
JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
JNIEXPORT void* JNICALL
JVM_GetManagement(jint version);
JNIEXPORT jobject JNICALL
JVM_InitAgentProperties(JNIEnv *env, jobject agent_props);
JNIEXPORT jstring JNICALL
JVM_GetTemporaryDirectory(JNIEnv *env);
JNIEXPORT jobjectArray JNICALL
JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass);
enum {
    JAVA_THREAD_STATE_NEW           = 0,
    JAVA_THREAD_STATE_RUNNABLE      = 1,
    JAVA_THREAD_STATE_BLOCKED       = 2,
    JAVA_THREAD_STATE_WAITING       = 3,
    JAVA_THREAD_STATE_TIMED_WAITING = 4,
    JAVA_THREAD_STATE_TERMINATED    = 5,
    JAVA_THREAD_STATE_COUNT         = 6
};
JNIEXPORT jintArray JNICALL
JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState);
JNIEXPORT jobjectArray JNICALL
JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
JNIEXPORT jboolean JNICALL
JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname);
JNIEXPORT jobjectArray JNICALL
JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader);
JNIEXPORT jintArray JNICALL
JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name);
typedef struct {
    unsigned int jvm_version; /* Consists of major.minor.0.build */
    unsigned int update_version : 8;         /* 0 in HotSpot Express VM */
    unsigned int special_update_version : 8; /* 0 in HotSpot Express VM */
    unsigned int reserved1 : 16;
    unsigned int reserved2;
    unsigned int is_attachable : 1;
    unsigned int : 31;
    unsigned int : 32;
    unsigned int : 32;
} jvm_version_info;
#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
#define JVM_VERSION_MINOR(version) ((version & 0x00FFFF00) >> 8)
#define JVM_VERSION_MICRO(version) 0
#define JVM_VERSION_BUILD(version) ((version & 0x000000FF))
JNIEXPORT void JNICALL
JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size);
typedef struct {
    unsigned int jdk_version;   /* Consists of major, minor, micro (n.n.n) */
    unsigned int update_version : 16;        /* Update release version (uu) */
    unsigned int special_update_version : 8; /* Special update release version (c)*/
    unsigned int reserved1 : 8;
    unsigned int reserved2;
    unsigned int thread_park_blocker : 1;
    unsigned int post_vm_init_hook_enabled : 1;
    unsigned int pending_list_uses_discovered_field : 1;
    unsigned int : 29;
    unsigned int : 32;
    unsigned int : 32;
} jdk_version_info;
#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
#define JDK_VERSION_MICRO(version) ((version & 0x0000FF00) >> 8)
#define JDK_VERSION_BUILD(version) ((version & 0x000000FF))
typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size);
typedef struct JDK1_1InitArgs {
    jint version;
    char **properties;
    jint checkSource;
    jint nativeStackSize;
    jint javaStackSize;
    jint minHeapSize;
    jint maxHeapSize;
    jint verifyMode;
    char *classpath;
    jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args);
    void (JNICALL *exit)(jint code);
    void (JNICALL *abort)(void);
    jint enableClassGC;
    jint enableVerboseGC;
    jint disableAsyncGC;
    jint verbose;
    jboolean debugging;
    jint debugPort;
} JDK1_1InitArgs;
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* !_JAVASOFT_JVM_H_ */
#endif // SHARE_VM_PRIMS_JVM_H
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiAgentThread.hpp
#ifndef SHARE_VM_PRIMS_JVMTIAGENTTHREAD_HPP
#define SHARE_VM_PRIMS_JVMTIAGENTTHREAD_HPP
#include "jvmtifiles/jvmtiEnv.hpp"
class JvmtiAgentThread : public JavaThread {
  jvmtiStartFunction _start_fn;
  JvmtiEnv* _env;
  const void *_start_arg;
public:
  JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg);
  bool is_jvmti_agent_thread() const    { return true; }
  static void start_function_wrapper(JavaThread *thread, TRAPS);
  void call_start_function();
};
#endif // SHARE_VM_PRIMS_JVMTIAGENTTHREAD_HPP
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiClassFileReconstituter.cpp
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "oops/fieldStreams.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
#include "runtime/signature.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_aarch64
# include "bytes_aarch64.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
void JvmtiClassFileReconstituter::write_field_infos() {
  HandleMark hm(thread());
  Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations();
  Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations();
  int java_fields = ikh()->java_fields_count();
  write_u2(java_fields);
  for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) {
    AccessFlags access_flags = fs.access_flags();
    int name_index = fs.name_index();
    int signature_index = fs.signature_index();
    int initial_value_index = fs.initval_index();
    guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");
    int generic_signature_index = fs.generic_signature_index();
    AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());
    AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());
    write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
    write_u2(name_index);
    write_u2(signature_index);
    int attr_count = 0;
    if (initial_value_index != 0) {
      ++attr_count;
    }
    if (access_flags.is_synthetic()) {
    }
    if (generic_signature_index != 0) {
      ++attr_count;
    }
    if (anno != NULL) {
      ++attr_count;     // has RuntimeVisibleAnnotations attribute
    }
    if (type_anno != NULL) {
      ++attr_count;     // has RuntimeVisibleTypeAnnotations attribute
    }
    write_u2(attr_count);
    if (initial_value_index != 0) {
      write_attribute_name_index("ConstantValue");
      write_u4(2); //length always 2
      write_u2(initial_value_index);
    }
    if (access_flags.is_synthetic()) {
    }
    if (generic_signature_index != 0) {
      write_signature_attribute(generic_signature_index);
    }
    if (anno != NULL) {
      write_annotations_attribute("RuntimeVisibleAnnotations", anno);
    }
    if (type_anno != NULL) {
      write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
    }
  }
}
void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
  ConstMethod* const_method = method->constMethod();
  u2 line_num_cnt = 0;
  int stackmap_len = 0;
  int local_variable_table_length = 0;
  int local_variable_type_table_length = 0;
  int attr_count = 0;
  int attr_size = 0;
  if (const_method->has_linenumber_table()) {
    line_num_cnt = line_number_table_entries(method);
    if (line_num_cnt != 0) {
      ++attr_count;
      attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
    }
  }
  if (method->has_stackmap_table()) {
    stackmap_len = method->stackmap_data()->length();
    if (stackmap_len != 0) {
      ++attr_count;
      attr_size += 2 + 4 + stackmap_len;
    }
  }
  if (method->has_localvariable_table()) {
    local_variable_table_length = method->localvariable_table_length();
    if (local_variable_table_length != 0) {
      ++attr_count;
      attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
      LocalVariableTableElement *elem = method->localvariable_table_start();
      for (int idx = 0; idx < local_variable_table_length; idx++) {
        if (elem[idx].signature_cp_index != 0) {
          local_variable_type_table_length++;
        }
      }
      if (local_variable_type_table_length != 0) {
        ++attr_count;
        attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);
      }
    }
  }
  ExceptionTable exception_table(method());
  int exception_table_length = exception_table.length();
  int code_size = const_method->code_size();
  int size =
    2+2+4 +                                // max_stack, max_locals, code_length
    code_size +                            // code
    2 +                                    // exception_table_length
    (2+2+2+2) * exception_table_length +   // exception_table
    2 +                                    // attributes_count
    attr_size;                             // attributes
  write_attribute_name_index("Code");
  write_u4(size);
  write_u2(method->verifier_max_stack());
  write_u2(method->max_locals());
  write_u4(code_size);
  copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
  write_u2(exception_table_length);
  for (int index = 0; index < exception_table_length; index++) {
    write_u2(exception_table.start_pc(index));
    write_u2(exception_table.end_pc(index));
    write_u2(exception_table.handler_pc(index));
    write_u2(exception_table.catch_type_index(index));
  }
  write_u2(attr_count);
  if (line_num_cnt != 0) {
    write_line_number_table_attribute(method, line_num_cnt);
  }
  if (stackmap_len != 0) {
    write_stackmap_table_attribute(method, stackmap_len);
  }
  if (local_variable_table_length != 0) {
    write_local_variable_table_attribute(method, local_variable_table_length);
  }
  if (local_variable_type_table_length != 0) {
    write_local_variable_type_table_attribute(method, local_variable_type_table_length);
  }
}
void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) {
  CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();
  int checked_exceptions_length = const_method->checked_exceptions_length();
  int size =
    2 +                                    // number_of_exceptions
    2 * checked_exceptions_length;         // exception_index_table
  write_attribute_name_index("Exceptions");
  write_u4(size);
  write_u2(checked_exceptions_length);
  for (int index = 0; index < checked_exceptions_length; index++) {
    write_u2(checked_exceptions[index].class_cp_index);
  }
}
void JvmtiClassFileReconstituter::write_source_file_attribute() {
  assert(ikh()->source_file_name() != NULL, "caller must check");
  write_attribute_name_index("SourceFile");
  write_u4(2);  // always length 2
  write_u2(symbol_to_cpool_index(ikh()->source_file_name()));
}
void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
  assert(ikh()->source_debug_extension() != NULL, "caller must check");
  write_attribute_name_index("SourceDebugExtension");
  int len = (int)strlen(ikh()->source_debug_extension());
  write_u4(len);
  u1* ext = (u1*)ikh()->source_debug_extension();
  for (int i=0; i<len; i++) {
    write_u1(ext[i]);
  }
}
void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) {
  write_attribute_name_index("Signature");
  write_u4(2);  // always length 2
  write_u2(generic_signature_index);
}
u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
  InnerClassesIterator iter(ikh());
  return iter.length();
}
void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,
                                                              AnnotationArray* annos) {
  u4 length = annos->length();
  write_attribute_name_index(attr_name);
  write_u4(length);
  memcpy(writeable_address(length), annos->adr_at(0), length);
}
void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
  Array<u2>* operands = cpool()->operands();
  write_attribute_name_index("BootstrapMethods");
  int num_bootstrap_methods = ConstantPool::operand_array_length(operands);
  int length = sizeof(u2); // num_bootstrap_methods
  for (int n = 0; n < num_bootstrap_methods; n++) {
    u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
    length += sizeof(u2); // bootstrap_method_ref
    length += sizeof(u2); // num_bootstrap_arguments
    length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
  }
  write_u4(length);
  write_u2(num_bootstrap_methods);
  for (int n = 0; n < num_bootstrap_methods; n++) {
    u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
    u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
    write_u2(bootstrap_method_ref);
    write_u2(num_bootstrap_arguments);
    for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
      u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
      write_u2(bootstrap_argument);
    }
  }
}
void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
  InnerClassesIterator iter(ikh());
  guarantee(iter.length() != 0 && iter.length() == length,
            "caller must check");
  u2 entry_count = length / InstanceKlass::inner_class_next_offset;
  u4 size = 2 + entry_count * (2+2+2+2);
  write_attribute_name_index("InnerClasses");
  write_u4(size);
  write_u2(entry_count);
  for (; !iter.done(); iter.next()) {
    write_u2(iter.inner_class_info_index());
    write_u2(iter.outer_class_info_index());
    write_u2(iter.inner_name_index());
    write_u2(iter.inner_access_flags());
  }
}
void JvmtiClassFileReconstituter::write_synthetic_attribute() {
  write_attribute_name_index("Synthetic");
  write_u4(0); //length always zero
}
u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) {
  u2 num_entries = 0;
  CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
  while (stream.read_pair()) {
    num_entries++;
  }
  return num_entries;
}
void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,
                                                                    u2 num_entries) {
  write_attribute_name_index("LineNumberTable");
  write_u4(2 + num_entries * (2 + 2));
  write_u2(num_entries);
  CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
  while (stream.read_pair()) {
    write_u2(stream.bci());
    write_u2(stream.line());
  }
}
void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
    write_attribute_name_index("LocalVariableTable");
    write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
    write_u2(num_entries);
    assert(method->localvariable_table_length() == num_entries, "just checking");
    LocalVariableTableElement *elem = method->localvariable_table_start();
    for (int j=0; j<method->localvariable_table_length(); j++) {
      write_u2(elem->start_bci);
      write_u2(elem->length);
      write_u2(elem->name_cp_index);
      write_u2(elem->descriptor_cp_index);
      write_u2(elem->slot);
      elem++;
    }
}
void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {
    write_attribute_name_index("LocalVariableTypeTable");
    write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
    write_u2(num_entries);
    LocalVariableTableElement *elem = method->localvariable_table_start();
    for (int j=0; j<method->localvariable_table_length(); j++) {
      if (elem->signature_cp_index > 0) {
        write_u2(elem->start_bci);
        write_u2(elem->length);
        write_u2(elem->name_cp_index);
        write_u2(elem->signature_cp_index);
        write_u2(elem->slot);
        num_entries--;
      }
      elem++;
    }
    assert(num_entries == 0, "just checking");
}
void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,
                                                                 int stackmap_len) {
  write_attribute_name_index("StackMapTable");
  write_u4(stackmap_len);
  memcpy(
    writeable_address(stackmap_len),
    (void*)(method->stackmap_data()->adr_at(0)),
    stackmap_len);
}
void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
  AccessFlags access_flags = method->access_flags();
  ConstMethod* const_method = method->constMethod();
  u2 generic_signature_index = const_method->generic_signature_index();
  AnnotationArray* anno = method->annotations();
  AnnotationArray* param_anno = method->parameter_annotations();
  AnnotationArray* default_anno = method->annotation_default();
  AnnotationArray* type_anno = method->type_annotations();
  if (method->is_overpass()) {
    return;
  }
  write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
  write_u2(const_method->name_index());
  write_u2(const_method->signature_index());
  int attr_count = 0;
  if (const_method->code_size() != 0) {
    ++attr_count;     // has Code attribute
  }
  if (const_method->has_checked_exceptions()) {
    ++attr_count;     // has Exceptions attribute
  }
  if (default_anno != NULL) {
    ++attr_count;     // has AnnotationDefault attribute
  }
  if (access_flags.is_synthetic()) { // FIXME
  }
  if (generic_signature_index != 0) {
    ++attr_count;
  }
  if (anno != NULL) {
    ++attr_count;     // has RuntimeVisibleAnnotations attribute
  }
  if (param_anno != NULL) {
    ++attr_count;     // has RuntimeVisibleParameterAnnotations attribute
  }
  if (type_anno != NULL) {
    ++attr_count;     // has RuntimeVisibleTypeAnnotations attribute
  }
  write_u2(attr_count);
  if (const_method->code_size() > 0) {
    write_code_attribute(method);
  }
  if (const_method->has_checked_exceptions()) {
    write_exceptions_attribute(const_method);
  }
  if (default_anno != NULL) {
    write_annotations_attribute("AnnotationDefault", default_anno);
  }
  if (access_flags.is_synthetic()) {
  }
  if (generic_signature_index != 0) {
    write_signature_attribute(generic_signature_index);
  }
  if (anno != NULL) {
    write_annotations_attribute("RuntimeVisibleAnnotations", anno);
  }
  if (param_anno != NULL) {
    write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
  }
  if (type_anno != NULL) {
    write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
  }
}
void JvmtiClassFileReconstituter::write_class_attributes() {
  u2 inner_classes_length = inner_classes_attribute_length();
  Symbol* generic_signature = ikh()->generic_signature();
  AnnotationArray* anno = ikh()->class_annotations();
  AnnotationArray* type_anno = ikh()->class_type_annotations();
  int attr_count = 0;
  if (generic_signature != NULL) {
    ++attr_count;
  }
  if (ikh()->source_file_name() != NULL) {
    ++attr_count;
  }
  if (ikh()->source_debug_extension() != NULL) {
    ++attr_count;
  }
  if (inner_classes_length > 0) {
    ++attr_count;
  }
  if (anno != NULL) {
    ++attr_count;     // has RuntimeVisibleAnnotations attribute
  }
  if (type_anno != NULL) {
    ++attr_count;     // has RuntimeVisibleTypeAnnotations attribute
  }
  if (cpool()->operands() != NULL) {
    ++attr_count;
  }
  write_u2(attr_count);
  if (generic_signature != NULL) {
    write_signature_attribute(symbol_to_cpool_index(generic_signature));
  }
  if (ikh()->source_file_name() != NULL) {
    write_source_file_attribute();
  }
  if (ikh()->source_debug_extension() != NULL) {
    write_source_debug_extension_attribute();
  }
  if (inner_classes_length > 0) {
    write_inner_classes_attribute(inner_classes_length);
  }
  if (anno != NULL) {
    write_annotations_attribute("RuntimeVisibleAnnotations", anno);
  }
  if (type_anno != NULL) {
    write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
  }
  if (cpool()->operands() != NULL) {
    write_bootstrapmethod_attribute();
  }
}
void JvmtiClassFileReconstituter::write_method_infos() {
  HandleMark hm(thread());
  Array<Method*>* methods = ikh()->methods();
  int num_methods = methods->length();
  int num_overpass = 0;
  for (int index = 0; index < num_methods; index++) {
    Method* method = methods->at(index);
    if (method->is_overpass()) {
      num_overpass++;
    }
  }
  write_u2(num_methods - num_overpass);
  if (JvmtiExport::can_maintain_original_method_order()) {
    int index;
    int original_index;
    intArray method_order(num_methods, 0);
    for (index = 0; index < num_methods; index++) {
      original_index = ikh()->method_ordering()->at(index);
      assert(original_index >= 0 && original_index < num_methods,
             "invalid original method index");
      method_order.at_put(original_index, index);
    }
    for (original_index = 0; original_index < num_methods; original_index++) {
      index = method_order.at(original_index);
      methodHandle method(thread(), methods->at(index));
      write_method_info(method);
    }
  } else {
    for (int index = 0; index < num_methods; index++) {
      methodHandle method(thread(), methods->at(index));
      write_method_info(method);
    }
  }
}
void JvmtiClassFileReconstituter::write_class_file_format() {
  ReallocMark();
  write_u4(0xCAFEBABE);
  write_u2(ikh()->minor_version());
  u2 major = ikh()->major_version();
  write_u2(major);
  write_u2(cpool()->length());
  copy_cpool_bytes(writeable_address(cpool_size()));
  write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS);
  write_u2(class_symbol_to_cpool_index(ikh()->name()));
  Klass* super_class = ikh()->super();
  write_u2(super_class == NULL? 0 :  // zero for java.lang.Object
                class_symbol_to_cpool_index(super_class->name()));
  Array<Klass*>* interfaces =  ikh()->local_interfaces();
  int num_interfaces = interfaces->length();
  write_u2(num_interfaces);
  for (int index = 0; index < num_interfaces; index++) {
    HandleMark hm(thread());
    instanceKlassHandle iikh(thread(), interfaces->at(index));
    write_u2(class_symbol_to_cpool_index(iikh->name()));
  }
  write_field_infos();
  write_method_infos();
  write_class_attributes();
}
address JvmtiClassFileReconstituter::writeable_address(size_t size) {
  size_t used_size = _buffer_ptr - _buffer;
  if (size + used_size >= _buffer_size) {
    size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size
    _buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size);
    _buffer_size = new_buffer_size;
    _buffer_ptr = _buffer + used_size;
  }
  u1* ret_ptr = _buffer_ptr;
  _buffer_ptr += size;
  return ret_ptr;
}
void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) {
  TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name));
  assert(sym != NULL, "attribute name symbol not found");
  u2 attr_name_index = symbol_to_cpool_index(sym);
  assert(attr_name_index != 0, "attribute name symbol not in constant pool");
  write_u2(attr_name_index);
}
void JvmtiClassFileReconstituter::write_u1(u1 x) {
}
void JvmtiClassFileReconstituter::write_u2(u2 x) {
  Bytes::put_Java_u2(writeable_address(2), x);
}
void JvmtiClassFileReconstituter::write_u4(u4 x) {
  Bytes::put_Java_u4(writeable_address(4), x);
}
void JvmtiClassFileReconstituter::write_u8(u8 x) {
  Bytes::put_Java_u8(writeable_address(8), x);
}
void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
                                                 unsigned char* bytecodes) {
  BytecodeStream bs(mh);
  unsigned char* p = bytecodes;
  Bytecodes::Code code;
  bool is_rewritten = mh->method_holder()->is_rewritten();
  while ((code = bs.next()) >= 0) {
    assert(Bytecodes::is_java_code(code), "sanity check");
    assert(code != Bytecodes::_breakpoint, "sanity check");
    address bcp = bs.bcp();
    int     len = bs.instruction_size();
    assert(len > 0, "length must be > 0");
    if (len > 1) {
      memcpy(p+1, bcp+1, len-1);
    }
    if (is_rewritten && len > 1) {
      bool is_wide = false;
      switch (code) {
      case Bytecodes::_getstatic       :  // fall through
      case Bytecodes::_putstatic       :  // fall through
      case Bytecodes::_getfield        :  // fall through
      case Bytecodes::_putfield        :  // fall through
      case Bytecodes::_invokevirtual   :  // fall through
      case Bytecodes::_invokespecial   :  // fall through
      case Bytecodes::_invokestatic    :  // fall through
      case Bytecodes::_invokedynamic   :  // fall through
      case Bytecodes::_invokeinterface : {
        assert(len == 3 ||
               (code == Bytecodes::_invokeinterface && len == 5) ||
               (code == Bytecodes::_invokedynamic   && len == 5),
               "sanity check");
        int cpci = Bytes::get_native_u2(bcp+1);
        bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);
        ConstantPoolCacheEntry* entry;
        if (is_invokedynamic) {
          cpci = Bytes::get_native_u4(bcp+1);
          entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci);
        } else {
          entry = mh->constants()->cache()->entry_at(cpci);
        }
        int i = entry->constant_pool_index();
        assert(i < mh->constants()->length(), "sanity check");
        Bytes::put_Java_u2((address)(p+1), (u2)i);     // java byte ordering
        if (is_invokedynamic)  *(p+3) = *(p+4) = 0;
        break;
      }
      case Bytecodes::_ldc_w:
        is_wide = true; // fall through
      case Bytecodes::_ldc: {
        if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) {
          int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1));
          int i = mh->constants()->object_to_cp_index(cpci);
          assert(i < mh->constants()->length(), "sanity check");
          if (is_wide) {
            Bytes::put_Java_u2((address)(p+1), (u2)i);     // java byte ordering
          } else {
          }
        }
        break;
        }
      }
    }
    p += len;
  }
}
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiClassFileReconstituter.hpp
#ifndef SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
#define SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
#include "jvmtifiles/jvmtiEnv.hpp"
class JvmtiConstantPoolReconstituter : public StackObj {
 private:
  int                  _cpool_size;
  SymbolHashMap*       _symmap;
  SymbolHashMap*       _classmap;
  constantPoolHandle   _cpool;
  instanceKlassHandle  _ikh;
  jvmtiError           _err;
 protected:
  instanceKlassHandle  ikh()     { return _ikh; };
  constantPoolHandle   cpool()   { return _cpool; };
  u2 symbol_to_cpool_index(Symbol* sym) {
    return _symmap->symbol_to_value(sym);
  }
  u2 class_symbol_to_cpool_index(Symbol* sym) {
    return _classmap->symbol_to_value(sym);
  }
 public:
  JvmtiConstantPoolReconstituter(instanceKlassHandle ikh){
    set_error(JVMTI_ERROR_NONE);
    _ikh = ikh;
    _cpool = constantPoolHandle(Thread::current(), ikh->constants());
    _symmap = new SymbolHashMap();
    _classmap = new SymbolHashMap();
    _cpool_size = _cpool->hash_entries_to(_symmap, _classmap);
    if (_cpool_size == 0) {
      set_error(JVMTI_ERROR_OUT_OF_MEMORY);
    } else if (_cpool_size < 0) {
      set_error(JVMTI_ERROR_INTERNAL);
    }
  }
  ~JvmtiConstantPoolReconstituter() {
    if (_symmap != NULL) {
      delete _symmap;
      _symmap = NULL;
    }
    if (_classmap != NULL) {
      delete _classmap;
      _classmap = NULL;
    }
  }
  void       set_error(jvmtiError err)    { _err = err; }
  jvmtiError get_error()                  { return _err; }
  int cpool_size()                        { return _cpool_size; }
  void copy_cpool_bytes(unsigned char *cpool_bytes) {
    if (cpool_bytes == NULL) {
      assert(cpool_bytes != NULL, "cpool_bytes pointer must not be NULL");
      return;
    }
    cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes);
  }
};
class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
 private:
  size_t               _buffer_size;
  u1*                  _buffer;
  u1*                  _buffer_ptr;
  Thread*              _thread;
  enum {
    initial_buffer_size = 1024
  };
  inline Thread* thread() { return _thread; }
  void write_class_file_format();
  void write_field_infos();
  void write_method_infos();
  void write_method_info(methodHandle method);
  void write_code_attribute(methodHandle method);
  void write_exceptions_attribute(ConstMethod* const_method);
  void write_synthetic_attribute();
  void write_class_attributes();
  void write_source_file_attribute();
  void write_source_debug_extension_attribute();
  u2 line_number_table_entries(methodHandle method);
  void write_line_number_table_attribute(methodHandle method, u2 num_entries);
  void write_local_variable_table_attribute(methodHandle method, u2 num_entries);
  void write_local_variable_type_table_attribute(methodHandle method, u2 num_entries);
  void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len);
  u2 inner_classes_attribute_length();
  void write_inner_classes_attribute(int length);
  void write_signature_attribute(u2 generic_signaure_index);
  void write_attribute_name_index(const char* name);
  void write_annotations_attribute(const char* attr_name, AnnotationArray* annos);
  void write_bootstrapmethod_attribute();
  address writeable_address(size_t size);
  void write_u1(u1 x);
  void write_u2(u2 x);
  void write_u4(u4 x);
  void write_u8(u8 x);
 public:
  JvmtiClassFileReconstituter(instanceKlassHandle ikh) :
                                      JvmtiConstantPoolReconstituter(ikh) {
    _buffer_size = initial_buffer_size;
    _buffer = _buffer_ptr = NEW_RESOURCE_ARRAY(u1, _buffer_size);
    _thread = Thread::current();
    write_class_file_format();
  };
  size_t class_file_size()    { return _buffer_ptr - _buffer; }
  u1* class_file_bytes()      { return _buffer; }
  static void copy_bytecodes(methodHandle method, unsigned char* bytecodes);
};
#endif // SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiCodeBlobEvents.cpp
#include "precompiled.hpp"
#include "code/codeBlob.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiCodeBlobEvents.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/vmThread.hpp"
class CodeBlobCollector : StackObj {
 private:
  GrowableArray<JvmtiCodeBlobDesc*>* _code_blobs;   // collected blobs
  int _pos;                                         // iterator position
  static GrowableArray<JvmtiCodeBlobDesc*>* _global_code_blobs;
  static void do_blob(CodeBlob* cb);
  static void do_vtable_stub(VtableStub* vs);
 public:
  CodeBlobCollector() {
    _code_blobs = NULL;
    _pos = -1;
  }
  ~CodeBlobCollector() {
    if (_code_blobs != NULL) {
      for (int i=0; i<_code_blobs->length(); i++) {
        FreeHeap(_code_blobs->at(i));
      }
      delete _code_blobs;
    }
  }
  void collect();
  JvmtiCodeBlobDesc* first() {
    assert(_code_blobs != NULL, "not collected");
    if (_code_blobs->length() == 0) {
      return NULL;
    }
    _pos = 0;
    return _code_blobs->at(0);
  }
  JvmtiCodeBlobDesc* next() {
    assert(_pos >= 0, "iteration not started");
    if (_pos+1 >= _code_blobs->length()) {
      return NULL;
    }
    return _code_blobs->at(++_pos);
  }
};
GrowableArray<JvmtiCodeBlobDesc*>* CodeBlobCollector::_global_code_blobs;
void CodeBlobCollector::do_blob(CodeBlob* cb) {
  if (cb->is_nmethod()) {
    return;
  }
  if (cb->is_buffer_blob() && strcmp(cb->name(), "vtable chunks") == 0) {
    return;
  }
  address addr = cb->code_begin();
  for (int i=0; i<_global_code_blobs->length(); i++) {
    JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i);
    if (addr == scb->code_begin()) {
      return;
    }
  }
  JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(cb->name(), cb->code_begin(), cb->code_end());
  _global_code_blobs->append(scb);
}
void CodeBlobCollector::do_vtable_stub(VtableStub* vs) {
    JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(vs->is_vtable_stub() ? "vtable stub" : "itable stub",
                                                   vs->code_begin(), vs->code_end());
    _global_code_blobs->append(scb);
}
void CodeBlobCollector::collect() {
  assert_locked_or_safepoint(CodeCache_lock);
  assert(_global_code_blobs == NULL, "checking");
  _global_code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(50,true);
  int index = 0;
  StubCodeDesc* desc;
  while ((desc = StubCodeDesc::desc_for_index(++index)) != NULL) {
    _global_code_blobs->append(new JvmtiCodeBlobDesc(desc->name(), desc->begin(), desc->end()));
  }
  VtableStubs::vtable_stub_do(do_vtable_stub);
  CodeCache::blobs_do(do_blob);
  _code_blobs = _global_code_blobs;
  _global_code_blobs = NULL;
}
jvmtiError JvmtiCodeBlobEvents::generate_dynamic_code_events(JvmtiEnv* env) {
  CodeBlobCollector collector;
  {
    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    collector.collect();
  }
  JvmtiCodeBlobDesc* blob = collector.first();
  while (blob != NULL) {
    JvmtiExport::post_dynamic_code_generated(env, blob->name(), blob->code_begin(), blob->code_end());
    blob = collector.next();
  }
  return JVMTI_ERROR_NONE;
}
jvmtiError JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv* env) {
  HandleMark hm;
  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  nmethod* current = CodeCache::first_nmethod();
  while (current != NULL) {
    if (current->is_alive()) {
      nmethodLocker nml(current);
      MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
      current->get_and_cache_jmethod_id();
      JvmtiExport::post_compiled_method_load(current);
    }
    current = CodeCache::next_nmethod(current);
  }
  return JVMTI_ERROR_NONE;
}
void JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nmethod *nm,
                                                        jvmtiAddrLocationMap** map_ptr,
                                                        jint *map_length_ptr)
{
  ResourceMark rm;
  jvmtiAddrLocationMap* map = NULL;
  jint map_length = 0;
  methodHandle mh(nm->method());
  if (!mh->is_native()) {
    PcDesc *pcd;
    int pcds_in_method;
    pcds_in_method = (nm->scopes_pcs_end() - nm->scopes_pcs_begin());
    map = NEW_C_HEAP_ARRAY(jvmtiAddrLocationMap, pcds_in_method, mtInternal);
    address scopes_data = nm->scopes_data_begin();
    for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
      ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop());
      ScopeDesc *sd  = &sc0;
      while( !sd->is_top() ) { sd = sd->sender(); }
      int bci = sd->bci();
      if (bci != InvocationEntryBci) {
        assert(map_length < pcds_in_method, "checking");
        map[map_length].start_address = (const void*)pcd->real_pc(nm);
        map[map_length].location = bci;
        ++map_length;
      }
    }
  }
}
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiCodeBlobEvents.hpp
#ifndef SHARE_VM_PRIMS_JVMTICODEBLOBEVENTS_HPP
#define SHARE_VM_PRIMS_JVMTICODEBLOBEVENTS_HPP
#include "jvmtifiles/jvmti.h"
class JvmtiEnv;
class JvmtiCodeBlobEvents : public AllStatic {
 public:
  static jvmtiError generate_dynamic_code_events(JvmtiEnv* env);
  static jvmtiError generate_compiled_method_load_events(JvmtiEnv* env);
  static void build_jvmti_addr_location_map(nmethod *nm, jvmtiAddrLocationMap** map,
                                            jint *map_length);
};
#endif // SHARE_VM_PRIMS_JVMTICODEBLOBEVENTS_HPP
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnter.hpp
#ifndef SHARE_VM_PRIMS_JVMTIENTER_HPP
#define SHARE_VM_PRIMS_JVMTIENTER_HPP
#include "classfile/systemDictionary.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvmtiImpl.hpp"
#include "runtime/interfaceSupport.hpp"
#endif // SHARE_VM_PRIMS_JVMTIENTER_HPP
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnv.cpp
#include "precompiled.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/interpreter.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "prims/jniCheck.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiAgentThread.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
#include "prims/jvmtiCodeBlobEvents.hpp"
#include "prims/jvmtiExtensions.hpp"
#include "prims/jvmtiGetLoadedClasses.hpp"
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiManageCapabilities.hpp"
#include "prims/jvmtiRawMonitor.hpp"
#include "prims/jvmtiRedefineClasses.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
#include "prims/jvmtiUtil.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/osThread.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/preserveException.hpp"
#define FIXLATER 0 // REMOVE this when completed.
#define TraceJVMTICalls false
JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
}
JvmtiEnv::~JvmtiEnv() {
}
JvmtiEnv*
JvmtiEnv::create_a_jvmti(jint version) {
  return new JvmtiEnv(version);
}
class VM_JNIFunctionTableCopier : public VM_Operation {
 private:
  const struct JNINativeInterface_ *_function_table;
 public:
  VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) {
    _function_table = func_tbl;
  };
  VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; }
  void doit() {
    copy_jni_function_table(_function_table);
  };
};
jvmtiError
JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) {
  return allocate(size, mem_ptr);
} /* end Allocate */
jvmtiError
JvmtiEnv::Deallocate(unsigned char* mem) {
  return deallocate(mem);
} /* end Deallocate */
jvmtiError
JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {
  JvmtiThreadState* state = java_thread->jvmti_thread_state();
  if (state == NULL) {
    if (data == NULL) {
      return JVMTI_ERROR_NONE;
    }
    state = JvmtiThreadState::state_for(java_thread);
    if (state == NULL) {
      return JVMTI_ERROR_THREAD_NOT_ALIVE;
    }
  }
  state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
  return JVMTI_ERROR_NONE;
} /* end SetThreadLocalStorage */
jvmtiError
JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {
  JavaThread* current_thread = JavaThread::current();
  if (thread == NULL) {
    JvmtiThreadState* state = current_thread->jvmti_thread_state();
      state->env_thread_state(this)->get_agent_thread_local_storage_data();
  } else {
    ThreadInVMfromNative __tiv(current_thread);
    VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
    debug_only(VMNativeEntryWrapper __vew;)
    oop thread_oop = JNIHandles::resolve_external_guard(thread);
    if (thread_oop == NULL) {
      return JVMTI_ERROR_INVALID_THREAD;
    }
    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
      return JVMTI_ERROR_INVALID_THREAD;
    }
    JavaThread* java_thread = java_lang_Thread::thread(thread_oop);
    if (java_thread == NULL) {
      return JVMTI_ERROR_THREAD_NOT_ALIVE;
    }
    JvmtiThreadState* state = java_thread->jvmti_thread_state();
      state->env_thread_state(this)->get_agent_thread_local_storage_data();
  }
  return JVMTI_ERROR_NONE;
} /* end GetThreadLocalStorage */
jvmtiError
JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {
  return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);
} /* end GetLoadedClasses */
jvmtiError
JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
  return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,
                                                  class_count_ptr, classes_ptr);
} /* end GetClassLoaderClasses */
jvmtiError
JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {
                                                       JNI_TRUE : JNI_FALSE;
  return JVMTI_ERROR_NONE;
} /* end IsModifiableClass */
jvmtiError
JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
  int index;
  JavaThread* current_thread = JavaThread::current();
  ResourceMark rm(current_thread);
  jvmtiClassDefinition* class_definitions =
                            NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);
  NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);
  for (index = 0; index < class_count; index++) {
    HandleMark hm(current_thread);
    jclass jcls = classes[index];
    oop k_mirror = JNIHandles::resolve_external_guard(jcls);
    if (k_mirror == NULL) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
    if (!k_mirror->is_a(SystemDictionary::Class_klass())) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_UNMODIFIABLE_CLASS;
    }
    Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
    KlassHandle klass(current_thread, k_oop);
    jint status = klass->jvmti_class_status();
    if (status & (JVMTI_CLASS_STATUS_ERROR)) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
    if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
      return JVMTI_ERROR_UNMODIFIABLE_CLASS;
    }
    instanceKlassHandle ikh(current_thread, k_oop);
    if (ikh->get_cached_class_file_bytes() == NULL) {
      constantPoolHandle  constants(current_thread, ikh->constants());
      MonitorLockerEx ml(constants->lock());    // lock constant pool while we query it
      JvmtiClassFileReconstituter reconstituter(ikh);
      if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
        return reconstituter.get_error();
      }
      class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();
      class_definitions[index].class_bytes      = (unsigned char*)
                                                       reconstituter.class_file_bytes();
    } else {
      class_definitions[index].class_byte_count = ikh->get_cached_class_file_len();
      class_definitions[index].class_bytes      = ikh->get_cached_class_file_bytes();
    }
    class_definitions[index].klass              = jcls;
  }
  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
  VMThread::execute(&op);
  return (op.check_error());
} /* end RetransformClasses */
jvmtiError
JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
  VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
  VMThread::execute(&op);
  return (op.check_error());
} /* end RedefineClasses */
jvmtiError
JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
  oop mirror = JNIHandles::resolve_external_guard(object);
  NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
  if (mirror->klass() == SystemDictionary::Class_klass() &&
      !java_lang_Class::is_primitive(mirror)) {
    Klass* k = java_lang_Class::as_Klass(mirror);
    assert(k != NULL, "class for non-primitive mirror must exist");
  } else {
    }
  return JVMTI_ERROR_NONE;
} /* end GetObjectSize */
jvmtiError
JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {
  return prefix == NULL?
              SetNativeMethodPrefixes(0, NULL) :
              SetNativeMethodPrefixes(1, (char**)&prefix);
} /* end SetNativeMethodPrefix */
jvmtiError
JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {
  if (Threads::number_of_threads() == 0) {
    return set_native_method_prefixes(prefix_count, prefixes);
  } else {
    MutexLocker mu(JvmtiThreadState_lock);
    return set_native_method_prefixes(prefix_count, prefixes);
  }
} /* end SetNativeMethodPrefixes */
jvmtiError
JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {
  JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);
  return JVMTI_ERROR_NONE;
} /* end SetEventCallbacks */
jvmtiError
JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
  JavaThread* java_thread = NULL;
  if (event_thread != NULL) {
    oop thread_oop = JNIHandles::resolve_external_guard(event_thread);
    if (thread_oop == NULL) {
      return JVMTI_ERROR_INVALID_THREAD;
    }
    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
      return JVMTI_ERROR_INVALID_THREAD;
    }
    java_thread = java_lang_Thread::thread(thread_oop);
    if (java_thread == NULL) {
      return JVMTI_ERROR_THREAD_NOT_ALIVE;
    }
  }
  if (!JvmtiEventController::is_valid_event_type(event_type)) {
    return JVMTI_ERROR_INVALID_EVENT_TYPE;
  }
  if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {
    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
  }
  bool enabled = (mode == JVMTI_ENABLE);
  if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
  }
  if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
    record_class_file_load_hook_enabled();
  }
  JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
  return JVMTI_ERROR_NONE;
} /* end SetEventNotificationMode */
jvmtiError
JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
  JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),
                                                      get_prohibited_capabilities(),
                                                      capabilities_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetPotentialCapabilities */
jvmtiError
JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
  return JvmtiManageCapabilities::add_capabilities(get_capabilities(),
                                                   get_prohibited_capabilities(),
                                                   capabilities_ptr,
                                                   get_capabilities());
} /* end AddCapabilities */
jvmtiError
JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
  JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
  return JVMTI_ERROR_NONE;
} /* end RelinquishCapabilities */
jvmtiError
JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
  JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetCapabilities */
jvmtiError
JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {
  jvmtiPhase phase = get_phase();
  if (phase == JVMTI_PHASE_ONLOAD) {
    Arguments::append_sysclasspath(segment);
    return JVMTI_ERROR_NONE;
  } else if (use_version_1_0_semantics()) {
    return JVMTI_ERROR_WRONG_PHASE;
  } else if (phase == JVMTI_PHASE_LIVE) {
    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
    if (zip_entry == NULL) {
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }
    Thread* thread = Thread::current();
    HandleMark hm;
    Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock());
    ObjectLocker ol(loader_lock, thread);
    if (TraceClassLoading) {
      tty->print_cr("[Opened %s]", zip_entry->name());
    }
    ClassLoaderExt::append_boot_classpath(zip_entry);
    return JVMTI_ERROR_NONE;
  } else {
    return JVMTI_ERROR_WRONG_PHASE;
  }
} /* end AddToBootstrapClassLoaderSearch */
jvmtiError
JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
  jvmtiPhase phase = get_phase();
  if (phase == JVMTI_PHASE_ONLOAD) {
    for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
      if (strcmp("java.class.path", p->key()) == 0) {
        p->append_value(segment);
        break;
      }
    }
    return JVMTI_ERROR_NONE;
  } else if (phase == JVMTI_PHASE_LIVE) {
    HandleMark hm;
    ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
    if (zip_entry == NULL) {
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }
    delete zip_entry;   // no longer needed
    Thread* THREAD = Thread::current();
    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
    ObjectLocker ol(loader, THREAD);
    Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      return JVMTI_ERROR_INTERNAL;
    }
    instanceKlassHandle loader_ik(THREAD, loader->klass());
    {
      JavaValue res(T_VOID);
      JavaCalls::call_special(&res,
                              loader,
                              loader_ik,
                              vmSymbols::appendToClassPathForInstrumentation_name(),
                              vmSymbols::appendToClassPathForInstrumentation_signature(),
                              path,
                              THREAD);
      if (HAS_PENDING_EXCEPTION) {
        Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
        CLEAR_PENDING_EXCEPTION;
        if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {
          return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;
        } else {
          return JVMTI_ERROR_INTERNAL;
        }
      }
    }
    return JVMTI_ERROR_NONE;
  } else {
    return JVMTI_ERROR_WRONG_PHASE;
  }
} /* end AddToSystemClassLoaderSearch */
jvmtiError
JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetPhase */
jvmtiError
JvmtiEnv::DisposeEnvironment() {
  dispose();
  return JVMTI_ERROR_NONE;
} /* end DisposeEnvironment */
jvmtiError
JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {
  set_env_local_storage(data);
  return JVMTI_ERROR_NONE;
} /* end SetEnvironmentLocalStorage */
jvmtiError
JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetEnvironmentLocalStorage */
jvmtiError
JvmtiEnv::GetVersionNumber(jint* version_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetVersionNumber */
jvmtiError
JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {
  if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {
    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
  }
  const char *name = JvmtiUtil::error_name(error);
  if (name == NULL) {
    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
  }
  size_t len = strlen(name) + 1;
  jvmtiError err = allocate(len, (unsigned char**)name_ptr);
  if (err == JVMTI_ERROR_NONE) {
    memcpy(*name_ptr, name, len);
  }
  return err;
} /* end GetErrorName */
jvmtiError
JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
  switch (flag) {
  case JVMTI_VERBOSE_OTHER:
    break;
  case JVMTI_VERBOSE_CLASS:
    TraceClassLoading = value != 0;
    TraceClassUnloading = value != 0;
    break;
  case JVMTI_VERBOSE_GC:
    PrintGC = value != 0;
    break;
  case JVMTI_VERBOSE_JNI:
    PrintJNIResolving = value != 0;
    break;
  default:
    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
  };
  return JVMTI_ERROR_NONE;
} /* end SetVerboseFlag */
jvmtiError
JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetJLocationFormat */
jvmtiError
JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {
  jint state;
  oop thread_oop;
  JavaThread* thr;
  if (thread == NULL) {
    thread_oop = JavaThread::current()->threadObj();
  } else {
    thread_oop = JNIHandles::resolve_external_guard(thread);
  }
  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
    return JVMTI_ERROR_INVALID_THREAD;
  }
  state = (jint)java_lang_Thread::get_thread_status(thread_oop);
  thr = java_lang_Thread::thread(thread_oop);
  if (thr != NULL) {
    JavaThreadState jts = thr->thread_state();
    if (thr->is_being_ext_suspended()) {
      state |= JVMTI_THREAD_STATE_SUSPENDED;
    }
    if (jts == _thread_in_native) {
      state |= JVMTI_THREAD_STATE_IN_NATIVE;
    }
    OSThread* osThread = thr->osthread();
    if (osThread != NULL && osThread->interrupted()) {
      state |= JVMTI_THREAD_STATE_INTERRUPTED;
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetThreadState */
jvmtiError
JvmtiEnv::GetCurrentThread(jthread* thread_ptr) {
  JavaThread* current_thread  = JavaThread::current();
  return JVMTI_ERROR_NONE;
} /* end GetCurrentThread */
jvmtiError
JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) {
  int nthreads        = 0;
  Handle *thread_objs = NULL;
  ResourceMark rm;
  HandleMark hm;
  ThreadsListEnumerator tle(Thread::current(), true);
  nthreads = tle.num_threads();
  if (nthreads == 0) {
    return JVMTI_ERROR_NONE;
  }
  thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads);
  NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY);
  for (int i = 0; i < nthreads; i++) {
    thread_objs[i] = Handle(tle.get_threadObj(i));
  }
  jthread *jthreads  = new_jthreadArray(nthreads, thread_objs);
  NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);
  return JVMTI_ERROR_NONE;
} /* end GetAllThreads */
jvmtiError
JvmtiEnv::SuspendThread(JavaThread* java_thread) {
  if (java_thread->is_hidden_from_external_view()) {
    return (JVMTI_ERROR_NONE);
  }
  {
    MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);
    if (java_thread->is_external_suspend()) {
      return (JVMTI_ERROR_THREAD_SUSPENDED);
    }
    if (java_thread->is_exiting()) { // thread is in the process of exiting
      return (JVMTI_ERROR_THREAD_NOT_ALIVE);
    }
    java_thread->set_external_suspend();
  }
  if (!JvmtiSuspendControl::suspend(java_thread)) {
    return (JVMTI_ERROR_THREAD_NOT_ALIVE);
  }
  return JVMTI_ERROR_NONE;
} /* end SuspendThread */
jvmtiError
JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
  int needSafepoint = 0;  // > 0 if we need a safepoint
  for (int i = 0; i < request_count; i++) {
    JavaThread *java_thread = get_JavaThread(request_list[i]);
    if (java_thread == NULL) {
      results[i] = JVMTI_ERROR_INVALID_THREAD;
      continue;
    }
    if (java_thread->threadObj() == NULL) {
      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
      continue;
    }
    if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
      continue;
    }
    if (java_thread->is_hidden_from_external_view()) {
      results[i] = JVMTI_ERROR_NONE;  // indicate successful suspend
      continue;
    }
    {
      MutexLockerEx ml(java_thread->SR_lock(), Mutex::_no_safepoint_check_flag);
      if (java_thread->is_external_suspend()) {
        results[i] = JVMTI_ERROR_THREAD_SUSPENDED;
        continue;
      }
      if (java_thread->is_exiting()) { // thread is in the process of exiting
        results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
        continue;
      }
      java_thread->set_external_suspend();
    }
    if (java_thread->thread_state() == _thread_in_native) {
      if (!JvmtiSuspendControl::suspend(java_thread)) {
        needSafepoint++;
        results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
        continue;
      }
    } else {
      needSafepoint++;
    }
    results[i] = JVMTI_ERROR_NONE;  // indicate successful suspend
  }
  if (needSafepoint > 0) {
    VM_ForceSafepoint vfs;
    VMThread::execute(&vfs);
  }
  return JVMTI_ERROR_NONE;
} /* end SuspendThreadList */
jvmtiError
JvmtiEnv::ResumeThread(JavaThread* java_thread) {
  if (java_thread->is_hidden_from_external_view()) {
    return JVMTI_ERROR_NONE;
  }
  if (!java_thread->is_being_ext_suspended()) {
    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
  }
  if (!JvmtiSuspendControl::resume(java_thread)) {
    return JVMTI_ERROR_INTERNAL;
  }
  return JVMTI_ERROR_NONE;
} /* end ResumeThread */
jvmtiError
JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
  for (int i = 0; i < request_count; i++) {
    JavaThread *java_thread = get_JavaThread(request_list[i]);
    if (java_thread == NULL) {
      results[i] = JVMTI_ERROR_INVALID_THREAD;
      continue;
    }
    if (java_thread->is_hidden_from_external_view()) {
      results[i] = JVMTI_ERROR_NONE;  // indicate successful resume
      continue;
    }
    if (!java_thread->is_being_ext_suspended()) {
      results[i] = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
      continue;
    }
    if (!JvmtiSuspendControl::resume(java_thread)) {
      results[i] = JVMTI_ERROR_INTERNAL;
      continue;
    }
    results[i] = JVMTI_ERROR_NONE;  // indicate successful suspend
  }
  return JVMTI_ERROR_NONE;
} /* end ResumeThreadList */
jvmtiError
JvmtiEnv::StopThread(JavaThread* java_thread, jobject exception) {
  oop e = JNIHandles::resolve_external_guard(exception);
  NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER);
  JavaThread::send_async_exception(java_thread->threadObj(), e);
  return JVMTI_ERROR_NONE;
} /* end StopThread */
jvmtiError
JvmtiEnv::InterruptThread(jthread thread) {
  oop thread_oop = JNIHandles::resolve_external_guard(thread);
  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
    return JVMTI_ERROR_INVALID_THREAD;
  JavaThread* current_thread  = JavaThread::current();
  MutexLockerEx ml(current_thread->threadObj() == thread_oop ? NULL : Threads_lock);
  JavaThread* java_thread = java_lang_Thread::thread(JNIHandles::resolve_external_guard(thread));
  NULL_CHECK(java_thread, JVMTI_ERROR_THREAD_NOT_ALIVE);
  Thread::interrupt(java_thread);
  return JVMTI_ERROR_NONE;
} /* end InterruptThread */
jvmtiError
JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
  ResourceMark rm;
  HandleMark hm;
  JavaThread* current_thread = JavaThread::current();
  oop thread_oop;
  if (thread == NULL) {
    thread_oop = current_thread->threadObj();
  } else {
    thread_oop = JNIHandles::resolve_external_guard(thread);
  }
  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
    return JVMTI_ERROR_INVALID_THREAD;
  Handle thread_obj(current_thread, thread_oop);
  Handle name;
  ThreadPriority priority;
  Handle     thread_group;
  Handle context_class_loader;
  bool          is_daemon;
  name = Handle(current_thread, java_lang_Thread::name(thread_obj()));
  priority = java_lang_Thread::priority(thread_obj());
  thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj()));
  is_daemon = java_lang_Thread::is_daemon(thread_obj());
  oop loader = java_lang_Thread::context_class_loader(thread_obj());
  context_class_loader = Handle(current_thread, loader);
  { const char *n;
    if (name() != NULL) {
      n = java_lang_String::as_utf8_string(name());
    } else {
      n = UNICODE::as_utf8(NULL, 0);
    }
    info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);
    if (info_ptr->name == NULL)
      return JVMTI_ERROR_OUT_OF_MEMORY;
    strcpy(info_ptr->name, n);
  }
  info_ptr->is_daemon = is_daemon;
  info_ptr->priority  = priority;
  info_ptr->context_class_loader = (context_class_loader.is_null()) ? NULL :
                                     jni_reference(context_class_loader);
  info_ptr->thread_group = jni_reference(thread_group);
  return JVMTI_ERROR_NONE;
} /* end GetThreadInfo */
jvmtiError
JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  JavaThread* calling_thread = JavaThread::current();
  GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
      new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
  if (java_thread == calling_thread) {
    err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
  } else {
    VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);
    VMThread::execute(&op);
    err = op.result();
  }
  jint owned_monitor_count = owned_monitors_list->length();
  if (err == JVMTI_ERROR_NONE) {
    if ((err = allocate(owned_monitor_count * sizeof(jobject *),
                      (unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {
      for (int i = 0; i < owned_monitor_count; i++) {
        (*owned_monitors_ptr)[i] =
          ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
      }
    }
  }
  for (int i = 0; i < owned_monitor_count; i++) {
    deallocate((unsigned char*)owned_monitors_list->at(i));
  }
  delete owned_monitors_list;
  return err;
} /* end GetOwnedMonitorInfo */
jvmtiError
JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  JavaThread* calling_thread  = JavaThread::current();
  GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
         new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
  if (java_thread == calling_thread) {
    err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
  } else {
    VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);
    VMThread::execute(&op);
    err = op.result();
  }
  jint owned_monitor_count = owned_monitors_list->length();
  if (err == JVMTI_ERROR_NONE) {
    if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),
                      (unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {
      for (int i = 0; i < owned_monitor_count; i++) {
        (*monitor_info_ptr)[i].monitor =
          ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
        (*monitor_info_ptr)[i].stack_depth =
          ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth;
      }
    }
  }
  for (int i = 0; i < owned_monitor_count; i++) {
    deallocate((unsigned char*)owned_monitors_list->at(i));
  }
  delete owned_monitors_list;
  return err;
} /* end GetOwnedMonitorStackDepthInfo */
jvmtiError
JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  JavaThread* calling_thread  = JavaThread::current();
  if (java_thread == calling_thread) {
    err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);
  } else {
    VM_GetCurrentContendedMonitor op(this, calling_thread, java_thread, monitor_ptr);
    VMThread::execute(&op);
    err = op.result();
  }
  return err;
} /* end GetCurrentContendedMonitor */
jvmtiError
JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
  oop thread_oop = JNIHandles::resolve_external_guard(thread);
  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
    return JVMTI_ERROR_INVALID_THREAD;
  }
  if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
    return JVMTI_ERROR_INVALID_PRIORITY;
  }
  JavaThread* current_thread = JavaThread::current();
  Handle thread_hndl(current_thread, thread_oop);
  {
    MutexLocker mu(Threads_lock); // grab Threads_lock
    JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);
    if (new_thread == NULL || new_thread->osthread() == NULL) {
      if (new_thread) delete new_thread;
      return JVMTI_ERROR_OUT_OF_MEMORY;
    }
    java_lang_Thread::set_thread(thread_hndl(), new_thread);
    java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);
    java_lang_Thread::set_daemon(thread_hndl());
    new_thread->set_threadObj(thread_hndl());
    Threads::add(new_thread);
    Thread::start(new_thread);
  } // unlock Threads_lock
  return JVMTI_ERROR_NONE;
} /* end RunAgentThread */
jvmtiError
JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) {
  JavaThread* current_thread = JavaThread::current();
  NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY);
  {
    HandleMark hm(current_thread);
    Handle system_thread_group(current_thread, Universe::system_thread_group());
  }
  return JVMTI_ERROR_NONE;
} /* end GetTopThreadGroups */
jvmtiError
JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) {
  ResourceMark rm;
  HandleMark hm;
  JavaThread* current_thread = JavaThread::current();
  Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));
  NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);
  typeArrayHandle name;
  Handle parent_group;
  bool is_daemon;
  ThreadPriority max_priority;
  name         = typeArrayHandle(current_thread,
                                 java_lang_ThreadGroup::name(group_obj()));
  parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));
  is_daemon    = java_lang_ThreadGroup::is_daemon(group_obj());
  max_priority = java_lang_ThreadGroup::maxPriority(group_obj());
  info_ptr->is_daemon    = is_daemon;
  info_ptr->max_priority = max_priority;
  info_ptr->parent       = jni_reference(parent_group);
  if (name() != NULL) {
    const char* n = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
    info_ptr->name = (char *)jvmtiMalloc(strlen(n)+1);
    NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);
    strcpy(info_ptr->name, n);
  } else {
    info_ptr->name = NULL;
  }
  return JVMTI_ERROR_NONE;
} /* end GetThreadGroupInfo */
jvmtiError
JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {
  JavaThread* current_thread = JavaThread::current();
  oop group_obj = (oop) JNIHandles::resolve_external_guard(group);
  NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP);
  Handle *thread_objs = NULL;
  Handle *group_objs  = NULL;
  int nthreads = 0;
  int ngroups = 0;
  int hidden_threads = 0;
  ResourceMark rm;
  HandleMark hm;
  Handle group_hdl(current_thread, group_obj);
  {
    ObjectLocker ol(group_hdl, current_thread);
    nthreads = java_lang_ThreadGroup::nthreads(group_hdl());
    ngroups  = java_lang_ThreadGroup::ngroups(group_hdl());
    if (nthreads > 0) {
      objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());
      assert(nthreads <= threads->length(), "too many threads");
      thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);
      for (int i = 0, j = 0; i < nthreads; i++) {
        oop thread_obj = threads->obj_at(i);
        assert(thread_obj != NULL, "thread_obj is NULL");
        JavaThread *javathread = java_lang_Thread::thread(thread_obj);
        if (javathread != NULL && javathread->is_hidden_from_external_view()) {
          hidden_threads++;
          continue;
        }
        thread_objs[j++] = Handle(current_thread, thread_obj);
      }
      nthreads -= hidden_threads;
    }
    if (ngroups > 0) {
      objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());
      assert(ngroups <= groups->length(), "too many threads");
      group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);
      for (int i = 0; i < ngroups; i++) {
        oop group_obj = groups->obj_at(i);
        assert(group_obj != NULL, "group_obj != NULL");
        group_objs[i] = Handle(current_thread, group_obj);
      }
    }
  } // ThreadGroup unlocked here
  if ((nthreads > 0) && (*threads_ptr == NULL)) {
    return JVMTI_ERROR_OUT_OF_MEMORY;
  }
  if ((ngroups > 0) && (*groups_ptr == NULL)) {
    return JVMTI_ERROR_OUT_OF_MEMORY;
  }
  return JVMTI_ERROR_NONE;
} /* end GetThreadGroupChildren */
jvmtiError
JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  if (java_thread == JavaThread::current()) {
    err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);
  } else {
    VM_GetStackTrace op(this, java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);
    VMThread::execute(&op);
    err = op.result();
  }
  return err;
} /* end GetStackTrace */
jvmtiError
JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  JavaThread* calling_thread = JavaThread::current();
  VM_GetAllStackTraces op(this, calling_thread, max_frame_count);
  VMThread::execute(&op);
  err = op.result();
  return err;
} /* end GetAllStackTraces */
jvmtiError
JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count);
  VMThread::execute(&op);
  err = op.result();
  if (err == JVMTI_ERROR_NONE) {
  }
  return err;
} /* end GetThreadListStackTraces */
jvmtiError
JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
  if (state == NULL) {
    return JVMTI_ERROR_THREAD_NOT_ALIVE;
  }
  uint32_t debug_bits = 0;
  if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {
    err = get_frame_count(state, count_ptr);
  } else {
    VM_GetFrameCount op(this, state, count_ptr);
    VMThread::execute(&op);
    err = op.result();
  }
  return err;
} /* end GetFrameCount */
jvmtiError
JvmtiEnv::PopFrame(JavaThread* java_thread) {
  JavaThread* current_thread  = JavaThread::current();
  HandleMark hm(current_thread);
  uint32_t debug_bits = 0;
  JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
  if (state == NULL) {
    return JVMTI_ERROR_THREAD_NOT_ALIVE;
  }
  if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) {
    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
  }
  if (java_thread->popframe_condition() != JavaThread::popframe_inactive) {
    return JVMTI_ERROR_INTERNAL;
  }
  {
    OSThread* osThread = java_thread->osthread();
    if (osThread->get_state() == MONITOR_WAIT) {
      return JVMTI_ERROR_OPAQUE_FRAME;
    }
  }
  {
    ResourceMark rm(current_thread);
    int frame_count = 0;
    bool is_interpreted[2];
    intptr_t *frame_sp[2];
    for (vframeStream vfs(java_thread, true); !vfs.at_end(); vfs.next()) {
      methodHandle mh(current_thread, vfs.method());
      if (mh->is_native()) return(JVMTI_ERROR_OPAQUE_FRAME);
      is_interpreted[frame_count] = vfs.is_interpreted_frame();
      frame_sp[frame_count] = vfs.frame_id();
      if (++frame_count > 1) break;
    }
    if (frame_count < 2)  {
      if(vframeFor(java_thread, 1) == NULL) {
        return JVMTI_ERROR_NO_MORE_FRAMES;
      } else {
        return JVMTI_ERROR_OPAQUE_FRAME;
      }
    }
    for (int i = 0; i < 2; i++) {
      if (!is_interpreted[i]) {
        Deoptimization::deoptimize_frame(java_thread, frame_sp[i]);
      }
    }
    state->update_for_pop_top_frame();
    java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);
    state->set_pending_step_for_popframe();
  }
  return JVMTI_ERROR_NONE;
} /* end PopFrame */
jvmtiError
JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  uint32_t debug_bits = 0;
  if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {
    err = get_frame_location(java_thread, depth, method_ptr, location_ptr);
  } else {
    VM_GetFrameLocation op(this, java_thread, depth, method_ptr, location_ptr);
    VMThread::execute(&op);
    err = op.result();
  }
  return err;
} /* end GetFrameLocation */
jvmtiError
JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
  ResourceMark rm;
  uint32_t debug_bits = 0;
  JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
  if (state == NULL) {
    return JVMTI_ERROR_THREAD_NOT_ALIVE;
  }
  if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) {
      return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
  }
  if (TraceJVMTICalls) {
    JvmtiSuspendControl::print();
  }
  vframe *vf = vframeFor(java_thread, depth);
  if (vf == NULL) {
    return JVMTI_ERROR_NO_MORE_FRAMES;
  }
  if (!vf->is_java_frame() || ((javaVFrame*) vf)->method()->is_native()) {
    return JVMTI_ERROR_OPAQUE_FRAME;
  }
  assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL");
  int frame_number = state->count_frames() - depth;
  state->env_thread_state(this)->set_frame_pop(frame_number);
  return JVMTI_ERROR_NONE;
} /* end NotifyFramePop */
jvmtiError
JvmtiEnv::ForceEarlyReturnObject(JavaThread* java_thread, jobject value) {
  jvalue val;
  val.l = value;
  return force_early_return(java_thread, val, atos);
} /* end ForceEarlyReturnObject */
jvmtiError
JvmtiEnv::ForceEarlyReturnInt(JavaThread* java_thread, jint value) {
  jvalue val;
  val.i = value;
  return force_early_return(java_thread, val, itos);
} /* end ForceEarlyReturnInt */
jvmtiError
JvmtiEnv::ForceEarlyReturnLong(JavaThread* java_thread, jlong value) {
  jvalue val;
  val.j = value;
  return force_early_return(java_thread, val, ltos);
} /* end ForceEarlyReturnLong */
jvmtiError
JvmtiEnv::ForceEarlyReturnFloat(JavaThread* java_thread, jfloat value) {
  jvalue val;
  val.f = value;
  return force_early_return(java_thread, val, ftos);
} /* end ForceEarlyReturnFloat */
jvmtiError
JvmtiEnv::ForceEarlyReturnDouble(JavaThread* java_thread, jdouble value) {
  jvalue val;
  val.d = value;
  return force_early_return(java_thread, val, dtos);
} /* end ForceEarlyReturnDouble */
jvmtiError
JvmtiEnv::ForceEarlyReturnVoid(JavaThread* java_thread) {
  jvalue val;
  val.j = 0L;
  return force_early_return(java_thread, val, vtos);
} /* end ForceEarlyReturnVoid */
jvmtiError
JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
  Klass* k_oop = NULL;
  if (klass != NULL) {
    oop k_mirror = JNIHandles::resolve_external_guard(klass);
    if (k_mirror == NULL) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_NONE;
    }
    k_oop = java_lang_Class::as_Klass(k_mirror);
    if (k_oop == NULL) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
  }
  if (initial_object != NULL) {
    oop init_obj = JNIHandles::resolve_external_guard(initial_object);
    if (init_obj == NULL) {
      return JVMTI_ERROR_INVALID_OBJECT;
    }
  }
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  KlassHandle kh (thread, k_oop);
  TraceTime t("FollowReferences", TraceJVMTIObjectTagging);
  JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, kh, initial_object, callbacks, user_data);
  return JVMTI_ERROR_NONE;
} /* end FollowReferences */
jvmtiError
JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
  Klass* k_oop = NULL;
  if (klass != NULL) {
    oop k_mirror = JNIHandles::resolve_external_guard(klass);
    if (k_mirror == NULL) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_NONE;
    }
    k_oop = java_lang_Class::as_Klass(k_mirror);
    if (k_oop == NULL) {
      return JVMTI_ERROR_INVALID_CLASS;
    }
  }
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  KlassHandle kh (thread, k_oop);
  TraceTime t("IterateThroughHeap", TraceJVMTIObjectTagging);
  JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, kh, callbacks, user_data);
  return JVMTI_ERROR_NONE;
} /* end IterateThroughHeap */
jvmtiError
JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) {
  oop o = JNIHandles::resolve_external_guard(object);
  NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
  return JVMTI_ERROR_NONE;
} /* end GetTag */
jvmtiError
JvmtiEnv::SetTag(jobject object, jlong tag) {
  oop o = JNIHandles::resolve_external_guard(object);
  NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
  JvmtiTagMap::tag_map_for(this)->set_tag(object, tag);
  return JVMTI_ERROR_NONE;
} /* end SetTag */
jvmtiError
JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
  TraceTime t("GetObjectsWithTags", TraceJVMTIObjectTagging);
  return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);
} /* end GetObjectsWithTags */
jvmtiError
JvmtiEnv::ForceGarbageCollection() {
  Universe::heap()->collect(GCCause::_jvmti_force_gc);
  return JVMTI_ERROR_NONE;
} /* end ForceGarbageCollection */
jvmtiError
JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {
  oop o = JNIHandles::resolve_external_guard(object);
  NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
  JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);
  return JVMTI_ERROR_NONE;
} /* end IterateOverObjectsReachableFromObject */
jvmtiError
JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {
  TraceTime t("IterateOverReachableObjects", TraceJVMTIObjectTagging);
  JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);
  return JVMTI_ERROR_NONE;
} /* end IterateOverReachableObjects */
jvmtiError
JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
  TraceTime t("IterateOverHeap", TraceJVMTIObjectTagging);
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, KlassHandle(), heap_object_callback, user_data);
  return JVMTI_ERROR_NONE;
} /* end IterateOverHeap */
jvmtiError
JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
  if (java_lang_Class::is_primitive(k_mirror)) {
    return JVMTI_ERROR_NONE;
  }
  Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
  if (k_oop == NULL) {
    return JVMTI_ERROR_INVALID_CLASS;
  }
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  KlassHandle klass (thread, k_oop);
  TraceTime t("IterateOverInstancesOfClass", TraceJVMTIObjectTagging);
  JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);
  return JVMTI_ERROR_NONE;
} /* end IterateOverInstancesOfClass */
jvmtiError
JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) {
  JavaThread* current_thread = JavaThread::current();
  ResourceMark rm(current_thread);
  VM_GetOrSetLocal op(java_thread, current_thread, depth, slot);
  VMThread::execute(&op);
  jvmtiError err = op.result();
  if (err != JVMTI_ERROR_NONE) {
    return err;
  } else {
    return JVMTI_ERROR_NONE;
  }
} /* end GetLocalObject */
jvmtiError
JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){
  JavaThread* current_thread = JavaThread::current();
  ResourceMark rm(current_thread);
  VM_GetReceiver op(java_thread, current_thread, depth);
  VMThread::execute(&op);
  jvmtiError err = op.result();
  if (err != JVMTI_ERROR_NONE) {
    return err;
  } else {
    return JVMTI_ERROR_NONE;
  }
} /* end GetLocalInstance */
jvmtiError
JvmtiEnv::GetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) {
  ResourceMark rm;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_INT);
  VMThread::execute(&op);
  return op.result();
} /* end GetLocalInt */
jvmtiError
JvmtiEnv::GetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) {
  ResourceMark rm;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG);
  VMThread::execute(&op);
  return op.result();
} /* end GetLocalLong */
jvmtiError
JvmtiEnv::GetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) {
  ResourceMark rm;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT);
  VMThread::execute(&op);
  return op.result();
} /* end GetLocalFloat */
jvmtiError
JvmtiEnv::GetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) {
  ResourceMark rm;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE);
  VMThread::execute(&op);
  return op.result();
} /* end GetLocalDouble */
jvmtiError
JvmtiEnv::SetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject value) {
  ResourceMark rm;
  jvalue val;
  val.l = value;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val);
  VMThread::execute(&op);
  return op.result();
} /* end SetLocalObject */
jvmtiError
JvmtiEnv::SetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint value) {
  ResourceMark rm;
  jvalue val;
  val.i = value;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val);
  VMThread::execute(&op);
  return op.result();
} /* end SetLocalInt */
jvmtiError
JvmtiEnv::SetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong value) {
  ResourceMark rm;
  jvalue val;
  val.j = value;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val);
  VMThread::execute(&op);
  return op.result();
} /* end SetLocalLong */
jvmtiError
JvmtiEnv::SetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat value) {
  ResourceMark rm;
  jvalue val;
  val.f = value;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val);
  VMThread::execute(&op);
  return op.result();
} /* end SetLocalFloat */
jvmtiError
JvmtiEnv::SetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble value) {
  ResourceMark rm;
  jvalue val;
  val.d = value;
  VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val);
  VMThread::execute(&op);
  return op.result();
} /* end SetLocalDouble */
jvmtiError
JvmtiEnv::SetBreakpoint(Method* method_oop, jlocation location) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  if (location < 0) {   // simple invalid location check first
    return JVMTI_ERROR_INVALID_LOCATION;
  }
  if (location >= (jlocation) method_oop->code_size()) {
    return JVMTI_ERROR_INVALID_LOCATION;
  }
  ResourceMark rm;
  JvmtiBreakpoint bp(method_oop, location);
  JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
  if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE)
    return JVMTI_ERROR_DUPLICATE;
  if (TraceJVMTICalls) {
    jvmti_breakpoints.print();
  }
  return JVMTI_ERROR_NONE;
} /* end SetBreakpoint */
jvmtiError
JvmtiEnv::ClearBreakpoint(Method* method_oop, jlocation location) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  if (location < 0) {   // simple invalid location check first
    return JVMTI_ERROR_INVALID_LOCATION;
  }
  if (location >= (jlocation) method_oop->code_size()) {
    return JVMTI_ERROR_INVALID_LOCATION;
  }
  JvmtiBreakpoint bp(method_oop, location);
  JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
  if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND)
    return JVMTI_ERROR_NOT_FOUND;
  if (TraceJVMTICalls) {
    jvmti_breakpoints.print();
  }
  return JVMTI_ERROR_NONE;
} /* end ClearBreakpoint */
jvmtiError
JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
  if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;
  fdesc_ptr->set_is_field_access_watched(true);
  JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);
  return JVMTI_ERROR_NONE;
} /* end SetFieldAccessWatch */
jvmtiError
JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
  if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;
  fdesc_ptr->set_is_field_access_watched(false);
  JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);
  return JVMTI_ERROR_NONE;
} /* end ClearFieldAccessWatch */
jvmtiError
JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
  if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;
  fdesc_ptr->set_is_field_modification_watched(true);
  JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);
  return JVMTI_ERROR_NONE;
} /* end SetFieldModificationWatch */
jvmtiError
JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
  if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;
  fdesc_ptr->set_is_field_modification_watched(false);
  JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);
  return JVMTI_ERROR_NONE;
} /* end ClearFieldModificationWatch */
jvmtiError
JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) {
  ResourceMark rm;
  bool isPrimitive = java_lang_Class::is_primitive(k_mirror);
  Klass* k = NULL;
  if (!isPrimitive) {
    k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
  }
  if (signature_ptr != NULL) {
    char* result = NULL;
    if (isPrimitive) {
      char tchar = type2char(java_lang_Class::primitive_type(k_mirror));
      result = (char*) jvmtiMalloc(2);
      result[0] = tchar;
      result[1] = '\0';
    } else {
      const char* class_sig = k->signature_name();
      result = (char *) jvmtiMalloc(strlen(class_sig)+1);
      strcpy(result, class_sig);
    }
  }
  if (generic_ptr != NULL) {
    if (!isPrimitive && k->oop_is_instance()) {
      Symbol* soo = InstanceKlass::cast(k)->generic_signature();
      if (soo != NULL) {
        const char *gen_sig = soo->as_C_string();
        if (gen_sig != NULL) {
          char* gen_result;
          jvmtiError err = allocate(strlen(gen_sig) + 1,
                                    (unsigned char **)&gen_result);
          if (err != JVMTI_ERROR_NONE) {
            return err;
          }
          strcpy(gen_result, gen_sig);
        }
      }
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetClassSignature */
jvmtiError
JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) {
  jint result = 0;
  if (java_lang_Class::is_primitive(k_mirror)) {
    result |= JVMTI_CLASS_STATUS_PRIMITIVE;
  } else {
    Klass* k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
    result = k->jvmti_class_status();
  }
  return JVMTI_ERROR_NONE;
} /* end GetClassStatus */
jvmtiError
JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) {
  if (java_lang_Class::is_primitive(k_mirror)) {
     return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  Klass* k_klass = java_lang_Class::as_Klass(k_mirror);
  NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);
  if (!k_klass->oop_is_instance()) {
    return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name();
  NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION);
  {
    JavaThread* current_thread  = JavaThread::current();
    ResourceMark rm(current_thread);
    const char* sfncp = (const char*) sfnOop->as_C_string();
    strcpy(*source_name_ptr, sfncp);
  }
  return JVMTI_ERROR_NONE;
} /* end GetSourceFileName */
jvmtiError
JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) {
  JavaThread* current_thread  = JavaThread::current();
  jint result = 0;
  if (!java_lang_Class::is_primitive(k_mirror)) {
    Klass* k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
    result = k->compute_modifier_flags(current_thread);
    JavaThread* THREAD = current_thread; // pass to macros
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
      return JVMTI_ERROR_INTERNAL;
    };
    if(k->is_super()) {
      result |= JVM_ACC_SUPER;
    }
  } else {
    result = (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
  }
  return JVMTI_ERROR_NONE;
} /* end GetClassModifiers */
jvmtiError
JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {
  JavaThread* current_thread  = JavaThread::current();
  HandleMark hm(current_thread);
  if (java_lang_Class::is_primitive(k_mirror)) {
    return JVMTI_ERROR_NONE;
  }
  Klass* k = java_lang_Class::as_Klass(k_mirror);
  NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
  if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
    return JVMTI_ERROR_CLASS_NOT_PREPARED;
  }
  if (!k->oop_is_instance()) {
    return JVMTI_ERROR_NONE;
  }
  instanceKlassHandle instanceK_h(current_thread, k);
  int result_length = instanceK_h->methods()->length();
  jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
  int index;
  if (JvmtiExport::can_maintain_original_method_order()) {
    for (index = 0; index < result_length; index++) {
      Method* m = instanceK_h->methods()->at(index);
      int original_index = instanceK_h->method_ordering()->at(index);
      assert(original_index >= 0 && original_index < result_length, "invalid original method index");
      jmethodID id = m->jmethod_id();
      result_list[original_index] = id;
    }
  } else {
    for (index = 0; index < result_length; index++) {
      Method* m = instanceK_h->methods()->at(index);
      jmethodID id = m->jmethod_id();
      result_list[index] = id;
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetClassMethods */
jvmtiError
JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {
  if (java_lang_Class::is_primitive(k_mirror)) {
    return JVMTI_ERROR_NONE;
  }
  JavaThread* current_thread = JavaThread::current();
  HandleMark hm(current_thread);
  Klass* k = java_lang_Class::as_Klass(k_mirror);
  NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
  if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
    return JVMTI_ERROR_CLASS_NOT_PREPARED;
  }
  if (!k->oop_is_instance()) {
    return JVMTI_ERROR_NONE;
  }
  instanceKlassHandle instanceK_h(current_thread, k);
  int result_count = 0;
  FilteredFieldStream flds(instanceK_h, true, true);
  result_count = flds.field_count();
  jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID));
  int id_index = (result_count - 1);
  for (FilteredFieldStream src_st(instanceK_h, true, true); !src_st.eos(); src_st.next()) {
    result_list[id_index--] = jfieldIDWorkaround::to_jfieldID(
                                            instanceK_h, src_st.offset(),
                                            src_st.access_flags().is_static());
  }
  assert(id_index == -1, "just checking");
  return JVMTI_ERROR_NONE;
} /* end GetClassFields */
jvmtiError
JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {
  {
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_NONE;
    }
    JavaThread* current_thread = JavaThread::current();
    HandleMark hm(current_thread);
    Klass* k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
    if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
      return JVMTI_ERROR_CLASS_NOT_PREPARED;
    if (!k->oop_is_instance()) {
      return JVMTI_ERROR_NONE;
    }
    Array<Klass*>* interface_list = InstanceKlass::cast(k)->local_interfaces();
    const int result_length = (interface_list == NULL ? 0 : interface_list->length());
    jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));
    for (int i_index = 0; i_index < result_length; i_index += 1) {
      Klass* klass_at = interface_list->at(i_index);
      assert(klass_at->is_klass(), "interfaces must be Klass*s");
      assert(klass_at->is_interface(), "interfaces must be interfaces");
      oop mirror_at = klass_at->java_mirror();
      Handle handle_at = Handle(current_thread, mirror_at);
      result_list[i_index] = (jclass) jni_reference(handle_at);
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetImplementedInterfaces */
jvmtiError
JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {
  if (java_lang_Class::is_primitive(k_mirror)) {
    return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  KlassHandle klass(thread, k_oop);
  jint status = klass->jvmti_class_status();
  if (status & (JVMTI_CLASS_STATUS_ERROR)) {
    return JVMTI_ERROR_INVALID_CLASS;
  }
  if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
    return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  instanceKlassHandle ik(thread, k_oop);
  return JVMTI_ERROR_NONE;
} /* end GetClassVersionNumbers */
jvmtiError
JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {
  if (java_lang_Class::is_primitive(k_mirror)) {
    return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
  Thread *thread = Thread::current();
  HandleMark hm(thread);
  ResourceMark rm(thread);
  KlassHandle klass(thread, k_oop);
  jint status = klass->jvmti_class_status();
  if (status & (JVMTI_CLASS_STATUS_ERROR)) {
    return JVMTI_ERROR_INVALID_CLASS;
  }
  if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
    return JVMTI_ERROR_ABSENT_INFORMATION;
  }
  instanceKlassHandle ikh(thread, k_oop);
  constantPoolHandle  constants(thread, ikh->constants());
  MonitorLockerEx ml(constants->lock());    // lock constant pool while we query it
  JvmtiConstantPoolReconstituter reconstituter(ikh);
  if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
    return reconstituter.get_error();
  }
  unsigned char *cpool_bytes;
  int cpool_size = reconstituter.cpool_size();
  if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
    return reconstituter.get_error();
  }
  jvmtiError res = allocate(cpool_size, &cpool_bytes);
  if (res != JVMTI_ERROR_NONE) {
    return res;
  }
  reconstituter.copy_cpool_bytes(cpool_bytes);
  if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
    return reconstituter.get_error();
  }
  return JVMTI_ERROR_NONE;
} /* end GetConstantPool */
jvmtiError
JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {
  {
    bool result = false;
    if (!java_lang_Class::is_primitive(k_mirror)) {
      Klass* k = java_lang_Class::as_Klass(k_mirror);
      if (k != NULL && k->is_interface()) {
        result = true;
      }
    }
  }
  return JVMTI_ERROR_NONE;
} /* end IsInterface */
jvmtiError
JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {
  {
    bool result = false;
    if (!java_lang_Class::is_primitive(k_mirror)) {
      Klass* k = java_lang_Class::as_Klass(k_mirror);
      if (k != NULL && k->oop_is_array()) {
        result = true;
      }
    }
  }
  return JVMTI_ERROR_NONE;
} /* end IsArrayClass */
jvmtiError
JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {
  {
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_NONE;
    }
    JavaThread* current_thread = JavaThread::current();
    HandleMark hm(current_thread);
    Klass* k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
    oop result_oop = k->class_loader();
    if (result_oop == NULL) {
      return JVMTI_ERROR_NONE;
    }
    Handle result_handle = Handle(current_thread, result_oop);
    jclass result_jnihandle = (jclass) jni_reference(result_handle);
  }
  return JVMTI_ERROR_NONE;
} /* end GetClassLoader */
jvmtiError
JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {
  {
    if (java_lang_Class::is_primitive(k_mirror)) {
      return JVMTI_ERROR_ABSENT_INFORMATION;
    }
    Klass* k = java_lang_Class::as_Klass(k_mirror);
    NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
    if (!k->oop_is_instance()) {
      return JVMTI_ERROR_ABSENT_INFORMATION;
    }
    char* sde = InstanceKlass::cast(k)->source_debug_extension();
    NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
    {
      strcpy(*source_debug_extension_ptr, sde);
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetSourceDebugExtension */
jvmtiError
JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {
  oop mirror = JNIHandles::resolve_external_guard(object);
  NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
  NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);
  {
    jint result = (jint) mirror->identity_hash();
  }
  return JVMTI_ERROR_NONE;
} /* end GetObjectHashCode */
jvmtiError
JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {
  JavaThread* calling_thread = JavaThread::current();
  jvmtiError err = get_object_monitor_usage(calling_thread, object, info_ptr);
  if (err == JVMTI_ERROR_THREAD_NOT_SUSPENDED) {
    VM_GetObjectMonitorUsage op(this, calling_thread, object, info_ptr);
    VMThread::execute(&op);
    err = op.result();
  }
  return err;
} /* end GetObjectMonitorUsage */
jvmtiError
JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {
  JavaThread* current_thread  = JavaThread::current();
  ResourceMark rm(current_thread);
  if (name_ptr == NULL) {
  } else {
    const char* fieldName = fdesc_ptr->name()->as_C_string();
    if (*name_ptr == NULL)
      return JVMTI_ERROR_OUT_OF_MEMORY;
    strcpy(*name_ptr, fieldName);
  }
  if (signature_ptr== NULL) {
  } else {
    const char* fieldSignature = fdesc_ptr->signature()->as_C_string();
    if (*signature_ptr == NULL)
      return JVMTI_ERROR_OUT_OF_MEMORY;
    strcpy(*signature_ptr, fieldSignature);
  }
  if (generic_ptr != NULL) {
    Symbol* soop = fdesc_ptr->generic_signature();
    if (soop != NULL) {
      const char* gen_sig = soop->as_C_string();
      if (gen_sig != NULL) {
        jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
        if (err != JVMTI_ERROR_NONE) {
          return err;
        }
        strcpy(*generic_ptr, gen_sig);
      }
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetFieldName */
jvmtiError
JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetFieldDeclaringClass */
jvmtiError
JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {
  AccessFlags resultFlags = fdesc_ptr->access_flags();
  jint result = resultFlags.as_int();
  return JVMTI_ERROR_NONE;
} /* end GetFieldModifiers */
jvmtiError
JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {
  return JVMTI_ERROR_NONE;
} /* end IsFieldSynthetic */
jvmtiError
JvmtiEnv::GetMethodName(Method* method_oop, char** name_ptr, char** signature_ptr, char** generic_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  JavaThread* current_thread  = JavaThread::current();
  ResourceMark rm(current_thread); // get the utf8 name and signature
  if (name_ptr == NULL) {
  } else {
    const char* utf8_name = (const char *) method_oop->name()->as_utf8();
    strcpy(*name_ptr, utf8_name);
  }
  if (signature_ptr == NULL) {
  } else {
    const char* utf8_signature = (const char *) method_oop->signature()->as_utf8();
    strcpy(*signature_ptr, utf8_signature);
  }
  if (generic_ptr != NULL) {
    Symbol* soop = method_oop->generic_signature();
    if (soop != NULL) {
      const char* gen_sig = soop->as_C_string();
      if (gen_sig != NULL) {
        jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
        if (err != JVMTI_ERROR_NONE) {
          return err;
        }
        strcpy(*generic_ptr, gen_sig);
      }
    }
  }
  return JVMTI_ERROR_NONE;
} /* end GetMethodName */
jvmtiError
JvmtiEnv::GetMethodDeclaringClass(Method* method_oop, jclass* declaring_class_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*declaring_class_ptr) = get_jni_class_non_null(method_oop->method_holder());
  return JVMTI_ERROR_NONE;
} /* end GetMethodDeclaringClass */
jvmtiError
JvmtiEnv::GetMethodModifiers(Method* method_oop, jint* modifiers_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*modifiers_ptr) = method_oop->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
  return JVMTI_ERROR_NONE;
} /* end GetMethodModifiers */
jvmtiError
JvmtiEnv::GetMaxLocals(Method* method_oop, jint* max_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*max_ptr) = method_oop->max_locals();
  return JVMTI_ERROR_NONE;
} /* end GetMaxLocals */
jvmtiError
JvmtiEnv::GetArgumentsSize(Method* method_oop, jint* size_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*size_ptr) = method_oop->size_of_parameters();
  return JVMTI_ERROR_NONE;
} /* end GetArgumentsSize */
jvmtiError
JvmtiEnv::GetLineNumberTable(Method* method_oop, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  if (!method_oop->has_linenumber_table()) {
    return (JVMTI_ERROR_ABSENT_INFORMATION);
  }
  jint num_entries = 0;
  CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table());
  while (stream.read_pair()) {
    num_entries++;
  }
  jvmtiLineNumberEntry *jvmti_table =
            (jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));
  if (num_entries > 0) {
    int index = 0;
    CompressedLineNumberReadStream stream(method_oop->compressed_linenumber_table());
    while (stream.read_pair()) {
      jvmti_table[index].start_location = (jlocation) stream.bci();
      jvmti_table[index].line_number = (jint) stream.line();
      index++;
    }
    assert(index == num_entries, "sanity check");
  }
  (*entry_count_ptr) = num_entries;
  (*table_ptr) = jvmti_table;
  return JVMTI_ERROR_NONE;
} /* end GetLineNumberTable */
jvmtiError
JvmtiEnv::GetMethodLocation(Method* method_oop, jlocation* start_location_ptr, jlocation* end_location_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*end_location_ptr) = (jlocation) (method_oop->code_size() - 1);
  if (method_oop->code_size() == 0) {
    (*start_location_ptr) = (jlocation)(-1);
  } else {
    (*start_location_ptr) = (jlocation)(0);
  }
  return JVMTI_ERROR_NONE;
} /* end GetMethodLocation */
jvmtiError
JvmtiEnv::GetLocalVariableTable(Method* method_oop, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  JavaThread* current_thread  = JavaThread::current();
  InstanceKlass* ik = method_oop->method_holder();
  if (!ik->access_flags().has_localvariable_table()) {
    return (JVMTI_ERROR_ABSENT_INFORMATION);
  }
  ConstantPool* constants = method_oop->constants();
  NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);
  jint num_entries = method_oop->localvariable_table_length();
  jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)
                jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));
  if (num_entries > 0) {
    LocalVariableTableElement* table = method_oop->localvariable_table_start();
    for (int i = 0; i < num_entries; i++) {
      jlocation start_location = (jlocation) table[i].start_bci;
      jint length = (jint) table[i].length;
      int name_index = (int) table[i].name_cp_index;
      int signature_index = (int) table[i].descriptor_cp_index;
      int generic_signature_index = (int) table[i].signature_cp_index;
      jint slot = (jint) table[i].slot;
      char *name_buf = NULL;
      char *sig_buf = NULL;
      char *gen_sig_buf = NULL;
      {
        ResourceMark rm(current_thread);
        const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();
        name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);
        strcpy(name_buf, utf8_name);
        const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();
        sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);
        strcpy(sig_buf, utf8_signature);
        if (generic_signature_index > 0) {
          const char *utf8_gen_sign = (const char *)
                                       constants->symbol_at(generic_signature_index)->as_utf8();
          gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);
          strcpy(gen_sig_buf, utf8_gen_sign);
        }
      }
      jvmti_table[i].start_location = start_location;
      jvmti_table[i].length = length;
      jvmti_table[i].name = name_buf;
      jvmti_table[i].signature = sig_buf;
      jvmti_table[i].generic_signature = gen_sig_buf;
      jvmti_table[i].slot = slot;
    }
  }
  (*entry_count_ptr) = num_entries;
  (*table_ptr) = jvmti_table;
  return JVMTI_ERROR_NONE;
} /* end GetLocalVariableTable */
jvmtiError
JvmtiEnv::GetBytecodes(Method* method_oop, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  HandleMark hm;
  methodHandle method(method_oop);
  jint size = (jint)method->code_size();
  jvmtiError err = allocate(size, bytecodes_ptr);
  if (err != JVMTI_ERROR_NONE) {
    return err;
  }
  (*bytecode_count_ptr) = size;
  JvmtiClassFileReconstituter::copy_bytecodes(method, *bytecodes_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetBytecodes */
jvmtiError
JvmtiEnv::IsMethodNative(Method* method_oop, jboolean* is_native_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*is_native_ptr) = method_oop->is_native();
  return JVMTI_ERROR_NONE;
} /* end IsMethodNative */
jvmtiError
JvmtiEnv::IsMethodSynthetic(Method* method_oop, jboolean* is_synthetic_ptr) {
  NULL_CHECK(method_oop, JVMTI_ERROR_INVALID_METHODID);
  (*is_synthetic_ptr) = method_oop->is_synthetic();
  return JVMTI_ERROR_NONE;
} /* end IsMethodSynthetic */
jvmtiError
JvmtiEnv::IsMethodObsolete(Method* method_oop, jboolean* is_obsolete_ptr) {
  if (use_version_1_0_semantics() &&
      get_capabilities()->can_redefine_classes == 0) {
    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
  }
  if (method_oop == NULL || method_oop->is_obsolete()) {
  } else {
  }
  return JVMTI_ERROR_NONE;
} /* end IsMethodObsolete */
jvmtiError
JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
  JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);
  NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
  return JVMTI_ERROR_NONE;
} /* end CreateRawMonitor */
jvmtiError
JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
  if (Threads::number_of_threads() == 0) {
    JvmtiPendingMonitors::destroy(rmonitor);
  } else {
    Thread* thread  = Thread::current();
    if (rmonitor->is_entered(thread)) {
      int r;
      intptr_t recursion = rmonitor->recursions();
      for (intptr_t i = 0; i <= recursion; i++) {
        r = rmonitor->raw_exit(thread);
        assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
        if (r != ObjectMonitor::OM_OK) {  // robustness
          return JVMTI_ERROR_INTERNAL;
        }
      }
    }
    if (rmonitor->owner() != NULL) {
      return JVMTI_ERROR_NOT_MONITOR_OWNER;
    }
  }
  delete rmonitor;
  return JVMTI_ERROR_NONE;
} /* end DestroyRawMonitor */
jvmtiError
JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
  if (Threads::number_of_threads() == 0) {
    JvmtiPendingMonitors::enter(rmonitor);
  } else {
    int r = 0;
    Thread* thread = Thread::current();
    if (thread->is_Java_thread()) {
      JavaThread* current_thread = (JavaThread*)thread;
#ifdef PROPER_TRANSITIONS
      ThreadInVMfromUnknown __tiv;
      {
        ThreadBlockInVM __tbivm(current_thread);
        r = rmonitor->raw_enter(current_thread);
      }
#else
      JavaThreadState state = current_thread->thread_state();
      assert(state == _thread_in_native, "Must be _thread_in_native");
      assert(!current_thread->has_last_Java_frame() ||
             current_thread->frame_anchor()->walkable(), "Must be walkable");
      current_thread->set_thread_state(_thread_blocked);
      r = rmonitor->raw_enter(current_thread);
      current_thread->set_thread_state(state);
#endif /* PROPER_TRANSITIONS */
      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
    } else {
      if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {
        r = rmonitor->raw_enter(thread);
      } else {
        ShouldNotReachHere();
      }
    }
    if (r != ObjectMonitor::OM_OK) {  // robustness
      return JVMTI_ERROR_INTERNAL;
    }
  }
  return JVMTI_ERROR_NONE;
} /* end RawMonitorEnter */
jvmtiError
JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
  jvmtiError err = JVMTI_ERROR_NONE;
  if (Threads::number_of_threads() == 0) {
    if (!JvmtiPendingMonitors::exit(rmonitor)) {
      err = JVMTI_ERROR_NOT_MONITOR_OWNER;
    }
  } else {
    int r = 0;
    Thread* thread = Thread::current();
    if (thread->is_Java_thread()) {
      JavaThread* current_thread = (JavaThread*)thread;
#ifdef PROPER_TRANSITIONS
      ThreadInVMfromUnknown __tiv;
#endif /* PROPER_TRANSITIONS */
      r = rmonitor->raw_exit(current_thread);
    } else {
      if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {
        r = rmonitor->raw_exit(thread);
      } else {
        ShouldNotReachHere();
      }
    }
    if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
      err = JVMTI_ERROR_NOT_MONITOR_OWNER;
    } else {
      assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
      if (r != ObjectMonitor::OM_OK) {  // robustness
        err = JVMTI_ERROR_INTERNAL;
      }
    }
  }
  return err;
} /* end RawMonitorExit */
jvmtiError
JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
  int r = 0;
  Thread* thread = Thread::current();
  if (thread->is_Java_thread()) {
    JavaThread* current_thread = (JavaThread*)thread;
#ifdef PROPER_TRANSITIONS
    ThreadInVMfromUnknown __tiv;
    {
      ThreadBlockInVM __tbivm(current_thread);
      r = rmonitor->raw_wait(millis, true, current_thread);
    }
#else
    JavaThreadState state = current_thread->thread_state();
    assert(state == _thread_in_native, "Must be _thread_in_native");
    assert(!current_thread->has_last_Java_frame() ||
           current_thread->frame_anchor()->walkable(), "Must be walkable");
    current_thread->set_thread_state(_thread_blocked);
    r = rmonitor->raw_wait(millis, true, current_thread);
    current_thread->set_thread_state(state);
#endif /* PROPER_TRANSITIONS */
  } else {
    if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {
      r = rmonitor->raw_wait(millis, true, thread);
    } else {
      ShouldNotReachHere();
    }
  }
  switch (r) {
  case ObjectMonitor::OM_INTERRUPTED:
    return JVMTI_ERROR_INTERRUPT;
  case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE:
    return JVMTI_ERROR_NOT_MONITOR_OWNER;
  }
  assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked");
  if (r != ObjectMonitor::OM_OK) {  // robustness
    return JVMTI_ERROR_INTERNAL;
  }
  return JVMTI_ERROR_NONE;
} /* end RawMonitorWait */
jvmtiError
JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
  int r = 0;
  Thread* thread = Thread::current();
  if (thread->is_Java_thread()) {
    JavaThread* current_thread = (JavaThread*)thread;
    ThreadInVMfromUnknown __tiv;
    r = rmonitor->raw_notify(current_thread);
  } else {
    if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {
      r = rmonitor->raw_notify(thread);
    } else {
      ShouldNotReachHere();
    }
  }
  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
    return JVMTI_ERROR_NOT_MONITOR_OWNER;
  }
  assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked");
  if (r != ObjectMonitor::OM_OK) {  // robustness
    return JVMTI_ERROR_INTERNAL;
  }
  return JVMTI_ERROR_NONE;
} /* end RawMonitorNotify */
jvmtiError
JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
  int r = 0;
  Thread* thread = Thread::current();
  if (thread->is_Java_thread()) {
    JavaThread* current_thread = (JavaThread*)thread;
    ThreadInVMfromUnknown __tiv;
    r = rmonitor->raw_notifyAll(current_thread);
  } else {
    if (thread->is_VM_thread() || thread->is_ConcurrentGC_thread()) {
      r = rmonitor->raw_notifyAll(thread);
    } else {
      ShouldNotReachHere();
    }
  }
  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
    return JVMTI_ERROR_NOT_MONITOR_OWNER;
  }
  assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked");
  if (r != ObjectMonitor::OM_OK) {  // robustness
    return JVMTI_ERROR_INTERNAL;
  }
  return JVMTI_ERROR_NONE;
} /* end RawMonitorNotifyAll */
jvmtiError
JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {
  VM_JNIFunctionTableCopier copier(function_table);
  VMThread::execute(&copier);
  return JVMTI_ERROR_NONE;
} /* end SetJNIFunctionTable */
jvmtiError
JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
  if (*function_table == NULL)
    return JVMTI_ERROR_OUT_OF_MEMORY;
  memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
  return JVMTI_ERROR_NONE;
} /* end GetJNIFunctionTable */
jvmtiError
JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {
  if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&
      event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {
    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
  }
  if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {
    if (get_capabilities()->can_generate_compiled_method_load_events == 0) {
      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
    }
    return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);
  } else {
    return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);
  }
} /* end GenerateEvents */
jvmtiError
JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {
  return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);
} /* end GetExtensionFunctions */
jvmtiError
JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {
  return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);
} /* end GetExtensionEvents */
jvmtiError
JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {
  return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);
} /* end SetExtensionEventCallback */
jvmtiError
JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
  os::current_thread_cpu_time_info(info_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetCurrentThreadCpuTimerInfo */
jvmtiError
JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetCurrentThreadCpuTime */
jvmtiError
JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
  os::thread_cpu_time_info(info_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetThreadCpuTimerInfo */
jvmtiError
JvmtiEnv::GetThreadCpuTime(JavaThread* java_thread, jlong* nanos_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetThreadCpuTime */
jvmtiError
JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {
  os::javaTimeNanos_info(info_ptr);
  return JVMTI_ERROR_NONE;
} /* end GetTimerInfo */
jvmtiError
JvmtiEnv::GetTime(jlong* nanos_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetTime */
jvmtiError
JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
  return JVMTI_ERROR_NONE;
} /* end GetAvailableProcessors */
jvmtiError
JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
  if (err != JVMTI_ERROR_NONE) {
    return err;
  }
  int i = 0 ;
  for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) {
    const char *key = p->key();
    char **tmp_value = *property_ptr+i;
    err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
    if (err == JVMTI_ERROR_NONE) {
      strcpy(*tmp_value, key);
    } else {
      for (int j = 0; j < i; j++) {
        Deallocate((unsigned char*)*property_ptr+j);
      }
      Deallocate((unsigned char*)property_ptr);
      break;
    }
  }
  return err;
} /* end GetSystemProperties */
jvmtiError
JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
  jvmtiError err = JVMTI_ERROR_NONE;
  const char *value;
  value = Arguments::PropertyList_get_value(Arguments::system_properties(), property);
  if (value == NULL) {
    err =  JVMTI_ERROR_NOT_AVAILABLE;
  } else {
    err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr);
    if (err == JVMTI_ERROR_NONE) {
      strcpy(*value_ptr, value);
    }
  }
  return err;
} /* end GetSystemProperty */
jvmtiError
JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
  jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE;
  for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
    if (strcmp(property, p->key()) == 0) {
      if (p->set_value((char *)value_ptr)) {
        err =  JVMTI_ERROR_NONE;
      }
    }
  }
  return err;
} /* end SetSystemProperty */
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnvBase.cpp
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "prims/jvmtiEnvBase.hpp"
#include "prims/jvmtiEventController.inline.hpp"
#include "prims/jvmtiExtensions.hpp"
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiManageCapabilities.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframe_hp.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
JvmtiEnvBase* JvmtiEnvBase::_head_environment = NULL;
bool JvmtiEnvBase::_globally_initialized = false;
volatile bool JvmtiEnvBase::_needs_clean_up = false;
jvmtiPhase JvmtiEnvBase::_phase = JVMTI_PHASE_PRIMORDIAL;
volatile int JvmtiEnvBase::_dying_thread_env_iteration_count = 0;
extern jvmtiInterface_1_ jvmti_Interface;
extern jvmtiInterface_1_ jvmtiTrace_Interface;
void
JvmtiEnvBase::globally_initialize() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
  assert(_globally_initialized == false, "bad call");
  JvmtiManageCapabilities::initialize();
  JvmtiExtensions::register_extensions();
#ifdef JVMTI_TRACE
  JvmtiTrace::initialize();
#endif
  _globally_initialized = true;
}
void
JvmtiEnvBase::initialize() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
  {
    JvmtiEnvIterator it;
    JvmtiEnvBase *previous_env = NULL;
    for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
      previous_env = env;
    }
    if (previous_env == NULL) {
      _head_environment = this;
    } else {
      previous_env->set_next_environment(this);
    }
  }
  if (_globally_initialized == false) {
    globally_initialize();
  }
}
bool
JvmtiEnvBase::is_valid() {
  jint value = 0;
  switch (sizeof(_magic)) {
  case 2:
    value = Bytes::get_native_u2((address)&_magic);
    break;
  case 4:
    value = Bytes::get_native_u4((address)&_magic);
    break;
  case 8:
    value = Bytes::get_native_u8((address)&_magic);
    break;
  default:
    guarantee(false, "_magic field is an unexpected size");
  }
  return value == JVMTI_MAGIC;
}
bool
JvmtiEnvBase::use_version_1_0_semantics() {
  int major, minor, micro;
  JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
  return major == 1 && minor == 0;  // micro version doesn't matter here
}
bool
JvmtiEnvBase::use_version_1_1_semantics() {
  int major, minor, micro;
  JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
  return major == 1 && minor == 1;  // micro version doesn't matter here
}
bool
JvmtiEnvBase::use_version_1_2_semantics() {
  int major, minor, micro;
  JvmtiExport::decode_version_values(_version, &major, &minor, &micro);
  return major == 1 && minor == 2;  // micro version doesn't matter here
}
JvmtiEnvBase::JvmtiEnvBase(jint version) : _env_event_enable() {
  _version = version;
  _env_local_storage = NULL;
  _tag_map = NULL;
  _native_method_prefix_count = 0;
  _native_method_prefixes = NULL;
  _next = NULL;
  _class_file_load_hook_ever_enabled = false;
  _is_retransformable = true;
  memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks));
  memset(&_current_capabilities, 0, sizeof(_current_capabilities));
  memset(&_prohibited_capabilities, 0, sizeof(_prohibited_capabilities));
  _magic = JVMTI_MAGIC;
  JvmtiEventController::env_initialize((JvmtiEnv*)this);
#ifdef JVMTI_TRACE
  _jvmti_external.functions = TraceJVMTI != NULL ? &jvmtiTrace_Interface : &jvmti_Interface;
#else
  _jvmti_external.functions = &jvmti_Interface;
#endif
}
void
JvmtiEnvBase::dispose() {
#ifdef JVMTI_TRACE
  JvmtiTrace::shutdown();
#endif
  JvmtiEventController::env_dispose(this);
}
void
JvmtiEnvBase::env_dispose() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
  _magic = DISPOSED_MAGIC;
  jvmtiCapabilities *caps = get_capabilities();
  JvmtiManageCapabilities::relinquish_capabilities(caps, caps, caps);
  set_native_method_prefixes(0, NULL);
  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
  set_tag_map(NULL);
  if (tag_map_to_deallocate != NULL) {
    delete tag_map_to_deallocate;
  }
  _needs_clean_up = true;
}
JvmtiEnvBase::~JvmtiEnvBase() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
  set_tag_map(NULL);
  if (tag_map_to_deallocate != NULL) {
    delete tag_map_to_deallocate;
  }
  _magic = BAD_MAGIC;
}
void
JvmtiEnvBase::periodic_clean_up() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  JvmtiThreadState::periodic_clean_up();
  JvmtiEnvIterator it;
  JvmtiEnvBase* previous_env = NULL;
  JvmtiEnvBase* env = it.first();
  while (env != NULL) {
    if (env->is_valid()) {
      previous_env = env;
      env = it.next(env);
    } else {
      JvmtiEnvBase* defunct_env = env;
      env = it.next(env);
      if (previous_env == NULL) {
        _head_environment = env;
      } else {
        previous_env->set_next_environment(env);
      }
      delete defunct_env;
    }
  }
}
void
JvmtiEnvBase::check_for_periodic_clean_up() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  class ThreadInsideIterationClosure: public ThreadClosure {
   private:
    bool _inside;
   public:
    ThreadInsideIterationClosure() : _inside(false) {};
    void do_thread(Thread* thread) {
      _inside |= thread->is_inside_jvmti_env_iteration();
    }
    bool is_inside_jvmti_env_iteration() {
      return _inside;
    }
  };
  if (_needs_clean_up) {
    ThreadInsideIterationClosure tiic;
    Threads::threads_do(&tiic);
    if (!tiic.is_inside_jvmti_env_iteration() &&
             !is_inside_dying_thread_env_iteration()) {
      _needs_clean_up = false;
      JvmtiEnvBase::periodic_clean_up();
    }
  }
}
void
JvmtiEnvBase::record_first_time_class_file_load_hook_enabled() {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),
         "sanity check");
  if (!_class_file_load_hook_ever_enabled) {
    _class_file_load_hook_ever_enabled = true;
    if (get_capabilities()->can_retransform_classes) {
      _is_retransformable = true;
    } else {
      _is_retransformable = false;
      get_prohibited_capabilities()->can_retransform_classes = 1;
    }
  }
}
void
JvmtiEnvBase::record_class_file_load_hook_enabled() {
  if (!_class_file_load_hook_ever_enabled) {
    if (Threads::number_of_threads() == 0) {
      record_first_time_class_file_load_hook_enabled();
    } else {
      MutexLocker mu(JvmtiThreadState_lock);
      record_first_time_class_file_load_hook_enabled();
    }
  }
}
jvmtiError
JvmtiEnvBase::set_native_method_prefixes(jint prefix_count, char** prefixes) {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),
         "sanity check");
  int old_prefix_count = get_native_method_prefix_count();
  char **old_prefixes = get_native_method_prefixes();
  if (prefix_count == 0 || !is_valid()) {
    _native_method_prefix_count = 0;
    _native_method_prefixes = NULL;
  } else {
    char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*), mtInternal);
    if (new_prefixes == NULL) {
      return JVMTI_ERROR_OUT_OF_MEMORY;
    }
    for (int i = 0; i < prefix_count; i++) {
      char* prefix = prefixes[i];
      if (prefix == NULL) {
        for (int j = 0; j < (i-1); j++) {
          os::free(new_prefixes[j]);
        }
        os::free(new_prefixes);
        return JVMTI_ERROR_NULL_POINTER;
      }
      prefix = os::strdup(prefixes[i]);
      if (prefix == NULL) {
        for (int j = 0; j < (i-1); j++) {
          os::free(new_prefixes[j]);
        }
        os::free(new_prefixes);
        return JVMTI_ERROR_OUT_OF_MEMORY;
      }
      new_prefixes[i] = prefix;
    }
    _native_method_prefix_count = prefix_count;
    _native_method_prefixes = new_prefixes;
  }
  if (old_prefix_count != 0) {
    for (int i = 0; i < old_prefix_count; i++) {
      os::free(old_prefixes[i]);
    }
    os::free(old_prefixes);
  }
  return JVMTI_ERROR_NONE;
}
char**
JvmtiEnvBase::get_all_native_method_prefixes(int* count_ptr) {
  assert(Threads::number_of_threads() == 0 ||
         SafepointSynchronize::is_at_safepoint() ||
         JvmtiThreadState_lock->is_locked(),
         "sanity check");
  int total_count = 0;
  GrowableArray<char*>* prefix_array =new GrowableArray<char*>(5);
  JvmtiEnvIterator it;
  for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
    int prefix_count = env->get_native_method_prefix_count();
    char** prefixes = env->get_native_method_prefixes();
    for (int j = 0; j < prefix_count; j++) {
      char* prefix = prefixes[j];
      char* prefix_copy = NEW_RESOURCE_ARRAY(char, strlen(prefix)+1);
      strcpy(prefix_copy, prefix);
      prefix_array->at_put_grow(total_count++, prefix_copy);
    }
  }
  char** all_prefixes = NEW_RESOURCE_ARRAY(char*, total_count);
  char** p = all_prefixes;
  for (int i = 0; i < total_count; ++i) {
  }
  return all_prefixes;
}
void
JvmtiEnvBase::set_event_callbacks(const jvmtiEventCallbacks* callbacks,
                                               jint size_of_callbacks) {
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
  size_t byte_cnt = sizeof(jvmtiEventCallbacks);
  memset(&_event_callbacks, 0, byte_cnt);
  if (callbacks != NULL && is_valid()) {
    if (size_of_callbacks < (jint)byte_cnt) {
      byte_cnt = size_of_callbacks;
    }
    memcpy(&_event_callbacks, callbacks, byte_cnt);
  }
}
bool
JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) {
  if (thr != JavaThread::current()) {
    if (wait_for_suspend) {
      if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount,
          SuspendRetryDelay, bits)) {
        return false;
      }
    }
    else if (!thr->is_ext_suspend_completed_with_lock(bits)) {
      return false;
    }
  }
  return true;
}
unsigned char *
JvmtiEnvBase::jvmtiMalloc(jlong size) {
  unsigned char* mem = NULL;
  jvmtiError result = allocate(size, &mem);
  assert(result == JVMTI_ERROR_NONE, "Allocate failed");
  return mem;
}
jobject *
JvmtiEnvBase::new_jobjectArray(int length, Handle *handles) {
  if (length == 0) {
    return NULL;
  }
  jobject *objArray = (jobject *) jvmtiMalloc(sizeof(jobject) * length);
  NULL_CHECK(objArray, NULL);
  for (int i=0; i<length; i++) {
    objArray[i] = jni_reference(handles[i]);
  }
  return objArray;
}
jthread *
JvmtiEnvBase::new_jthreadArray(int length, Handle *handles) {
  return (jthread *) new_jobjectArray(length,handles);
}
jthreadGroup *
JvmtiEnvBase::new_jthreadGroupArray(int length, Handle *handles) {
  return (jthreadGroup *) new_jobjectArray(length,handles);
}
JavaThread *
JvmtiEnvBase::get_JavaThread(jthread jni_thread) {
  oop t = JNIHandles::resolve_external_guard(jni_thread);
  if (t == NULL || !t->is_a(SystemDictionary::Thread_klass())) {
    return NULL;
  }
  return java_lang_Thread::thread(t);
}
vframe*
JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
  if (!java_thread->has_last_Java_frame()) {
    return NULL;
  }
  RegisterMap reg_map(java_thread);
  vframe *vf = java_thread->last_java_vframe(&reg_map);
  int d = 0;
  while ((vf != NULL) && (d < depth)) {
    vf = vf->java_sender();
    d++;
  }
  return vf;
}
jclass
JvmtiEnvBase::get_jni_class_non_null(Klass* k) {
  assert(k != NULL, "k != NULL");
  return (jclass)jni_reference(k->java_mirror());
}
bool
JvmtiEnvBase::get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd) {
  if (!jfieldIDWorkaround::is_valid_jfieldID(k, field)) {
    return false;
  }
  bool found = false;
  if (jfieldIDWorkaround::is_static_jfieldID(field)) {
    JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field);
    found = id->find_local_field(fd);
  } else {
    int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field);
    found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, fd);
  }
  return found;
}
jint
JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
  jint ret = 0;
  if (!java_thread->has_last_Java_frame()) {
    return ret;  // no Java frames so no monitors
  }
  ResourceMark rm;
  HandleMark   hm;
  RegisterMap  reg_map(java_thread);
  for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL;
                                                 jvf = jvf->java_sender()) {
    GrowableArray<MonitorInfo*>* mons = jvf->monitors();
    if (!mons->is_empty()) {
      for (int i = 0; i < mons->length(); i++) {
        MonitorInfo *mi = mons->at(i);
        if (mi->owner_is_scalar_replaced()) continue;
        if (mi->owner() != NULL && mi->owner() == hobj()) {
          ret++;
        }
      }
    }
  }
  return ret;
}
jvmtiError
JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert((SafepointSynchronize::is_at_safepoint() ||
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
         "at safepoint or target thread is suspended");
  oop obj = NULL;
  ObjectMonitor *mon = java_thread->current_waiting_monitor();
  if (mon == NULL) {
    mon = java_thread->current_pending_monitor();
    if (mon != NULL) {
      obj = (oop)mon->object();
    }
  } else {
    obj = (oop)mon->object();
    assert(obj != NULL, "Object.wait() should have an object");
  }
  if (obj == NULL) {
  } else {
    HandleMark hm;
    Handle     hobj(obj);
  }
  return JVMTI_ERROR_NONE;
}
jvmtiError
JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
                                 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
  jvmtiError err = JVMTI_ERROR_NONE;
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert((SafepointSynchronize::is_at_safepoint() ||
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
         "at safepoint or target thread is suspended");
  if (java_thread->has_last_Java_frame()) {
    ResourceMark rm;
    HandleMark   hm;
    RegisterMap  reg_map(java_thread);
    int depth = 0;
    for (javaVFrame *jvf = java_thread->last_java_vframe(&reg_map); jvf != NULL;
         jvf = jvf->java_sender()) {
      if (depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
        err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
        if (err != JVMTI_ERROR_NONE) {
          return err;
        }
      }
    }
  }
  JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this);
  ObjectSynchronizer::monitors_iterate(&jmc);
  err = jmc.error();
  return err;
}
jvmtiError
JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) {
  jvmtiError err = JVMTI_ERROR_NONE;
  ResourceMark rm;
  GrowableArray<MonitorInfo*>* mons = jvf->monitors();
  if (mons->is_empty()) {
    return err;  // this javaVFrame holds no monitors
  }
  HandleMark hm;
  oop wait_obj = NULL;
  {
    ObjectMonitor *mon = java_thread->current_waiting_monitor();
    if (mon != NULL) {
      wait_obj = (oop)mon->object();
    }
  }
  oop pending_obj = NULL;
  {
    ObjectMonitor *mon = java_thread->current_pending_monitor();
    if (mon != NULL) {
      pending_obj = (oop)mon->object();
    }
  }
  for (int i = 0; i < mons->length(); i++) {
    MonitorInfo *mi = mons->at(i);
    if (mi->owner_is_scalar_replaced()) continue;
    oop obj = mi->owner();
    if (obj == NULL) {
      continue;
    }
    if (wait_obj == obj) {
      continue;
    }
    if (pending_obj == obj) {
      continue;
    }
    if (owned_monitors_list->length() > 0) {
      bool found = false;
      for (int j = 0; j < owned_monitors_list->length(); j++) {
        jobject jobj = ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(j))->monitor;
        oop check = JNIHandles::resolve(jobj);
        if (check == obj) {
          found = true;  // we found the object
          break;
        }
      }
      if (found) {
        continue;
      }
    }
    jvmtiMonitorStackDepthInfo *jmsdi;
    err = allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
    if (err != JVMTI_ERROR_NONE) {
        return err;
    }
    Handle hobj(obj);
    jmsdi->monitor = jni_reference(calling_thread, hobj);
    jmsdi->stack_depth = stack_depth;
    owned_monitors_list->append(jmsdi);
  }
  return err;
}
jvmtiError
JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
                              jint start_depth, jint max_count,
                              jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert((SafepointSynchronize::is_at_safepoint() ||
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
         "at safepoint or target thread is suspended");
  int count = 0;
  if (java_thread->has_last_Java_frame()) {
    RegisterMap reg_map(java_thread);
    Thread* current_thread = Thread::current();
    ResourceMark rm(current_thread);
    javaVFrame *jvf = java_thread->last_java_vframe(&reg_map);
    HandleMark hm(current_thread);
    if (start_depth != 0) {
      if (start_depth > 0) {
        for (int j = 0; j < start_depth && jvf != NULL; j++) {
          jvf = jvf->java_sender();
        }
        if (jvf == NULL) {
          return JVMTI_ERROR_ILLEGAL_ARGUMENT;
        }
      } else { // start_depth < 0
        javaVFrame *jvf_cursor = jvf;
        javaVFrame *jvf_prev = NULL;
        javaVFrame *jvf_prev_prev;
        int j = 0;
        while (jvf_cursor != NULL) {
          jvf_prev_prev = jvf_prev;
          jvf_prev = jvf_cursor;
          for (j = 0; j > start_depth && jvf_cursor != NULL; j--) {
            jvf_cursor = jvf_cursor->java_sender();
          }
        }
        if (j == start_depth) {
          jvf = jvf_prev;
        } else {
          if (jvf_prev_prev == NULL) {
            return JVMTI_ERROR_ILLEGAL_ARGUMENT;
          }
          jvf = jvf_prev_prev;
          for (; j < 0; j++) {
            jvf = jvf->java_sender();
          }
        }
      }
    }
    for (; count < max_count && jvf != NULL; count++) {
      frame_buffer[count].method = jvf->method()->jmethod_id();
      frame_buffer[count].location = (jvf->method()->is_native() ? -1 : jvf->bci());
      jvf = jvf->java_sender();
    }
  } else {
    if (start_depth != 0) {
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }
  }
  return JVMTI_ERROR_NONE;
}
jvmtiError
JvmtiEnvBase::get_frame_count(JvmtiThreadState *state, jint *count_ptr) {
  assert((state != NULL),
         "JavaThread should create JvmtiThreadState before calling this method");
  return JVMTI_ERROR_NONE;
}
jvmtiError
JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth,
                                 jmethodID* method_ptr, jlocation* location_ptr) {
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert((SafepointSynchronize::is_at_safepoint() ||
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
         "at safepoint or target thread is suspended");
  Thread* current_thread = Thread::current();
  ResourceMark rm(current_thread);
  vframe *vf = vframeFor(java_thread, depth);
  if (vf == NULL) {
    return JVMTI_ERROR_NO_MORE_FRAMES;
  }
#ifdef PRODUCT
  if (!vf->is_java_frame()) {
    return JVMTI_ERROR_INTERNAL;
  }
#endif
  HandleMark hm(current_thread);
  javaVFrame *jvf = javaVFrame::cast(vf);
  Method* method = jvf->method();
  if (method->is_native()) {
  } else {
  }
  return JVMTI_ERROR_NONE;
}
jvmtiError
JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
  HandleMark hm;
  Handle hobj;
  bool at_safepoint = SafepointSynchronize::is_at_safepoint();
  {
    oop mirror = JNIHandles::resolve_external_guard(object);
    NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
    NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER);
    hobj = Handle(mirror);
  }
  JavaThread *owning_thread = NULL;
  ObjectMonitor *mon = NULL;
  jvmtiMonitorUsage ret = {
      NULL, 0, 0, NULL, 0, NULL
  };
  uint32_t debug_bits = 0;
  {
    if (SafepointSynchronize::is_at_safepoint()) {
      BiasedLocking::revoke_at_safepoint(hobj);
    } else {
      BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
    }
    address owner = NULL;
    {
      markOop mark = hobj()->mark();
      if (!mark->has_monitor()) {
        if (mark->has_locker()) {
          owner = (address)mark->locker(); // save the address of the Lock word
        }
      } else {
        mon = mark->monitor();
        owner = (address)mon->owner();
      }
    }
    if (owner != NULL) {
      owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
      if (owning_thread != NULL) {
        if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
          return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
        }
        HandleMark hm;
        Handle     th(owning_thread->threadObj());
        ret.owner = (jthread)jni_reference(calling_thread, th);
      }
    }
    if (owning_thread != NULL) {  // monitor is owned
      if ((address)owning_thread == owner) {
        assert(mon != NULL,
          "must have heavyweight monitor with JavaThread * owner");
        ret.entry_count = mon->recursions() + 1;
      } else {
        ResourceMark rm;
        ret.entry_count = count_locked_objects(owning_thread, hobj);
      }
    }
  }
  int nWant = 0, nWait = 0;
  if (mon != NULL) {
    nWant = mon->contentions(); // # of threads contending for monitor
    nWait = mon->waiters();     // # of threads in Object.wait()
    ret.waiter_count = nWant + nWait;
    ret.notify_waiter_count = nWait;
  } else {
    ret.waiter_count = 0;
    ret.notify_waiter_count = 0;
  }
  jvmtiError err;
  err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
  if (err != JVMTI_ERROR_NONE) {
    return err;
  }
  err = allocate(ret.notify_waiter_count * sizeof(jthread *),
                 (unsigned char**)&ret.notify_waiters);
  if (err != JVMTI_ERROR_NONE) {
    deallocate((unsigned char*)ret.waiters);
    return err;
  }
  if (mon != NULL) {
    memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
    memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
    if (ret.waiter_count > 0) {
      HandleMark hm;
      if (nWant > 0) {
        ResourceMark rm;
        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(
          nWant, (address)mon, !at_safepoint);
        if (wantList->length() < nWant) {
          nWant = wantList->length();
        }
        for (int i = 0; i < nWant; i++) {
          JavaThread *pending_thread = wantList->at(i);
          if (owning_thread == NULL && !at_safepoint &&
              !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) {
            if (ret.owner != NULL) {
              destroy_jni_reference(calling_thread, ret.owner);
            }
            for (int j = 0; j < i; j++) {
              destroy_jni_reference(calling_thread, ret.waiters[j]);
            }
            deallocate((unsigned char*)ret.waiters);
            deallocate((unsigned char*)ret.notify_waiters);
            return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
          }
          Handle th(pending_thread->threadObj());
          ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
        }
      }
      if (nWait > 0) {
        int offset = nWant;  // add after any contending threads
        ObjectWaiter *waiter = mon->first_waiter();
        for (int i = 0, j = 0; i < nWait; i++) {
          if (waiter == NULL) {
            nWait = j;
            break;
          }
          Thread *t = mon->thread_of_waiter(waiter);
          if (t != NULL && t->is_Java_thread()) {
            JavaThread *wjava_thread = (JavaThread *)t;
            Handle th(wjava_thread->threadObj());
            ret.waiters[offset + j] = (jthread)jni_reference(calling_thread, th);
            ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th);
          }
          waiter = mon->next_waiter(waiter);
        }
      }
    }
    ret.waiter_count = nWant + nWait;
    ret.notify_waiter_count = nWait;
  } else {
  }
  return JVMTI_ERROR_NONE;
}
ResourceTracker::ResourceTracker(JvmtiEnv* env) {
  _env = env;
  _allocations = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<unsigned char*>(20, true);
  _failed = false;
}
ResourceTracker::~ResourceTracker() {
  if (_failed) {
    for (int i=0; i<_allocations->length(); i++) {
      _env->deallocate(_allocations->at(i));
    }
  }
  delete _allocations;
}
jvmtiError ResourceTracker::allocate(jlong size, unsigned char** mem_ptr) {
  unsigned char *ptr;
  jvmtiError err = _env->allocate(size, &ptr);
  if (err == JVMTI_ERROR_NONE) {
    _allocations->append(ptr);
  } else {
    _failed = true;
  }
  return err;
 }
unsigned char* ResourceTracker::allocate(jlong size) {
  unsigned char* ptr;
  allocate(size, &ptr);
  return ptr;
}
char* ResourceTracker::strdup(const char* str) {
  char *dup_str = (char*)allocate(strlen(str)+1);
  if (dup_str != NULL) {
    strcpy(dup_str, str);
  }
  return dup_str;
}
struct StackInfoNode {
  struct StackInfoNode *next;
  jvmtiStackInfo info;
};
void
VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  jint state = 0;
  struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode);
  jvmtiStackInfo *infop = &(node->info);
  node->next = head();
  set_head(node);
  infop->frame_count = 0;
  infop->thread = jt;
  if (thread_oop != NULL) {
    state = (jint)java_lang_Thread::get_thread_status(thread_oop);
  }
  if (thr != NULL) {    // add more state bits if there is a JavaThead to query
    if (thr->is_ext_suspended() || thr->is_external_suspend()) {
      state |= JVMTI_THREAD_STATE_SUSPENDED;
    }
    JavaThreadState jts = thr->thread_state();
    if (jts == _thread_in_native) {
      state |= JVMTI_THREAD_STATE_IN_NATIVE;
    }
    OSThread* osThread = thr->osthread();
    if (osThread != NULL && osThread->interrupted()) {
      state |= JVMTI_THREAD_STATE_INTERRUPTED;
    }
  }
  infop->state = state;
  if (thr != NULL || (state & JVMTI_THREAD_STATE_ALIVE) != 0) {
    infop->frame_buffer = NEW_RESOURCE_ARRAY(jvmtiFrameInfo, max_frame_count());
    env()->get_stack_trace(thr, 0, max_frame_count(),
                           infop->frame_buffer, &(infop->frame_count));
  } else {
    infop->frame_buffer = NULL;
    infop->frame_count = 0;
  }
  _frame_count_total += infop->frame_count;
}
void
VM_GetMultipleStackTraces::allocate_and_fill_stacks(jint thread_count) {
  jlong alloc_size =  thread_count       * sizeof(jvmtiStackInfo)
                    + _frame_count_total * sizeof(jvmtiFrameInfo);
  env()->allocate(alloc_size, (unsigned char **)&_stack_info);
  jvmtiStackInfo *si = _stack_info + thread_count;      // bottom of stack info
  jvmtiFrameInfo *fi = (jvmtiFrameInfo *)si;            // is the top of frame info
  for (struct StackInfoNode *sin = head(); sin != NULL; sin = sin->next) {
    jint frame_count = sin->info.frame_count;
    size_t frames_size = frame_count * sizeof(jvmtiFrameInfo);
    --si;
    memcpy(si, &(sin->info), sizeof(jvmtiStackInfo));
    if (frames_size == 0) {
      si->frame_buffer = NULL;
    } else {
      memcpy(fi, sin->info.frame_buffer, frames_size);
      si->frame_buffer = fi;  // point to the new allocated copy of the frames
      fi += frame_count;
    }
  }
  assert(si == _stack_info, "the last copied stack info must be the first record");
  assert((unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size,
         "the last copied frame info must be the last record");
}
void
VM_GetThreadListStackTraces::doit() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  ResourceMark rm;
  for (int i = 0; i < _thread_count; ++i) {
    jthread jt = _thread_list[i];
    oop thread_oop = JNIHandles::resolve_external_guard(jt);
    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
      set_result(JVMTI_ERROR_INVALID_THREAD);
      return;
    }
    fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop);
  }
  allocate_and_fill_stacks(_thread_count);
}
void
VM_GetAllStackTraces::doit() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  ResourceMark rm;
  _final_thread_count = 0;
  for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) {
    oop thread_oop = jt->threadObj();
    if (thread_oop != NULL &&
        !jt->is_exiting() &&
        java_lang_Thread::is_alive(thread_oop) &&
        !jt->is_hidden_from_external_view()) {
      ++_final_thread_count;
      fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
                  jt, thread_oop);
    }
  }
  allocate_and_fill_stacks(_final_thread_count);
}
jvmtiError
JvmtiEnvBase::check_top_frame(JavaThread* current_thread, JavaThread* java_thread,
                              jvalue value, TosState tos, Handle* ret_ob_h) {
  ResourceMark rm(current_thread);
  vframe *vf = vframeFor(java_thread, 0);
  NULL_CHECK(vf, JVMTI_ERROR_NO_MORE_FRAMES);
  javaVFrame *jvf = (javaVFrame*) vf;
  if (!vf->is_java_frame() || jvf->method()->is_native()) {
    return JVMTI_ERROR_OPAQUE_FRAME;
  }
  if (vf->is_compiled_frame()) {
    if (!vf->fr().can_be_deoptimized()) {
      return JVMTI_ERROR_OPAQUE_FRAME;
    }
    Deoptimization::deoptimize_frame(java_thread, jvf->fr().id());
  }
  Symbol* signature = jvf->method()->signature();
  ResultTypeFinder rtf(signature);
  TosState fr_tos = as_TosState(rtf.type());
  if (fr_tos != tos) {
    if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) {
      return JVMTI_ERROR_TYPE_MISMATCH;
    }
  }
  jobject jobj = value.l;
  if (tos == atos && jobj != NULL) { // NULL reference is allowed
    Handle ob_h = Handle(current_thread, JNIHandles::resolve_external_guard(jobj));
    NULL_CHECK(ob_h, JVMTI_ERROR_INVALID_OBJECT);
    KlassHandle ob_kh = KlassHandle(current_thread, ob_h()->klass());
    NULL_CHECK(ob_kh, JVMTI_ERROR_INVALID_OBJECT);
    char* ty_sign = 1 + strchr(signature->as_C_string(), ')');
    if (!VM_GetOrSetLocal::is_assignable(ty_sign, ob_kh(), current_thread)) {
      return JVMTI_ERROR_TYPE_MISMATCH;
    }
  }
  return JVMTI_ERROR_NONE;
} /* end check_top_frame */
jvmtiError
JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) {
  JavaThread* current_thread = JavaThread::current();
  HandleMark   hm(current_thread);
  uint32_t debug_bits = 0;
  JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
  if (state == NULL) {
    return JVMTI_ERROR_THREAD_NOT_ALIVE;
  }
  if (!is_thread_fully_suspended(java_thread,
                                 true /* wait for suspend completion */,
                                 &debug_bits)) {
    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
  }
  if (state->is_earlyret_pending()) {
    return JVMTI_ERROR_INTERNAL;
  }
  {
    OSThread* osThread = java_thread->osthread();
    if (osThread->get_state() == MONITOR_WAIT) {
      return JVMTI_ERROR_OPAQUE_FRAME;
    }
  }
  Handle ret_ob_h = Handle();
  jvmtiError err = check_top_frame(current_thread, java_thread, value, tos, &ret_ob_h);
  if (err != JVMTI_ERROR_NONE) {
    return err;
  }
  assert(tos != atos || value.l == NULL || ret_ob_h() != NULL,
         "return object oop must not be NULL if jobject is not NULL");
  state->set_earlyret_pending();
  state->set_earlyret_oop(ret_ob_h());
  state->set_earlyret_value(value, tos);
  state->set_pending_step_for_earlyret();
  return JVMTI_ERROR_NONE;
} /* end force_early_return */
void
JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
  if ( _error != JVMTI_ERROR_NONE) {
    return;
  }
  if (mon->owner() == _java_thread ) {
    oop obj = (oop)mon->object();
    bool found = false;
    for (int j = 0; j < _owned_monitors_list->length(); j++) {
      jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor;
      oop check = JNIHandles::resolve(jobj);
      if (check == obj) {
        found = true;
        break;
      }
    }
    if (found == false) {
      jvmtiError err;
      jvmtiMonitorStackDepthInfo *jmsdi;
      err = _env->allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
      if (err != JVMTI_ERROR_NONE) {
        _error = err;
        return;
      }
      Handle hobj(obj);
      jmsdi->monitor = _env->jni_reference(_calling_thread, hobj);
      jmsdi->stack_depth = -1;
      _owned_monitors_list->append(jmsdi);
    }
  }
}
C:\hotspot-69087d08d473\src\share\vm/prims/jvmtiEnvBase.hpp
#ifndef SHARE_VM_PRIMS_JVMTIENVBASE_HPP
#define SHARE_VM_PRIMS_JVMTIENVBASE_HPP
#include "classfile/classLoader.hpp"
#include "prims/jvmtiEnvThreadState.hpp"
#include "prims/jvmtiEventController.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/frame.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/thread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
class JvmtiEnv;
class JvmtiThreadState;
class JvmtiRawMonitor; // for jvmtiEnv.hpp
class JvmtiEventControllerPrivate;
class JvmtiTagMap;
class JvmtiEnvBase : public CHeapObj<mtInternal> {
 private:
#if INCLUDE_JVMTI
  static JvmtiEnvBase*     _head_environment;  // head of environment list
#endif // INCLUDE_JVMTI
  static bool              _globally_initialized;
  static jvmtiPhase        _phase;
  static volatile int      _dying_thread_env_iteration_count;
 public:
  enum {
    JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 +  33,  /* version: 1.0.33  */
    JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102,  /* version: 1.1.102 */
    JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 +   2   /* version: 1.2.2   */
  };
  static jvmtiPhase  get_phase()                    { return _phase; }
  static void  set_phase(jvmtiPhase phase)          { _phase = phase; }
  static bool is_vm_live()                          { return _phase == JVMTI_PHASE_LIVE; }
  static void entering_dying_thread_env_iteration() { ++_dying_thread_env_iteration_count; }
  static void leaving_dying_thread_env_iteration()  { --_dying_thread_env_iteration_count; }
  static bool is_inside_dying_thread_env_iteration(){ return _dying_thread_env_iteration_count > 0; }
 private:
  enum {
      JVMTI_MAGIC    = 0x71EE,
      DISPOSED_MAGIC = 0xDEFC,
      BAD_MAGIC      = 0xDEAD
  };
  jvmtiEnv _jvmti_external;
  jint _magic;
  jint _version;  // version value passed to JNI GetEnv()
  JvmtiEnvBase* _next;
  bool _is_retransformable;
  const void *_env_local_storage;     // per env agent allocated data.
  jvmtiEventCallbacks _event_callbacks;
  jvmtiExtEventCallbacks _ext_event_callbacks;
  JvmtiTagMap* volatile _tag_map;
  JvmtiEnvEventEnable _env_event_enable;
  jvmtiCapabilities _current_capabilities;
  jvmtiCapabilities _prohibited_capabilities;
  volatile bool _class_file_load_hook_ever_enabled;
  static volatile bool _needs_clean_up;
  char** _native_method_prefixes;
  int    _native_method_prefix_count;
 protected:
  JvmtiEnvBase(jint version);
  ~JvmtiEnvBase();
  void dispose();
  void env_dispose();
  void set_env_local_storage(const void* data)     { _env_local_storage = data; }
  const void* get_env_local_storage()              { return _env_local_storage; }
  void record_class_file_load_hook_enabled();
  void record_first_time_class_file_load_hook_enabled();
  char** get_native_method_prefixes()              { return _native_method_prefixes; }
  int    get_native_method_prefix_count()          { return _native_method_prefix_count; }
  jvmtiError set_native_method_prefixes(jint prefix_count, char** prefixes);
 private:
  friend class JvmtiEventControllerPrivate;
  void initialize();
  void set_event_callbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks);
  static void globally_initialize();
  static void periodic_clean_up();
  friend class JvmtiEnvIterator;
  JvmtiEnv* next_environment()                     { return (JvmtiEnv*)_next; }
  void set_next_environment(JvmtiEnvBase* env)     { _next = env; }
  static JvmtiEnv* head_environment()              {
    JVMTI_ONLY(return (JvmtiEnv*)_head_environment);
    NOT_JVMTI(return NULL);
  }
 public:
  bool is_valid();
  bool use_version_1_0_semantics();  // agent asked for version 1.0
  bool use_version_1_1_semantics();  // agent asked for version 1.1
  bool use_version_1_2_semantics();  // agent asked for version 1.2
  bool is_retransformable()                        { return _is_retransformable; }
  static ByteSize jvmti_external_offset() {
    return byte_offset_of(JvmtiEnvBase, _jvmti_external);
  };
  static JvmtiEnv* JvmtiEnv_from_jvmti_env(jvmtiEnv *env) {
    return (JvmtiEnv*)((intptr_t)env - in_bytes(jvmti_external_offset()));
  };
  jvmtiCapabilities *get_capabilities()             { return &_current_capabilities; }
  jvmtiCapabilities *get_prohibited_capabilities()  { return &_prohibited_capabilities; }
  static char** get_all_native_method_prefixes(int* count_ptr);
  static bool environments_might_exist() {
    return head_environment() != NULL;
  }
  static void check_for_periodic_clean_up();
  JvmtiEnvEventEnable *env_event_enable() {
    return &_env_event_enable;
  }
  jvmtiError allocate(jlong size, unsigned char** mem_ptr) {
    if (size < 0) {
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
    }
    if (size == 0) {
    } else {
      if (*mem_ptr == NULL) {
        return JVMTI_ERROR_OUT_OF_MEMORY;
      }
    }
    return JVMTI_ERROR_NONE;
  }
  jvmtiError deallocate(unsigned char* mem) {
    if (mem != NULL) {
      os::free(mem, mtInternal);
    }
    return JVMTI_ERROR_NONE;
  }
  unsigned char* jvmtiMalloc(jlong size);  // don't use this - call allocate
  jobject jni_reference(Handle hndl) {
    return JNIHandles::make_local(hndl());
  }
  jobject jni_reference(JavaThread *thread, Handle hndl) {
    return JNIHandles::make_local(thread, hndl());
  }
  void destroy_jni_reference(jobject jobj) {
    JNIHandles::destroy_local(jobj);
  }
  void destroy_jni_reference(JavaThread *thread, jobject jobj) {
    destroy_jni_reference(jobj);
  }
  jvmtiEnv* jvmti_external() { return &_jvmti_external; };
  bool has_callback(jvmtiEvent event_type) {
    assert(event_type >= JVMTI_MIN_EVENT_TYPE_VAL &&
           event_type <= JVMTI_MAX_EVENT_TYPE_VAL, "checking");
    return ((void**)&_event_callbacks)[event_type-JVMTI_MIN_EVENT_TYPE_VAL] != NULL;
  }
  jvmtiEventCallbacks* callbacks() {
    return &_event_callbacks;
  }
  jvmtiExtEventCallbacks* ext_callbacks() {
    return &_ext_event_callbacks;
  }
  void set_tag_map(JvmtiTagMap* tag_map) {
    _tag_map = tag_map;
  }
  JvmtiTagMap* tag_map() {
    return _tag_map;
  }
  JvmtiTagMap* tag_map_acquire() {
    return (JvmtiTagMap*)OrderAccess::load_ptr_acquire(&_tag_map);
  }
  void release_set_tag_map(JvmtiTagMap* tag_map) {
    OrderAccess::release_store_ptr(&_tag_map, tag_map);
  }
  bool is_enabled(jvmtiEvent event_type) {
    return _env_event_enable.is_enabled(event_type);
  }
 protected:
  jobject * new_jobjectArray(int length, Handle *handles);
  jthread * new_jthreadArray(int length, Handle *handles);
  jthreadGroup * new_jthreadGroupArray(int length, Handle *handles);
  JavaThread  * get_JavaThread(jthread jni_thread);
  jclass get_jni_class_non_null(Klass* k);
  jint count_locked_objects(JavaThread *java_thread, Handle hobj);
  jvmtiError get_locked_objects_in_frame(JavaThread *calling_thread,
                                   JavaThread* java_thread,
                                   javaVFrame *jvf,
                                   GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list,
                                   jint depth);
  vframe* vframeFor(JavaThread* java_thread, jint depth);
 public:
  static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
  static bool is_thread_fully_suspended(JavaThread *thread,
                                        bool wait_for_suspend,
                                        uint32_t *bits);
  jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
  jvmtiError get_frame_location(JavaThread* java_thread, jint depth,
                                              jmethodID* method_ptr, jlocation* location_ptr);
  jvmtiError get_object_monitor_usage(JavaThread *calling_thread,
                                                    jobject object, jvmtiMonitorUsage* info_ptr);
  jvmtiError get_stack_trace(JavaThread *java_thread,
                                           jint stack_depth, jint max_count,
                                           jvmtiFrameInfo* frame_buffer, jint* count_ptr);
  jvmtiError get_current_contended_monitor(JavaThread *calling_thread,
                                                         JavaThread *java_thread,
                                                         jobject *monitor_ptr);
  jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
                          GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
  jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread,
                             jvalue value, TosState tos, Handle* ret_ob_h);
  jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos);
};
class JvmtiEnvIterator : public StackObj {
 private:
  bool _entry_was_marked;
 public:
  JvmtiEnvIterator() {
    if (Threads::number_of_threads() == 0) {
      _entry_was_marked = false; // we are single-threaded, no need
    } else {
      Thread::current()->entering_jvmti_env_iteration();
      _entry_was_marked = true;
    }
  }
  ~JvmtiEnvIterator() {
    if (_entry_was_marked) {
      Thread::current()->leaving_jvmti_env_iteration();
    }
  }
  JvmtiEnv* first()                 { return JvmtiEnvBase::head_environment(); }
  JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }
};
class VM_GetOwnedMonitorInfo : public VM_Operation {
private:
  JvmtiEnv *_env;
  JavaThread* _calling_thread;
  JavaThread *_java_thread;
  jvmtiError _result;
  GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
public:
  VM_GetOwnedMonitorInfo(JvmtiEnv* env, JavaThread* calling_thread,
                                   JavaThread* java_thread,
                                   GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list) {
    _env = env;
    _calling_thread = calling_thread;
    _java_thread = java_thread;
    _owned_monitors_list = owned_monitor_list;
    _result = JVMTI_ERROR_NONE;
  }
  VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; }
  void doit() {
    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
    if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
                                        && _java_thread->threadObj() != NULL) {
      _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
                                                            _owned_monitors_list);
    }
  }
  jvmtiError result() { return _result; }
};
class VM_GetObjectMonitorUsage : public VM_Operation {
private:
  JvmtiEnv *_env;
  jobject _object;
  JavaThread* _calling_thread;
  jvmtiMonitorUsage* _info_ptr;
  jvmtiError _result;
public:
  VM_GetObjectMonitorUsage(JvmtiEnv *env, JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
    _env = env;
    _object = object;
    _calling_thread = calling_thread;
    _info_ptr = info_ptr;
  }
  VMOp_Type type() const { return VMOp_GetObjectMonitorUsage; }
  jvmtiError result() { return _result; }
  void doit() {
    _result = ((JvmtiEnvBase*) _env)->get_object_monitor_usage(_calling_thread, _object, _info_ptr);
  }
};
class VM_GetCurrentContendedMonitor : public VM_Operation {
private:
  JvmtiEnv *_env;
  JavaThread *_calling_thread;
  JavaThread *_java_thread;
  jobject *_owned_monitor_ptr;
  jvmtiError _result;
public:
  VM_GetCurrentContendedMonitor(JvmtiEnv *env, JavaThread *calling_thread, JavaThread *java_thread, jobject *mon_ptr) {
    _env = env;
    _calling_thread = calling_thread;
    _java_thread = java_thread;
    _owned_monitor_ptr = mon_ptr;
  }
  VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
  jvmtiError result() { return _result; }
  void doit() {
    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
        _java_thread->threadObj() != NULL) {
      _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
    }
  }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值