Skip to content
This repository was archived by the owner on May 29, 2024. It is now read-only.

Commit 51a5808

Browse files
committed
[GR-44799] ZGC and nmethod entry barrier fixes
PullRequest: labsjdk-ce-17/107
2 parents 90f5597 + e0434fb commit 51a5808

File tree

14 files changed

+138
-82
lines changed

14 files changed

+138
-82
lines changed

src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,13 @@ class NativeNMethodBarrier {
6262
address barrier_address;
6363
#if INCLUDE_JVMCI
6464
if (nm->is_compiled_by_jvmci()) {
65-
_instruction_address = nm->code_begin() + nm->frame_complete_offset();
66-
_guard_addr = reinterpret_cast<int*>(nm->consts_begin() + nm->jvmci_nmethod_data()->nmethod_entry_patch_offset());
65+
address pc = nm->code_begin() + nm->jvmci_nmethod_data()->nmethod_entry_patch_offset();
66+
RelocIterator iter(nm, pc, pc + 4);
67+
guarantee(iter.next(), "missing relocs");
68+
guarantee(iter.type() == relocInfo::section_word_type, "unexpected reloc");
69+
70+
_guard_addr = (int*) iter.section_word_reloc()->target();
71+
_instruction_address = pc;
6772
} else
6873
#endif
6974
{

src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset
9090
if (inst->is_adr_aligned() || inst->is_ldr_literal()
9191
|| (NativeInstruction::maybe_cpool_ref(pc))) {
9292
address dest = _constants->start() + data_offset;
93-
if (_nmethod_entry_patch_offset == pc_offset) {
94-
// Remember the offset into constants
95-
_nmethod_entry_patch_offset = data_offset;
96-
}
9793
_instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS));
9894
JVMCI_event_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);
9995
} else {

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "oops/instanceMirrorKlass.hpp"
4848
#include "oops/instanceKlass.inline.hpp"
4949
#include "oops/method.inline.hpp"
50+
#include "oops/objArrayKlass.inline.hpp"
5051
#include "oops/typeArrayOop.inline.hpp"
5152
#include "prims/jvmtiExport.hpp"
5253
#include "prims/methodHandles.hpp"
@@ -403,56 +404,93 @@ C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(
403404
}
404405

405406
C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
406-
JVMCIKlassHandle klass(THREAD);
407407
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()) {
410415
if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
411416
Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
412417
klass = base_oop->klass();
413418
} else {
414-
assert(false, "What types are we actually expecting here?");
419+
goto unexpected;
415420
}
416421
} 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;
428460
}
461+
} else {
462+
if (!base_oop.is_null()) {
463+
base_desc = FormatBufferResource("[%s]", base_oop()->klass()->signature_name());
464+
}
465+
goto unexpected;
429466
}
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;
433473
}
474+
} else {
475+
goto unexpected;
434476
}
435-
klass = *((Klass**) (intptr_t) (base_address + offset));
477+
} else {
478+
goto unexpected;
479+
}
480+
481+
{
436482
if (klass == nullptr) {
437483
return nullptr;
438484
}
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);
452487
}
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"));
456494
}
457495

458496
C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), ARGUMENT_PAIR(method)))

src/hotspot/share/jvmci/jvmciEnv.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,16 +1169,19 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
11691169
if (method() == NULL) {
11701170
return method_object;
11711171
}
1172+
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
1173+
JVMCIKlassHandle holder_klass(THREAD, method->method_holder());
1174+
JVMCIObject holder = get_jvmci_type(holder_klass, JVMCI_CHECK_(JVMCIObject()));
11721175

11731176
CompilerOracle::tag_blackhole_if_possible(method);
11741177

1175-
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
11761178
jmetadata handle = _runtime->allocate_handle(method);
11771179
jboolean exception = false;
11781180
if (is_hotspot()) {
11791181
JavaValue result(T_OBJECT);
11801182
JavaCallArguments args;
11811183
args.push_long((jlong) handle);
1184+
args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(holder)));
11821185
JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
11831186
vmSymbols::fromMetaspace_name(),
11841187
vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
@@ -1191,7 +1194,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
11911194
JNIAccessMark jni(this, THREAD);
11921195
method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
11931196
JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
1194-
(jlong) handle));
1197+
(jlong) handle, holder.as_jobject()));
11951198
exception = jni()->ExceptionCheck();
11961199
}
11971200

@@ -1214,6 +1217,9 @@ JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS)
12141217
return type;
12151218
}
12161219

1220+
guarantee(klass->is_klass(), "must be valid klass");
1221+
guarantee(klass->is_loader_alive(), "klass must be alive");
1222+
12171223
jlong pointer = (jlong) klass();
12181224
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
12191225
jboolean exception = false;
@@ -1571,6 +1577,9 @@ void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* c
15711577
set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
15721578
}
15731579

1580+
MethodData* JVMCIEnv::asMethodData(JVMCIObject obj) {
1581+
return (MethodData*) get_HotSpotMethodData_methodDataPointer(obj);
1582+
}
15741583

