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