|
47 | 47 | #include "oops/instanceMirrorKlass.hpp" |
48 | 48 | #include "oops/instanceKlass.inline.hpp" |
49 | 49 | #include "oops/method.inline.hpp" |
| 50 | +#include "oops/objArrayKlass.inline.hpp" |
50 | 51 | #include "oops/typeArrayOop.inline.hpp" |
51 | 52 | #include "prims/jvmtiExport.hpp" |
52 | 53 | #include "prims/methodHandles.hpp" |
@@ -403,56 +404,93 @@ C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, ARGUMENT_PAIR( |
403 | 404 | } |
404 | 405 |
|
405 | 406 | C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed)) |
406 | | - JVMCIKlassHandle klass(THREAD); |
407 | 407 | JVMCIObject base_object = JVMCIENV->wrap(base); |
408 | | - jlong base_address = 0; |
409 | | - if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) { |
| 408 | + if (base_object.is_null()) { |
| 409 | + JVMCI_THROW_MSG_NULL(NullPointerException, "base object is null"); |
| 410 | + } |
| 411 | + |
| 412 | + const char* base_desc = nullptr; |
| 413 | + JVMCIKlassHandle klass(THREAD); |
| 414 | + if (offset == oopDesc::klass_offset_in_bytes()) { |
410 | 415 | if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) { |
411 | 416 | Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL); |
412 | 417 | klass = base_oop->klass(); |
413 | 418 | } else { |
414 | | - assert(false, "What types are we actually expecting here?"); |
| 419 | + goto unexpected; |
415 | 420 | } |
416 | 421 | } else if (!compressed) { |
417 | | - if (base_object.is_non_null()) { |
418 | | - if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) { |
419 | | - base_address = (intptr_t) JVMCIENV->asMethod(base_object); |
420 | | - } else if (JVMCIENV->isa_HotSpotConstantPool(base_object)) { |
421 | | - base_address = (intptr_t) JVMCIENV->asConstantPool(base_object); |
422 | | - } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) { |
423 | | - base_address = (intptr_t) JVMCIENV->asKlass(base_object); |
424 | | - } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) { |
425 | | - Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL); |
426 | | - if (base_oop->is_a(vmClasses::Class_klass())) { |
427 | | - base_address = cast_from_oop<jlong>(base_oop()); |
| 422 | + if (JVMCIENV->isa_HotSpotConstantPool(base_object)) { |
| 423 | + ConstantPool* cp = JVMCIENV->asConstantPool(base_object); |
| 424 | + if (offset == ConstantPool::pool_holder_offset_in_bytes()) { |
| 425 | + klass = cp->pool_holder(); |
| 426 | + } else { |
| 427 | + base_desc = FormatBufferResource("[constant pool for %s]", cp->pool_holder()->signature_name()); |
| 428 | + goto unexpected; |
| 429 | + } |
| 430 | + } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) { |
| 431 | + Klass* base_klass = JVMCIENV->asKlass(base_object); |
| 432 | + if (offset == in_bytes(Klass::subklass_offset())) { |
| 433 | + klass = base_klass->subklass(); |
| 434 | + } else if (offset == in_bytes(Klass::super_offset())) { |
| 435 | + klass = base_klass->super(); |
| 436 | + } else if (offset == in_bytes(Klass::next_sibling_offset())) { |
| 437 | + klass = base_klass->next_sibling(); |
| 438 | + } else if (offset == in_bytes(ObjArrayKlass::element_klass_offset()) && base_klass->is_objArray_klass()) { |
| 439 | + klass = ObjArrayKlass::cast(base_klass)->element_klass(); |
| 440 | + } else if (offset >= in_bytes(Klass::primary_supers_offset()) && |
| 441 | + offset < in_bytes(Klass::primary_supers_offset()) + (int) (sizeof(Klass*) * Klass::primary_super_limit()) && |
| 442 | + offset % sizeof(Klass*) == 0) { |
| 443 | + // Offset is within the primary supers array |
| 444 | + int index = (int) ((offset - in_bytes(Klass::primary_supers_offset())) / sizeof(Klass*)); |
| 445 | + klass = base_klass->primary_super_of_depth(index); |
| 446 | + } else { |
| 447 | + base_desc = FormatBufferResource("[%s]", base_klass->signature_name()); |
| 448 | + goto unexpected; |
| 449 | + } |
| 450 | + } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) { |
| 451 | + Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL); |
| 452 | + if (base_oop->is_a(vmClasses::Class_klass())) { |
| 453 | + if (offset == java_lang_Class::klass_offset()) { |
| 454 | + klass = java_lang_Class::as_Klass(base_oop()); |
| 455 | + } else if (offset == java_lang_Class::array_klass_offset()) { |
| 456 | + klass = java_lang_Class::array_klass_acquire(base_oop()); |
| 457 | + } else { |
| 458 | + base_desc = FormatBufferResource("[Class=%s]", java_lang_Class::as_Klass(base_oop())->signature_name()); |
| 459 | + goto unexpected; |
428 | 460 | } |
| 461 | + } else { |
| 462 | + if (!base_oop.is_null()) { |
| 463 | + base_desc = FormatBufferResource("[%s]", base_oop()->klass()->signature_name()); |
| 464 | + } |
| 465 | + goto unexpected; |
429 | 466 | } |
430 | | - if (base_address == 0) { |
431 | | - JVMCI_THROW_MSG_NULL(IllegalArgumentException, |
432 | | - err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", JVMCIENV->klass_name(base_object), offset, compressed ? "true" : "false")); |
| 467 | + } else if (JVMCIENV->isa_HotSpotMethodData(base_object)) { |
| 468 | + jlong base_address = (intptr_t) JVMCIENV->asMethodData(base_object); |
| 469 | + klass = *((Klass**) (intptr_t) (base_address + offset)); |
| 470 | + if (klass == nullptr || !klass->is_loader_alive()) { |
| 471 | + // Klasses in methodData might be concurrently unloading so return null in that case. |
| 472 | + return nullptr; |
433 | 473 | } |
| 474 | + } else { |
| 475 | + goto unexpected; |
434 | 476 | } |
435 | | - klass = *((Klass**) (intptr_t) (base_address + offset)); |
| 477 | + } else { |
| 478 | + goto unexpected; |
| 479 | + } |
| 480 | + |
| 481 | + { |
436 | 482 | if (klass == nullptr) { |
437 | 483 | return nullptr; |
438 | 484 | } |
439 | | - if (base_object.is_non_null()) { |
440 | | - // Reads from real objects are expected to be strongly reachable |
441 | | - guarantee(klass->is_loader_alive(), "klass must be alive"); |
442 | | - } else if (!klass->is_loader_alive()) { |
443 | | - // Reads from other memory like the HotSpotMethodData might be concurrently unloading so |
444 | | - // return null in that case. |
445 | | - return nullptr; |
446 | | - } |
447 | | - } else { |
448 | | - JVMCI_THROW_MSG_NULL(IllegalArgumentException, |
449 | | - err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", |
450 | | - base_object.is_non_null() ? JVMCIENV->klass_name(base_object) : "null", |
451 | | - offset, compressed ? "true" : "false")); |
| 485 | + JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL); |
| 486 | + return JVMCIENV->get_jobject(result); |
452 | 487 | } |
453 | | - assert (klass == NULL || klass->is_klass(), "invalid read"); |
454 | | - JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL); |
455 | | - return JVMCIENV->get_jobject(result); |
| 488 | + |
| 489 | +unexpected: |
| 490 | + JVMCI_THROW_MSG_NULL(IllegalArgumentException, |
| 491 | + err_msg("Unexpected arguments: %s%s " JLONG_FORMAT " %s", |
| 492 | + JVMCIENV->klass_name(base_object), base_desc == nullptr ? "" : base_desc, |
| 493 | + offset, compressed ? "true" : "false")); |
456 | 494 | } |
457 | 495 |
|
458 | 496 | C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), ARGUMENT_PAIR(method))) |
|
0 commit comments