15751584
void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JVMCI_TRAPS) {
15761585
if (mirror.is_null()) {

src/hotspot/share/jvmci/jvmciEnv.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "classfile/javaClasses.hpp"
2929
#include "jvmci/jvmciJavaClasses.hpp"
30+
#include "oops/klass.inline.hpp"
3031
#include "runtime/jniHandles.hpp"
3132
#include "runtime/thread.hpp"
3233

@@ -376,6 +377,9 @@ class JVMCIEnv : public ResourceObj {
376377
// Unpack an instance of HotSpotResolvedObjectTypeImpl into the original Klass*
377378
Klass* asKlass(JVMCIObject jvmci_type);
378379

380+
// Unpack an instance of HotSpotMethodData into the original MethodData*
381+
MethodData* asMethodData(JVMCIObject jvmci_method_data);
382+
379383
JVMCIObject get_jvmci_method(const methodHandle& method, JVMCI_TRAPS);
380384

381385
JVMCIObject get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS);

src/hotspot/share/jvmci/jvmciJavaClasses.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@
7979
start_class(HotSpotResolvedJavaMethodImpl, jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl) \
8080
long_field(HotSpotResolvedJavaMethodImpl, methodHandle) \
8181
end_class \
82+
start_class(HotSpotMethodData, jdk_vm_ci_hotspot_HotSpotMethodData) \
83+
long_field(HotSpotMethodData, methodDataPointer) \
84+
end_class \
8285
start_class(InstalledCode, jdk_vm_ci_code_InstalledCode) \
8386
long_field(InstalledCode, address) \
8487
long_field(InstalledCode, entryPoint) \

src/hotspot/share/jvmci/vmSymbols_jvmci.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
template(jdk_vm_ci_hotspot_HotSpotResolvedJavaFieldImpl, "jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl") \
4343
template(jdk_vm_ci_hotspot_HotSpotCompressedNullConstant, "jdk/vm/ci/hotspot/HotSpotCompressedNullConstant") \
4444
template(jdk_vm_ci_hotspot_HotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/HotSpotObjectConstantImpl") \
45+
template(jdk_vm_ci_hotspot_HotSpotMethodData, "jdk/vm/ci/hotspot/HotSpotMethodData") \
4546
template(jdk_vm_ci_hotspot_DirectHotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl") \
4647
template(jdk_vm_ci_hotspot_IndirectHotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl") \
4748
template(jdk_vm_ci_hotspot_HotSpotStackFrameReference, "jdk/vm/ci/hotspot/HotSpotStackFrameReference") \
@@ -80,7 +81,7 @@
8081
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
8182
template(isGCSupported_name, "isGCSupported") \
8283
template(fromMetaspace_name, "fromMetaspace") \
83-
template(method_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
84+
template(method_fromMetaspace_signature, "(JLjdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
8485
template(constantPool_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotConstantPool;") \
8586
template(klass_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;") \
8687
template(primitive_fromMetaspace_signature, "(Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;C)Ljdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType;") \

src/hotspot/share/oops/klass.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ class Klass : public Metadata {
367367
static ByteSize modifier_flags_offset() { return in_ByteSize(offset_of(Klass, _modifier_flags)); }
368368
static ByteSize layout_helper_offset() { return in_ByteSize(offset_of(Klass, _layout_helper)); }
369369
static ByteSize access_flags_offset() { return in_ByteSize(offset_of(Klass, _access_flags)); }
370+
#if INCLUDE_JVMCI
371+
static ByteSize subklass_offset() { return in_ByteSize(offset_of(Klass, _subklass)); }
372+
static ByteSize next_sibling_offset() { return in_ByteSize(offset_of(Klass, _next_sibling)); }
373+
#endif
370374

371375
// Unpacking layout_helper:
372376
static const int _lh_neutral_value = 0; // neutral non-array non-instance value

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -868,23 +868,33 @@ HotSpotConstantPool getConstantPool(MetaspaceObject object) {
868868

869869
/**
870870
* Read a {@code Klass*} value from the memory location described by {@code base} plus
871-
* {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This
872-
* method does no checking that the memory location actually contains a valid pointer and may
873-
* crash the VM if an invalid location is provided. If the {@code base} is null then
874-
* {@code displacement} is used by itself. If {@code base} is a
875-
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
876-
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
877-
* and added to {@code displacement}. Any other non-null object type causes an
878-
* {@link IllegalArgumentException} to be thrown.
871+
* {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This method
872+
* only performs the read if the memory location is known to contain a valid Klass*. If
873+
* {@code base} is a {@link HotSpotConstantPool}, {@link HotSpotMethodData}, {@link HotSpotObjectConstantImpl},
874+
* or {@link HotSpotResolvedObjectTypeImpl} then the field
875+
* corresopnding to {@code displacement} is fetched using the appropriate HotSpot accessor. Any
876+
* other object type or an unexpected displacement causes an {@link IllegalArgumentException} to
877+
* be thrown. The set of fields which can be read in this fashion corresponds to the {@link VMField}
878+
* with type {@code Klass*} that are described in the {@link HotSpotVMConfigStore#getFields()}.
879+
* Additionally several injected fields in {@link Class} are also handled.
879880
*
880-
* @param base an object to read from or null
881+
* @param base an object to read from
881882
* @param displacement
882883
* @param compressed true if the location contains a compressed Klass*
883884
* @return null or the resolved method for this location
885+
* @throws NullPointerException if {@code base == null}
884886
*/
885887
private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed);
886888

887-
HotSpotResolvedObjectTypeImpl getResolvedJavaType(MetaspaceObject base, long displacement, boolean compressed) {
889+
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotConstantPool base, long displacement) {
890+
return getResolvedJavaType0(base, displacement, false);
891+
}
892+
893+
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotMethodData base, long displacement) {
894+
return getResolvedJavaType0(base, displacement, false);
895+
}
896+
897+
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotResolvedObjectTypeImpl base, long displacement, boolean compressed) {
888898
return getResolvedJavaType0(base, displacement, compressed);
889899
}
890900

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ private HotSpotConstantPool(long constantPoolHandle) {
238238
*/
239239
private HotSpotResolvedObjectType getHolder() {
240240
if (holder == null) {
241-
holder = compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false);
241+
holder = compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset);
242242
}
243243
return holder;
244244
}

0 commit comments

Comments
 (0)