1 /* 2 * Copyright (c) 2016, 2018, 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 "jni.h" 27 #include "classfile/javaClasses.hpp" 28 #include "classfile/symbolTable.hpp" 29 #include "classfile/systemDictionary.hpp" 30 #include "classfile/vmSymbols.hpp" 31 #include "jfr/jni/jfrJavaCall.hpp" 32 #include "jfr/jni/jfrJavaSupport.hpp" 33 #include "jfr/support/jfrThreadId.hpp" 34 #include "memory/resourceArea.hpp" 35 #include "oops/instanceOop.hpp" 36 #include "oops/oop.inline.hpp" 37 #include "oops/objArrayKlass.hpp" 38 #include "oops/objArrayOop.hpp" 39 #include "runtime/handles.inline.hpp" 40 #include "runtime/fieldDescriptor.hpp" 41 #include "runtime/java.hpp" 42 #include "runtime/jniHandles.hpp" 43 #include "runtime/synchronizer.hpp" 44 #include "runtime/thread.inline.hpp" 45 //#include "runtime/threadSMR.hpp" 46 47 #ifdef ASSERT 48 void JfrJavaSupport::check_java_thread_in_vm(Thread* t) { 49 assert(t != NULL, "invariant"); 50 assert(t->is_Java_thread(), "invariant"); 51 assert(((JavaThread*)t)->thread_state() == _thread_in_vm, "invariant"); 52 } 53 54 void JfrJavaSupport::check_java_thread_in_native(Thread* t) { 55 assert(t != NULL, "invariant"); 56 assert(t->is_Java_thread(), "invariant"); 57 assert(((JavaThread*)t)->thread_state() == _thread_in_native, "invariant"); 58 } 59 #endif 60 61 /* 62 * Handles and references 63 */ 64 jobject JfrJavaSupport::local_jni_handle(const oop obj, Thread* t) { 65 DEBUG_ONLY(check_java_thread_in_vm(t)); 66 return t->active_handles()->allocate_handle(obj); 67 } 68 69 jobject JfrJavaSupport::local_jni_handle(const jobject handle, Thread* t) { 70 DEBUG_ONLY(check_java_thread_in_vm(t)); 71 const oop obj = JNIHandles::resolve(handle); 72 return obj == NULL ? NULL : local_jni_handle(obj, t); 73 } 74 75 void JfrJavaSupport::destroy_local_jni_handle(jobject handle) { 76 JNIHandles::destroy_local(handle); 77 } 78 79 jobject JfrJavaSupport::global_jni_handle(const oop obj, Thread* t) { 80 DEBUG_ONLY(check_java_thread_in_vm(t)); 81 HandleMark hm(t); 82 return JNIHandles::make_global(Handle(t, obj)); 83 } 84 85 jobject JfrJavaSupport::global_jni_handle(const jobject handle, Thread* t) { 86 const oop obj = JNIHandles::resolve(handle); 87 return obj == NULL ? NULL : global_jni_handle(obj, t); 88 } 89 90 void JfrJavaSupport::destroy_global_jni_handle(const jobject handle) { 91 JNIHandles::destroy_global(handle); 92 } 93 94 oop JfrJavaSupport::resolve_non_null(jobject obj) { 95 return JNIHandles::resolve_non_null(obj); 96 } 97 98 /* 99 * Method invocation 100 */ 101 void JfrJavaSupport::call_static(JfrJavaArguments* args, TRAPS) { 102 JfrJavaCall::call_static(args, THREAD); 103 } 104 105 void JfrJavaSupport::call_special(JfrJavaArguments* args, TRAPS) { 106 JfrJavaCall::call_special(args, THREAD); 107 } 108 109 void JfrJavaSupport::call_virtual(JfrJavaArguments* args, TRAPS) { 110 JfrJavaCall::call_virtual(args, THREAD); 111 } 112 113 void JfrJavaSupport::notify_all(jobject object, TRAPS) { 114 assert(object != NULL, "invariant"); 115 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 116 HandleMark hm(THREAD); 117 Handle h_obj(THREAD, resolve_non_null(object)); 118 assert(h_obj.not_null(), "invariant"); 119 ObjectSynchronizer::jni_enter(h_obj, THREAD); 120 ObjectSynchronizer::notifyall(h_obj, THREAD); 121 ObjectSynchronizer::jni_exit(h_obj(), THREAD); 122 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 123 } 124 125 /* 126 * Object construction 127 */ 128 static void object_construction(JfrJavaArguments* args, JavaValue* result, InstanceKlass* klass, TRAPS) { 129 assert(args != NULL, "invariant"); 130 assert(result != NULL, "invariant"); 131 assert(klass != NULL, "invariant"); 132 assert(klass->is_initialized(), "invariant"); 133 134 HandleMark hm(THREAD); 135 instanceOop obj = klass->allocate_instance(CHECK); 136 instanceHandle h_obj(THREAD, obj); 137 assert(h_obj.not_null(), "invariant"); 138 args->set_receiver(h_obj); 139 result->set_type(T_VOID); // constructor result type 140 JfrJavaSupport::call_special(args, CHECK); 141 result->set_type(T_OBJECT); // set back to original result type 142 result->set_jobject((jobject)h_obj()); 143 } 144 145 static void array_construction(JfrJavaArguments* args, JavaValue* result, InstanceKlass* klass, int array_length, TRAPS) { 146 assert(args != NULL, "invariant"); 147 assert(result != NULL, "invariant"); 148 assert(klass != NULL, "invariant"); 149 assert(klass->is_initialized(), "invariant"); 150 151 Klass* const ak = klass->array_klass(THREAD); 152 ObjArrayKlass::cast(ak)->initialize(THREAD); 153 HandleMark hm(THREAD); 154 objArrayOop arr = ObjArrayKlass::cast(ak)->allocate(array_length, CHECK); 155 result->set_jobject((jobject)arr); 156 } 157 158 static void create_object(JfrJavaArguments* args, JavaValue* result, TRAPS) { 159 assert(args != NULL, "invariant"); 160 assert(result != NULL, "invariant"); 161 assert(result->get_type() == T_OBJECT, "invariant"); 162 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 163 164 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass()); 165 klass->initialize(CHECK); 166 167 const int array_length = args->array_length(); 168 169 if (array_length > 0) { 170 array_construction(args, result, klass, array_length, CHECK); 171 } else { 172 object_construction(args, result, klass, THREAD); 173 } 174 } 175 176 static void handle_result(JavaValue* result, bool global_ref, Thread* t) { 177 assert(result != NULL, "invariant"); 178 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(t)); 179 const oop result_oop = (const oop)result->get_jobject(); 180 if (result_oop == NULL) { 181 return; 182 } 183 result->set_jobject(global_ref ? 184 JfrJavaSupport::global_jni_handle(result_oop, t) : 185 JfrJavaSupport::local_jni_handle(result_oop, t)); 186 } 187 188 void JfrJavaSupport::new_object(JfrJavaArguments* args, TRAPS) { 189 assert(args != NULL, "invariant"); 190 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 191 create_object(args, args->result(), THREAD); 192 } 193 194 void JfrJavaSupport::new_object_local_ref(JfrJavaArguments* args, TRAPS) { 195 assert(args != NULL, "invariant"); 196 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 197 JavaValue* const result = args->result(); 198 assert(result != NULL, "invariant"); 199 create_object(args, result, CHECK); 200 handle_result(result, false, THREAD); 201 } 202 203 void JfrJavaSupport::new_object_global_ref(JfrJavaArguments* args, TRAPS) { 204 assert(args != NULL, "invariant"); 205 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 206 JavaValue* const result = args->result(); 207 assert(result != NULL, "invariant"); 208 create_object(args, result, CHECK); 209 handle_result(result, true, THREAD); 210 } 211 212 jstring JfrJavaSupport::new_string(const char* c_str, TRAPS) { 213 assert(c_str != NULL, "invariant"); 214 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 215 const oop result = java_lang_String::create_oop_from_str(c_str, THREAD); 216 return (jstring)local_jni_handle(result, THREAD); 217 } 218 219 jobjectArray JfrJavaSupport::new_string_array(int length, TRAPS) { 220 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 221 JavaValue result(T_OBJECT); 222 JfrJavaArguments args(&result, "java/lang/String", "<init>", "()V", CHECK_NULL); 223 args.set_array_length(length); 224 new_object_local_ref(&args, THREAD); 225 return (jobjectArray)args.result()->get_jobject(); 226 } 227 228 jobject JfrJavaSupport::new_java_lang_Boolean(bool value, TRAPS) { 229 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 230 JavaValue result(T_OBJECT); 231 JfrJavaArguments args(&result, "java/lang/Boolean", "<init>", "(Z)V", CHECK_NULL); 232 args.push_int(value ? (jint)JNI_TRUE : (jint)JNI_FALSE); 233 new_object_local_ref(&args, THREAD); 234 return args.result()->get_jobject(); 235 } 236 237 jobject JfrJavaSupport::new_java_lang_Integer(jint value, TRAPS) { 238 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 239 JavaValue result(T_OBJECT); 240 JfrJavaArguments args(&result, "java/lang/Integer", "<init>", "(I)V", CHECK_NULL); 241 args.push_int(value); 242 new_object_local_ref(&args, THREAD); 243 return args.result()->get_jobject(); 244 } 245 246 jobject JfrJavaSupport::new_java_lang_Long(jlong value, TRAPS) { 247 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 248 JavaValue result(T_OBJECT); 249 JfrJavaArguments args(&result, "java/lang/Long", "<init>", "(J)V", CHECK_NULL); 250 args.push_long(value); 251 new_object_local_ref(&args, THREAD); 252 return args.result()->get_jobject(); 253 } 254 255 void JfrJavaSupport::set_array_element(jobjectArray arr, jobject element, int index, Thread* t) { 256 assert(arr != NULL, "invariant"); 257 DEBUG_ONLY(check_java_thread_in_vm(t)); 258 HandleMark hm(t); 259 objArrayHandle a(t, (objArrayOop)resolve_non_null(arr)); 260 a->obj_at_put(index, resolve_non_null(element)); 261 } 262 263 /* 264 * Field access 265 */ 266 static void write_int_field(const Handle& h_oop, fieldDescriptor* fd, jint value) { 267 assert(h_oop.not_null(), "invariant"); 268 assert(fd != NULL, "invariant"); 269 h_oop->int_field_put(fd->offset(), value); 270 } 271 272 static void write_float_field(const Handle& h_oop, fieldDescriptor* fd, jfloat value) { 273 assert(h_oop.not_null(), "invariant"); 274 assert(fd != NULL, "invariant"); 275 h_oop->float_field_put(fd->offset(), value); 276 } 277 278 static void write_double_field(const Handle& h_oop, fieldDescriptor* fd, jdouble value) { 279 assert(h_oop.not_null(), "invariant"); 280 assert(fd != NULL, "invariant"); 281 h_oop->double_field_put(fd->offset(), value); 282 } 283 284 static void write_long_field(const Handle& h_oop, fieldDescriptor* fd, jlong value) { 285 assert(h_oop.not_null(), "invariant"); 286 assert(fd != NULL, "invariant"); 287 h_oop->long_field_put(fd->offset(), value); 288 } 289 290 static void write_oop_field(const Handle& h_oop, fieldDescriptor* fd, const oop value) { 291 assert(h_oop.not_null(), "invariant"); 292 assert(fd != NULL, "invariant"); 293 h_oop->obj_field_put(fd->offset(), value); 294 } 295 296 static void write_specialized_field(JfrJavaArguments* args, const Handle& h_oop, fieldDescriptor* fd, bool static_field) { 297 assert(args != NULL, "invariant"); 298 assert(h_oop.not_null(), "invariant"); 299 assert(fd != NULL, "invariant"); 300 assert(fd->offset() > 0, "invariant"); 301 assert(args->length() >= 1, "invariant"); 302 303 // attempt must set a real value 304 assert(args->param(1).get_type() != T_VOID, "invariant"); 305 306 switch(fd->field_type()) { 307 case T_BOOLEAN: 308 case T_CHAR: 309 case T_SHORT: 310 case T_INT: 311 write_int_field(h_oop, fd, args->param(1).get_jint()); 312 break; 313 case T_FLOAT: 314 write_float_field(h_oop, fd, args->param(1).get_jfloat()); 315 break; 316 case T_DOUBLE: 317 write_double_field(h_oop, fd, args->param(1).get_jdouble()); 318 break; 319 case T_LONG: 320 write_long_field(h_oop, fd, args->param(1).get_jlong()); 321 break; 322 case T_OBJECT: 323 write_oop_field(h_oop, fd, (oop)args->param(1).get_jobject()); 324 break; 325 case T_ADDRESS: 326 write_oop_field(h_oop, fd, JfrJavaSupport::resolve_non_null(args->param(1).get_jobject())); 327 break; 328 default: 329 ShouldNotReachHere(); 330 } 331 } 332 333 static void read_specialized_field(JavaValue* result, const Handle& h_oop, fieldDescriptor* fd) { 334 assert(result != NULL, "invariant"); 335 assert(h_oop.not_null(), "invariant"); 336 assert(fd != NULL, "invariant"); 337 assert(fd->offset() > 0, "invariant"); 338 339 switch(fd->field_type()) { 340 case T_BOOLEAN: 341 case T_CHAR: 342 case T_SHORT: 343 case T_INT: 344 result->set_jint(h_oop->int_field(fd->offset())); 345 break; 346 case T_FLOAT: 347 result->set_jfloat(h_oop->float_field(fd->offset())); 348 break; 349 case T_DOUBLE: 350 result->set_jdouble(h_oop->double_field(fd->offset())); 351 break; 352 case T_LONG: 353 result->set_jlong(h_oop->long_field(fd->offset())); 354 break; 355 case T_OBJECT: 356 result->set_jobject((jobject)h_oop->obj_field(fd->offset())); 357 break; 358 default: 359 ShouldNotReachHere(); 360 } 361 } 362 363 static bool find_field(InstanceKlass* ik, 364 Symbol* name_symbol, 365 Symbol* signature_symbol, 366 fieldDescriptor* fd, 367 bool is_static = false, 368 bool allow_super = false) { 369 if (allow_super || is_static) { 370 return ik->find_field(name_symbol, signature_symbol, is_static, fd) != NULL; 371 } 372 return ik->find_local_field(name_symbol, signature_symbol, fd); 373 } 374 375 static void lookup_field(JfrJavaArguments* args, InstanceKlass* klass, fieldDescriptor* fd, bool static_field) { 376 assert(args != NULL, "invariant"); 377 assert(klass != NULL, "invariant"); 378 assert(klass->is_initialized(), "invariant"); 379 assert(fd != NULL, "invariant"); 380 find_field(klass, args->name(), args->signature(), fd, static_field, true); 381 } 382 383 static void read_field(JfrJavaArguments* args, JavaValue* result, TRAPS) { 384 assert(args != NULL, "invariant"); 385 assert(result != NULL, "invariant"); 386 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 387 388 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass()); 389 klass->initialize(CHECK); 390 const bool static_field = !args->has_receiver(); 391 fieldDescriptor fd; 392 lookup_field(args, klass, &fd, static_field); 393 assert(fd.offset() > 0, "invariant"); 394 395 HandleMark hm(THREAD); 396 Handle h_oop(static_field ? Handle(THREAD, klass->java_mirror()) : Handle(THREAD, args->receiver())); 397 read_specialized_field(result, h_oop, &fd); 398 } 399 400 static void write_field(JfrJavaArguments* args, JavaValue* result, TRAPS) { 401 assert(args != NULL, "invariant"); 402 assert(result != NULL, "invariant"); 403 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 404 405 InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass()); 406 klass->initialize(CHECK); 407 408 const bool static_field = !args->has_receiver(); 409 fieldDescriptor fd; 410 lookup_field(args, klass, &fd, static_field); 411 assert(fd.offset() > 0, "invariant"); 412 413 HandleMark hm(THREAD); 414 Handle h_oop(static_field ? Handle(THREAD, klass->java_mirror()) : Handle(THREAD, args->receiver())); 415 write_specialized_field(args, h_oop, &fd, static_field); 416 } 417 418 void JfrJavaSupport::set_field(JfrJavaArguments* args, TRAPS) { 419 assert(args != NULL, "invariant"); 420 write_field(args, args->result(), THREAD); 421 } 422 423 void JfrJavaSupport::get_field(JfrJavaArguments* args, TRAPS) { 424 assert(args != NULL, "invariant"); 425 read_field(args, args->result(), THREAD); 426 } 427 428 void JfrJavaSupport::get_field_local_ref(JfrJavaArguments* args, TRAPS) { 429 assert(args != NULL, "invariant"); 430 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 431 432 JavaValue* const result = args->result(); 433 assert(result != NULL, "invariant"); 434 assert(result->get_type() == T_OBJECT, "invariant"); 435 436 read_field(args, result, CHECK); 437 const oop obj = (const oop)result->get_jobject(); 438 439 if (obj != NULL) { 440 result->set_jobject(local_jni_handle(obj, THREAD)); 441 } 442 } 443 444 void JfrJavaSupport::get_field_global_ref(JfrJavaArguments* args, TRAPS) { 445 assert(args != NULL, "invariant"); 446 DEBUG_ONLY(check_java_thread_in_vm(THREAD)); 447 448 JavaValue* const result = args->result(); 449 assert(result != NULL, "invariant"); 450 assert(result->get_type() == T_OBJECT, "invariant"); 451 read_field(args, result, CHECK); 452 const oop obj = (const oop)result->get_jobject(); 453 if (obj != NULL) { 454 result->set_jobject(global_jni_handle(obj, THREAD)); 455 } 456 } 457 458 /* 459 * Misc 460 */ 461 Klass* JfrJavaSupport::klass(const jobject handle) { 462 const oop obj = resolve_non_null(handle); 463 assert(obj != NULL, "invariant"); 464 return obj->klass(); 465 } 466 467 // caller needs ResourceMark 468 const char* JfrJavaSupport::c_str(jstring string, Thread* t) { 469 DEBUG_ONLY(check_java_thread_in_vm(t)); 470 if (string == NULL) { 471 return NULL; 472 } 473 const char* temp = NULL; 474 const oop java_string = resolve_non_null(string); 475 if (java_lang_String::value(java_string) != NULL) { 476 const size_t length = java_lang_String::utf8_length(java_string); 477 temp = NEW_RESOURCE_ARRAY_IN_THREAD(t, const char, (length + 1)); 478 if (temp == NULL) { 479 JfrJavaSupport::throw_out_of_memory_error("Unable to allocate thread local native memory", t); 480 return NULL; 481 } 482 assert(temp != NULL, "invariant"); 483 java_lang_String::as_utf8_string(java_string, const_cast<char*>(temp), (int) length + 1); 484 } 485 return temp; 486 } 487 488 /* 489 * Exceptions and errors 490 */ 491 static void create_and_throw(Symbol* name, const char* message, TRAPS) { 492 assert(name != NULL, "invariant"); 493 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 494 assert(!HAS_PENDING_EXCEPTION, "invariant"); 495 THROW_MSG(name, message); 496 } 497 498 void JfrJavaSupport::throw_illegal_state_exception(const char* message, TRAPS) { 499 create_and_throw(vmSymbols::java_lang_IllegalStateException(), message, THREAD); 500 } 501 502 void JfrJavaSupport::throw_internal_error(const char* message, TRAPS) { 503 create_and_throw(vmSymbols::java_lang_InternalError(), message, THREAD); 504 } 505 506 void JfrJavaSupport::throw_illegal_argument_exception(const char* message, TRAPS) { 507 create_and_throw(vmSymbols::java_lang_IllegalArgumentException(), message, THREAD); 508 } 509 510 void JfrJavaSupport::throw_out_of_memory_error(const char* message, TRAPS) { 511 create_and_throw(vmSymbols::java_lang_OutOfMemoryError(), message, THREAD); 512 } 513 514 void JfrJavaSupport::throw_class_format_error(const char* message, TRAPS) { 515 create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD); 516 } 517 518 void JfrJavaSupport::abort(jstring errorMsg, Thread* t) { 519 DEBUG_ONLY(check_java_thread_in_vm(t)); 520 521 ResourceMark rm(t); 522 const char* const error_msg = c_str(errorMsg, t); 523 if (error_msg != NULL) { 524 if (true) tty->print_cr("%s",error_msg); 525 } 526 if (true) tty->print_cr("%s", "An irrecoverable error in Jfr. Shutting down VM..."); 527 vm_abort(); 528 } 529 530 JfrJavaSupport::CAUSE JfrJavaSupport::_cause = JfrJavaSupport::VM_ERROR; 531 void JfrJavaSupport::set_cause(jthrowable throwable, Thread* t) { 532 DEBUG_ONLY(check_java_thread_in_vm(t)); 533 534 HandleMark hm(t); 535 Handle ex(t, JNIHandles::resolve_external_guard(throwable)); 536 537 if (ex.is_null()) { 538 return; 539 } 540 541 if (ex->is_a(SystemDictionary::OutOfMemoryError_klass())) { 542 _cause = OUT_OF_MEMORY; 543 return; 544 } 545 if (ex->is_a(SystemDictionary::StackOverflowError_klass())) { 546 _cause = STACK_OVERFLOW; 547 return; 548 } 549 if (ex->is_a(SystemDictionary::Error_klass())) { 550 _cause = VM_ERROR; 551 return; 552 } 553 if (ex->is_a(SystemDictionary::RuntimeException_klass())) { 554 _cause = RUNTIME_EXCEPTION; 555 return; 556 } 557 if (ex->is_a(SystemDictionary::Exception_klass())) { 558 _cause = UNKNOWN; 559 return; 560 } 561 } 562 563 void JfrJavaSupport::uncaught_exception(jthrowable throwable, Thread* t) { 564 DEBUG_ONLY(check_java_thread_in_vm(t)); 565 assert(throwable != NULL, "invariant"); 566 set_cause(throwable, t); 567 } 568 569 JfrJavaSupport::CAUSE JfrJavaSupport::cause() { 570 return _cause; 571 } 572 573 // XXX 574 //const char* const JDK_JFR_MODULE_NAME = "jdk.jfr"; 575 //const char* const JDK_JFR_PACKAGE_NAME = "jdk/jfr"; 576 577 jlong JfrJavaSupport::jfr_thread_id(jobject target_thread) { 578 // ThreadsListHandle tlh; 579 // XXX is it correct and safe? 580 JavaThread* native_thread = java_lang_Thread::thread(JNIHandles::resolve_non_null(target_thread)); 581 // (void)tlh.cv_internal_thread_to_JavaThread(target_thread, &native_thread, NULL); 582 return native_thread != NULL ? JFR_THREAD_ID(native_thread) : 0; 583 }