1 /*
   2  * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "classfile/javaClasses.inline.hpp"
  26 #include "classfile/stringTable.hpp"
  27 #include "classfile/modules.hpp"
  28 #include "classfile/systemDictionary.hpp"
  29 #include "classfile/vmClasses.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "interpreter/bytecodeStream.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "jfr/jfrEvents.hpp"
  35 #include "jvmtifiles/jvmtiEnv.hpp"
  36 #include "logging/log.hpp"
  37 #include "logging/logConfiguration.hpp"
  38 #include "memory/allocation.hpp"
  39 #include "memory/resourceArea.hpp"
  40 #include "memory/universe.hpp"
  41 #include "oops/instanceKlass.hpp"
  42 #include "oops/klass.inline.hpp"
  43 #include "oops/objArrayOop.inline.hpp"
  44 #include "oops/oop.inline.hpp"
  45 #include "prims/jniCheck.hpp"
  46 #include "prims/jvm_misc.hpp"
  47 #include "prims/jvmtiAgentThread.hpp"
  48 #include "prims/jvmtiClassFileReconstituter.hpp"
  49 #include "prims/jvmtiCodeBlobEvents.hpp"
  50 #include "prims/jvmtiExtensions.hpp"
  51 #include "prims/jvmtiGetLoadedClasses.hpp"
  52 #include "prims/jvmtiImpl.hpp"
  53 #include "prims/jvmtiManageCapabilities.hpp"
  54 #include "prims/jvmtiRawMonitor.hpp"
  55 #include "prims/jvmtiRedefineClasses.hpp"
  56 #include "prims/jvmtiTagMap.hpp"
  57 #include "prims/jvmtiThreadState.inline.hpp"
  58 #include "prims/jvmtiUtil.hpp"
  59 #include "runtime/arguments.hpp"
  60 #include "runtime/deoptimization.hpp"
  61 #include "runtime/fieldDescriptor.inline.hpp"
  62 #include "runtime/handles.inline.hpp"
  63 #include "runtime/interfaceSupport.inline.hpp"
  64 #include "runtime/javaCalls.hpp"
  65 #include "runtime/javaThread.inline.hpp"
  66 #include "runtime/jfieldIDWorkaround.hpp"
  67 #include "runtime/jniHandles.inline.hpp"
  68 #include "runtime/objectMonitor.inline.hpp"
  69 #include "runtime/os.hpp"
  70 #include "runtime/osThread.hpp"
  71 #include "runtime/reflectionUtils.hpp"
  72 #include "runtime/signature.hpp"
  73 #include "runtime/threadHeapSampler.hpp"
  74 #include "runtime/threads.hpp"
  75 #include "runtime/threadSMR.hpp"
  76 #include "runtime/timerTrace.hpp"
  77 #include "runtime/vframe.inline.hpp"
  78 #include "runtime/vmThread.hpp"
  79 #include "services/threadService.hpp"
  80 #include "utilities/exceptions.hpp"
  81 #include "utilities/preserveException.hpp"
  82 #include "utilities/utf8.hpp"
  83 
  84 
  85 #define FIXLATER 0 // REMOVE this when completed.
  86 
  87  // FIXLATER: hook into JvmtiTrace
  88 #define TraceJVMTICalls false
  89 
  90 JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
  91 }
  92 
  93 JvmtiEnv::~JvmtiEnv() {
  94 }
  95 
  96 JvmtiEnv*
  97 JvmtiEnv::create_a_jvmti(jint version) {
  98   return new JvmtiEnv(version);
  99 }
 100 
 101 // VM operation class to copy jni function table at safepoint.
 102 // More than one java threads or jvmti agents may be reading/
 103 // modifying jni function tables. To reduce the risk of bad
 104 // interaction b/w these threads it is copied at safepoint.
 105 class VM_JNIFunctionTableCopier : public VM_Operation {
 106  private:
 107   const struct JNINativeInterface_ *_function_table;
 108  public:
 109   VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) {
 110     _function_table = func_tbl;
 111   };
 112 
 113   VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; }
 114   void doit() {
 115     copy_jni_function_table(_function_table);
 116   };
 117 };
 118 
 119 //
 120 // Do not change the "prefix" marker below, everything above it is copied
 121 // unchanged into the filled stub, everything below is controlled by the
 122 // stub filler (only method bodies are carried forward, and then only for
 123 // functionality still in the spec).
 124 //
 125 // end file prefix
 126 
 127   //
 128   // Memory Management functions
 129   //
 130 
 131 // mem_ptr - pre-checked for null
 132 jvmtiError
 133 JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) {
 134   return allocate(size, mem_ptr);
 135 } /* end Allocate */
 136 
 137 
 138 // mem - null is a valid value, must be checked
 139 jvmtiError
 140 JvmtiEnv::Deallocate(unsigned char* mem) {
 141   return deallocate(mem);
 142 } /* end Deallocate */
 143 
 144 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
 145 // data - null is a valid value, must be checked
 146 jvmtiError
 147 JvmtiEnv::SetThreadLocalStorage(jthread thread, const void* data) {
 148   JavaThread* current = JavaThread::current();
 149   JvmtiThreadState* state = nullptr;
 150   JvmtiVTMSTransitionDisabler disabler(thread);
 151   ThreadsListHandle tlh(current);
 152 
 153   JavaThread* java_thread = nullptr;
 154   oop thread_obj = nullptr;
 155   if (thread == nullptr) {
 156     java_thread = current;
 157     state = java_thread->jvmti_thread_state();
 158   } else {
 159     jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current, &java_thread, &thread_obj);
 160     if (err != JVMTI_ERROR_NONE) {
 161       return err;
 162     }
 163     state = java_lang_Thread::jvmti_thread_state(thread_obj);
 164   }
 165   if (state == nullptr) {
 166     if (data == nullptr) {
 167       // leaving state unset same as data set to null
 168       return JVMTI_ERROR_NONE;
 169     }
 170     // otherwise, create the state
 171     HandleMark hm(current);
 172     Handle thread_handle(current, thread_obj);
 173     state = JvmtiThreadState::state_for(java_thread, thread_handle);
 174     if (state == nullptr) {
 175       return JVMTI_ERROR_THREAD_NOT_ALIVE;
 176     }
 177   }
 178   state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
 179   return JVMTI_ERROR_NONE;
 180 } /* end SetThreadLocalStorage */
 181 
 182 
 183 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
 184 // data_ptr - pre-checked for null
 185 jvmtiError
 186 JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {
 187   JavaThread* current_thread = JavaThread::current();
 188   if (thread == nullptr) {
 189     JvmtiThreadState* state = current_thread->jvmti_thread_state();
 190     *data_ptr = (state == nullptr) ? nullptr :
 191       state->env_thread_state(this)->get_agent_thread_local_storage_data();
 192   } else {
 193     // jvmti_GetThreadLocalStorage is "in native" and doesn't transition
 194     // the thread to _thread_in_vm. However, when the TLS for a thread
 195     // other than the current thread is required we need to transition
 196     // from native so as to resolve the jthread.
 197 
 198     MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));
 199     ThreadInVMfromNative __tiv(current_thread);
 200     VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
 201     DEBUG_ONLY(VMNativeEntryWrapper __vew;)
 202 
 203     JvmtiVTMSTransitionDisabler disabler(thread);
 204     ThreadsListHandle tlh(current_thread);
 205 
 206     JavaThread* java_thread = nullptr;
 207     oop thread_obj = nullptr;
 208     jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
 209     if (err != JVMTI_ERROR_NONE) {
 210       return err;
 211     }
 212 
 213     HandleMark hm(current_thread);
 214     Handle thread_handle(current_thread, thread_obj);
 215     JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread, thread_handle);
 216     *data_ptr = (state == nullptr) ? nullptr :
 217       state->env_thread_state(this)->get_agent_thread_local_storage_data();
 218   }
 219   return JVMTI_ERROR_NONE;
 220 } /* end GetThreadLocalStorage */
 221 
 222   //
 223   // Module functions
 224   //
 225 
 226 // module_count_ptr - pre-checked for null
 227 // modules_ptr - pre-checked for null
 228 jvmtiError
 229 JvmtiEnv::GetAllModules(jint* module_count_ptr, jobject** modules_ptr) {
 230     JvmtiModuleClosure jmc;
 231 
 232     return jmc.get_all_modules(this, module_count_ptr, modules_ptr);
 233 } /* end GetAllModules */
 234 
 235 
 236 // class_loader - null is a valid value, must be pre-checked
 237 // package_name - pre-checked for null
 238 // module_ptr - pre-checked for null
 239 jvmtiError
 240 JvmtiEnv::GetNamedModule(jobject class_loader, const char* package_name, jobject* module_ptr) {
 241   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 242   ResourceMark rm(THREAD);
 243 
 244   Handle h_loader (THREAD, JNIHandles::resolve(class_loader));
 245   // Check that loader is a subclass of java.lang.ClassLoader.
 246   if (h_loader.not_null() && !java_lang_ClassLoader::is_subclass(h_loader->klass())) {
 247     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 248   }
 249   oop module = Modules::get_named_module(h_loader, package_name);
 250   *module_ptr = module != nullptr ? JNIHandles::make_local(THREAD, module) : nullptr;
 251   return JVMTI_ERROR_NONE;
 252 } /* end GetNamedModule */
 253 
 254 
 255 // module - pre-checked for null
 256 // to_module - pre-checked for null
 257 jvmtiError
 258 JvmtiEnv::AddModuleReads(jobject module, jobject to_module) {
 259   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 260 
 261   // check module
 262   Handle h_module(THREAD, JNIHandles::resolve(module));
 263   if (!java_lang_Module::is_instance(h_module())) {
 264     return JVMTI_ERROR_INVALID_MODULE;
 265   }
 266   // check to_module
 267   Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
 268   if (!java_lang_Module::is_instance(h_to_module())) {
 269     return JVMTI_ERROR_INVALID_MODULE;
 270   }
 271   return JvmtiExport::add_module_reads(h_module, h_to_module, THREAD);
 272 } /* end AddModuleReads */
 273 
 274 
 275 // module - pre-checked for null
 276 // pkg_name - pre-checked for null
 277 // to_module - pre-checked for null
 278 jvmtiError
 279 JvmtiEnv::AddModuleExports(jobject module, const char* pkg_name, jobject to_module) {
 280   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 281   Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);
 282 
 283   // check module
 284   Handle h_module(THREAD, JNIHandles::resolve(module));
 285   if (!java_lang_Module::is_instance(h_module())) {
 286     return JVMTI_ERROR_INVALID_MODULE;
 287   }
 288   // check to_module
 289   Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
 290   if (!java_lang_Module::is_instance(h_to_module())) {
 291     return JVMTI_ERROR_INVALID_MODULE;
 292   }
 293   return JvmtiExport::add_module_exports(h_module, h_pkg, h_to_module, THREAD);
 294 } /* end AddModuleExports */
 295 
 296 
 297 // module - pre-checked for null
 298 // pkg_name - pre-checked for null
 299 // to_module - pre-checked for null
 300 jvmtiError
 301 JvmtiEnv::AddModuleOpens(jobject module, const char* pkg_name, jobject to_module) {
 302   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 303   Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);
 304 
 305   // check module
 306   Handle h_module(THREAD, JNIHandles::resolve(module));
 307   if (!java_lang_Module::is_instance(h_module())) {
 308     return JVMTI_ERROR_INVALID_MODULE;
 309   }
 310   // check to_module
 311   Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
 312   if (!java_lang_Module::is_instance(h_to_module())) {
 313     return JVMTI_ERROR_INVALID_MODULE;
 314   }
 315   return JvmtiExport::add_module_opens(h_module, h_pkg, h_to_module, THREAD);
 316 } /* end AddModuleOpens */
 317 
 318 
 319 // module - pre-checked for null
 320 // service - pre-checked for null
 321 jvmtiError
 322 JvmtiEnv::AddModuleUses(jobject module, jclass service) {
 323   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 324 
 325   // check module
 326   Handle h_module(THREAD, JNIHandles::resolve(module));
 327   if (!java_lang_Module::is_instance(h_module())) {
 328     return JVMTI_ERROR_INVALID_MODULE;
 329   }
 330   // check service
 331   Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));
 332   if (!java_lang_Class::is_instance(h_service()) ||
 333       java_lang_Class::is_primitive(h_service())) {
 334     return JVMTI_ERROR_INVALID_CLASS;
 335   }
 336   return JvmtiExport::add_module_uses(h_module, h_service, THREAD);
 337 } /* end AddModuleUses */
 338 
 339 
 340 // module - pre-checked for null
 341 // service - pre-checked for null
 342 // impl_class - pre-checked for null
 343 jvmtiError
 344 JvmtiEnv::AddModuleProvides(jobject module, jclass service, jclass impl_class) {
 345   JavaThread* THREAD = JavaThread::current(); // For exception macros.
 346 
 347   // check module
 348   Handle h_module(THREAD, JNIHandles::resolve(module));
 349   if (!java_lang_Module::is_instance(h_module())) {
 350     return JVMTI_ERROR_INVALID_MODULE;
 351   }
 352   // check service
 353   Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));
 354   if (!java_lang_Class::is_instance(h_service()) ||
 355       java_lang_Class::is_primitive(h_service())) {
 356     return JVMTI_ERROR_INVALID_CLASS;
 357   }
 358   // check impl_class
 359   Handle h_impl_class(THREAD, JNIHandles::resolve_external_guard(impl_class));
 360   if (!java_lang_Class::is_instance(h_impl_class()) ||
 361       java_lang_Class::is_primitive(h_impl_class())) {
 362     return JVMTI_ERROR_INVALID_CLASS;
 363   }
 364   return JvmtiExport::add_module_provides(h_module, h_service, h_impl_class, THREAD);
 365 } /* end AddModuleProvides */
 366 
 367 // module - pre-checked for null
 368 // is_modifiable_class_ptr - pre-checked for null
 369 jvmtiError
 370 JvmtiEnv::IsModifiableModule(jobject module, jboolean* is_modifiable_module_ptr) {
 371   JavaThread* current = JavaThread::current();
 372 
 373   // check module
 374   Handle h_module(current, JNIHandles::resolve(module));
 375   if (!java_lang_Module::is_instance(h_module())) {
 376     return JVMTI_ERROR_INVALID_MODULE;
 377   }
 378 
 379   *is_modifiable_module_ptr = JNI_TRUE;
 380   return JVMTI_ERROR_NONE;
 381 } /* end IsModifiableModule */
 382 
 383 
 384   //
 385   // Class functions
 386   //
 387 
 388 // class_count_ptr - pre-checked for null
 389 // classes_ptr - pre-checked for null
 390 jvmtiError
 391 JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {
 392   return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);
 393 } /* end GetLoadedClasses */
 394 
 395 
 396 // initiating_loader - null is a valid value, must be checked
 397 // class_count_ptr - pre-checked for null
 398 // classes_ptr - pre-checked for null
 399 jvmtiError
 400 JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
 401   return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,
 402                                                   class_count_ptr, classes_ptr);
 403 } /* end GetClassLoaderClasses */
 404 
 405 // k_mirror - may be primitive, this must be checked
 406 // is_modifiable_class_ptr - pre-checked for null
 407 jvmtiError
 408 JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {
 409   *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?
 410                                                        JNI_TRUE : JNI_FALSE;
 411   return JVMTI_ERROR_NONE;
 412 } /* end IsModifiableClass */
 413 
 414 // class_count - pre-checked to be greater than or equal to 0
 415 // classes - pre-checked for null
 416 jvmtiError
 417 JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
 418 //TODO: add locking
 419 
 420   int index;
 421   JavaThread* current_thread = JavaThread::current();
 422   ResourceMark rm(current_thread);
 423 
 424   jvmtiClassDefinition* class_definitions =
 425                             NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);
 426   NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);
 427 
 428   for (index = 0; index < class_count; index++) {
 429     HandleMark hm(current_thread);
 430 
 431     jclass jcls = classes[index];
 432     oop k_mirror = JNIHandles::resolve_external_guard(jcls);
 433     if (k_mirror == nullptr) {
 434       return JVMTI_ERROR_INVALID_CLASS;
 435     }
 436     if (!k_mirror->is_a(vmClasses::Class_klass())) {
 437       return JVMTI_ERROR_INVALID_CLASS;
 438     }
 439 
 440     if (!VM_RedefineClasses::is_modifiable_class(k_mirror)) {
 441       return JVMTI_ERROR_UNMODIFIABLE_CLASS;
 442     }
 443 
 444     Klass* klass = java_lang_Class::as_Klass(k_mirror);
 445 
 446     jint status = klass->jvmti_class_status();
 447     if (status & (JVMTI_CLASS_STATUS_ERROR)) {
 448       return JVMTI_ERROR_INVALID_CLASS;
 449     }
 450 
 451     InstanceKlass* ik = InstanceKlass::cast(klass);
 452     if (ik->get_cached_class_file_bytes() == nullptr) {
 453       // Not cached, we need to reconstitute the class file from the
 454       // VM representation. We don't attach the reconstituted class
 455       // bytes to the InstanceKlass here because they have not been
 456       // validated and we're not at a safepoint.
 457       JvmtiClassFileReconstituter reconstituter(ik);
 458       if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
 459         return reconstituter.get_error();
 460       }
 461 
 462       class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();
 463       class_definitions[index].class_bytes      = (unsigned char*)
 464                                                        reconstituter.class_file_bytes();
 465     } else {
 466       // it is cached, get it from the cache
 467       class_definitions[index].class_byte_count = ik->get_cached_class_file_len();
 468       class_definitions[index].class_bytes      = ik->get_cached_class_file_bytes();
 469     }
 470     class_definitions[index].klass              = jcls;
 471   }
 472   EventRetransformClasses event;
 473   VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
 474   VMThread::execute(&op);
 475   jvmtiError error = op.check_error();
 476   if (error == JVMTI_ERROR_NONE) {
 477     event.set_classCount(class_count);
 478     event.set_redefinitionId(op.id());
 479     event.commit();
 480   }
 481   return error;
 482 } /* end RetransformClasses */
 483 
 484 
 485 // class_count - pre-checked to be greater than or equal to 0
 486 // class_definitions - pre-checked for null
 487 jvmtiError
 488 JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
 489 //TODO: add locking
 490   EventRedefineClasses event;
 491   VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
 492   VMThread::execute(&op);
 493   jvmtiError error = op.check_error();
 494   if (error == JVMTI_ERROR_NONE) {
 495     event.set_classCount(class_count);
 496     event.set_redefinitionId(op.id());
 497     event.commit();
 498   }
 499   return error;
 500 } /* end RedefineClasses */
 501 
 502 
 503   //
 504   // Object functions
 505   //
 506 
 507 // size_ptr - pre-checked for null
 508 jvmtiError
 509 JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
 510   oop mirror = JNIHandles::resolve_external_guard(object);
 511   NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
 512   *size_ptr = (jlong)mirror->size() * wordSize;
 513   return JVMTI_ERROR_NONE;
 514 } /* end GetObjectSize */
 515 
 516   //
 517   // Method functions
 518   //
 519 
 520 // prefix - null is a valid value, must be checked
 521 jvmtiError
 522 JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {
 523   return prefix == nullptr?
 524               SetNativeMethodPrefixes(0, nullptr) :
 525               SetNativeMethodPrefixes(1, (char**)&prefix);
 526 } /* end SetNativeMethodPrefix */
 527 
 528 
 529 // prefix_count - pre-checked to be greater than or equal to 0
 530 // prefixes - pre-checked for null
 531 jvmtiError
 532 JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {
 533   // Have to grab JVMTI thread state lock to be sure that some thread
 534   // isn't accessing the prefixes at the same time we are setting them.
 535   // No locks during VM bring-up.
 536   if (Threads::number_of_threads() == 0) {
 537     return set_native_method_prefixes(prefix_count, prefixes);
 538   } else {
 539     MutexLocker mu(JvmtiThreadState_lock);
 540     return set_native_method_prefixes(prefix_count, prefixes);
 541   }
 542 } /* end SetNativeMethodPrefixes */
 543 
 544   //
 545   // Event Management functions
 546   //
 547 
 548 // callbacks - null is a valid value, must be checked
 549 // size_of_callbacks - pre-checked to be greater than or equal to 0
 550 jvmtiError
 551 JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {
 552   JvmtiVTMSTransitionDisabler disabler;
 553   JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);
 554   return JVMTI_ERROR_NONE;
 555 } /* end SetEventCallbacks */
 556 
 557 
 558 // event_thread - null is a valid value, must be checked
 559 jvmtiError
 560 JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
 561   bool enabled = (mode == JVMTI_ENABLE);
 562 
 563   // event_type must be valid
 564   if (!JvmtiEventController::is_valid_event_type(event_type)) {
 565     return JVMTI_ERROR_INVALID_EVENT_TYPE;
 566   }
 567 
 568   // assure that needed capabilities are present
 569   if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
 570     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
 571   }
 572 
 573   if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
 574     record_class_file_load_hook_enabled();
 575   }
 576   JvmtiVTMSTransitionDisabler disabler;
 577 
 578   if (event_thread == nullptr) {
 579     // Can be called at Agent_OnLoad() time with event_thread == nullptr
 580     // when Thread::current() does not work yet so we cannot create a
 581     // ThreadsListHandle that is common to both thread-specific and
 582     // global code paths.
 583 
 584     JvmtiEventController::set_user_enabled(this, nullptr, (oop) nullptr, event_type, enabled);
 585   } else {
 586     // We have a specified event_thread.
 587     JavaThread* current = JavaThread::current();
 588     ThreadsListHandle tlh(current);
 589 
 590     JavaThread* java_thread = nullptr;
 591     oop thread_obj = nullptr;
 592     jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), event_thread, current, &java_thread, &thread_obj);
 593     if (err != JVMTI_ERROR_NONE) {
 594       return err;
 595     }
 596 
 597     // global events cannot be controlled at thread level.
 598     if (JvmtiEventController::is_global_event(event_type)) {
 599       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 600     }
 601 
 602     JvmtiEventController::set_user_enabled(this, java_thread, thread_obj, event_type, enabled);
 603   }
 604 
 605   return JVMTI_ERROR_NONE;
 606 } /* end SetEventNotificationMode */
 607 
 608   //
 609   // Capability functions
 610   //
 611 
 612 // capabilities_ptr - pre-checked for null
 613 jvmtiError
 614 JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
 615   JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),
 616                                                       get_prohibited_capabilities(),
 617                                                       capabilities_ptr);
 618   return JVMTI_ERROR_NONE;
 619 } /* end GetPotentialCapabilities */
 620 
 621 
 622 // capabilities_ptr - pre-checked for null
 623 jvmtiError
 624 JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
 625   return JvmtiManageCapabilities::add_capabilities(get_capabilities(),
 626                                                    get_prohibited_capabilities(),
 627                                                    capabilities_ptr,
 628                                                    get_capabilities());
 629 } /* end AddCapabilities */
 630 
 631 
 632 // capabilities_ptr - pre-checked for null
 633 jvmtiError
 634 JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
 635   JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
 636   return JVMTI_ERROR_NONE;
 637 } /* end RelinquishCapabilities */
 638 
 639 
 640 // capabilities_ptr - pre-checked for null
 641 jvmtiError
 642 JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
 643   JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);
 644   return JVMTI_ERROR_NONE;
 645 } /* end GetCapabilities */
 646 
 647   //
 648   // Class Loader Search functions
 649   //
 650 
 651 // segment - pre-checked for null
 652 jvmtiError
 653 JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {
 654   jvmtiPhase phase = get_phase();
 655   if (phase == JVMTI_PHASE_ONLOAD) {
 656     Arguments::append_sysclasspath(segment);
 657     return JVMTI_ERROR_NONE;
 658   } else if (use_version_1_0_semantics()) {
 659     // This JvmtiEnv requested version 1.0 semantics and this function
 660     // is only allowed in the ONLOAD phase in version 1.0 so we need to
 661     // return an error here.
 662     return JVMTI_ERROR_WRONG_PHASE;
 663   } else if (phase == JVMTI_PHASE_LIVE) {
 664     // The phase is checked by the wrapper that called this function,
 665     // but this thread could be racing with the thread that is
 666     // terminating the VM so we check one more time.
 667 
 668     // create the zip entry
 669     ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
 670     if (zip_entry == nullptr) {
 671       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 672     }
 673 
 674     // add the jar file to the bootclasspath
 675     log_info(class, load)("opened: %s", zip_entry->name());
 676 #if INCLUDE_CDS
 677     ClassLoader::append_boot_classpath(zip_entry);
 678 #else
 679     ClassLoader::add_to_boot_append_entries(zip_entry);
 680 #endif
 681     return JVMTI_ERROR_NONE;
 682   } else {
 683     return JVMTI_ERROR_WRONG_PHASE;
 684   }
 685 
 686 } /* end AddToBootstrapClassLoaderSearch */
 687 
 688 
 689 // segment - pre-checked for null
 690 jvmtiError
 691 JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
 692   jvmtiPhase phase = get_phase();
 693 
 694   if (phase == JVMTI_PHASE_ONLOAD) {
 695     for (SystemProperty* p = Arguments::system_properties(); p != nullptr; p = p->next()) {
 696       if (strcmp("java.class.path", p->key()) == 0) {
 697         p->append_value(segment);
 698         break;
 699       }
 700     }
 701     return JVMTI_ERROR_NONE;
 702   } else if (phase == JVMTI_PHASE_LIVE) {
 703     // The phase is checked by the wrapper that called this function,
 704     // but this thread could be racing with the thread that is
 705     // terminating the VM so we check one more time.
 706     JavaThread* THREAD = JavaThread::current(); // For exception macros.
 707     HandleMark hm(THREAD);
 708 
 709     // create the zip entry (which will open the zip file and hence
 710     // check that the segment is indeed a zip file).
 711     ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment);
 712     if (zip_entry == nullptr) {
 713       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 714     }
 715     delete zip_entry;   // no longer needed
 716 
 717     Handle loader(THREAD, SystemDictionary::java_system_loader());
 718 
 719     // need the path as java.lang.String
 720     Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);
 721     if (HAS_PENDING_EXCEPTION) {
 722       CLEAR_PENDING_EXCEPTION;
 723       return JVMTI_ERROR_INTERNAL;
 724     }
 725 
 726     // Invoke the appendToClassPathForInstrumentation method - if the method
 727     // is not found it means the loader doesn't support adding to the class path
 728     // in the live phase.
 729     {
 730       JavaValue res(T_VOID);
 731       JavaCalls::call_special(&res,
 732                               loader,
 733                               loader->klass(),
 734                               vmSymbols::appendToClassPathForInstrumentation_name(),
 735                               vmSymbols::appendToClassPathForInstrumentation_signature(),
 736                               path,
 737                               THREAD);
 738       if (HAS_PENDING_EXCEPTION) {
 739         Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
 740         CLEAR_PENDING_EXCEPTION;
 741 
 742         if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {
 743           return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;
 744         } else {
 745           return JVMTI_ERROR_INTERNAL;
 746         }
 747       }
 748     }
 749 
 750     return JVMTI_ERROR_NONE;
 751   } else {
 752     return JVMTI_ERROR_WRONG_PHASE;
 753   }
 754 } /* end AddToSystemClassLoaderSearch */
 755 
 756   //
 757   // General functions
 758   //
 759 
 760 // phase_ptr - pre-checked for null
 761 jvmtiError
 762 JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {
 763   *phase_ptr = phase();
 764   return JVMTI_ERROR_NONE;
 765 } /* end GetPhase */
 766 
 767 
 768 jvmtiError
 769 JvmtiEnv::DisposeEnvironment() {
 770   dispose();
 771   return JVMTI_ERROR_NONE;
 772 } /* end DisposeEnvironment */
 773 
 774 
 775 // data - null is a valid value, must be checked
 776 jvmtiError
 777 JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {
 778   set_env_local_storage(data);
 779   return JVMTI_ERROR_NONE;
 780 } /* end SetEnvironmentLocalStorage */
 781 
 782 
 783 // data_ptr - pre-checked for null
 784 jvmtiError
 785 JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {
 786   *data_ptr = (void*)get_env_local_storage();
 787   return JVMTI_ERROR_NONE;
 788 } /* end GetEnvironmentLocalStorage */
 789 
 790 // version_ptr - pre-checked for null
 791 jvmtiError
 792 JvmtiEnv::GetVersionNumber(jint* version_ptr) {
 793   *version_ptr = JVMTI_VERSION;
 794   return JVMTI_ERROR_NONE;
 795 } /* end GetVersionNumber */
 796 
 797 
 798 // name_ptr - pre-checked for null
 799 jvmtiError
 800 JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {
 801   if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {
 802     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 803   }
 804   const char *name = JvmtiUtil::error_name(error);
 805   if (name == nullptr) {
 806     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 807   }
 808   size_t len = strlen(name) + 1;
 809   jvmtiError err = allocate(len, (unsigned char**)name_ptr);
 810   if (err == JVMTI_ERROR_NONE) {
 811     memcpy(*name_ptr, name, len);
 812   }
 813   return err;
 814 } /* end GetErrorName */
 815 
 816 
 817 jvmtiError
 818 JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
 819   LogLevelType level = value == 0 ? LogLevel::Off : LogLevel::Info;
 820   switch (flag) {
 821   case JVMTI_VERBOSE_OTHER:
 822     // ignore
 823     break;
 824   case JVMTI_VERBOSE_CLASS:
 825     LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
 826     LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
 827     break;
 828   case JVMTI_VERBOSE_GC:
 829     LogConfiguration::configure_stdout(level, true, LOG_TAGS(gc));
 830     break;
 831   case JVMTI_VERBOSE_JNI:
 832     level = value == 0 ? LogLevel::Off : LogLevel::Debug;
 833     LogConfiguration::configure_stdout(level, true, LOG_TAGS(jni, resolve));
 834     break;
 835   default:
 836     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 837   };
 838   return JVMTI_ERROR_NONE;
 839 } /* end SetVerboseFlag */
 840 
 841 
 842 // format_ptr - pre-checked for null
 843 jvmtiError
 844 JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
 845   *format_ptr = JVMTI_JLOCATION_JVMBCI;
 846   return JVMTI_ERROR_NONE;
 847 } /* end GetJLocationFormat */
 848 
 849   //
 850   // Thread functions
 851   //
 852 
 853 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
 854 // thread_state_ptr - pre-checked for null
 855 jvmtiError
 856 JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {
 857   JavaThread* current_thread = JavaThread::current();
 858   JvmtiVTMSTransitionDisabler disabler(thread);
 859   ThreadsListHandle tlh(current_thread);
 860 
 861   JavaThread* java_thread = nullptr;
 862   oop thread_oop = nullptr;
 863   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_oop);
 864   if (err != JVMTI_ERROR_NONE && err != JVMTI_ERROR_THREAD_NOT_ALIVE) {
 865     // We got an error code so we don't have a JavaThread*, but only
 866     // return an error from here if the error is not because the thread
 867     // is a virtual thread.
 868     return err;
 869   }
 870   *thread_state_ptr = JvmtiEnvBase::get_thread_or_vthread_state(thread_oop, java_thread);
 871   return JVMTI_ERROR_NONE;
 872 } /* end GetThreadState */
 873 
 874 
 875 // thread_ptr - pre-checked for null
 876 jvmtiError
 877 JvmtiEnv::GetCurrentThread(jthread* thread_ptr) {
 878   JavaThread* cur_thread = JavaThread::current();
 879   oop thread_oop = get_vthread_or_thread_oop(cur_thread);
 880 
 881   *thread_ptr = (jthread)JNIHandles::make_local(cur_thread, thread_oop);
 882   return JVMTI_ERROR_NONE;
 883 } /* end GetCurrentThread */
 884 
 885 
 886 // threads_count_ptr - pre-checked for null
 887 // threads_ptr - pre-checked for null
 888 jvmtiError
 889 JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) {
 890   int nthreads        = 0;
 891   Handle *thread_objs = nullptr;
 892   Thread* current_thread = Thread::current();
 893   ResourceMark rm(current_thread);
 894   HandleMark hm(current_thread);
 895 
 896   // enumerate threads (including agent threads)
 897   ThreadsListEnumerator tle(current_thread, true);
 898   nthreads = tle.num_threads();
 899   *threads_count_ptr = nthreads;
 900 
 901   if (nthreads == 0) {
 902     *threads_ptr = nullptr;
 903     return JVMTI_ERROR_NONE;
 904   }
 905 
 906   thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads);
 907   NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY);
 908 
 909   for (int i = 0; i < nthreads; i++) {
 910     thread_objs[i] = Handle(tle.get_threadObj(i));
 911   }
 912 
 913   jthread *jthreads  = new_jthreadArray(nthreads, thread_objs);
 914   NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);
 915 
 916   *threads_ptr = jthreads;
 917   return JVMTI_ERROR_NONE;
 918 } /* end GetAllThreads */
 919 
 920 
 921 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
 922 jvmtiError
 923 JvmtiEnv::SuspendThread(jthread thread) {
 924   JavaThread* current = JavaThread::current();
 925   HandleMark hm(current);
 926   Handle self_tobj;
 927 
 928   jvmtiError err;
 929   {
 930     JvmtiVTMSTransitionDisabler disabler(true);
 931     ThreadsListHandle tlh(current);
 932     JavaThread* java_thread = nullptr;
 933     oop thread_oop = nullptr;
 934 
 935     err = get_threadOop_and_JavaThread(tlh.list(), thread, current, &java_thread, &thread_oop);
 936     if (err != JVMTI_ERROR_NONE) {
 937       return err;
 938     }
 939 
 940     // Do not use JvmtiVTMSTransitionDisabler in context of self suspend to avoid deadlocks.
 941     if (java_thread != current) {
 942       err = suspend_thread(thread_oop, java_thread, /* single_suspend */ true);
 943       return err;
 944     }
 945     // protect thread_oop as a safepoint can be reached in disabler destructor
 946     self_tobj = Handle(current, thread_oop);
 947   }
 948   // Do self suspend for current JavaThread.
 949   err = suspend_thread(self_tobj(), current, /* single_suspend */ true);
 950   return err;
 951 } /* end SuspendThread */
 952 
 953 
 954 // request_count - pre-checked to be greater than or equal to 0
 955 // request_list - pre-checked for null
 956 // results - pre-checked for null
 957 jvmtiError
 958 JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
 959   JavaThread* current = JavaThread::current();
 960   HandleMark hm(current);
 961   Handle self_tobj;
 962   int self_idx = -1;
 963 
 964   {
 965     JvmtiVTMSTransitionDisabler disabler(true);
 966     ThreadsListHandle tlh(current);
 967 
 968     for (int i = 0; i < request_count; i++) {
 969       JavaThread *java_thread = nullptr;
 970       oop thread_oop = nullptr;
 971       jthread thread = request_list[i];
 972       jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
 973 
 974       if (thread_oop != nullptr &&
 975           java_lang_VirtualThread::is_instance(thread_oop) &&
 976           !JvmtiEnvBase::is_vthread_alive(thread_oop)) {
 977         err = JVMTI_ERROR_THREAD_NOT_ALIVE;
 978       }
 979       if (err != JVMTI_ERROR_NONE) {
 980         if (thread_oop == nullptr || err != JVMTI_ERROR_INVALID_THREAD) {
 981           results[i] = err;
 982           continue;
 983         }
 984       }
 985       if (java_thread == current) {
 986         self_idx = i;
 987         self_tobj = Handle(current, thread_oop);
 988         continue; // self suspend after all other suspends
 989       }
 990       if (java_lang_VirtualThread::is_instance(thread_oop)) {
 991         oop carrier_thread = java_lang_VirtualThread::carrier_thread(thread_oop);
 992         java_thread = carrier_thread == nullptr ? nullptr : java_lang_Thread::thread(carrier_thread);
 993       }
 994       results[i] = suspend_thread(thread_oop, java_thread, /* single_suspend */ true);
 995     }
 996   }
 997   // Self suspend after all other suspends if necessary.
 998   // Do not use JvmtiVTMSTransitionDisabler in context of self suspend to avoid deadlocks.
 999   if (self_tobj() != nullptr) {
1000     // there should not be any error for current java_thread
1001     results[self_idx] = suspend_thread(self_tobj(), current, /* single_suspend */ true);
1002   }
1003   // per-thread suspend results returned via results parameter
1004   return JVMTI_ERROR_NONE;
1005 } /* end SuspendThreadList */
1006 
1007 
1008 jvmtiError
1009 JvmtiEnv::SuspendAllVirtualThreads(jint except_count, const jthread* except_list) {
1010   if (get_capabilities()->can_support_virtual_threads == 0) {
1011     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
1012   }
1013   JavaThread* current = JavaThread::current();
1014   HandleMark hm(current);
1015   Handle self_tobj;
1016 
1017   {
1018     ResourceMark rm(current);
1019     JvmtiVTMSTransitionDisabler disabler(true);
1020     ThreadsListHandle tlh(current);
1021     GrowableArray<jthread>* elist = new GrowableArray<jthread>(except_count);
1022 
1023     jvmtiError err = JvmtiEnvBase::check_thread_list(except_count, except_list);
1024     if (err != JVMTI_ERROR_NONE) {
1025       return err;
1026     }
1027 
1028     // Collect threads from except_list for which resumed status must be restored (only for VirtualThread case)
1029     for (int idx = 0; idx < except_count; idx++) {
1030       jthread thread = except_list[idx];
1031       oop thread_oop = JNIHandles::resolve_external_guard(thread);
1032       if (java_lang_VirtualThread::is_instance(thread_oop) && !JvmtiVTSuspender::is_vthread_suspended(thread_oop)) {
1033           // is not suspended, so its resumed status must be restored
1034           elist->append(except_list[idx]);
1035       }
1036     }
1037 
1038     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *java_thread = jtiwh.next(); ) {
1039       oop vt_oop = java_thread->jvmti_vthread();
1040       if (!java_thread->is_exiting() &&
1041           !java_thread->is_jvmti_agent_thread() &&
1042           !java_thread->is_hidden_from_external_view() &&
1043           vt_oop != nullptr &&
1044           ((java_lang_VirtualThread::is_instance(vt_oop) &&
1045             JvmtiEnvBase::is_vthread_alive(vt_oop) &&
1046             !JvmtiVTSuspender::is_vthread_suspended(vt_oop)) ||
1047             (vt_oop->is_a(vmClasses::BoundVirtualThread_klass()) && !java_thread->is_suspended())) &&
1048           !is_in_thread_list(except_count, except_list, vt_oop)
1049          ) {
1050         if (java_thread == current) {
1051           self_tobj = Handle(current, vt_oop);
1052           continue; // self suspend after all other suspends
1053         }
1054         suspend_thread(vt_oop, java_thread, /* single_suspend */ false);
1055       }
1056     }
1057     JvmtiVTSuspender::register_all_vthreads_suspend();
1058 
1059     // Restore resumed state for threads from except list that were not suspended before.
1060     for (int idx = 0; idx < elist->length(); idx++) {
1061       jthread thread = elist->at(idx);
1062       oop thread_oop = JNIHandles::resolve_external_guard(thread);
1063       if (JvmtiVTSuspender::is_vthread_suspended(thread_oop)) {
1064         JvmtiVTSuspender::register_vthread_resume(thread_oop);
1065       }
1066     }
1067   }
1068   // Self suspend after all other suspends if necessary.
1069   // Do not use JvmtiVTMSTransitionDisabler in context of self suspend to avoid deadlocks.
1070   if (self_tobj() != nullptr) {
1071     suspend_thread(self_tobj(), current, /* single_suspend */ false);
1072   }
1073   return JVMTI_ERROR_NONE;
1074 } /* end SuspendAllVirtualThreads */
1075 
1076 
1077 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1078 jvmtiError
1079 JvmtiEnv::ResumeThread(jthread thread) {
1080   JvmtiVTMSTransitionDisabler disabler(true);
1081   JavaThread* current = JavaThread::current();
1082   ThreadsListHandle tlh(current);
1083 
1084   JavaThread* java_thread = nullptr;
1085   oop thread_oop = nullptr;
1086   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current, &java_thread, &thread_oop);
1087   if (err != JVMTI_ERROR_NONE) {
1088     return err;
1089   }
1090   err = resume_thread(thread_oop, java_thread, /* single_resume */ true);
1091   return err;
1092 } /* end ResumeThread */
1093 
1094 
1095 // request_count - pre-checked to be greater than or equal to 0
1096 // request_list - pre-checked for null
1097 // results - pre-checked for null
1098 jvmtiError
1099 JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
1100   oop thread_oop = nullptr;
1101   JavaThread* java_thread = nullptr;
1102   JvmtiVTMSTransitionDisabler disabler(true);
1103   ThreadsListHandle tlh;
1104 
1105   for (int i = 0; i < request_count; i++) {
1106     jthread thread = request_list[i];
1107     jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
1108 
1109     if (thread_oop != nullptr &&
1110         java_lang_VirtualThread::is_instance(thread_oop) &&
1111         !JvmtiEnvBase::is_vthread_alive(thread_oop)) {
1112       err = JVMTI_ERROR_THREAD_NOT_ALIVE;
1113     }
1114     if (err != JVMTI_ERROR_NONE) {
1115       if (thread_oop == nullptr || err != JVMTI_ERROR_INVALID_THREAD) {
1116         results[i] = err;
1117         continue;
1118       }
1119     }
1120     if (java_lang_VirtualThread::is_instance(thread_oop)) {
1121       oop carrier_thread = java_lang_VirtualThread::carrier_thread(thread_oop);
1122       java_thread = carrier_thread == nullptr ? nullptr : java_lang_Thread::thread(carrier_thread);
1123     }
1124     results[i] = resume_thread(thread_oop, java_thread, /* single_resume */ true);
1125   }
1126   // per-thread resume results returned via results parameter
1127   return JVMTI_ERROR_NONE;
1128 } /* end ResumeThreadList */
1129 
1130 
1131 jvmtiError
1132 JvmtiEnv::ResumeAllVirtualThreads(jint except_count, const jthread* except_list) {
1133   if (get_capabilities()->can_support_virtual_threads == 0) {
1134     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
1135   }
1136   jvmtiError err = JvmtiEnvBase::check_thread_list(except_count, except_list);
1137   if (err != JVMTI_ERROR_NONE) {
1138     return err;
1139   }
1140   ResourceMark rm;
1141   JvmtiVTMSTransitionDisabler disabler(true);
1142   GrowableArray<jthread>* elist = new GrowableArray<jthread>(except_count);
1143 
1144   // Collect threads from except_list for which suspended status must be restored (only for VirtualThread case)
1145   for (int idx = 0; idx < except_count; idx++) {
1146     jthread thread = except_list[idx];
1147     oop thread_oop = JNIHandles::resolve_external_guard(thread);
1148     if (java_lang_VirtualThread::is_instance(thread_oop) && JvmtiVTSuspender::is_vthread_suspended(thread_oop)) {
1149       // is suspended, so its suspended status must be restored
1150       elist->append(except_list[idx]);
1151     }
1152   }
1153 
1154   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *java_thread = jtiwh.next(); ) {
1155     oop vt_oop = java_thread->jvmti_vthread();
1156     if (!java_thread->is_exiting() &&
1157         !java_thread->is_jvmti_agent_thread() &&
1158         !java_thread->is_hidden_from_external_view() &&
1159         vt_oop != nullptr &&
1160         ((java_lang_VirtualThread::is_instance(vt_oop) &&
1161           JvmtiEnvBase::is_vthread_alive(vt_oop) &&
1162           JvmtiVTSuspender::is_vthread_suspended(vt_oop)) ||
1163           (vt_oop->is_a(vmClasses::BoundVirtualThread_klass()) && java_thread->is_suspended())) &&
1164         !is_in_thread_list(except_count, except_list, vt_oop)
1165     ) {
1166       resume_thread(vt_oop, java_thread, /* single_resume */ false);
1167     }
1168   }
1169   JvmtiVTSuspender::register_all_vthreads_resume();
1170 
1171   // Restore suspended state for threads from except list that were suspended before.
1172   for (int idx = 0; idx < elist->length(); idx++) {
1173     jthread thread = elist->at(idx);
1174     oop thread_oop = JNIHandles::resolve_external_guard(thread);
1175     if (!JvmtiVTSuspender::is_vthread_suspended(thread_oop)) {
1176       JvmtiVTSuspender::register_vthread_suspend(thread_oop);
1177     }
1178   }
1179   return JVMTI_ERROR_NONE;
1180 } /* end ResumeAllVirtualThreads */
1181 
1182 
1183 jvmtiError
1184 JvmtiEnv::StopThread(jthread thread, jobject exception) {
1185   JavaThread* current_thread = JavaThread::current();
1186 
1187   JvmtiVTMSTransitionDisabler disabler(thread);
1188   ThreadsListHandle tlh(current_thread);
1189   JavaThread* java_thread = nullptr;
1190   oop thread_oop = nullptr;
1191 
1192   NULL_CHECK(thread, JVMTI_ERROR_INVALID_THREAD);
1193 
1194   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_oop);
1195 
1196   bool is_virtual = thread_oop != nullptr && thread_oop->is_a(vmClasses::BaseVirtualThread_klass());
1197 
1198   if (is_virtual && !is_JavaThread_current(java_thread, thread_oop)) {
1199     if (!is_vthread_suspended(thread_oop, java_thread)) {
1200       return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1201     }
1202     if (java_thread == nullptr) { // unmounted virtual thread
1203       return JVMTI_ERROR_OPAQUE_FRAME;
1204     }
1205   }
1206   if (err != JVMTI_ERROR_NONE) {
1207     return err;
1208   }
1209   oop e = JNIHandles::resolve_external_guard(exception);
1210   NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER);
1211 
1212   JavaThread::send_async_exception(java_thread, e);
1213 
1214   return JVMTI_ERROR_NONE;
1215 
1216 } /* end StopThread */
1217 
1218 
1219 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1220 jvmtiError
1221 JvmtiEnv::InterruptThread(jthread thread) {
1222   JavaThread* current_thread = JavaThread::current();
1223   HandleMark hm(current_thread);
1224 
1225   JvmtiVTMSTransitionDisabler disabler(thread);
1226   ThreadsListHandle tlh(current_thread);
1227 
1228   JavaThread* java_thread = nullptr;
1229   oop thread_obj = nullptr;
1230   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
1231   if (err != JVMTI_ERROR_NONE) {
1232     return err;
1233   }
1234 
1235   if (java_lang_VirtualThread::is_instance(thread_obj)) {
1236     // For virtual threads we have to call into Java to interrupt:
1237     Handle obj(current_thread, thread_obj);
1238     JvmtiJavaUpcallMark jjum(current_thread); // hide JVMTI events for Java upcall
1239     JavaValue result(T_VOID);
1240     JavaCalls::call_virtual(&result,
1241                             obj,
1242                             vmClasses::Thread_klass(),
1243                             vmSymbols::interrupt_method_name(),
1244                             vmSymbols::void_method_signature(),
1245                             current_thread);
1246 
1247     return JVMTI_ERROR_NONE;
1248   }
1249 
1250   // Really this should be a Java call to Thread.interrupt to ensure the same
1251   // semantics, however historically this has not been done for some reason.
1252   // So we continue with that (which means we don't interact with any Java-level
1253   // Interruptible object) but we must set the Java-level interrupted state.
1254   java_lang_Thread::set_interrupted(thread_obj, true);
1255   java_thread->interrupt();
1256 
1257   return JVMTI_ERROR_NONE;
1258 } /* end InterruptThread */
1259 
1260 
1261 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1262 // info_ptr - pre-checked for null
1263 jvmtiError
1264 JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
1265   JavaThread* current_thread = JavaThread::current();
1266   ResourceMark rm(current_thread);
1267   HandleMark hm(current_thread);
1268   JavaThread* java_thread = nullptr;
1269   oop thread_oop = nullptr;
1270 
1271   JvmtiVTMSTransitionDisabler disabler(thread);
1272   ThreadsListHandle tlh(current_thread);
1273 
1274   // if thread is null the current thread is used
1275   if (thread == nullptr) {
1276     java_thread = JavaThread::current();
1277     thread_oop = get_vthread_or_thread_oop(java_thread);
1278     if (thread_oop == nullptr || !thread_oop->is_a(vmClasses::Thread_klass())) {
1279       return JVMTI_ERROR_INVALID_THREAD;
1280     }
1281   } else {
1282     jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
1283     if (err != JVMTI_ERROR_NONE) {
1284       // We got an error code so we don't have a JavaThread *, but
1285       // only return an error from here if we didn't get a valid
1286       // thread_oop.
1287       // In the virtual thread case the cv_external_thread_to_JavaThread is expected to correctly set
1288       // the thread_oop and return JVMTI_ERROR_INVALID_THREAD which we ignore here.
1289       if (thread_oop == nullptr) {
1290         return err;
1291       }
1292     }
1293   }
1294   // We have a valid thread_oop so we can return some thread info.
1295 
1296   Handle thread_obj(current_thread, thread_oop);
1297   Handle name;
1298   ThreadPriority priority;
1299   Handle     thread_group;
1300   Handle context_class_loader;
1301   bool          is_daemon;
1302 
1303   name = Handle(current_thread, java_lang_Thread::name(thread_obj()));
1304 
1305   if (java_lang_VirtualThread::is_instance(thread_obj())) {
1306     priority = (ThreadPriority)JVMTI_THREAD_NORM_PRIORITY;
1307     is_daemon = true;
1308     if (java_lang_VirtualThread::state(thread_obj()) == java_lang_VirtualThread::TERMINATED) {
1309       thread_group = Handle(current_thread, nullptr);
1310     } else {
1311       thread_group = Handle(current_thread, java_lang_Thread_Constants::get_VTHREAD_GROUP());
1312     }
1313   } else {
1314     priority = java_lang_Thread::priority(thread_obj());
1315     is_daemon = java_lang_Thread::is_daemon(thread_obj());
1316     if (java_lang_Thread::get_thread_status(thread_obj()) == JavaThreadStatus::TERMINATED) {
1317       thread_group = Handle(current_thread, nullptr);
1318     } else {
1319       thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj()));
1320     }
1321   }
1322 
1323   oop loader = java_lang_Thread::context_class_loader(thread_obj());
1324   context_class_loader = Handle(current_thread, loader);
1325 
1326   { const char *n;
1327 
1328     if (name() != nullptr) {
1329       n = java_lang_String::as_utf8_string(name());
1330     } else {
1331       size_t utf8_length = 0;
1332       n = UNICODE::as_utf8((jchar*) nullptr, utf8_length);
1333     }
1334 
1335     info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);
1336     if (info_ptr->name == nullptr)
1337       return JVMTI_ERROR_OUT_OF_MEMORY;
1338 
1339     strcpy(info_ptr->name, n);
1340   }
1341   info_ptr->is_daemon = is_daemon;
1342   info_ptr->priority  = priority;
1343 
1344   info_ptr->context_class_loader = (context_class_loader.is_null()) ? nullptr :
1345                                     jni_reference(context_class_loader);
1346   info_ptr->thread_group = jni_reference(thread_group);
1347 
1348   return JVMTI_ERROR_NONE;
1349 } /* end GetThreadInfo */
1350 
1351 
1352 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1353 // owned_monitor_count_ptr - pre-checked for null
1354 // owned_monitors_ptr - pre-checked for null
1355 jvmtiError
1356 JvmtiEnv::GetOwnedMonitorInfo(jthread thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
1357   JavaThread* calling_thread = JavaThread::current();
1358   HandleMark hm(calling_thread);
1359 
1360   JvmtiVTMSTransitionDisabler disabler(thread);
1361   ThreadsListHandle tlh(calling_thread);
1362 
1363   JavaThread* java_thread = nullptr;
1364   oop thread_oop = nullptr;
1365   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, calling_thread, &java_thread, &thread_oop);
1366   if (err != JVMTI_ERROR_NONE) {
1367     return err;
1368   }
1369 
1370   if (LockingMode == LM_LEGACY && java_thread == nullptr) {
1371     *owned_monitor_count_ptr = 0;
1372     return JVMTI_ERROR_NONE;
1373   }
1374 
1375   // growable array of jvmti monitors info on the C-heap
1376   GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
1377       new (mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
1378 
1379   Handle thread_handle(calling_thread, thread_oop);
1380   EscapeBarrier eb(java_thread != nullptr, calling_thread, java_thread);
1381   if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
1382     delete owned_monitors_list;
1383     return JVMTI_ERROR_OUT_OF_MEMORY;
1384   }
1385   // get owned monitors info with handshake
1386   GetOwnedMonitorInfoClosure op(this, calling_thread, owned_monitors_list);
1387   JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
1388   err = op.result();
1389 
1390   jint owned_monitor_count = owned_monitors_list->length();
1391   if (err == JVMTI_ERROR_NONE) {
1392     if ((err = allocate(owned_monitor_count * sizeof(jobject *),
1393                       (unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {
1394       // copy into the returned array
1395       for (int i = 0; i < owned_monitor_count; i++) {
1396         (*owned_monitors_ptr)[i] =
1397           ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
1398       }
1399       *owned_monitor_count_ptr = owned_monitor_count;
1400     }
1401   }
1402   // clean up.
1403   for (int i = 0; i < owned_monitor_count; i++) {
1404     deallocate((unsigned char*)owned_monitors_list->at(i));
1405   }
1406   delete owned_monitors_list;
1407 
1408   return err;
1409 } /* end GetOwnedMonitorInfo */
1410 
1411 
1412 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1413 // monitor_info_count_ptr - pre-checked for null
1414 // monitor_info_ptr - pre-checked for null
1415 jvmtiError
1416 JvmtiEnv::GetOwnedMonitorStackDepthInfo(jthread thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
1417   JavaThread* calling_thread = JavaThread::current();
1418   HandleMark hm(calling_thread);
1419 
1420   JvmtiVTMSTransitionDisabler disabler(thread);
1421   ThreadsListHandle tlh(calling_thread);
1422 
1423   JavaThread* java_thread = nullptr;
1424   oop thread_oop = nullptr;
1425   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, calling_thread, &java_thread, &thread_oop);
1426   if (err != JVMTI_ERROR_NONE) {
1427     return err;
1428   }
1429 
1430   if (LockingMode == LM_LEGACY && java_thread == nullptr) {
1431     *monitor_info_count_ptr = 0;
1432     return JVMTI_ERROR_NONE;
1433   }
1434 
1435   // growable array of jvmti monitors info on the C-heap
1436   GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
1437       new (mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
1438 
1439   Handle thread_handle(calling_thread, thread_oop);
1440   EscapeBarrier eb(java_thread != nullptr, calling_thread, java_thread);
1441   if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
1442     delete owned_monitors_list;
1443     return JVMTI_ERROR_OUT_OF_MEMORY;
1444   }
1445   // get owned monitors info with handshake
1446   GetOwnedMonitorInfoClosure op(this, calling_thread, owned_monitors_list);
1447   JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
1448   err = op.result();
1449 
1450   jint owned_monitor_count = owned_monitors_list->length();
1451   if (err == JVMTI_ERROR_NONE) {
1452     if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),
1453                         (unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {
1454       // copy to output array.
1455       for (int i = 0; i < owned_monitor_count; i++) {
1456         (*monitor_info_ptr)[i].monitor =
1457           ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
1458         (*monitor_info_ptr)[i].stack_depth =
1459           ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth;
1460       }
1461     }
1462     *monitor_info_count_ptr = owned_monitor_count;
1463   }
1464 
1465   // clean up.
1466   for (int i = 0; i < owned_monitor_count; i++) {
1467     deallocate((unsigned char*)owned_monitors_list->at(i));
1468   }
1469   delete owned_monitors_list;
1470 
1471   return err;
1472 } /* end GetOwnedMonitorStackDepthInfo */
1473 
1474 
1475 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1476 // monitor_ptr - pre-checked for null
1477 jvmtiError
1478 JvmtiEnv::GetCurrentContendedMonitor(jthread thread, jobject* monitor_ptr) {
1479   JavaThread* current = JavaThread::current();
1480 
1481   *monitor_ptr = nullptr;
1482 
1483   // get contended monitor information with handshake
1484   GetCurrentContendedMonitorClosure op(this, current, monitor_ptr);
1485   JvmtiHandshake::execute(&op, thread);
1486   return op.result();
1487 } /* end GetCurrentContendedMonitor */
1488 
1489 
1490 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1491 // proc - pre-checked for null
1492 // arg - null is a valid value, must be checked
1493 jvmtiError
1494 JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
1495   JavaThread* current_thread = JavaThread::current();
1496 
1497   JavaThread* java_thread = nullptr;
1498   oop thread_oop = nullptr;
1499   ThreadsListHandle tlh(current_thread);
1500   jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
1501   if (err != JVMTI_ERROR_NONE) {
1502     // We got an error code so we don't have a JavaThread *, but
1503     // only return an error from here if we didn't get a valid
1504     // thread_oop.
1505     if (thread_oop == nullptr) {
1506       return err;
1507     }
1508     // We have a valid thread_oop.
1509   }
1510 
1511   if (thread_oop->is_a(vmClasses::BaseVirtualThread_klass())) {
1512     // No support for virtual threads.
1513     return JVMTI_ERROR_UNSUPPORTED_OPERATION;
1514   }
1515   if (java_thread != nullptr) {
1516     // 'thread' refers to an existing JavaThread.
1517     return JVMTI_ERROR_INVALID_THREAD;
1518   }
1519 
1520   if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
1521     return JVMTI_ERROR_INVALID_PRIORITY;
1522   }
1523 
1524   Handle thread_hndl(current_thread, thread_oop);
1525 
1526   JvmtiAgentThread* new_thread = new JvmtiAgentThread(this, proc, arg);
1527 
1528   // At this point it may be possible that no osthread was created for the
1529   // JavaThread due to lack of resources.
1530   if (new_thread->osthread() == nullptr) {
1531     // The new thread is not known to Thread-SMR yet so we can just delete.
1532     delete new_thread;
1533     return JVMTI_ERROR_OUT_OF_MEMORY;
1534   }
1535 
1536   JavaThread::start_internal_daemon(current_thread, new_thread, thread_hndl,
1537                                     (ThreadPriority)priority);
1538 
1539   return JVMTI_ERROR_NONE;
1540 } /* end RunAgentThread */
1541 
1542   //
1543   // Thread Group functions
1544   //
1545 
1546 // group_count_ptr - pre-checked for null
1547 // groups_ptr - pre-checked for null
1548 jvmtiError
1549 JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) {
1550   JavaThread* current_thread = JavaThread::current();
1551 
1552   // Only one top level thread group now.
1553   *group_count_ptr = 1;
1554 
1555   // Allocate memory to store global-refs to the thread groups.
1556   // Assume this area is freed by caller.
1557   *groups_ptr = (jthreadGroup *) jvmtiMalloc((sizeof(jthreadGroup)) * (*group_count_ptr));
1558 
1559   NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY);
1560 
1561   // Convert oop to Handle, then convert Handle to global-ref.
1562   {
1563     HandleMark hm(current_thread);
1564     Handle system_thread_group(current_thread, Universe::system_thread_group());
1565     *groups_ptr[0] = jni_reference(system_thread_group);
1566   }
1567 
1568   return JVMTI_ERROR_NONE;
1569 } /* end GetTopThreadGroups */
1570 
1571 
1572 // info_ptr - pre-checked for null
1573 jvmtiError
1574 JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) {
1575   Thread* current_thread = Thread::current();
1576   ResourceMark rm(current_thread);
1577   HandleMark hm(current_thread);
1578 
1579   Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));
1580   NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);
1581 
1582   const char* name;
1583   Handle parent_group;
1584   bool is_daemon;
1585   ThreadPriority max_priority;
1586 
1587   name         = java_lang_ThreadGroup::name(group_obj());
1588   parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));
1589   is_daemon    = java_lang_ThreadGroup::is_daemon(group_obj());
1590   max_priority = java_lang_ThreadGroup::maxPriority(group_obj());
1591 
1592   info_ptr->is_daemon    = is_daemon;
1593   info_ptr->max_priority = max_priority;
1594   info_ptr->parent       = jni_reference(parent_group);
1595 
1596   if (name != nullptr) {
1597     info_ptr->name = (char*)jvmtiMalloc(strlen(name)+1);
1598     NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);
1599     strcpy(info_ptr->name, name);
1600   } else {
1601     info_ptr->name = nullptr;
1602   }
1603 
1604   return JVMTI_ERROR_NONE;
1605 } /* end GetThreadGroupInfo */
1606 
1607 // thread_count_ptr - pre-checked for null
1608 // threads_ptr - pre-checked for null
1609 // group_count_ptr - pre-checked for null
1610 // groups_ptr - pre-checked for null
1611 jvmtiError
1612 JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {
1613   jvmtiError err;
1614   JavaThread* current_thread = JavaThread::current();
1615   oop group_obj = JNIHandles::resolve_external_guard(group);
1616   NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP);
1617 
1618   Handle *thread_objs = nullptr;
1619   objArrayHandle group_objs;
1620   jint nthreads = 0;
1621   jint ngroups = 0;
1622   int hidden_threads = 0;
1623 
1624   ResourceMark rm(current_thread);
1625   HandleMark hm(current_thread);
1626 
1627   Handle group_hdl(current_thread, group_obj);
1628 
1629   err = get_live_threads(current_thread, group_hdl, &nthreads, &thread_objs);
1630   if (err != JVMTI_ERROR_NONE) {
1631     return err;
1632   }
1633   err = get_subgroups(current_thread, group_hdl, &ngroups, &group_objs);
1634   if (err != JVMTI_ERROR_NONE) {
1635     return err;
1636   }
1637 
1638   *group_count_ptr  = ngroups;
1639   *thread_count_ptr = nthreads;
1640   *threads_ptr     = new_jthreadArray(nthreads, thread_objs);
1641   *groups_ptr      = new_jthreadGroupArray(ngroups, group_objs);
1642   if (nthreads > 0 && *threads_ptr == nullptr) {
1643     return JVMTI_ERROR_OUT_OF_MEMORY;
1644   }
1645   if (ngroups > 0 && *groups_ptr == nullptr) {
1646     return JVMTI_ERROR_OUT_OF_MEMORY;
1647   }
1648 
1649   return JVMTI_ERROR_NONE;
1650 } /* end GetThreadGroupChildren */
1651 
1652 
1653   //
1654   // Stack Frame functions
1655   //
1656 
1657 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1658 // max_frame_count - pre-checked to be greater than or equal to 0
1659 // frame_buffer - pre-checked for null
1660 // count_ptr - pre-checked for null
1661 jvmtiError
1662 JvmtiEnv::GetStackTrace(jthread thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
1663   GetStackTraceClosure op(this, start_depth, max_frame_count, frame_buffer, count_ptr);
1664   JvmtiHandshake::execute(&op, thread);
1665   return op.result();
1666 } /* end GetStackTrace */
1667 
1668 
1669 // max_frame_count - pre-checked to be greater than or equal to 0
1670 // stack_info_ptr - pre-checked for null
1671 // thread_count_ptr - pre-checked for null
1672 jvmtiError
1673 JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {
1674   jvmtiError err = JVMTI_ERROR_NONE;
1675   JavaThread* calling_thread = JavaThread::current();
1676 
1677   // JVMTI get stack traces at safepoint.
1678   VM_GetAllStackTraces op(this, calling_thread, max_frame_count);
1679   VMThread::execute(&op);
1680   *thread_count_ptr = op.final_thread_count();
1681   *stack_info_ptr = op.stack_info();
1682   err = op.result();
1683   return err;
1684 } /* end GetAllStackTraces */
1685 
1686 
1687 // thread_count - pre-checked to be greater than or equal to 0
1688 // thread_list - pre-checked for null
1689 // max_frame_count - pre-checked to be greater than or equal to 0
1690 // stack_info_ptr - pre-checked for null
1691 jvmtiError
1692 JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {
1693   jvmtiError err = JVMTI_ERROR_NONE;
1694 
1695   if (thread_count == 1) {
1696     // Use direct handshake if we need to get only one stack trace.
1697     JavaThread *current_thread = JavaThread::current();
1698 
1699     jthread thread = thread_list[0];
1700 
1701     GetSingleStackTraceClosure op(this, current_thread, thread, max_frame_count);
1702     JvmtiHandshake::execute(&op, thread);
1703     err = op.result();
1704     if (err == JVMTI_ERROR_NONE) {
1705       *stack_info_ptr = op.stack_info();
1706     }
1707   } else {
1708     JvmtiVTMSTransitionDisabler disabler;
1709 
1710     // JVMTI get stack traces at safepoint.
1711     VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count);
1712     VMThread::execute(&op);
1713     err = op.result();
1714     if (err == JVMTI_ERROR_NONE) {
1715       *stack_info_ptr = op.stack_info();
1716     }
1717   }
1718   return err;
1719 } /* end GetThreadListStackTraces */
1720 
1721 
1722 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1723 // count_ptr - pre-checked for null
1724 jvmtiError
1725 JvmtiEnv::GetFrameCount(jthread thread, jint* count_ptr) {
1726   GetFrameCountClosure op(this, count_ptr);
1727   JvmtiHandshake::execute(&op, thread);
1728   return op.result();
1729 } /* end GetFrameCount */
1730 
1731 
1732 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1733 jvmtiError
1734 JvmtiEnv::PopFrame(jthread thread) {
1735   JavaThread* current_thread = JavaThread::current();
1736   HandleMark hm(current_thread);
1737 
1738   if (thread == nullptr) {
1739     return JVMTI_ERROR_INVALID_THREAD;
1740   }
1741   JvmtiVTMSTransitionDisabler disabler(thread);
1742   ThreadsListHandle tlh(current_thread);
1743 
1744   JavaThread* java_thread = nullptr;
1745   oop thread_obj = nullptr;
1746   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
1747   Handle thread_handle(current_thread, thread_obj);
1748 
1749   if (err != JVMTI_ERROR_NONE) {
1750     return err;
1751   }
1752   bool self = java_thread == current_thread;
1753 
1754   err = check_non_suspended_or_opaque_frame(java_thread, thread_obj, self);
1755   if (err != JVMTI_ERROR_NONE) {
1756     return err;
1757   }
1758 
1759   // retrieve or create the state
1760   JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
1761   if (state == nullptr) {
1762     return JVMTI_ERROR_THREAD_NOT_ALIVE;
1763   }
1764 
1765   // Eagerly reallocate scalar replaced objects.
1766   EscapeBarrier eb(true, current_thread, java_thread);
1767   if (!eb.deoptimize_objects(1)) {
1768     // Reallocation of scalar replaced objects failed -> return with error
1769     return JVMTI_ERROR_OUT_OF_MEMORY;
1770   }
1771 
1772   MutexLocker mu(JvmtiThreadState_lock);
1773   UpdateForPopTopFrameClosure op(state);
1774   JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
1775   return op.result();
1776 } /* end PopFrame */
1777 
1778 
1779 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1780 // depth - pre-checked as non-negative
1781 // method_ptr - pre-checked for null
1782 // location_ptr - pre-checked for null
1783 jvmtiError
1784 JvmtiEnv::GetFrameLocation(jthread thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {
1785   GetFrameLocationClosure op(this, depth, method_ptr, location_ptr);
1786   JvmtiHandshake::execute(&op, thread);
1787   return op.result();
1788 } /* end GetFrameLocation */
1789 
1790 
1791 // Threads_lock NOT held, java_thread not protected by lock
1792 // depth - pre-checked as non-negative
1793 jvmtiError
1794 JvmtiEnv::NotifyFramePop(jthread thread, jint depth) {
1795   ResourceMark rm;
1796   JvmtiVTMSTransitionDisabler disabler(thread);
1797   JavaThread* current = JavaThread::current();
1798   ThreadsListHandle tlh(current);
1799 
1800   JavaThread* java_thread = nullptr;
1801   oop thread_obj = nullptr;
1802   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current, &java_thread, &thread_obj);
1803   if (err != JVMTI_ERROR_NONE) {
1804     return err;
1805   }
1806 
1807   HandleMark hm(current);
1808   Handle thread_handle(current, thread_obj);
1809   JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread, thread_handle);
1810   if (state == nullptr) {
1811     return JVMTI_ERROR_THREAD_NOT_ALIVE;
1812   }
1813 
1814   SetOrClearFramePopClosure op(this, state, true /* set */, depth);
1815   MutexLocker mu(current, JvmtiThreadState_lock);
1816   JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
1817   return op.result();
1818 } /* end NotifyFramePop */
1819 
1820 // Threads_lock NOT held, java_thread not protected by lock
1821 jvmtiError
1822 JvmtiEnv::ClearAllFramePops(jthread thread) {
1823   ResourceMark rm;
1824   JvmtiVTMSTransitionDisabler disabler(thread);
1825   JavaThread* current = JavaThread::current();
1826   ThreadsListHandle tlh(current);
1827 
1828   JavaThread* java_thread = nullptr;
1829   oop thread_obj = nullptr;
1830   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current, &java_thread, &thread_obj);
1831   if (err != JVMTI_ERROR_NONE) {
1832     return err;
1833   }
1834 
1835   HandleMark hm(current);
1836   Handle thread_handle(current, thread_obj);
1837   JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread, thread_handle);
1838   if (state == nullptr) {
1839     return JVMTI_ERROR_THREAD_NOT_ALIVE;
1840   }
1841 
1842   SetOrClearFramePopClosure op(this, state, false /* clear all frame pops*/);
1843   MutexLocker mu(current, JvmtiThreadState_lock);
1844   JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
1845   return op.result();
1846 } /* end ClearAllFramePops */
1847 
1848   //
1849   // Force Early Return functions
1850   //
1851 
1852 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1853 jvmtiError
1854 JvmtiEnv::ForceEarlyReturnObject(jthread thread, jobject value) {
1855   jvalue val;
1856   val.l = value;
1857   return force_early_return(thread, val, atos);
1858 } /* end ForceEarlyReturnObject */
1859 
1860 
1861 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1862 jvmtiError
1863 JvmtiEnv::ForceEarlyReturnInt(jthread thread, jint value) {
1864   jvalue val;
1865   val.i = value;
1866   return force_early_return(thread, val, itos);
1867 } /* end ForceEarlyReturnInt */
1868 
1869 
1870 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1871 jvmtiError
1872 JvmtiEnv::ForceEarlyReturnLong(jthread thread, jlong value) {
1873   jvalue val;
1874   val.j = value;
1875   return force_early_return(thread, val, ltos);
1876 } /* end ForceEarlyReturnLong */
1877 
1878 
1879 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1880 jvmtiError
1881 JvmtiEnv::ForceEarlyReturnFloat(jthread thread, jfloat value) {
1882   jvalue val;
1883   val.f = value;
1884   return force_early_return(thread, val, ftos);
1885 } /* end ForceEarlyReturnFloat */
1886 
1887 
1888 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1889 jvmtiError
1890 JvmtiEnv::ForceEarlyReturnDouble(jthread thread, jdouble value) {
1891   jvalue val;
1892   val.d = value;
1893   return force_early_return(thread, val, dtos);
1894 } /* end ForceEarlyReturnDouble */
1895 
1896 
1897 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
1898 jvmtiError
1899 JvmtiEnv::ForceEarlyReturnVoid(jthread thread) {
1900   jvalue val;
1901   val.j = 0L;
1902   return force_early_return(thread, val, vtos);
1903 } /* end ForceEarlyReturnVoid */
1904 
1905 
1906   //
1907   // Heap functions
1908   //
1909 
1910 // klass - null is a valid value, must be checked
1911 // initial_object - null is a valid value, must be checked
1912 // callbacks - pre-checked for null
1913 // user_data - null is a valid value, must be checked
1914 jvmtiError
1915 JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
1916   // check klass if provided
1917   Klass* k = nullptr;
1918   if (klass != nullptr) {
1919     oop k_mirror = JNIHandles::resolve_external_guard(klass);
1920     if (k_mirror == nullptr) {
1921       return JVMTI_ERROR_INVALID_CLASS;
1922     }
1923     if (java_lang_Class::is_primitive(k_mirror)) {
1924       return JVMTI_ERROR_NONE;
1925     }
1926     k = java_lang_Class::as_Klass(k_mirror);
1927     if (klass == nullptr) {
1928       return JVMTI_ERROR_INVALID_CLASS;
1929     }
1930   }
1931 
1932   if (initial_object != nullptr) {
1933     oop init_obj = JNIHandles::resolve_external_guard(initial_object);
1934     if (init_obj == nullptr) {
1935       return JVMTI_ERROR_INVALID_OBJECT;
1936     }
1937   }
1938 
1939   Thread *thread = Thread::current();
1940   HandleMark hm(thread);
1941 
1942   TraceTime t("FollowReferences", TRACETIME_LOG(Debug, jvmti, objecttagging));
1943   JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, k, initial_object, callbacks, user_data);
1944   return JVMTI_ERROR_NONE;
1945 } /* end FollowReferences */
1946 
1947 
1948 // klass - null is a valid value, must be checked
1949 // callbacks - pre-checked for null
1950 // user_data - null is a valid value, must be checked
1951 jvmtiError
1952 JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
1953   // check klass if provided
1954   Klass* k = nullptr;
1955   if (klass != nullptr) {
1956     oop k_mirror = JNIHandles::resolve_external_guard(klass);
1957     if (k_mirror == nullptr) {
1958       return JVMTI_ERROR_INVALID_CLASS;
1959     }
1960     if (java_lang_Class::is_primitive(k_mirror)) {
1961       return JVMTI_ERROR_NONE;
1962     }
1963     k = java_lang_Class::as_Klass(k_mirror);
1964     if (k == nullptr) {
1965       return JVMTI_ERROR_INVALID_CLASS;
1966     }
1967   }
1968 
1969   TraceTime t("IterateThroughHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));
1970   JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, k, callbacks, user_data);
1971   return JVMTI_ERROR_NONE;
1972 } /* end IterateThroughHeap */
1973 
1974 
1975 // tag_ptr - pre-checked for null
1976 jvmtiError
1977 JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) {
1978   oop o = JNIHandles::resolve_external_guard(object);
1979   NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
1980   *tag_ptr = JvmtiTagMap::tag_map_for(this)->get_tag(object);
1981   return JVMTI_ERROR_NONE;
1982 } /* end GetTag */
1983 
1984 
1985 jvmtiError
1986 JvmtiEnv::SetTag(jobject object, jlong tag) {
1987   oop o = JNIHandles::resolve_external_guard(object);
1988   NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
1989   JvmtiTagMap::tag_map_for(this)->set_tag(object, tag);
1990   return JVMTI_ERROR_NONE;
1991 } /* end SetTag */
1992 
1993 
1994 // tag_count - pre-checked to be greater than or equal to 0
1995 // tags - pre-checked for null
1996 // count_ptr - pre-checked for null
1997 // object_result_ptr - null is a valid value, must be checked
1998 // tag_result_ptr - null is a valid value, must be checked
1999 jvmtiError
2000 JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
2001   TraceTime t("GetObjectsWithTags", TRACETIME_LOG(Debug, jvmti, objecttagging));
2002   return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);
2003 } /* end GetObjectsWithTags */
2004 
2005 
2006 jvmtiError
2007 JvmtiEnv::ForceGarbageCollection() {
2008   Universe::heap()->collect(GCCause::_jvmti_force_gc);
2009   return JVMTI_ERROR_NONE;
2010 } /* end ForceGarbageCollection */
2011 
2012 
2013   //
2014   // Heap (1.0) functions
2015   //
2016 
2017 // object_reference_callback - pre-checked for null
2018 // user_data - null is a valid value, must be checked
2019 jvmtiError
2020 JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {
2021   oop o = JNIHandles::resolve_external_guard(object);
2022   NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
2023   JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);
2024   return JVMTI_ERROR_NONE;
2025 } /* end IterateOverObjectsReachableFromObject */
2026 
2027 
2028 // heap_root_callback - null is a valid value, must be checked
2029 // stack_ref_callback - null is a valid value, must be checked
2030 // object_ref_callback - null is a valid value, must be checked
2031 // user_data - null is a valid value, must be checked
2032 jvmtiError
2033 JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {
2034   TraceTime t("IterateOverReachableObjects", TRACETIME_LOG(Debug, jvmti, objecttagging));
2035   JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);
2036   return JVMTI_ERROR_NONE;
2037 } /* end IterateOverReachableObjects */
2038 
2039 
2040 // heap_object_callback - pre-checked for null
2041 // user_data - null is a valid value, must be checked
2042 jvmtiError
2043 JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
2044   TraceTime t("IterateOverHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));
2045   Thread *thread = Thread::current();
2046   HandleMark hm(thread);
2047   JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, nullptr, heap_object_callback, user_data);
2048   return JVMTI_ERROR_NONE;
2049 } /* end IterateOverHeap */
2050 
2051 
2052 // k_mirror - may be primitive, this must be checked
2053 // heap_object_callback - pre-checked for null
2054 // user_data - null is a valid value, must be checked
2055 jvmtiError
2056 JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
2057   if (java_lang_Class::is_primitive(k_mirror)) {
2058     // DO PRIMITIVE CLASS PROCESSING
2059     return JVMTI_ERROR_NONE;
2060   }
2061   Klass* klass = java_lang_Class::as_Klass(k_mirror);
2062   if (klass == nullptr) {
2063     return JVMTI_ERROR_INVALID_CLASS;
2064   }
2065   TraceTime t("IterateOverInstancesOfClass", TRACETIME_LOG(Debug, jvmti, objecttagging));
2066   JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);
2067   return JVMTI_ERROR_NONE;
2068 } /* end IterateOverInstancesOfClass */
2069 
2070 
2071   //
2072   // Local Variable functions
2073   //
2074 
2075 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2076 // depth - pre-checked as non-negative
2077 // value_ptr - pre-checked for null
2078 jvmtiError
2079 JvmtiEnv::GetLocalObject(jthread thread, jint depth, jint slot, jobject* value_ptr) {
2080   JavaThread* current_thread = JavaThread::current();
2081   // rm object is created to clean up the javaVFrame created in
2082   // doit_prologue(), but after doit() is finished with it.
2083   ResourceMark rm(current_thread);
2084   HandleMark hm(current_thread);
2085   JvmtiVTMSTransitionDisabler disabler(thread);
2086   ThreadsListHandle tlh(current_thread);
2087 
2088   JavaThread* java_thread = nullptr;
2089   oop thread_obj = nullptr;
2090   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2091   if (err != JVMTI_ERROR_NONE) {
2092     return err;
2093   }
2094   bool self = is_JavaThread_current(java_thread, thread_obj);
2095 
2096   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2097     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2098                                      current_thread, depth, slot, self);
2099     VMThread::execute(&op);
2100     err = op.result();
2101     if (err == JVMTI_ERROR_NONE) {
2102       *value_ptr = op.value().l;
2103     }
2104   } else {
2105     // Support for ordinary threads
2106     VM_GetOrSetLocal op(java_thread, current_thread, depth, slot, self);
2107     VMThread::execute(&op);
2108     err = op.result();
2109     if (err == JVMTI_ERROR_NONE) {
2110       *value_ptr = op.value().l;
2111     }
2112   }
2113   return err;
2114 } /* end GetLocalObject */
2115 
2116 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2117 // depth - pre-checked as non-negative
2118 // value - pre-checked for null
2119 jvmtiError
2120 JvmtiEnv::GetLocalInstance(jthread thread, jint depth, jobject* value_ptr){
2121   JavaThread* current_thread = JavaThread::current();
2122   // rm object is created to clean up the javaVFrame created in
2123   // doit_prologue(), but after doit() is finished with it.
2124   ResourceMark rm(current_thread);
2125   HandleMark hm(current_thread);
2126   JvmtiVTMSTransitionDisabler disabler(thread);
2127   ThreadsListHandle tlh(current_thread);
2128 
2129   JavaThread* java_thread = nullptr;
2130   oop thread_obj = nullptr;
2131   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2132   if (err != JVMTI_ERROR_NONE) {
2133     return err;
2134   }
2135   bool self = is_JavaThread_current(java_thread, thread_obj);
2136 
2137   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2138     VM_VirtualThreadGetReceiver op(this, Handle(current_thread, thread_obj),
2139                                    current_thread, depth, self);
2140     VMThread::execute(&op);
2141     err = op.result();
2142     if (err == JVMTI_ERROR_NONE) {
2143       *value_ptr = op.value().l;
2144     }
2145   } else {
2146     // Support for ordinary threads
2147     VM_GetReceiver op(java_thread, current_thread, depth, self);
2148     VMThread::execute(&op);
2149     err = op.result();
2150     if (err == JVMTI_ERROR_NONE) {
2151       *value_ptr = op.value().l;
2152     }
2153   }
2154   return err;
2155 } /* end GetLocalInstance */
2156 
2157 
2158 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2159 // depth - pre-checked as non-negative
2160 // value_ptr - pre-checked for null
2161 jvmtiError
2162 JvmtiEnv::GetLocalInt(jthread thread, jint depth, jint slot, jint* value_ptr) {
2163   JavaThread* current_thread = JavaThread::current();
2164   // rm object is created to clean up the javaVFrame created in
2165   // doit_prologue(), but after doit() is finished with it.
2166   ResourceMark rm(current_thread);
2167   HandleMark hm(current_thread);
2168   JvmtiVTMSTransitionDisabler disabler(thread);
2169   ThreadsListHandle tlh(current_thread);
2170 
2171   JavaThread* java_thread = nullptr;
2172   oop thread_obj = nullptr;
2173   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2174   if (err != JVMTI_ERROR_NONE) {
2175     return err;
2176   }
2177   bool self = is_JavaThread_current(java_thread, thread_obj);
2178 
2179   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2180     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2181                                      depth, slot, T_INT, self);
2182     VMThread::execute(&op);
2183     err = op.result();
2184     if (err == JVMTI_ERROR_NONE) {
2185       *value_ptr = op.value().i;
2186     }
2187   } else {
2188     // Support for ordinary threads
2189     VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, self);
2190     VMThread::execute(&op);
2191     err = op.result();
2192     if (err == JVMTI_ERROR_NONE) {
2193       *value_ptr = op.value().i;
2194     }
2195   }
2196   return err;
2197 } /* end GetLocalInt */
2198 
2199 
2200 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2201 // depth - pre-checked as non-negative
2202 // value_ptr - pre-checked for null
2203 jvmtiError
2204 JvmtiEnv::GetLocalLong(jthread thread, jint depth, jint slot, jlong* value_ptr) {
2205   JavaThread* current_thread = JavaThread::current();
2206   // rm object is created to clean up the javaVFrame created in
2207   // doit_prologue(), but after doit() is finished with it.
2208   ResourceMark rm(current_thread);
2209   HandleMark hm(current_thread);
2210   JvmtiVTMSTransitionDisabler disabler(thread);
2211   ThreadsListHandle tlh(current_thread);
2212 
2213   JavaThread* java_thread = nullptr;
2214   oop thread_obj = nullptr;
2215   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2216   if (err != JVMTI_ERROR_NONE) {
2217     return err;
2218   }
2219   bool self = is_JavaThread_current(java_thread, thread_obj);
2220 
2221   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2222     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2223                                      depth, slot, T_LONG, self);
2224     VMThread::execute(&op);
2225     err = op.result();
2226     if (err == JVMTI_ERROR_NONE) {
2227       *value_ptr = op.value().j;
2228     }
2229   } else {
2230     // Support for ordinary threads
2231     VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, self);
2232     VMThread::execute(&op);
2233     err = op.result();
2234     if (err == JVMTI_ERROR_NONE) {
2235       *value_ptr = op.value().j;
2236     }
2237   }
2238   return err;
2239 } /* end GetLocalLong */
2240 
2241 
2242 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2243 // depth - pre-checked as non-negative
2244 // value_ptr - pre-checked for null
2245 jvmtiError
2246 JvmtiEnv::GetLocalFloat(jthread thread, jint depth, jint slot, jfloat* value_ptr) {
2247   JavaThread* current_thread = JavaThread::current();
2248   // rm object is created to clean up the javaVFrame created in
2249   // doit_prologue(), but after doit() is finished with it.
2250   ResourceMark rm(current_thread);
2251   HandleMark hm(current_thread);
2252   JvmtiVTMSTransitionDisabler disabler(thread);
2253   ThreadsListHandle tlh(current_thread);
2254 
2255   JavaThread* java_thread = nullptr;
2256   oop thread_obj = nullptr;
2257   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2258   if (err != JVMTI_ERROR_NONE) {
2259     return err;
2260   }
2261   bool self = is_JavaThread_current(java_thread, thread_obj);
2262 
2263   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2264     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2265                                      depth, slot, T_FLOAT, self);
2266     VMThread::execute(&op);
2267     err = op.result();
2268     if (err == JVMTI_ERROR_NONE) {
2269       *value_ptr = op.value().f;
2270     }
2271   } else {
2272     // Support for ordinary threads
2273     VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, self);
2274     VMThread::execute(&op);
2275     err = op.result();
2276     if (err == JVMTI_ERROR_NONE) {
2277       *value_ptr = op.value().f;
2278     }
2279   }
2280   return err;
2281 } /* end GetLocalFloat */
2282 
2283 
2284 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2285 // depth - pre-checked as non-negative
2286 // value_ptr - pre-checked for null
2287 jvmtiError
2288 JvmtiEnv::GetLocalDouble(jthread thread, jint depth, jint slot, jdouble* value_ptr) {
2289   JavaThread* current_thread = JavaThread::current();
2290   // rm object is created to clean up the javaVFrame created in
2291   // doit_prologue(), but after doit() is finished with it.
2292   ResourceMark rm(current_thread);
2293   HandleMark hm(current_thread);
2294   JvmtiVTMSTransitionDisabler disabler(thread);
2295   ThreadsListHandle tlh(current_thread);
2296 
2297   JavaThread* java_thread = nullptr;
2298   oop thread_obj = nullptr;
2299   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2300   if (err != JVMTI_ERROR_NONE) {
2301     return err;
2302   }
2303   bool self = is_JavaThread_current(java_thread, thread_obj);
2304 
2305   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2306     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2307                                      depth, slot, T_DOUBLE, self);
2308     VMThread::execute(&op);
2309     err = op.result();
2310     if (err == JVMTI_ERROR_NONE) {
2311       *value_ptr = op.value().d;
2312     }
2313   } else {
2314     // Support for ordinary threads
2315     VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, self);
2316     VMThread::execute(&op);
2317     err = op.result();
2318     if (err == JVMTI_ERROR_NONE) {
2319       *value_ptr = op.value().d;
2320     }
2321   }
2322   return err;
2323 } /* end GetLocalDouble */
2324 
2325 
2326 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2327 // depth - pre-checked as non-negative
2328 jvmtiError
2329 JvmtiEnv::SetLocalObject(jthread thread, jint depth, jint slot, jobject value) {
2330   JavaThread* current_thread = JavaThread::current();
2331   // rm object is created to clean up the javaVFrame created in
2332   // doit_prologue(), but after doit() is finished with it.
2333   ResourceMark rm(current_thread);
2334   HandleMark hm(current_thread);
2335   JvmtiVTMSTransitionDisabler disabler(thread);
2336   ThreadsListHandle tlh(current_thread);
2337 
2338   JavaThread* java_thread = nullptr;
2339   oop thread_obj = nullptr;
2340   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2341   if (err != JVMTI_ERROR_NONE) {
2342     return err;
2343   }
2344   bool self = is_JavaThread_current(java_thread, thread_obj);
2345   jvalue val;
2346   val.l = value;
2347 
2348   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2349     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2350                                      depth, slot, T_OBJECT, val, self);
2351     VMThread::execute(&op);
2352     err = op.result();
2353   } else {
2354     // Support for ordinary threads
2355     VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val, self);
2356     VMThread::execute(&op);
2357     err = op.result();
2358   }
2359   return err;
2360 } /* end SetLocalObject */
2361 
2362 
2363 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2364 // depth - pre-checked as non-negative
2365 jvmtiError
2366 JvmtiEnv::SetLocalInt(jthread thread, jint depth, jint slot, jint value) {
2367   JavaThread* current_thread = JavaThread::current();
2368   // rm object is created to clean up the javaVFrame created in
2369   // doit_prologue(), but after doit() is finished with it.
2370   ResourceMark rm(current_thread);
2371   HandleMark hm(current_thread);
2372   JvmtiVTMSTransitionDisabler disabler(thread);
2373   ThreadsListHandle tlh(current_thread);
2374 
2375   JavaThread* java_thread = nullptr;
2376   oop thread_obj = nullptr;
2377   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2378   if (err != JVMTI_ERROR_NONE) {
2379     return err;
2380   }
2381   bool self = is_JavaThread_current(java_thread, thread_obj);
2382   jvalue val;
2383   val.i = value;
2384 
2385   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2386     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2387                                      depth, slot, T_INT, val, self);
2388     VMThread::execute(&op);
2389     err = op.result();
2390   } else {
2391     // Support for ordinary threads
2392     VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val, self);
2393     VMThread::execute(&op);
2394     err = op.result();
2395   }
2396   return err;
2397 } /* end SetLocalInt */
2398 
2399 
2400 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2401 // depth - pre-checked as non-negative
2402 jvmtiError
2403 JvmtiEnv::SetLocalLong(jthread thread, jint depth, jint slot, jlong value) {
2404   JavaThread* current_thread = JavaThread::current();
2405   // rm object is created to clean up the javaVFrame created in
2406   // doit_prologue(), but after doit() is finished with it.
2407   ResourceMark rm(current_thread);
2408   HandleMark hm(current_thread);
2409   JvmtiVTMSTransitionDisabler disabler(thread);
2410   ThreadsListHandle tlh(current_thread);
2411 
2412   JavaThread* java_thread = nullptr;
2413   oop thread_obj = nullptr;
2414   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2415   if (err != JVMTI_ERROR_NONE) {
2416     return err;
2417   }
2418   bool self = is_JavaThread_current(java_thread, thread_obj);
2419   jvalue val;
2420   val.j = value;
2421 
2422   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2423     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2424                                      depth, slot, T_LONG, val, self);
2425     VMThread::execute(&op);
2426     err = op.result();
2427   } else {
2428     // Support for ordinary threads
2429     VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val, self);
2430     VMThread::execute(&op);
2431     err = op.result();
2432   }
2433   return err;
2434 } /* end SetLocalLong */
2435 
2436 
2437 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2438 // depth - pre-checked as non-negative
2439 jvmtiError
2440 JvmtiEnv::SetLocalFloat(jthread thread, jint depth, jint slot, jfloat value) {
2441   JavaThread* current_thread = JavaThread::current();
2442   // rm object is created to clean up the javaVFrame created in
2443   // doit_prologue(), but after doit() is finished with it.
2444   ResourceMark rm(current_thread);
2445   HandleMark hm(current_thread);
2446   JvmtiVTMSTransitionDisabler disabler(thread);
2447   ThreadsListHandle tlh(current_thread);
2448 
2449   JavaThread* java_thread = nullptr;
2450   oop thread_obj = nullptr;
2451   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2452   if (err != JVMTI_ERROR_NONE) {
2453     return err;
2454   }
2455   bool self = is_JavaThread_current(java_thread, thread_obj);
2456   jvalue val;
2457   val.f = value;
2458 
2459   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2460     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2461                                      depth, slot, T_FLOAT, val, self);
2462     VMThread::execute(&op);
2463     err = op.result();
2464   } else {
2465     // Support for ordinary threads
2466     VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val, self);
2467     VMThread::execute(&op);
2468     err = op.result();
2469   }
2470   return err;
2471 } /* end SetLocalFloat */
2472 
2473 
2474 // thread - NOT protected by ThreadsListHandle and NOT pre-checked
2475 // depth - pre-checked as non-negative
2476 jvmtiError
2477 JvmtiEnv::SetLocalDouble(jthread thread, jint depth, jint slot, jdouble value) {
2478   JavaThread* current_thread = JavaThread::current();
2479   // rm object is created to clean up the javaVFrame created in
2480   // doit_prologue(), but after doit() is finished with it.
2481   ResourceMark rm(current_thread);
2482   HandleMark hm(current_thread);
2483   JvmtiVTMSTransitionDisabler disabler(thread);
2484   ThreadsListHandle tlh(current_thread);
2485 
2486   JavaThread* java_thread = nullptr;
2487   oop thread_obj = nullptr;
2488   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_obj);
2489   if (err != JVMTI_ERROR_NONE) {
2490     return err;
2491   }
2492   bool self = is_JavaThread_current(java_thread, thread_obj);
2493   jvalue val;
2494   val.d = value;
2495 
2496   if (java_lang_VirtualThread::is_instance(thread_obj)) {
2497     VM_VirtualThreadGetOrSetLocal op(this, Handle(current_thread, thread_obj),
2498                                      depth, slot, T_DOUBLE, val, self);
2499     VMThread::execute(&op);
2500     err = op.result();
2501   } else {
2502     // Support for ordinary threads
2503     VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val, self);
2504     VMThread::execute(&op);
2505     err = op.result();
2506   }
2507   return err;
2508 } /* end SetLocalDouble */
2509 
2510 
2511   //
2512   // Breakpoint functions
2513   //
2514 
2515 // method - pre-checked for validity, but may be null meaning obsolete method
2516 jvmtiError
2517 JvmtiEnv::SetBreakpoint(Method* method, jlocation location) {
2518   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2519   if (location < 0) {   // simple invalid location check first
2520     return JVMTI_ERROR_INVALID_LOCATION;
2521   }
2522   // verify that the breakpoint is not past the end of the method
2523   if (location >= (jlocation) method->code_size()) {
2524     return JVMTI_ERROR_INVALID_LOCATION;
2525   }
2526 
2527   ResourceMark rm;
2528   JvmtiBreakpoint bp(method, location);
2529   JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
2530   if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE)
2531     return JVMTI_ERROR_DUPLICATE;
2532 
2533   if (TraceJVMTICalls) {
2534     jvmti_breakpoints.print();
2535   }
2536 
2537   return JVMTI_ERROR_NONE;
2538 } /* end SetBreakpoint */
2539 
2540 
2541 // method - pre-checked for validity, but may be null meaning obsolete method
2542 jvmtiError
2543 JvmtiEnv::ClearBreakpoint(Method* method, jlocation location) {
2544   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2545 
2546   if (location < 0) {   // simple invalid location check first
2547     return JVMTI_ERROR_INVALID_LOCATION;
2548   }
2549 
2550   // verify that the breakpoint is not past the end of the method
2551   if (location >= (jlocation) method->code_size()) {
2552     return JVMTI_ERROR_INVALID_LOCATION;
2553   }
2554 
2555   JvmtiBreakpoint bp(method, location);
2556 
2557   JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
2558   if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND)
2559     return JVMTI_ERROR_NOT_FOUND;
2560 
2561   if (TraceJVMTICalls) {
2562     jvmti_breakpoints.print();
2563   }
2564 
2565   return JVMTI_ERROR_NONE;
2566 } /* end ClearBreakpoint */
2567 
2568 
2569   //
2570   // Watched Field functions
2571   //
2572 
2573 jvmtiError
2574 JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
2575   JvmtiVTMSTransitionDisabler disabler;
2576   // make sure we haven't set this watch before
2577   if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;
2578   fdesc_ptr->set_is_field_access_watched(true);
2579 
2580   JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);
2581 
2582   return JVMTI_ERROR_NONE;
2583 } /* end SetFieldAccessWatch */
2584 
2585 
2586 jvmtiError
2587 JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
2588   JvmtiVTMSTransitionDisabler disabler;
2589   // make sure we have a watch to clear
2590   if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;
2591   fdesc_ptr->set_is_field_access_watched(false);
2592 
2593   JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);
2594 
2595   return JVMTI_ERROR_NONE;
2596 } /* end ClearFieldAccessWatch */
2597 
2598 
2599 jvmtiError
2600 JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
2601   JvmtiVTMSTransitionDisabler disabler;
2602   // make sure we haven't set this watch before
2603   if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;
2604   fdesc_ptr->set_is_field_modification_watched(true);
2605 
2606   JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);
2607 
2608   return JVMTI_ERROR_NONE;
2609 } /* end SetFieldModificationWatch */
2610 
2611 
2612 jvmtiError
2613 JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
2614   JvmtiVTMSTransitionDisabler disabler;
2615    // make sure we have a watch to clear
2616   if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;
2617   fdesc_ptr->set_is_field_modification_watched(false);
2618 
2619   JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);
2620 
2621   return JVMTI_ERROR_NONE;
2622 } /* end ClearFieldModificationWatch */
2623 
2624   //
2625   // Class functions
2626   //
2627 
2628 
2629 // k_mirror - may be primitive, this must be checked
2630 // signature_ptr - null is a valid value, must be checked
2631 // generic_ptr - null is a valid value, must be checked
2632 jvmtiError
2633 JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) {
2634   ResourceMark rm;
2635   bool isPrimitive = java_lang_Class::is_primitive(k_mirror);
2636   Klass* k = nullptr;
2637   if (!isPrimitive) {
2638     k = java_lang_Class::as_Klass(k_mirror);
2639     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2640   }
2641   if (signature_ptr != nullptr) {
2642     char* result = nullptr;
2643     if (isPrimitive) {
2644       char tchar = type2char(java_lang_Class::primitive_type(k_mirror));
2645       result = (char*) jvmtiMalloc(2);
2646       result[0] = tchar;
2647       result[1] = '\0';
2648     } else {
2649       const char* class_sig = k->signature_name();
2650       result = (char *) jvmtiMalloc(strlen(class_sig)+1);
2651       strcpy(result, class_sig);
2652     }
2653     *signature_ptr = result;
2654   }
2655   if (generic_ptr != nullptr) {
2656     *generic_ptr = nullptr;
2657     if (!isPrimitive && k->is_instance_klass()) {
2658       Symbol* soo = InstanceKlass::cast(k)->generic_signature();
2659       if (soo != nullptr) {
2660         const char *gen_sig = soo->as_C_string();
2661         if (gen_sig != nullptr) {
2662           char* gen_result;
2663           jvmtiError err = allocate(strlen(gen_sig) + 1,
2664                                     (unsigned char **)&gen_result);
2665           if (err != JVMTI_ERROR_NONE) {
2666             return err;
2667           }
2668           strcpy(gen_result, gen_sig);
2669           *generic_ptr = gen_result;
2670         }
2671       }
2672     }
2673   }
2674   return JVMTI_ERROR_NONE;
2675 } /* end GetClassSignature */
2676 
2677 
2678 // k_mirror - may be primitive, this must be checked
2679 // status_ptr - pre-checked for null
2680 jvmtiError
2681 JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) {
2682   jint result = 0;
2683   if (java_lang_Class::is_primitive(k_mirror)) {
2684     result |= JVMTI_CLASS_STATUS_PRIMITIVE;
2685   } else {
2686     Klass* k = java_lang_Class::as_Klass(k_mirror);
2687     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2688     result = k->jvmti_class_status();
2689   }
2690   *status_ptr = result;
2691 
2692   return JVMTI_ERROR_NONE;
2693 } /* end GetClassStatus */
2694 
2695 
2696 // k_mirror - may be primitive, this must be checked
2697 // source_name_ptr - pre-checked for null
2698 jvmtiError
2699 JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) {
2700   if (java_lang_Class::is_primitive(k_mirror)) {
2701      return JVMTI_ERROR_ABSENT_INFORMATION;
2702   }
2703   Klass* k_klass = java_lang_Class::as_Klass(k_mirror);
2704   NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);
2705 
2706   if (!k_klass->is_instance_klass()) {
2707     return JVMTI_ERROR_ABSENT_INFORMATION;
2708   }
2709 
2710   Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name();
2711   NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION);
2712   {
2713     JavaThread* current_thread  = JavaThread::current();
2714     ResourceMark rm(current_thread);
2715     const char* sfncp = (const char*) sfnOop->as_C_string();
2716     *source_name_ptr = (char *) jvmtiMalloc(strlen(sfncp)+1);
2717     strcpy(*source_name_ptr, sfncp);
2718   }
2719 
2720   return JVMTI_ERROR_NONE;
2721 } /* end GetSourceFileName */
2722 
2723 
2724 // k_mirror - may be primitive, this must be checked
2725 // modifiers_ptr - pre-checked for null
2726 jvmtiError
2727 JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) {
2728   jint result = java_lang_Class::modifiers(k_mirror);
2729   if (!java_lang_Class::is_primitive(k_mirror)) {
2730     // Reset the deleted  ACC_SUPER bit (deleted in compute_modifier_flags()).
2731     result |= JVM_ACC_SUPER;
2732   }
2733   *modifiers_ptr = result;
2734 
2735   return JVMTI_ERROR_NONE;
2736 } /* end GetClassModifiers */
2737 
2738 
2739 // k_mirror - may be primitive, this must be checked
2740 // method_count_ptr - pre-checked for null
2741 // methods_ptr - pre-checked for null
2742 jvmtiError
2743 JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {
2744   JavaThread* current_thread  = JavaThread::current();
2745   HandleMark hm(current_thread);
2746 
2747   if (java_lang_Class::is_primitive(k_mirror)) {
2748     *method_count_ptr = 0;
2749     *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2750     return JVMTI_ERROR_NONE;
2751   }
2752   Klass* k = java_lang_Class::as_Klass(k_mirror);
2753   NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2754 
2755   // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2756   if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2757     return JVMTI_ERROR_CLASS_NOT_PREPARED;
2758   }
2759 
2760   if (!k->is_instance_klass()) {
2761     *method_count_ptr = 0;
2762     *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2763     return JVMTI_ERROR_NONE;
2764   }
2765   InstanceKlass* ik = InstanceKlass::cast(k);
2766   // Allocate the result and fill it in
2767   int result_length = ik->methods()->length();
2768   jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
2769   int index;
2770   int skipped = 0;  // skip overpass methods
2771 
2772   // Make jmethodIDs for all non-overpass methods.
2773   ik->make_methods_jmethod_ids();
2774 
2775   for (index = 0; index < result_length; index++) {
2776     Method* m = ik->methods()->at(index);
2777     // Depending on can_maintain_original_method_order capability use the original
2778     // method ordering indices stored in the class, so we can emit jmethodIDs in
2779     // the order they appeared in the class file or just copy in current order.
2780     int result_index = JvmtiExport::can_maintain_original_method_order() ? ik->method_ordering()->at(index) : index;
2781     assert(result_index >= 0 && result_index < result_length, "invalid original method index");
2782     if (m->is_overpass()) {
2783       result_list[result_index] = nullptr;
2784       skipped++;
2785       continue;
2786     }
2787     jmethodID id = m->find_jmethod_id_or_null();
2788     assert(id != nullptr, "should be created above");
2789     result_list[result_index] = id;
2790   }
2791 
2792   // Fill in return value.
2793   if (skipped > 0) {
2794     // copy results skipping null methodIDs
2795     *methods_ptr = (jmethodID*)jvmtiMalloc((result_length - skipped) * sizeof(jmethodID));
2796     *method_count_ptr = result_length - skipped;
2797     for (index = 0, skipped = 0; index < result_length; index++) {
2798       if (result_list[index] == nullptr) {
2799         skipped++;
2800       } else {
2801         (*methods_ptr)[index - skipped] = result_list[index];
2802       }
2803     }
2804     deallocate((unsigned char *)result_list);
2805   } else {
2806     *method_count_ptr = result_length;
2807     *methods_ptr = result_list;
2808   }
2809 
2810   return JVMTI_ERROR_NONE;
2811 } /* end GetClassMethods */
2812 
2813 
2814 // k_mirror - may be primitive, this must be checked
2815 // field_count_ptr - pre-checked for null
2816 // fields_ptr - pre-checked for null
2817 jvmtiError
2818 JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {
2819   if (java_lang_Class::is_primitive(k_mirror)) {
2820     *field_count_ptr = 0;
2821     *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2822     return JVMTI_ERROR_NONE;
2823   }
2824   JavaThread* current_thread = JavaThread::current();
2825   HandleMark hm(current_thread);
2826   Klass* k = java_lang_Class::as_Klass(k_mirror);
2827   NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2828 
2829   // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2830   if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2831     return JVMTI_ERROR_CLASS_NOT_PREPARED;
2832   }
2833 
2834   if (!k->is_instance_klass()) {
2835     *field_count_ptr = 0;
2836     *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2837     return JVMTI_ERROR_NONE;
2838   }
2839 
2840   InstanceKlass* ik = InstanceKlass::cast(k);
2841 
2842   FilteredJavaFieldStream flds(ik);
2843 
2844   int result_count = flds.field_count();
2845 
2846   // Allocate the result and fill it in.
2847   jfieldID* result_list = (jfieldID*)jvmtiMalloc(result_count * sizeof(jfieldID));
2848   for (int i = 0; i < result_count; i++, flds.next()) {
2849     result_list[i] = jfieldIDWorkaround::to_jfieldID(ik, flds.offset(),
2850                                                      flds.access_flags().is_static());
2851   }
2852   assert(flds.done(), "just checking");
2853 
2854   // Fill in the results
2855   *field_count_ptr = result_count;
2856   *fields_ptr = result_list;
2857 
2858   return JVMTI_ERROR_NONE;
2859 } /* end GetClassFields */
2860 
2861 
2862 // k_mirror - may be primitive, this must be checked
2863 // interface_count_ptr - pre-checked for null
2864 // interfaces_ptr - pre-checked for null
2865 jvmtiError
2866 JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {
2867   {
2868     if (java_lang_Class::is_primitive(k_mirror)) {
2869       *interface_count_ptr = 0;
2870       *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2871       return JVMTI_ERROR_NONE;
2872     }
2873     JavaThread* current_thread = JavaThread::current();
2874     HandleMark hm(current_thread);
2875     Klass* k = java_lang_Class::as_Klass(k_mirror);
2876     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2877 
2878     // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2879     if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
2880       return JVMTI_ERROR_CLASS_NOT_PREPARED;
2881 
2882     if (!k->is_instance_klass()) {
2883       *interface_count_ptr = 0;
2884       *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2885       return JVMTI_ERROR_NONE;
2886     }
2887 
2888     Array<InstanceKlass*>* interface_list = InstanceKlass::cast(k)->local_interfaces();
2889     const int result_length = (interface_list == nullptr ? 0 : interface_list->length());
2890     jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));
2891     for (int i_index = 0; i_index < result_length; i_index += 1) {
2892       InstanceKlass* klass_at = interface_list->at(i_index);
2893       assert(klass_at->is_klass(), "interfaces must be Klass*s");
2894       assert(klass_at->is_interface(), "interfaces must be interfaces");
2895       oop mirror_at = klass_at->java_mirror();
2896       Handle handle_at = Handle(current_thread, mirror_at);
2897       result_list[i_index] = (jclass) jni_reference(handle_at);
2898     }
2899     *interface_count_ptr = result_length;
2900     *interfaces_ptr = result_list;
2901   }
2902 
2903   return JVMTI_ERROR_NONE;
2904 } /* end GetImplementedInterfaces */
2905 
2906 
2907 // k_mirror - may be primitive, this must be checked
2908 // minor_version_ptr - pre-checked for null
2909 // major_version_ptr - pre-checked for null
2910 jvmtiError
2911 JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {
2912   if (java_lang_Class::is_primitive(k_mirror)) {
2913     return JVMTI_ERROR_ABSENT_INFORMATION;
2914   }
2915   Klass* klass = java_lang_Class::as_Klass(k_mirror);
2916 
2917   jint status = klass->jvmti_class_status();
2918   if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2919     return JVMTI_ERROR_INVALID_CLASS;
2920   }
2921   if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2922     return JVMTI_ERROR_ABSENT_INFORMATION;
2923   }
2924 
2925   InstanceKlass* ik = InstanceKlass::cast(klass);
2926   *minor_version_ptr = ik->minor_version();
2927   *major_version_ptr = ik->major_version();
2928 
2929   return JVMTI_ERROR_NONE;
2930 } /* end GetClassVersionNumbers */
2931 
2932 
2933 // k_mirror - may be primitive, this must be checked
2934 // constant_pool_count_ptr - pre-checked for null
2935 // constant_pool_byte_count_ptr - pre-checked for null
2936 // constant_pool_bytes_ptr - pre-checked for null
2937 jvmtiError
2938 JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {
2939   if (java_lang_Class::is_primitive(k_mirror)) {
2940     return JVMTI_ERROR_ABSENT_INFORMATION;
2941   }
2942 
2943   Klass* klass = java_lang_Class::as_Klass(k_mirror);
2944   Thread *thread = Thread::current();
2945   ResourceMark rm(thread);
2946 
2947   jint status = klass->jvmti_class_status();
2948   if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2949     return JVMTI_ERROR_INVALID_CLASS;
2950   }
2951   if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2952     return JVMTI_ERROR_ABSENT_INFORMATION;
2953   }
2954 
2955   InstanceKlass* ik = InstanceKlass::cast(klass);
2956   JvmtiConstantPoolReconstituter reconstituter(ik);
2957   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2958     return reconstituter.get_error();
2959   }
2960 
2961   unsigned char *cpool_bytes;
2962   int cpool_size = reconstituter.cpool_size();
2963   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2964     return reconstituter.get_error();
2965   }
2966   jvmtiError res = allocate(cpool_size, &cpool_bytes);
2967   if (res != JVMTI_ERROR_NONE) {
2968     return res;
2969   }
2970   reconstituter.copy_cpool_bytes(cpool_bytes);
2971   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2972     return reconstituter.get_error();
2973   }
2974 
2975   constantPoolHandle  constants(thread, ik->constants());
2976   *constant_pool_count_ptr      = constants->length();
2977   *constant_pool_byte_count_ptr = cpool_size;
2978   *constant_pool_bytes_ptr      = cpool_bytes;
2979 
2980   return JVMTI_ERROR_NONE;
2981 } /* end GetConstantPool */
2982 
2983 
2984 // k_mirror - may be primitive, this must be checked
2985 // is_interface_ptr - pre-checked for null
2986 jvmtiError
2987 JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {
2988   {
2989     bool result = false;
2990     if (!java_lang_Class::is_primitive(k_mirror)) {
2991       Klass* k = java_lang_Class::as_Klass(k_mirror);
2992       if (k != nullptr && k->is_interface()) {
2993         result = true;
2994       }
2995     }
2996     *is_interface_ptr = result;
2997   }
2998 
2999   return JVMTI_ERROR_NONE;
3000 } /* end IsInterface */
3001 
3002 
3003 // k_mirror - may be primitive, this must be checked
3004 // is_array_class_ptr - pre-checked for null
3005 jvmtiError
3006 JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {
3007   {
3008     bool result = false;
3009     if (!java_lang_Class::is_primitive(k_mirror)) {
3010       Klass* k = java_lang_Class::as_Klass(k_mirror);
3011       if (k != nullptr && k->is_array_klass()) {
3012         result = true;
3013       }
3014     }
3015     *is_array_class_ptr = result;
3016   }
3017 
3018   return JVMTI_ERROR_NONE;
3019 } /* end IsArrayClass */
3020 
3021 
3022 // k_mirror - may be primitive, this must be checked
3023 // classloader_ptr - pre-checked for null
3024 jvmtiError
3025 JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {
3026   {
3027     if (java_lang_Class::is_primitive(k_mirror)) {
3028       *classloader_ptr = (jclass) jni_reference(Handle());
3029       return JVMTI_ERROR_NONE;
3030     }
3031     JavaThread* current_thread = JavaThread::current();
3032     HandleMark hm(current_thread);
3033     Klass* k = java_lang_Class::as_Klass(k_mirror);
3034     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
3035 
3036     oop result_oop = k->class_loader();
3037     if (result_oop == nullptr) {
3038       *classloader_ptr = (jclass) jni_reference(Handle());
3039       return JVMTI_ERROR_NONE;
3040     }
3041     Handle result_handle = Handle(current_thread, result_oop);
3042     jclass result_jnihandle = (jclass) jni_reference(result_handle);
3043     *classloader_ptr = result_jnihandle;
3044   }
3045   return JVMTI_ERROR_NONE;
3046 } /* end GetClassLoader */
3047 
3048 
3049 // k_mirror - may be primitive, this must be checked
3050 // source_debug_extension_ptr - pre-checked for null
3051 jvmtiError
3052 JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {
3053   {
3054     if (java_lang_Class::is_primitive(k_mirror)) {
3055       return JVMTI_ERROR_ABSENT_INFORMATION;
3056     }
3057     Klass* k = java_lang_Class::as_Klass(k_mirror);
3058     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
3059     if (!k->is_instance_klass()) {
3060       return JVMTI_ERROR_ABSENT_INFORMATION;
3061     }
3062     const char* sde = InstanceKlass::cast(k)->source_debug_extension();
3063     NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
3064 
3065     {
3066       *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
3067       strcpy(*source_debug_extension_ptr, sde);
3068     }
3069   }
3070 
3071   return JVMTI_ERROR_NONE;
3072 } /* end GetSourceDebugExtension */
3073 
3074   //
3075   // Object functions
3076   //
3077 
3078 // hash_code_ptr - pre-checked for null
3079 jvmtiError
3080 JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {
3081   oop mirror = JNIHandles::resolve_external_guard(object);
3082   NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
3083   NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);
3084 
3085   {
3086     jint result = (jint) mirror->identity_hash();
3087     *hash_code_ptr = result;
3088   }
3089   return JVMTI_ERROR_NONE;
3090 } /* end GetObjectHashCode */
3091 
3092 
3093 // info_ptr - pre-checked for null
3094 jvmtiError
3095 JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {
3096   // This needs to be performed at a safepoint to gather stable data
3097   // because monitor owner / waiters might not be suspended.
3098   VM_GetObjectMonitorUsage op(this, JavaThread::current(), object, info_ptr);
3099   VMThread::execute(&op);
3100   return op.result();
3101 } /* end GetObjectMonitorUsage */
3102 
3103 
3104   //
3105   // Field functions
3106   //
3107 
3108 // name_ptr - null is a valid value, must be checked
3109 // signature_ptr - null is a valid value, must be checked
3110 // generic_ptr - null is a valid value, must be checked
3111 jvmtiError
3112 JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {
3113   JavaThread* current_thread  = JavaThread::current();
3114   ResourceMark rm(current_thread);
3115   if (name_ptr == nullptr) {
3116     // just don't return the name
3117   } else {
3118     const char* fieldName = fdesc_ptr->name()->as_C_string();
3119     *name_ptr =  (char*) jvmtiMalloc(strlen(fieldName) + 1);
3120     if (*name_ptr == nullptr)
3121       return JVMTI_ERROR_OUT_OF_MEMORY;
3122     strcpy(*name_ptr, fieldName);
3123   }
3124   if (signature_ptr== nullptr) {
3125     // just don't return the signature
3126   } else {
3127     const char* fieldSignature = fdesc_ptr->signature()->as_C_string();
3128     *signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1);
3129     if (*signature_ptr == nullptr)
3130       return JVMTI_ERROR_OUT_OF_MEMORY;
3131     strcpy(*signature_ptr, fieldSignature);
3132   }
3133   if (generic_ptr != nullptr) {
3134     *generic_ptr = nullptr;
3135     Symbol* soop = fdesc_ptr->generic_signature();
3136     if (soop != nullptr) {
3137       const char* gen_sig = soop->as_C_string();
3138       if (gen_sig != nullptr) {
3139         jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
3140         if (err != JVMTI_ERROR_NONE) {
3141           return err;
3142         }
3143         strcpy(*generic_ptr, gen_sig);
3144       }
3145     }
3146   }
3147   return JVMTI_ERROR_NONE;
3148 } /* end GetFieldName */
3149 
3150 
3151 // declaring_class_ptr - pre-checked for null
3152 jvmtiError
3153 JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {
3154   // As for the GetFieldDeclaringClass method, the XSL generated C++ code that calls it has
3155   // a jclass of the relevant class or a subclass of it, which is fine in terms of ensuring
3156   // the holder is kept alive.
3157   *declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder());
3158   return JVMTI_ERROR_NONE;
3159 } /* end GetFieldDeclaringClass */
3160 
3161 
3162 // modifiers_ptr - pre-checked for null
3163 jvmtiError
3164 JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {
3165 
3166   AccessFlags resultFlags = fdesc_ptr->access_flags();
3167   jint result = resultFlags.as_field_flags();
3168   *modifiers_ptr = result;
3169 
3170   return JVMTI_ERROR_NONE;
3171 } /* end GetFieldModifiers */
3172 
3173 
3174 // is_synthetic_ptr - pre-checked for null
3175 jvmtiError
3176 JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {
3177   *is_synthetic_ptr = fdesc_ptr->is_synthetic();
3178   return JVMTI_ERROR_NONE;
3179 } /* end IsFieldSynthetic */
3180 
3181 
3182   //
3183   // Method functions
3184   //
3185 
3186 // method - pre-checked for validity, but may be null meaning obsolete method
3187 // name_ptr - null is a valid value, must be checked
3188 // signature_ptr - null is a valid value, must be checked
3189 // generic_ptr - null is a valid value, must be checked
3190 jvmtiError
3191 JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, char** generic_ptr) {
3192   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3193   JavaThread* current_thread  = JavaThread::current();
3194 
3195   ResourceMark rm(current_thread); // get the utf8 name and signature
3196   if (name_ptr == nullptr) {
3197     // just don't return the name
3198   } else {
3199     const char* utf8_name = (const char *) method->name()->as_utf8();
3200     *name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1);
3201     strcpy(*name_ptr, utf8_name);
3202   }
3203   if (signature_ptr == nullptr) {
3204     // just don't return the signature
3205   } else {
3206     const char* utf8_signature = (const char *) method->signature()->as_utf8();
3207     *signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1);
3208     strcpy(*signature_ptr, utf8_signature);
3209   }
3210 
3211   if (generic_ptr != nullptr) {
3212     *generic_ptr = nullptr;
3213     Symbol* soop = method->generic_signature();
3214     if (soop != nullptr) {
3215       const char* gen_sig = soop->as_C_string();
3216       if (gen_sig != nullptr) {
3217         jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
3218         if (err != JVMTI_ERROR_NONE) {
3219           return err;
3220         }
3221         strcpy(*generic_ptr, gen_sig);
3222       }
3223     }
3224   }
3225   return JVMTI_ERROR_NONE;
3226 } /* end GetMethodName */
3227 
3228 
3229 // method - pre-checked for validity, but may be null meaning obsolete method
3230 // declaring_class_ptr - pre-checked for null
3231 jvmtiError
3232 JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) {
3233   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3234   Klass* k = method->method_holder();
3235   Handle holder(Thread::current(), k->klass_holder()); // keep the klass alive
3236   (*declaring_class_ptr) = get_jni_class_non_null(k);
3237   return JVMTI_ERROR_NONE;
3238 } /* end GetMethodDeclaringClass */
3239 
3240 
3241 // method - pre-checked for validity, but may be null meaning obsolete method
3242 // modifiers_ptr - pre-checked for null
3243 jvmtiError
3244 JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) {
3245   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3246   (*modifiers_ptr) = method->access_flags().as_method_flags();
3247   return JVMTI_ERROR_NONE;
3248 } /* end GetMethodModifiers */
3249 
3250 
3251 // method - pre-checked for validity, but may be null meaning obsolete method
3252 // max_ptr - pre-checked for null
3253 jvmtiError
3254 JvmtiEnv::GetMaxLocals(Method* method, jint* max_ptr) {
3255   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3256   // get max stack
3257   (*max_ptr) = method->max_locals();
3258   return JVMTI_ERROR_NONE;
3259 } /* end GetMaxLocals */
3260 
3261 
3262 // method - pre-checked for validity, but may be null meaning obsolete method
3263 // size_ptr - pre-checked for null
3264 jvmtiError
3265 JvmtiEnv::GetArgumentsSize(Method* method, jint* size_ptr) {
3266   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3267   // get size of arguments
3268 
3269   (*size_ptr) = method->size_of_parameters();
3270   return JVMTI_ERROR_NONE;
3271 } /* end GetArgumentsSize */
3272 
3273 
3274 // method - pre-checked for validity, but may be null meaning obsolete method
3275 // entry_count_ptr - pre-checked for null
3276 // table_ptr - pre-checked for null
3277 jvmtiError
3278 JvmtiEnv::GetLineNumberTable(Method* method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {
3279   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3280   if (!method->has_linenumber_table()) {
3281     return (JVMTI_ERROR_ABSENT_INFORMATION);
3282   }
3283 
3284   // The line number table is compressed so we don't know how big it is until decompressed.
3285   // Decompression is really fast so we just do it twice.
3286 
3287   // Compute size of table
3288   jint num_entries = 0;
3289   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
3290   while (stream.read_pair()) {
3291     num_entries++;
3292   }
3293   jvmtiLineNumberEntry *jvmti_table =
3294             (jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));
3295 
3296   // Fill jvmti table
3297   if (num_entries > 0) {
3298     int index = 0;
3299     CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
3300     while (stream.read_pair()) {
3301       jvmti_table[index].start_location = (jlocation) stream.bci();
3302       jvmti_table[index].line_number = (jint) stream.line();
3303       index++;
3304     }
3305     assert(index == num_entries, "sanity check");
3306   }
3307 
3308   // Set up results
3309   (*entry_count_ptr) = num_entries;
3310   (*table_ptr) = jvmti_table;
3311 
3312   return JVMTI_ERROR_NONE;
3313 } /* end GetLineNumberTable */
3314 
3315 
3316 // method - pre-checked for validity, but may be null meaning obsolete method
3317 // start_location_ptr - pre-checked for null
3318 // end_location_ptr - pre-checked for null
3319 jvmtiError
3320 JvmtiEnv::GetMethodLocation(Method* method, jlocation* start_location_ptr, jlocation* end_location_ptr) {
3321 
3322   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3323   // get start and end location
3324   (*end_location_ptr) = (jlocation) (method->code_size() - 1);
3325   if (method->code_size() == 0) {
3326     // there is no code so there is no start location
3327     (*start_location_ptr) = (jlocation)(-1);
3328   } else {
3329     (*start_location_ptr) = (jlocation)(0);
3330   }
3331 
3332   return JVMTI_ERROR_NONE;
3333 } /* end GetMethodLocation */
3334 
3335 
3336 // method - pre-checked for validity, but may be null meaning obsolete method
3337 // entry_count_ptr - pre-checked for null
3338 // table_ptr - pre-checked for null
3339 jvmtiError
3340 JvmtiEnv::GetLocalVariableTable(Method* method, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {
3341 
3342   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3343   JavaThread* current_thread  = JavaThread::current();
3344 
3345   // does the klass have any local variable information?
3346   InstanceKlass* ik = method->method_holder();
3347   if (!ik->has_localvariable_table()) {
3348     return (JVMTI_ERROR_ABSENT_INFORMATION);
3349   }
3350 
3351   ConstantPool* constants = method->constants();
3352   NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);
3353 
3354   // in the vm localvariable table representation, 6 consecutive elements in the table
3355   // represent a 6-tuple of shorts
3356   // [start_pc, length, name_index, descriptor_index, signature_index, index]
3357   jint num_entries = method->localvariable_table_length();
3358   jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)
3359                 jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));
3360 
3361   if (num_entries > 0) {
3362     LocalVariableTableElement* table = method->localvariable_table_start();
3363     for (int i = 0; i < num_entries; i++) {
3364       // get the 5 tuple information from the vm table
3365       jlocation start_location = (jlocation) table[i].start_bci;
3366       jint length = (jint) table[i].length;
3367       int name_index = (int) table[i].name_cp_index;
3368       int signature_index = (int) table[i].descriptor_cp_index;
3369       int generic_signature_index = (int) table[i].signature_cp_index;
3370       jint slot = (jint) table[i].slot;
3371 
3372       // get utf8 name and signature
3373       char *name_buf = nullptr;
3374       char *sig_buf = nullptr;
3375       char *gen_sig_buf = nullptr;
3376       {
3377         ResourceMark rm(current_thread);
3378 
3379         const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();
3380         name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);
3381         strcpy(name_buf, utf8_name);
3382 
3383         const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();
3384         sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);
3385         strcpy(sig_buf, utf8_signature);
3386 
3387         if (generic_signature_index > 0) {
3388           const char *utf8_gen_sign = (const char *)
3389                                        constants->symbol_at(generic_signature_index)->as_utf8();
3390           gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);
3391           strcpy(gen_sig_buf, utf8_gen_sign);
3392         }
3393       }
3394 
3395       // fill in the jvmti local variable table
3396       jvmti_table[i].start_location = start_location;
3397       jvmti_table[i].length = length;
3398       jvmti_table[i].name = name_buf;
3399       jvmti_table[i].signature = sig_buf;
3400       jvmti_table[i].generic_signature = gen_sig_buf;
3401       jvmti_table[i].slot = slot;
3402     }
3403   }
3404 
3405   // set results
3406   (*entry_count_ptr) = num_entries;
3407   (*table_ptr) = jvmti_table;
3408 
3409   return JVMTI_ERROR_NONE;
3410 } /* end GetLocalVariableTable */
3411 
3412 
3413 // method - pre-checked for validity, but may be null meaning obsolete method
3414 // bytecode_count_ptr - pre-checked for null
3415 // bytecodes_ptr - pre-checked for null
3416 jvmtiError
3417 JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
3418   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3419 
3420   methodHandle mh(Thread::current(), method);
3421   jint size = (jint)mh->code_size();
3422   jvmtiError err = allocate(size, bytecodes_ptr);
3423   if (err != JVMTI_ERROR_NONE) {
3424     return err;
3425   }
3426 
3427   (*bytecode_count_ptr) = size;
3428   // get byte codes
3429   JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);
3430 
3431   return JVMTI_ERROR_NONE;
3432 } /* end GetBytecodes */
3433 
3434 
3435 // method - pre-checked for validity, but may be null meaning obsolete method
3436 // is_native_ptr - pre-checked for null
3437 jvmtiError
3438 JvmtiEnv::IsMethodNative(Method* method, jboolean* is_native_ptr) {
3439   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3440   (*is_native_ptr) = method->is_native();
3441   return JVMTI_ERROR_NONE;
3442 } /* end IsMethodNative */
3443 
3444 
3445 // method - pre-checked for validity, but may be null meaning obsolete method
3446 // is_synthetic_ptr - pre-checked for null
3447 jvmtiError
3448 JvmtiEnv::IsMethodSynthetic(Method* method, jboolean* is_synthetic_ptr) {
3449   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3450   (*is_synthetic_ptr) = method->is_synthetic();
3451   return JVMTI_ERROR_NONE;
3452 } /* end IsMethodSynthetic */
3453 
3454 
3455 // method - pre-checked for validity, but may be null meaning obsolete method
3456 // is_obsolete_ptr - pre-checked for null
3457 jvmtiError
3458 JvmtiEnv::IsMethodObsolete(Method* method, jboolean* is_obsolete_ptr) {
3459   if (use_version_1_0_semantics() &&
3460       get_capabilities()->can_redefine_classes == 0) {
3461     // This JvmtiEnv requested version 1.0 semantics and this function
3462     // requires the can_redefine_classes capability in version 1.0 so
3463     // we need to return an error here.
3464     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3465   }
3466 
3467   if (method == nullptr || method->is_obsolete()) {
3468     *is_obsolete_ptr = true;
3469   } else {
3470     *is_obsolete_ptr = false;
3471   }
3472   return JVMTI_ERROR_NONE;
3473 } /* end IsMethodObsolete */
3474 
3475   //
3476   // Raw Monitor functions
3477   //
3478 
3479 // name - pre-checked for null
3480 // monitor_ptr - pre-checked for null
3481 jvmtiError
3482 JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
3483   JvmtiRawMonitor* rmonitor = new (std::nothrow) JvmtiRawMonitor(name);
3484   NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
3485 
3486   *monitor_ptr = (jrawMonitorID)rmonitor;
3487 
3488   return JVMTI_ERROR_NONE;
3489 } /* end CreateRawMonitor */
3490 
3491 
3492 // rmonitor - pre-checked for validity
3493 jvmtiError
3494 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
3495   if (Threads::number_of_threads() == 0) {
3496     // Remove this monitor from pending raw monitors list
3497     // if it has entered in onload or start phase.
3498     JvmtiPendingMonitors::destroy(rmonitor);
3499   } else {
3500     Thread* thread  = Thread::current();
3501     if (rmonitor->owner() == thread) {
3502       // The caller owns this monitor which we are about to destroy.
3503       // We exit the underlying synchronization object so that the
3504       // "delete monitor" call below can work without an assertion
3505       // failure on systems that don't like destroying synchronization
3506       // objects that are locked.
3507       int r;
3508       int recursion = rmonitor->recursions();
3509       for (int i = 0; i <= recursion; i++) {
3510         r = rmonitor->raw_exit(thread);
3511         assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
3512         if (r != JvmtiRawMonitor::M_OK) {  // robustness
3513           return JVMTI_ERROR_INTERNAL;
3514         }
3515       }
3516     }
3517     if (rmonitor->owner() != nullptr) {
3518       // The caller is trying to destroy a monitor that is locked by
3519       // someone else. While this is not forbidden by the JVMTI
3520       // spec, it will cause an assertion failure on systems that don't
3521       // like destroying synchronization objects that are locked.
3522       // We indicate a problem with the error return (and leak the
3523       // monitor's memory).
3524       return JVMTI_ERROR_NOT_MONITOR_OWNER;
3525     }
3526   }
3527 
3528   delete rmonitor;
3529 
3530   return JVMTI_ERROR_NONE;
3531 } /* end DestroyRawMonitor */
3532 
3533 
3534 // rmonitor - pre-checked for validity
3535 jvmtiError
3536 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
3537   if (Threads::number_of_threads() == 0) {
3538     // No JavaThreads exist so JvmtiRawMonitor enter cannot be
3539     // used, add this raw monitor to the pending list.
3540     // The pending monitors will be actually entered when
3541     // the VM is setup.
3542     // See transition_pending_raw_monitors in create_vm()
3543     // in thread.cpp.
3544     JvmtiPendingMonitors::enter(rmonitor);
3545   } else {
3546     Thread* thread = Thread::current();
3547     // 8266889: raw_enter changes Java thread state, needs WXWrite
3548     MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));
3549     rmonitor->raw_enter(thread);
3550   }
3551   return JVMTI_ERROR_NONE;
3552 } /* end RawMonitorEnter */
3553 
3554 
3555 // rmonitor - pre-checked for validity
3556 jvmtiError
3557 JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
3558   jvmtiError err = JVMTI_ERROR_NONE;
3559 
3560   if (Threads::number_of_threads() == 0) {
3561     // No JavaThreads exist so just remove this monitor from the pending list.
3562     // Bool value from exit is false if rmonitor is not in the list.
3563     if (!JvmtiPendingMonitors::exit(rmonitor)) {
3564       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3565     }
3566   } else {
3567     Thread* thread = Thread::current();
3568     int r = rmonitor->raw_exit(thread);
3569     if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3570       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3571     }
3572   }
3573   return err;
3574 } /* end RawMonitorExit */
3575 
3576 
3577 // rmonitor - pre-checked for validity
3578 jvmtiError
3579 JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
3580   Thread* thread = Thread::current();
3581   // 8266889: raw_wait changes Java thread state, needs WXWrite
3582   MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));
3583   int r = rmonitor->raw_wait(millis, thread);
3584 
3585   switch (r) {
3586   case JvmtiRawMonitor::M_INTERRUPTED:
3587     return JVMTI_ERROR_INTERRUPT;
3588   case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
3589     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3590   default:
3591     return JVMTI_ERROR_NONE;
3592   }
3593 } /* end RawMonitorWait */
3594 
3595 
3596 // rmonitor - pre-checked for validity
3597 jvmtiError
3598 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
3599   Thread* thread = Thread::current();
3600   int r = rmonitor->raw_notify(thread);
3601 
3602   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3603     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3604   }
3605   return JVMTI_ERROR_NONE;
3606 } /* end RawMonitorNotify */
3607 
3608 
3609 // rmonitor - pre-checked for validity
3610 jvmtiError
3611 JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
3612   Thread* thread = Thread::current();
3613   int r = rmonitor->raw_notifyAll(thread);
3614 
3615   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3616     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3617   }
3618   return JVMTI_ERROR_NONE;
3619 } /* end RawMonitorNotifyAll */
3620 
3621 
3622   //
3623   // JNI Function Interception functions
3624   //
3625 
3626 
3627 // function_table - pre-checked for null
3628 jvmtiError
3629 JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {
3630   // Copy jni function table at safepoint.
3631   VM_JNIFunctionTableCopier copier(function_table);
3632   VMThread::execute(&copier);
3633 
3634   return JVMTI_ERROR_NONE;
3635 } /* end SetJNIFunctionTable */
3636 
3637 
3638 // function_table - pre-checked for null
3639 jvmtiError
3640 JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
3641   *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));
3642   if (*function_table == nullptr)
3643     return JVMTI_ERROR_OUT_OF_MEMORY;
3644   memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
3645   return JVMTI_ERROR_NONE;
3646 } /* end GetJNIFunctionTable */
3647 
3648 
3649   //
3650   // Event Management functions
3651   //
3652 
3653 jvmtiError
3654 JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {
3655   // can only generate two event types
3656   if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&
3657       event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {
3658     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3659   }
3660 
3661   // for compiled_method_load events we must check that the environment
3662   // has the can_generate_compiled_method_load_events capability.
3663   if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {
3664     if (get_capabilities()->can_generate_compiled_method_load_events == 0) {
3665       return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3666     }
3667     return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);
3668   } else {
3669     return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);
3670   }
3671 
3672 } /* end GenerateEvents */
3673 
3674 
3675   //
3676   // Extension Mechanism functions
3677   //
3678 
3679 // extension_count_ptr - pre-checked for null
3680 // extensions - pre-checked for null
3681 jvmtiError
3682 JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {
3683   return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);
3684 } /* end GetExtensionFunctions */
3685 
3686 
3687 // extension_count_ptr - pre-checked for null
3688 // extensions - pre-checked for null
3689 jvmtiError
3690 JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {
3691   return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);
3692 } /* end GetExtensionEvents */
3693 
3694 
3695 // callback - null is a valid value, must be checked
3696 jvmtiError
3697 JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {
3698   return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);
3699 } /* end SetExtensionEventCallback */
3700 
3701   //
3702   // Timers functions
3703   //
3704 
3705 // info_ptr - pre-checked for null
3706 jvmtiError
3707 JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3708   os::current_thread_cpu_time_info(info_ptr);
3709   return JVMTI_ERROR_NONE;
3710 } /* end GetCurrentThreadCpuTimerInfo */
3711 
3712 
3713 // nanos_ptr - pre-checked for null
3714 jvmtiError
3715 JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {
3716   Thread* thread = Thread::current();
3717 
3718   // Surprisingly the GetCurrentThreadCpuTime is used by non-JavaThread's.
3719   if (thread->is_Java_thread()) {
3720     if (JavaThread::cast(thread)->is_vthread_mounted()) {
3721       // No support for a VirtualThread (yet).
3722       return JVMTI_ERROR_UNSUPPORTED_OPERATION;
3723     }
3724   }
3725   *nanos_ptr = os::current_thread_cpu_time();
3726   return JVMTI_ERROR_NONE;
3727 } /* end GetCurrentThreadCpuTime */
3728 
3729 
3730 // info_ptr - pre-checked for null
3731 jvmtiError
3732 JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3733   os::thread_cpu_time_info(info_ptr);
3734   return JVMTI_ERROR_NONE;
3735 } /* end GetThreadCpuTimerInfo */
3736 
3737 
3738 // nanos_ptr - pre-checked for null
3739 jvmtiError
3740 JvmtiEnv::GetThreadCpuTime(jthread thread, jlong* nanos_ptr) {
3741   JavaThread* current_thread = JavaThread::current();
3742   ThreadsListHandle tlh(current_thread);
3743   JavaThread* java_thread = nullptr;
3744   oop thread_oop = nullptr;
3745 
3746   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_oop);
3747 
3748   if (thread_oop != nullptr && thread_oop->is_a(vmClasses::BaseVirtualThread_klass())) {
3749     // No support for virtual threads (yet).
3750     return JVMTI_ERROR_UNSUPPORTED_OPERATION;
3751   }
3752   if (err != JVMTI_ERROR_NONE) {
3753     return err;
3754   }
3755   NULL_CHECK(nanos_ptr, JVMTI_ERROR_NULL_POINTER);
3756 
3757   *nanos_ptr = os::thread_cpu_time(java_thread);
3758   return JVMTI_ERROR_NONE;
3759 } /* end GetThreadCpuTime */
3760 
3761 
3762 // info_ptr - pre-checked for null
3763 jvmtiError
3764 JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {
3765   os::javaTimeNanos_info(info_ptr);
3766   return JVMTI_ERROR_NONE;
3767 } /* end GetTimerInfo */
3768 
3769 
3770 // nanos_ptr - pre-checked for null
3771 jvmtiError
3772 JvmtiEnv::GetTime(jlong* nanos_ptr) {
3773   *nanos_ptr = os::javaTimeNanos();
3774   return JVMTI_ERROR_NONE;
3775 } /* end GetTime */
3776 
3777 
3778 // processor_count_ptr - pre-checked for null
3779 jvmtiError
3780 JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
3781   *processor_count_ptr = os::active_processor_count();
3782   return JVMTI_ERROR_NONE;
3783 } /* end GetAvailableProcessors */
3784 
3785 jvmtiError
3786 JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
3787   if (sampling_interval < 0) {
3788     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3789   }
3790   ThreadHeapSampler::set_sampling_interval(sampling_interval);
3791   return JVMTI_ERROR_NONE;
3792 } /* end SetHeapSamplingInterval */
3793 
3794   //
3795   // System Properties functions
3796   //
3797 
3798 // count_ptr - pre-checked for null
3799 // property_ptr - pre-checked for null
3800 jvmtiError
3801 JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
3802   jvmtiError err = JVMTI_ERROR_NONE;
3803 
3804   // Get the number of readable properties.
3805   *count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());
3806 
3807   // Allocate memory to hold the exact number of readable properties.
3808   err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
3809   if (err != JVMTI_ERROR_NONE) {
3810     return err;
3811   }
3812   int readable_count = 0;
3813   // Loop through the system properties until all the readable properties are found.
3814   for (SystemProperty* p = Arguments::system_properties(); p != nullptr && readable_count < *count_ptr; p = p->next()) {
3815     if (p->readable()) {
3816       const char *key = p->key();
3817       char **tmp_value = *property_ptr+readable_count;
3818       readable_count++;
3819       err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
3820       if (err == JVMTI_ERROR_NONE) {
3821         strcpy(*tmp_value, key);
3822       } else {
3823         // clean up previously allocated memory.
3824         for (int j = 0; j < readable_count; j++) {
3825           Deallocate((unsigned char*)*property_ptr+j);
3826         }
3827         Deallocate((unsigned char*)property_ptr);
3828         break;
3829       }
3830     }
3831   }
3832   assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");
3833   return err;
3834 } /* end GetSystemProperties */
3835 
3836 
3837 // property - pre-checked for null
3838 // value_ptr - pre-checked for null
3839 jvmtiError
3840 JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
3841   jvmtiError err = JVMTI_ERROR_NONE;
3842   const char *value;
3843 
3844   // Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.
3845   value = Arguments::PropertyList_get_readable_value(Arguments::system_properties(), property);
3846   if (value == nullptr) {
3847     err =  JVMTI_ERROR_NOT_AVAILABLE;
3848   } else {
3849     err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr);
3850     if (err == JVMTI_ERROR_NONE) {
3851       strcpy(*value_ptr, value);
3852     }
3853   }
3854   return err;
3855 } /* end GetSystemProperty */
3856 
3857 
3858 // property - pre-checked for null
3859 // value - null is a valid value, must be checked
3860 jvmtiError
3861 JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
3862   for (SystemProperty* p = Arguments::system_properties(); p != nullptr; p = p->next()) {
3863     if (strcmp(property, p->key()) == 0) {
3864       if (p->writeable()) {
3865         if (p->set_value(value_ptr, AllocFailStrategy::RETURN_NULL)) {
3866           return JVMTI_ERROR_NONE;
3867         } else {
3868           return JVMTI_ERROR_OUT_OF_MEMORY;
3869         }
3870       } else {
3871         // We found a property, but it's not writeable
3872         return JVMTI_ERROR_NOT_AVAILABLE;
3873       }
3874     }
3875   }
3876 
3877   // We cannot find a property of the given name
3878   return JVMTI_ERROR_NOT_AVAILABLE;
3879 } /* end SetSystemProperty */