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