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/modules.hpp"
  27 #include "classfile/stringTable.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   *modifiers_ptr = result;
2730 
2731   return JVMTI_ERROR_NONE;
2732 } /* end GetClassModifiers */
2733 
2734 
2735 // k_mirror - may be primitive, this must be checked
2736 // method_count_ptr - pre-checked for null
2737 // methods_ptr - pre-checked for null
2738 jvmtiError
2739 JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {
2740   JavaThread* current_thread  = JavaThread::current();
2741   HandleMark hm(current_thread);
2742 
2743   if (java_lang_Class::is_primitive(k_mirror)) {
2744     *method_count_ptr = 0;
2745     *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2746     return JVMTI_ERROR_NONE;
2747   }
2748   Klass* k = java_lang_Class::as_Klass(k_mirror);
2749   NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2750 
2751   // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2752   if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2753     return JVMTI_ERROR_CLASS_NOT_PREPARED;
2754   }
2755 
2756   if (!k->is_instance_klass()) {
2757     *method_count_ptr = 0;
2758     *methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2759     return JVMTI_ERROR_NONE;
2760   }
2761   InstanceKlass* ik = InstanceKlass::cast(k);
2762   // Allocate the result and fill it in
2763   int result_length = ik->methods()->length();
2764   jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
2765   int index;
2766   int skipped = 0;  // skip overpass methods
2767 
2768   // Make jmethodIDs for all non-overpass methods.
2769   ik->make_methods_jmethod_ids();
2770 
2771   for (index = 0; index < result_length; index++) {
2772     Method* m = ik->methods()->at(index);
2773     // Depending on can_maintain_original_method_order capability use the original
2774     // method ordering indices stored in the class, so we can emit jmethodIDs in
2775     // the order they appeared in the class file or just copy in current order.
2776     int result_index = JvmtiExport::can_maintain_original_method_order() ? ik->method_ordering()->at(index) : index;
2777     assert(result_index >= 0 && result_index < result_length, "invalid original method index");
2778     if (m->is_overpass()) {
2779       result_list[result_index] = nullptr;
2780       skipped++;
2781       continue;
2782     }
2783     jmethodID id = m->find_jmethod_id_or_null();
2784     assert(id != nullptr, "should be created above");
2785     result_list[result_index] = id;
2786   }
2787 
2788   // Fill in return value.
2789   if (skipped > 0) {
2790     // copy results skipping null methodIDs
2791     *methods_ptr = (jmethodID*)jvmtiMalloc((result_length - skipped) * sizeof(jmethodID));
2792     *method_count_ptr = result_length - skipped;
2793     for (index = 0, skipped = 0; index < result_length; index++) {
2794       if (result_list[index] == nullptr) {
2795         skipped++;
2796       } else {
2797         (*methods_ptr)[index - skipped] = result_list[index];
2798       }
2799     }
2800     deallocate((unsigned char *)result_list);
2801   } else {
2802     *method_count_ptr = result_length;
2803     *methods_ptr = result_list;
2804   }
2805 
2806   return JVMTI_ERROR_NONE;
2807 } /* end GetClassMethods */
2808 
2809 
2810 // k_mirror - may be primitive, this must be checked
2811 // field_count_ptr - pre-checked for null
2812 // fields_ptr - pre-checked for null
2813 jvmtiError
2814 JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {
2815   if (java_lang_Class::is_primitive(k_mirror)) {
2816     *field_count_ptr = 0;
2817     *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2818     return JVMTI_ERROR_NONE;
2819   }
2820   JavaThread* current_thread = JavaThread::current();
2821   HandleMark hm(current_thread);
2822   Klass* k = java_lang_Class::as_Klass(k_mirror);
2823   NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2824 
2825   // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2826   if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2827     return JVMTI_ERROR_CLASS_NOT_PREPARED;
2828   }
2829 
2830   if (!k->is_instance_klass()) {
2831     *field_count_ptr = 0;
2832     *fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2833     return JVMTI_ERROR_NONE;
2834   }
2835 
2836   InstanceKlass* ik = InstanceKlass::cast(k);
2837 
2838   FilteredJavaFieldStream flds(ik);
2839 
2840   int result_count = flds.field_count();
2841 
2842   // Allocate the result and fill it in.
2843   jfieldID* result_list = (jfieldID*)jvmtiMalloc(result_count * sizeof(jfieldID));
2844   for (int i = 0; i < result_count; i++, flds.next()) {
2845     result_list[i] = jfieldIDWorkaround::to_jfieldID(ik, flds.offset(),
2846                                                      flds.access_flags().is_static(),
2847                                                      flds.field_descriptor().is_flat());
2848   }
2849   assert(flds.done(), "just checking");
2850 
2851   // Fill in the results
2852   *field_count_ptr = result_count;
2853   *fields_ptr = result_list;
2854 
2855   return JVMTI_ERROR_NONE;
2856 } /* end GetClassFields */
2857 
2858 
2859 // k_mirror - may be primitive, this must be checked
2860 // interface_count_ptr - pre-checked for null
2861 // interfaces_ptr - pre-checked for null
2862 jvmtiError
2863 JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {
2864   {
2865     if (java_lang_Class::is_primitive(k_mirror)) {
2866       *interface_count_ptr = 0;
2867       *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2868       return JVMTI_ERROR_NONE;
2869     }
2870     JavaThread* current_thread = JavaThread::current();
2871     HandleMark hm(current_thread);
2872     Klass* k = java_lang_Class::as_Klass(k_mirror);
2873     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2874 
2875     // Return CLASS_NOT_PREPARED error as per JVMTI spec.
2876     if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
2877       return JVMTI_ERROR_CLASS_NOT_PREPARED;
2878 
2879     if (!k->is_instance_klass()) {
2880       *interface_count_ptr = 0;
2881       *interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2882       return JVMTI_ERROR_NONE;
2883     }
2884 
2885     InstanceKlass* ik = InstanceKlass::cast(k);
2886     Array<InstanceKlass*>* interface_list = ik->local_interfaces();
2887     int result_length = (interface_list == nullptr ? 0 : interface_list->length());
2888     jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));
2889     for (int i_index = 0; i_index < result_length; i_index += 1) {
2890       InstanceKlass* klass_at = interface_list->at(i_index);
2891       assert(klass_at->is_klass(), "interfaces must be Klass*s");
2892       assert(klass_at->is_interface(), "interfaces must be interfaces");
2893       oop mirror_at = klass_at->java_mirror();
2894       Handle handle_at = Handle(current_thread, mirror_at);
2895       result_list[i_index] = (jclass) jni_reference(handle_at);
2896     }
2897     *interface_count_ptr = result_length;
2898     *interfaces_ptr = result_list;
2899   }
2900 
2901   return JVMTI_ERROR_NONE;
2902 } /* end GetImplementedInterfaces */
2903 
2904 
2905 // k_mirror - may be primitive, this must be checked
2906 // minor_version_ptr - pre-checked for null
2907 // major_version_ptr - pre-checked for null
2908 jvmtiError
2909 JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {
2910   if (java_lang_Class::is_primitive(k_mirror)) {
2911     return JVMTI_ERROR_ABSENT_INFORMATION;
2912   }
2913   Klass* klass = java_lang_Class::as_Klass(k_mirror);
2914 
2915   jint status = klass->jvmti_class_status();
2916   if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2917     return JVMTI_ERROR_INVALID_CLASS;
2918   }
2919   if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2920     return JVMTI_ERROR_ABSENT_INFORMATION;
2921   }
2922 
2923   InstanceKlass* ik = InstanceKlass::cast(klass);
2924   *minor_version_ptr = ik->minor_version();
2925   *major_version_ptr = ik->major_version();
2926 
2927   return JVMTI_ERROR_NONE;
2928 } /* end GetClassVersionNumbers */
2929 
2930 
2931 // k_mirror - may be primitive, this must be checked
2932 // constant_pool_count_ptr - pre-checked for null
2933 // constant_pool_byte_count_ptr - pre-checked for null
2934 // constant_pool_bytes_ptr - pre-checked for null
2935 jvmtiError
2936 JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {
2937   if (java_lang_Class::is_primitive(k_mirror)) {
2938     return JVMTI_ERROR_ABSENT_INFORMATION;
2939   }
2940 
2941   Klass* klass = java_lang_Class::as_Klass(k_mirror);
2942   Thread *thread = Thread::current();
2943   ResourceMark rm(thread);
2944 
2945   jint status = klass->jvmti_class_status();
2946   if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2947     return JVMTI_ERROR_INVALID_CLASS;
2948   }
2949   if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2950     return JVMTI_ERROR_ABSENT_INFORMATION;
2951   }
2952 
2953   InstanceKlass* ik = InstanceKlass::cast(klass);
2954   JvmtiConstantPoolReconstituter reconstituter(ik);
2955   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2956     return reconstituter.get_error();
2957   }
2958 
2959   unsigned char *cpool_bytes;
2960   int cpool_size = reconstituter.cpool_size();
2961   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2962     return reconstituter.get_error();
2963   }
2964   jvmtiError res = allocate(cpool_size, &cpool_bytes);
2965   if (res != JVMTI_ERROR_NONE) {
2966     return res;
2967   }
2968   reconstituter.copy_cpool_bytes(cpool_bytes);
2969   if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2970     return reconstituter.get_error();
2971   }
2972 
2973   constantPoolHandle  constants(thread, ik->constants());
2974   *constant_pool_count_ptr      = constants->length();
2975   *constant_pool_byte_count_ptr = cpool_size;
2976   *constant_pool_bytes_ptr      = cpool_bytes;
2977 
2978   return JVMTI_ERROR_NONE;
2979 } /* end GetConstantPool */
2980 
2981 
2982 // k_mirror - may be primitive, this must be checked
2983 // is_interface_ptr - pre-checked for null
2984 jvmtiError
2985 JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {
2986   {
2987     bool result = false;
2988     if (!java_lang_Class::is_primitive(k_mirror)) {
2989       Klass* k = java_lang_Class::as_Klass(k_mirror);
2990       if (k != nullptr && k->is_interface()) {
2991         result = true;
2992       }
2993     }
2994     *is_interface_ptr = result;
2995   }
2996 
2997   return JVMTI_ERROR_NONE;
2998 } /* end IsInterface */
2999 
3000 
3001 // k_mirror - may be primitive, this must be checked
3002 // is_array_class_ptr - pre-checked for null
3003 jvmtiError
3004 JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {
3005   {
3006     bool result = false;
3007     if (!java_lang_Class::is_primitive(k_mirror)) {
3008       Klass* k = java_lang_Class::as_Klass(k_mirror);
3009       if (k != nullptr && k->is_array_klass()) {
3010         result = true;
3011       }
3012     }
3013     *is_array_class_ptr = result;
3014   }
3015 
3016   return JVMTI_ERROR_NONE;
3017 } /* end IsArrayClass */
3018 
3019 
3020 // k_mirror - may be primitive, this must be checked
3021 // classloader_ptr - pre-checked for null
3022 jvmtiError
3023 JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {
3024   {
3025     if (java_lang_Class::is_primitive(k_mirror)) {
3026       *classloader_ptr = (jclass) jni_reference(Handle());
3027       return JVMTI_ERROR_NONE;
3028     }
3029     JavaThread* current_thread = JavaThread::current();
3030     HandleMark hm(current_thread);
3031     Klass* k = java_lang_Class::as_Klass(k_mirror);
3032     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
3033 
3034     oop result_oop = k->class_loader();
3035     if (result_oop == nullptr) {
3036       *classloader_ptr = (jclass) jni_reference(Handle());
3037       return JVMTI_ERROR_NONE;
3038     }
3039     Handle result_handle = Handle(current_thread, result_oop);
3040     jclass result_jnihandle = (jclass) jni_reference(result_handle);
3041     *classloader_ptr = result_jnihandle;
3042   }
3043   return JVMTI_ERROR_NONE;
3044 } /* end GetClassLoader */
3045 
3046 
3047 // k_mirror - may be primitive, this must be checked
3048 // source_debug_extension_ptr - pre-checked for null
3049 jvmtiError
3050 JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {
3051   {
3052     if (java_lang_Class::is_primitive(k_mirror)) {
3053       return JVMTI_ERROR_ABSENT_INFORMATION;
3054     }
3055     Klass* k = java_lang_Class::as_Klass(k_mirror);
3056     NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
3057     if (!k->is_instance_klass()) {
3058       return JVMTI_ERROR_ABSENT_INFORMATION;
3059     }
3060     const char* sde = InstanceKlass::cast(k)->source_debug_extension();
3061     NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
3062 
3063     {
3064       *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
3065       strcpy(*source_debug_extension_ptr, sde);
3066     }
3067   }
3068 
3069   return JVMTI_ERROR_NONE;
3070 } /* end GetSourceDebugExtension */
3071 
3072   //
3073   // Object functions
3074   //
3075 
3076 // hash_code_ptr - pre-checked for null
3077 jvmtiError
3078 JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {
3079   oop mirror = JNIHandles::resolve_external_guard(object);
3080   NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
3081   NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);
3082 
3083   if (mirror->is_inline_type()) {
3084     // For inline types, use the klass as a hash code.
3085     // TBD to improve this (see also JvmtiTagMapKey::get_hash for similar case).
3086     *hash_code_ptr = (jint)((int64_t)mirror->klass() >> 3);
3087   } else {
3088     *hash_code_ptr = (jint)mirror->identity_hash();
3089   }
3090   return JVMTI_ERROR_NONE;
3091 } /* end GetObjectHashCode */
3092 
3093 
3094 // info_ptr - pre-checked for null
3095 jvmtiError
3096 JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {
3097   // This needs to be performed at a safepoint to gather stable data
3098   // because monitor owner / waiters might not be suspended.
3099   VM_GetObjectMonitorUsage op(this, JavaThread::current(), object, info_ptr);
3100   VMThread::execute(&op);
3101   return op.result();
3102 } /* end GetObjectMonitorUsage */
3103 
3104 
3105   //
3106   // Field functions
3107   //
3108 
3109 // name_ptr - null is a valid value, must be checked
3110 // signature_ptr - null is a valid value, must be checked
3111 // generic_ptr - null is a valid value, must be checked
3112 jvmtiError
3113 JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {
3114   JavaThread* current_thread  = JavaThread::current();
3115   ResourceMark rm(current_thread);
3116   if (name_ptr == nullptr) {
3117     // just don't return the name
3118   } else {
3119     const char* fieldName = fdesc_ptr->name()->as_C_string();
3120     *name_ptr =  (char*) jvmtiMalloc(strlen(fieldName) + 1);
3121     if (*name_ptr == nullptr)
3122       return JVMTI_ERROR_OUT_OF_MEMORY;
3123     strcpy(*name_ptr, fieldName);
3124   }
3125   if (signature_ptr== nullptr) {
3126     // just don't return the signature
3127   } else {
3128     const char* fieldSignature = fdesc_ptr->signature()->as_C_string();
3129     *signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1);
3130     if (*signature_ptr == nullptr)
3131       return JVMTI_ERROR_OUT_OF_MEMORY;
3132     strcpy(*signature_ptr, fieldSignature);
3133   }
3134   if (generic_ptr != nullptr) {
3135     *generic_ptr = nullptr;
3136     Symbol* soop = fdesc_ptr->generic_signature();
3137     if (soop != nullptr) {
3138       const char* gen_sig = soop->as_C_string();
3139       if (gen_sig != nullptr) {
3140         jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
3141         if (err != JVMTI_ERROR_NONE) {
3142           return err;
3143         }
3144         strcpy(*generic_ptr, gen_sig);
3145       }
3146     }
3147   }
3148   return JVMTI_ERROR_NONE;
3149 } /* end GetFieldName */
3150 
3151 
3152 // declaring_class_ptr - pre-checked for null
3153 jvmtiError
3154 JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {
3155   // As for the GetFieldDeclaringClass method, the XSL generated C++ code that calls it has
3156   // a jclass of the relevant class or a subclass of it, which is fine in terms of ensuring
3157   // the holder is kept alive.
3158   *declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder());
3159   return JVMTI_ERROR_NONE;
3160 } /* end GetFieldDeclaringClass */
3161 
3162 
3163 // modifiers_ptr - pre-checked for null
3164 jvmtiError
3165 JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {
3166 
3167   AccessFlags resultFlags = fdesc_ptr->access_flags();
3168   jint result = resultFlags.as_field_flags();
3169   *modifiers_ptr = result;
3170 
3171   return JVMTI_ERROR_NONE;
3172 } /* end GetFieldModifiers */
3173 
3174 
3175 // is_synthetic_ptr - pre-checked for null
3176 jvmtiError
3177 JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {
3178   *is_synthetic_ptr = fdesc_ptr->is_synthetic();
3179   return JVMTI_ERROR_NONE;
3180 } /* end IsFieldSynthetic */
3181 
3182 
3183   //
3184   // Method functions
3185   //
3186 
3187 // method - pre-checked for validity, but may be null meaning obsolete method
3188 // name_ptr - null is a valid value, must be checked
3189 // signature_ptr - null is a valid value, must be checked
3190 // generic_ptr - null is a valid value, must be checked
3191 jvmtiError
3192 JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, char** generic_ptr) {
3193   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3194   JavaThread* current_thread  = JavaThread::current();
3195 
3196   ResourceMark rm(current_thread); // get the utf8 name and signature
3197   if (name_ptr == nullptr) {
3198     // just don't return the name
3199   } else {
3200     const char* utf8_name = (const char *) method->name()->as_utf8();
3201     *name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1);
3202     strcpy(*name_ptr, utf8_name);
3203   }
3204   if (signature_ptr == nullptr) {
3205     // just don't return the signature
3206   } else {
3207     const char* utf8_signature = (const char *) method->signature()->as_utf8();
3208     *signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1);
3209     strcpy(*signature_ptr, utf8_signature);
3210   }
3211 
3212   if (generic_ptr != nullptr) {
3213     *generic_ptr = nullptr;
3214     Symbol* soop = method->generic_signature();
3215     if (soop != nullptr) {
3216       const char* gen_sig = soop->as_C_string();
3217       if (gen_sig != nullptr) {
3218         jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
3219         if (err != JVMTI_ERROR_NONE) {
3220           return err;
3221         }
3222         strcpy(*generic_ptr, gen_sig);
3223       }
3224     }
3225   }
3226   return JVMTI_ERROR_NONE;
3227 } /* end GetMethodName */
3228 
3229 
3230 // method - pre-checked for validity, but may be null meaning obsolete method
3231 // declaring_class_ptr - pre-checked for null
3232 jvmtiError
3233 JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) {
3234   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3235   Klass* k = method->method_holder();
3236   Handle holder(Thread::current(), k->klass_holder()); // keep the klass alive
3237   (*declaring_class_ptr) = get_jni_class_non_null(k);
3238   return JVMTI_ERROR_NONE;
3239 } /* end GetMethodDeclaringClass */
3240 
3241 
3242 // method - pre-checked for validity, but may be null meaning obsolete method
3243 // modifiers_ptr - pre-checked for null
3244 jvmtiError
3245 JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) {
3246   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3247   (*modifiers_ptr) = method->access_flags().as_method_flags();
3248   return JVMTI_ERROR_NONE;
3249 } /* end GetMethodModifiers */
3250 
3251 
3252 // method - pre-checked for validity, but may be null meaning obsolete method
3253 // max_ptr - pre-checked for null
3254 jvmtiError
3255 JvmtiEnv::GetMaxLocals(Method* method, jint* max_ptr) {
3256   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3257   // get max stack
3258   (*max_ptr) = method->max_locals();
3259   return JVMTI_ERROR_NONE;
3260 } /* end GetMaxLocals */
3261 
3262 
3263 // method - pre-checked for validity, but may be null meaning obsolete method
3264 // size_ptr - pre-checked for null
3265 jvmtiError
3266 JvmtiEnv::GetArgumentsSize(Method* method, jint* size_ptr) {
3267   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3268   // get size of arguments
3269 
3270   (*size_ptr) = method->size_of_parameters();
3271   return JVMTI_ERROR_NONE;
3272 } /* end GetArgumentsSize */
3273 
3274 
3275 // method - pre-checked for validity, but may be null meaning obsolete method
3276 // entry_count_ptr - pre-checked for null
3277 // table_ptr - pre-checked for null
3278 jvmtiError
3279 JvmtiEnv::GetLineNumberTable(Method* method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {
3280   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3281   if (!method->has_linenumber_table()) {
3282     return (JVMTI_ERROR_ABSENT_INFORMATION);
3283   }
3284 
3285   // The line number table is compressed so we don't know how big it is until decompressed.
3286   // Decompression is really fast so we just do it twice.
3287 
3288   // Compute size of table
3289   jint num_entries = 0;
3290   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
3291   while (stream.read_pair()) {
3292     num_entries++;
3293   }
3294   jvmtiLineNumberEntry *jvmti_table =
3295             (jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));
3296 
3297   // Fill jvmti table
3298   if (num_entries > 0) {
3299     int index = 0;
3300     CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
3301     while (stream.read_pair()) {
3302       jvmti_table[index].start_location = (jlocation) stream.bci();
3303       jvmti_table[index].line_number = (jint) stream.line();
3304       index++;
3305     }
3306     assert(index == num_entries, "sanity check");
3307   }
3308 
3309   // Set up results
3310   (*entry_count_ptr) = num_entries;
3311   (*table_ptr) = jvmti_table;
3312 
3313   return JVMTI_ERROR_NONE;
3314 } /* end GetLineNumberTable */
3315 
3316 
3317 // method - pre-checked for validity, but may be null meaning obsolete method
3318 // start_location_ptr - pre-checked for null
3319 // end_location_ptr - pre-checked for null
3320 jvmtiError
3321 JvmtiEnv::GetMethodLocation(Method* method, jlocation* start_location_ptr, jlocation* end_location_ptr) {
3322 
3323   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3324   // get start and end location
3325   (*end_location_ptr) = (jlocation) (method->code_size() - 1);
3326   if (method->code_size() == 0) {
3327     // there is no code so there is no start location
3328     (*start_location_ptr) = (jlocation)(-1);
3329   } else {
3330     (*start_location_ptr) = (jlocation)(0);
3331   }
3332 
3333   return JVMTI_ERROR_NONE;
3334 } /* end GetMethodLocation */
3335 
3336 
3337 // method - pre-checked for validity, but may be null meaning obsolete method
3338 // entry_count_ptr - pre-checked for null
3339 // table_ptr - pre-checked for null
3340 jvmtiError
3341 JvmtiEnv::GetLocalVariableTable(Method* method, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {
3342 
3343   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3344   JavaThread* current_thread  = JavaThread::current();
3345 
3346   // does the klass have any local variable information?
3347   InstanceKlass* ik = method->method_holder();
3348   if (!ik->has_localvariable_table()) {
3349     return (JVMTI_ERROR_ABSENT_INFORMATION);
3350   }
3351 
3352   ConstantPool* constants = method->constants();
3353   NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);
3354 
3355   // in the vm localvariable table representation, 6 consecutive elements in the table
3356   // represent a 6-tuple of shorts
3357   // [start_pc, length, name_index, descriptor_index, signature_index, index]
3358   jint num_entries = method->localvariable_table_length();
3359   jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)
3360                 jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));
3361 
3362   if (num_entries > 0) {
3363     LocalVariableTableElement* table = method->localvariable_table_start();
3364     for (int i = 0; i < num_entries; i++) {
3365       // get the 5 tuple information from the vm table
3366       jlocation start_location = (jlocation) table[i].start_bci;
3367       jint length = (jint) table[i].length;
3368       int name_index = (int) table[i].name_cp_index;
3369       int signature_index = (int) table[i].descriptor_cp_index;
3370       int generic_signature_index = (int) table[i].signature_cp_index;
3371       jint slot = (jint) table[i].slot;
3372 
3373       // get utf8 name and signature
3374       char *name_buf = nullptr;
3375       char *sig_buf = nullptr;
3376       char *gen_sig_buf = nullptr;
3377       {
3378         ResourceMark rm(current_thread);
3379 
3380         const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();
3381         name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);
3382         strcpy(name_buf, utf8_name);
3383 
3384         const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();
3385         sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);
3386         strcpy(sig_buf, utf8_signature);
3387 
3388         if (generic_signature_index > 0) {
3389           const char *utf8_gen_sign = (const char *)
3390                                        constants->symbol_at(generic_signature_index)->as_utf8();
3391           gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);
3392           strcpy(gen_sig_buf, utf8_gen_sign);
3393         }
3394       }
3395 
3396       // fill in the jvmti local variable table
3397       jvmti_table[i].start_location = start_location;
3398       jvmti_table[i].length = length;
3399       jvmti_table[i].name = name_buf;
3400       jvmti_table[i].signature = sig_buf;
3401       jvmti_table[i].generic_signature = gen_sig_buf;
3402       jvmti_table[i].slot = slot;
3403     }
3404   }
3405 
3406   // set results
3407   (*entry_count_ptr) = num_entries;
3408   (*table_ptr) = jvmti_table;
3409 
3410   return JVMTI_ERROR_NONE;
3411 } /* end GetLocalVariableTable */
3412 
3413 
3414 // method - pre-checked for validity, but may be null meaning obsolete method
3415 // bytecode_count_ptr - pre-checked for null
3416 // bytecodes_ptr - pre-checked for null
3417 jvmtiError
3418 JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
3419   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3420 
3421   methodHandle mh(Thread::current(), method);
3422   jint size = (jint)mh->code_size();
3423   jvmtiError err = allocate(size, bytecodes_ptr);
3424   if (err != JVMTI_ERROR_NONE) {
3425     return err;
3426   }
3427 
3428   (*bytecode_count_ptr) = size;
3429   // get byte codes
3430   JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);
3431 
3432   return JVMTI_ERROR_NONE;
3433 } /* end GetBytecodes */
3434 
3435 
3436 // method - pre-checked for validity, but may be null meaning obsolete method
3437 // is_native_ptr - pre-checked for null
3438 jvmtiError
3439 JvmtiEnv::IsMethodNative(Method* method, jboolean* is_native_ptr) {
3440   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3441   (*is_native_ptr) = method->is_native();
3442   return JVMTI_ERROR_NONE;
3443 } /* end IsMethodNative */
3444 
3445 
3446 // method - pre-checked for validity, but may be null meaning obsolete method
3447 // is_synthetic_ptr - pre-checked for null
3448 jvmtiError
3449 JvmtiEnv::IsMethodSynthetic(Method* method, jboolean* is_synthetic_ptr) {
3450   NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3451   (*is_synthetic_ptr) = method->is_synthetic();
3452   return JVMTI_ERROR_NONE;
3453 } /* end IsMethodSynthetic */
3454 
3455 
3456 // method - pre-checked for validity, but may be null meaning obsolete method
3457 // is_obsolete_ptr - pre-checked for null
3458 jvmtiError
3459 JvmtiEnv::IsMethodObsolete(Method* method, jboolean* is_obsolete_ptr) {
3460   if (use_version_1_0_semantics() &&
3461       get_capabilities()->can_redefine_classes == 0) {
3462     // This JvmtiEnv requested version 1.0 semantics and this function
3463     // requires the can_redefine_classes capability in version 1.0 so
3464     // we need to return an error here.
3465     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3466   }
3467 
3468   if (method == nullptr || method->is_obsolete()) {
3469     *is_obsolete_ptr = true;
3470   } else {
3471     *is_obsolete_ptr = false;
3472   }
3473   return JVMTI_ERROR_NONE;
3474 } /* end IsMethodObsolete */
3475 
3476   //
3477   // Raw Monitor functions
3478   //
3479 
3480 // name - pre-checked for null
3481 // monitor_ptr - pre-checked for null
3482 jvmtiError
3483 JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
3484   JvmtiRawMonitor* rmonitor = new (std::nothrow) JvmtiRawMonitor(name);
3485   NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
3486 
3487   *monitor_ptr = (jrawMonitorID)rmonitor;
3488 
3489   return JVMTI_ERROR_NONE;
3490 } /* end CreateRawMonitor */
3491 
3492 
3493 // rmonitor - pre-checked for validity
3494 jvmtiError
3495 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
3496   if (Threads::number_of_threads() == 0) {
3497     // Remove this monitor from pending raw monitors list
3498     // if it has entered in onload or start phase.
3499     JvmtiPendingMonitors::destroy(rmonitor);
3500   } else {
3501     Thread* thread  = Thread::current();
3502     if (rmonitor->owner() == thread) {
3503       // The caller owns this monitor which we are about to destroy.
3504       // We exit the underlying synchronization object so that the
3505       // "delete monitor" call below can work without an assertion
3506       // failure on systems that don't like destroying synchronization
3507       // objects that are locked.
3508       int r;
3509       int recursion = rmonitor->recursions();
3510       for (int i = 0; i <= recursion; i++) {
3511         r = rmonitor->raw_exit(thread);
3512         assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
3513         if (r != JvmtiRawMonitor::M_OK) {  // robustness
3514           return JVMTI_ERROR_INTERNAL;
3515         }
3516       }
3517     }
3518     if (rmonitor->owner() != nullptr) {
3519       // The caller is trying to destroy a monitor that is locked by
3520       // someone else. While this is not forbidden by the JVMTI
3521       // spec, it will cause an assertion failure on systems that don't
3522       // like destroying synchronization objects that are locked.
3523       // We indicate a problem with the error return (and leak the
3524       // monitor's memory).
3525       return JVMTI_ERROR_NOT_MONITOR_OWNER;
3526     }
3527   }
3528 
3529   delete rmonitor;
3530 
3531   return JVMTI_ERROR_NONE;
3532 } /* end DestroyRawMonitor */
3533 
3534 
3535 // rmonitor - pre-checked for validity
3536 jvmtiError
3537 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
3538   if (Threads::number_of_threads() == 0) {
3539     // No JavaThreads exist so JvmtiRawMonitor enter cannot be
3540     // used, add this raw monitor to the pending list.
3541     // The pending monitors will be actually entered when
3542     // the VM is setup.
3543     // See transition_pending_raw_monitors in create_vm()
3544     // in thread.cpp.
3545     JvmtiPendingMonitors::enter(rmonitor);
3546   } else {
3547     Thread* thread = Thread::current();
3548     // 8266889: raw_enter changes Java thread state, needs WXWrite
3549     MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));
3550     rmonitor->raw_enter(thread);
3551   }
3552   return JVMTI_ERROR_NONE;
3553 } /* end RawMonitorEnter */
3554 
3555 
3556 // rmonitor - pre-checked for validity
3557 jvmtiError
3558 JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
3559   jvmtiError err = JVMTI_ERROR_NONE;
3560 
3561   if (Threads::number_of_threads() == 0) {
3562     // No JavaThreads exist so just remove this monitor from the pending list.
3563     // Bool value from exit is false if rmonitor is not in the list.
3564     if (!JvmtiPendingMonitors::exit(rmonitor)) {
3565       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3566     }
3567   } else {
3568     Thread* thread = Thread::current();
3569     int r = rmonitor->raw_exit(thread);
3570     if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3571       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3572     }
3573   }
3574   return err;
3575 } /* end RawMonitorExit */
3576 
3577 
3578 // rmonitor - pre-checked for validity
3579 jvmtiError
3580 JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
3581   Thread* thread = Thread::current();
3582   // 8266889: raw_wait changes Java thread state, needs WXWrite
3583   MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));
3584   int r = rmonitor->raw_wait(millis, thread);
3585 
3586   switch (r) {
3587   case JvmtiRawMonitor::M_INTERRUPTED:
3588     return JVMTI_ERROR_INTERRUPT;
3589   case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
3590     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3591   default:
3592     return JVMTI_ERROR_NONE;
3593   }
3594 } /* end RawMonitorWait */
3595 
3596 
3597 // rmonitor - pre-checked for validity
3598 jvmtiError
3599 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
3600   Thread* thread = Thread::current();
3601   int r = rmonitor->raw_notify(thread);
3602 
3603   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3604     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3605   }
3606   return JVMTI_ERROR_NONE;
3607 } /* end RawMonitorNotify */
3608 
3609 
3610 // rmonitor - pre-checked for validity
3611 jvmtiError
3612 JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
3613   Thread* thread = Thread::current();
3614   int r = rmonitor->raw_notifyAll(thread);
3615 
3616   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3617     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3618   }
3619   return JVMTI_ERROR_NONE;
3620 } /* end RawMonitorNotifyAll */
3621 
3622 
3623   //
3624   // JNI Function Interception functions
3625   //
3626 
3627 
3628 // function_table - pre-checked for null
3629 jvmtiError
3630 JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {
3631   // Copy jni function table at safepoint.
3632   VM_JNIFunctionTableCopier copier(function_table);
3633   VMThread::execute(&copier);
3634 
3635   return JVMTI_ERROR_NONE;
3636 } /* end SetJNIFunctionTable */
3637 
3638 
3639 // function_table - pre-checked for null
3640 jvmtiError
3641 JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
3642   *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));
3643   if (*function_table == nullptr)
3644     return JVMTI_ERROR_OUT_OF_MEMORY;
3645   memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
3646   return JVMTI_ERROR_NONE;
3647 } /* end GetJNIFunctionTable */
3648 
3649 
3650   //
3651   // Event Management functions
3652   //
3653 
3654 jvmtiError
3655 JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {
3656   // can only generate two event types
3657   if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&
3658       event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {
3659     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3660   }
3661 
3662   // for compiled_method_load events we must check that the environment
3663   // has the can_generate_compiled_method_load_events capability.
3664   if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {
3665     if (get_capabilities()->can_generate_compiled_method_load_events == 0) {
3666       return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3667     }
3668     return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);
3669   } else {
3670     return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);
3671   }
3672 
3673 } /* end GenerateEvents */
3674 
3675 
3676   //
3677   // Extension Mechanism functions
3678   //
3679 
3680 // extension_count_ptr - pre-checked for null
3681 // extensions - pre-checked for null
3682 jvmtiError
3683 JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {
3684   return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);
3685 } /* end GetExtensionFunctions */
3686 
3687 
3688 // extension_count_ptr - pre-checked for null
3689 // extensions - pre-checked for null
3690 jvmtiError
3691 JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {
3692   return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);
3693 } /* end GetExtensionEvents */
3694 
3695 
3696 // callback - null is a valid value, must be checked
3697 jvmtiError
3698 JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {
3699   return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);
3700 } /* end SetExtensionEventCallback */
3701 
3702   //
3703   // Timers functions
3704   //
3705 
3706 // info_ptr - pre-checked for null
3707 jvmtiError
3708 JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3709   os::current_thread_cpu_time_info(info_ptr);
3710   return JVMTI_ERROR_NONE;
3711 } /* end GetCurrentThreadCpuTimerInfo */
3712 
3713 
3714 // nanos_ptr - pre-checked for null
3715 jvmtiError
3716 JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {
3717   Thread* thread = Thread::current();
3718 
3719   // Surprisingly the GetCurrentThreadCpuTime is used by non-JavaThread's.
3720   if (thread->is_Java_thread()) {
3721     if (JavaThread::cast(thread)->is_vthread_mounted()) {
3722       // No support for a VirtualThread (yet).
3723       return JVMTI_ERROR_UNSUPPORTED_OPERATION;
3724     }
3725   }
3726   *nanos_ptr = os::current_thread_cpu_time();
3727   return JVMTI_ERROR_NONE;
3728 } /* end GetCurrentThreadCpuTime */
3729 
3730 
3731 // info_ptr - pre-checked for null
3732 jvmtiError
3733 JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3734   os::thread_cpu_time_info(info_ptr);
3735   return JVMTI_ERROR_NONE;
3736 } /* end GetThreadCpuTimerInfo */
3737 
3738 
3739 // nanos_ptr - pre-checked for null
3740 jvmtiError
3741 JvmtiEnv::GetThreadCpuTime(jthread thread, jlong* nanos_ptr) {
3742   JavaThread* current_thread = JavaThread::current();
3743   ThreadsListHandle tlh(current_thread);
3744   JavaThread* java_thread = nullptr;
3745   oop thread_oop = nullptr;
3746 
3747   jvmtiError err = get_threadOop_and_JavaThread(tlh.list(), thread, current_thread, &java_thread, &thread_oop);
3748 
3749   if (thread_oop != nullptr && thread_oop->is_a(vmClasses::BaseVirtualThread_klass())) {
3750     // No support for virtual threads (yet).
3751     return JVMTI_ERROR_UNSUPPORTED_OPERATION;
3752   }
3753   if (err != JVMTI_ERROR_NONE) {
3754     return err;
3755   }
3756   NULL_CHECK(nanos_ptr, JVMTI_ERROR_NULL_POINTER);
3757 
3758   *nanos_ptr = os::thread_cpu_time(java_thread);
3759   return JVMTI_ERROR_NONE;
3760 } /* end GetThreadCpuTime */
3761 
3762 
3763 // info_ptr - pre-checked for null
3764 jvmtiError
3765 JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {
3766   os::javaTimeNanos_info(info_ptr);
3767   return JVMTI_ERROR_NONE;
3768 } /* end GetTimerInfo */
3769 
3770 
3771 // nanos_ptr - pre-checked for null
3772 jvmtiError
3773 JvmtiEnv::GetTime(jlong* nanos_ptr) {
3774   *nanos_ptr = os::javaTimeNanos();
3775   return JVMTI_ERROR_NONE;
3776 } /* end GetTime */
3777 
3778 
3779 // processor_count_ptr - pre-checked for null
3780 jvmtiError
3781 JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
3782   *processor_count_ptr = os::active_processor_count();
3783   return JVMTI_ERROR_NONE;
3784 } /* end GetAvailableProcessors */
3785 
3786 jvmtiError
3787 JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
3788   if (sampling_interval < 0) {
3789     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3790   }
3791   ThreadHeapSampler::set_sampling_interval(sampling_interval);
3792   return JVMTI_ERROR_NONE;
3793 } /* end SetHeapSamplingInterval */
3794 
3795   //
3796   // System Properties functions
3797   //
3798 
3799 // count_ptr - pre-checked for null
3800 // property_ptr - pre-checked for null
3801 jvmtiError
3802 JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
3803   jvmtiError err = JVMTI_ERROR_NONE;
3804 
3805   // Get the number of readable properties.
3806   *count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());
3807 
3808   // Allocate memory to hold the exact number of readable properties.
3809   err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
3810   if (err != JVMTI_ERROR_NONE) {
3811     return err;
3812   }
3813   int readable_count = 0;
3814   // Loop through the system properties until all the readable properties are found.
3815   for (SystemProperty* p = Arguments::system_properties(); p != nullptr && readable_count < *count_ptr; p = p->next()) {
3816     if (p->readable()) {
3817       const char *key = p->key();
3818       char **tmp_value = *property_ptr+readable_count;
3819       readable_count++;
3820       err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
3821       if (err == JVMTI_ERROR_NONE) {
3822         strcpy(*tmp_value, key);
3823       } else {
3824         // clean up previously allocated memory.
3825         for (int j = 0; j < readable_count; j++) {
3826           Deallocate((unsigned char*)*property_ptr+j);
3827         }
3828         Deallocate((unsigned char*)property_ptr);
3829         break;
3830       }
3831     }
3832   }
3833   assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");
3834   return err;
3835 } /* end GetSystemProperties */
3836 
3837 
3838 // property - pre-checked for null
3839 // value_ptr - pre-checked for null
3840 jvmtiError
3841 JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
3842   jvmtiError err = JVMTI_ERROR_NONE;
3843   const char *value;
3844 
3845   // Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.
3846   value = Arguments::PropertyList_get_readable_value(Arguments::system_properties(), property);
3847   if (value == nullptr) {
3848     err =  JVMTI_ERROR_NOT_AVAILABLE;
3849   } else {
3850     err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr);
3851     if (err == JVMTI_ERROR_NONE) {
3852       strcpy(*value_ptr, value);
3853     }
3854   }
3855   return err;
3856 } /* end GetSystemProperty */
3857 
3858 
3859 // property - pre-checked for null
3860 // value - null is a valid value, must be checked
3861 jvmtiError
3862 JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
3863   for (SystemProperty* p = Arguments::system_properties(); p != nullptr; p = p->next()) {
3864     if (strcmp(property, p->key()) == 0) {
3865       if (p->writeable()) {
3866         if (p->set_value(value_ptr, AllocFailStrategy::RETURN_NULL)) {
3867           return JVMTI_ERROR_NONE;
3868         } else {
3869           return JVMTI_ERROR_OUT_OF_MEMORY;
3870         }
3871       } else {
3872         // We found a property, but it's not writeable
3873         return JVMTI_ERROR_NOT_AVAILABLE;
3874       }
3875     }
3876   }
3877 
3878   // We cannot find a property of the given name
3879   return JVMTI_ERROR_NOT_AVAILABLE;
3880 } /* end SetSystemProperty */