Skip to content

Commit 3d9e209

Browse files
committed
[GR-69676] Backport JVMCI changes to labsjdk25.
PullRequest: labsjdk-ce/206
2 parents 6dc8bf3 + e68f650 commit 3d9e209

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+570
-108
lines changed

src/hotspot/share/code/nmethod.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,11 @@ bool nmethod::is_maybe_on_stack() {
19421942
void nmethod::inc_decompile_count() {
19431943
if (!is_compiled_by_c2() && !is_compiled_by_jvmci()) return;
19441944
// Could be gated by ProfileTraps, but do not bother...
1945+
#if INCLUDE_JVMCI
1946+
if (jvmci_skip_profile_deopt()) {
1947+
return;
1948+
}
1949+
#endif
19451950
Method* m = method();
19461951
if (m == nullptr) return;
19471952
MethodData* mdo = m->method_data();
@@ -4064,4 +4069,8 @@ const char* nmethod::jvmci_name() {
40644069
}
40654070
return nullptr;
40664071
}
4072+
4073+
bool nmethod::jvmci_skip_profile_deopt() const {
4074+
return jvmci_nmethod_data() != nullptr && !jvmci_nmethod_data()->profile_deopt();
4075+
}
40674076
#endif

src/hotspot/share/code/nmethod.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,10 @@ class nmethod : public CodeBlob {
837837
JVMCINMethodData* jvmci_nmethod_data() const {
838838
return jvmci_data_size() == 0 ? nullptr : (JVMCINMethodData*) jvmci_data_begin();
839839
}
840+
841+
// Returns true if the runtime should NOT collect deoptimization profile for a JVMCI
842+
// compiled method
843+
bool jvmci_skip_profile_deopt() const;
840844
#endif
841845

842846
void oops_do(OopClosure* f) { oops_do(f, false); }

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,7 +2263,7 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredFieldsInfo, (JNIEnv* env, jobject, ARG
22632263
InstanceKlass* iklass = InstanceKlass::cast(klass);
22642264
int java_fields, injected_fields;
22652265
GrowableArray<FieldInfo>* fields = FieldInfoStream::create_FieldInfoArray(iklass->fieldinfo_stream(), &java_fields, &injected_fields);
2266-
JVMCIObjectArray array = JVMCIENV->new_FieldInfo_array(fields->length(), JVMCIENV);
2266+
JVMCIObjectArray array = JVMCIENV->new_FieldInfo_array(fields->length(), JVMCI_CHECK_NULL);
22672267
for (int i = 0; i < fields->length(); i++) {
22682268
JVMCIObject field_info = JVMCIENV->new_FieldInfo(fields->adr_at(i), JVMCI_CHECK_NULL);
22692269
JVMCIENV->put_object_at(array, i, field_info);
@@ -2876,11 +2876,12 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
28762876
JVMCIObject methodObject = thisEnv->get_HotSpotNmethod_method(obj);
28772877
methodHandle mh(THREAD, thisEnv->asMethod(methodObject));
28782878
jboolean isDefault = thisEnv->get_HotSpotNmethod_isDefault(obj);
2879+
jboolean profileDeopt = thisEnv->get_HotSpotNmethod_profileDeopt(obj);
28792880
jlong compileIdSnapshot = thisEnv->get_HotSpotNmethod_compileIdSnapshot(obj);
28802881
JVMCIObject name_string = thisEnv->get_InstalledCode_name(obj);
28812882
const char* cstring = name_string.is_null() ? nullptr : thisEnv->as_utf8_string(name_string);
28822883
// Create a new HotSpotNmethod instance in the peer runtime
2883-
result = PEER_JVMCIENV->new_HotSpotNmethod(mh, cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);
2884+
result = PEER_JVMCIENV->new_HotSpotNmethod(mh, cstring, isDefault, profileDeopt, compileIdSnapshot, JVMCI_CHECK_0);
28842885
JVMCINMethodHandle nmethod_handle(THREAD);
28852886
nmethod* nm = JVMCIENV->get_nmethod(obj, nmethod_handle);
28862887
if (result.is_null()) {
@@ -2969,13 +2970,21 @@ C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMEN
29692970
return JNIHandles::make_local(THREAD, executable);
29702971
C2V_END
29712972

2973+
// Checks that `index` denotes a non-injected field in `klass`
29722974
static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) {
29732975
if (!klass->is_instance_klass()) {
29742976
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
29752977
err_msg("Expected non-primitive type, got %s", klass->external_name()));
29762978
}
29772979
InstanceKlass* iklass = InstanceKlass::cast(klass);
2978-
if (index < 0 || index > iklass->total_fields_count()) {
2980+
if (index < 0 || index >= iklass->java_fields_count()) {
2981+
if (index >= 0 && index < iklass->total_fields_count()) {
2982+
fieldDescriptor fd(iklass, index);
2983+
if (fd.is_injected()) {
2984+
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
2985+
err_msg("Cannot get Field for injected %s.%s", klass->external_name(), fd.name()->as_C_string()));
2986+
}
2987+
}
29792988
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
29802989
err_msg("Field index %d out of bounds for %s", index, klass->external_name()));
29812990
}
@@ -2985,15 +2994,15 @@ static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) {
29852994
C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index))
29862995
requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL);
29872996
Klass* klass = UNPACK_PAIR(Klass, klass);
2988-
InstanceKlass* iklass = check_field(klass, index, JVMCIENV);
2997+
InstanceKlass* iklass = check_field(klass, index, JVMCI_CHECK_NULL);
29892998
fieldDescriptor fd(iklass, index);
29902999
oop reflected = Reflection::new_field(&fd, CHECK_NULL);
29913000
return JNIHandles::make_local(THREAD, reflected);
29923001
C2V_END
29933002

29943003
static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationArray* annotations_array, bool for_class,
29953004
jint filter_length, jlong filter_klass_pointers,
2996-
JavaThread* THREAD, JVMCIEnv* JVMCIENV) {
3005+
JavaThread* THREAD, JVMCI_TRAPS) {
29973006
// Get a ConstantPool object for annotation parsing
29983007
Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
29993008
reflect_ConstantPool::set_cp(jcp(), holder->constants());
@@ -3071,7 +3080,7 @@ C2V_END
30713080
C2V_VMENTRY_NULL(jbyteArray, getEncodedFieldAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index,
30723081
jobject filter, jint filter_length, jlong filter_klass_pointers))
30733082
CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support
3074-
InstanceKlass* holder = check_field(InstanceKlass::cast(UNPACK_PAIR(Klass, klass)), index, JVMCIENV);
3083+
InstanceKlass* holder = check_field(InstanceKlass::cast(UNPACK_PAIR(Klass, klass)), index, JVMCI_CHECK_NULL);
30753084
fieldDescriptor fd(holder, index);
30763085
return get_encoded_annotation_data(holder, fd.annotations(), false, filter_length, filter_klass_pointers, THREAD, JVMCIENV);
30773086
C2V_END

src/hotspot/share/jvmci/jvmciEnv.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci,
12101210
}
12111211
}
12121212

1213-
JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
1213+
JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jboolean profileDeopt, jlong compileId, JVMCI_TRAPS) {
12141214
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros.
12151215

12161216
JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
@@ -1230,11 +1230,12 @@ JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char*
12301230
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
12311231
jargs.push_oop(nameStr);
12321232
jargs.push_int(isDefault);
1233+
jargs.push_int(profileDeopt);
12331234
jargs.push_long(compileId);
12341235
JavaValue result(T_VOID);
12351236
JavaCalls::call_special(&result, ik,
12361237
vmSymbols::object_initializer_name(),
1237-
vmSymbols::method_string_bool_long_signature(),
1238+
vmSymbols::method_string_bool_bool_long_signature(),
12381239
&jargs, CHECK_(JVMCIObject()));
12391240
return wrap(obj_h());
12401241
} else {

src/hotspot/share/jvmci/jvmciEnv.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ class JVMCIEnv : public ResourceObj {
426426
JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS);
427427

428428
JVMCIObject new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS);
429-
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);
429+
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jboolean profileDeopt, jlong compileId, JVMCI_TRAPS);
430430
JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);
431431
JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);
432432
JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS);

src/hotspot/share/jvmci/jvmciJavaClasses.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -100,9 +100,10 @@
100100
end_class \
101101
start_class(HotSpotNmethod, jdk_vm_ci_hotspot_HotSpotNmethod) \
102102
boolean_field(HotSpotNmethod, isDefault) \
103+
boolean_field(HotSpotNmethod, profileDeopt) \
103104
long_field(HotSpotNmethod, compileIdSnapshot) \
104105
object_field(HotSpotNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;") \
105-
jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
106+
jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZZJ)V") \
106107
end_class \
107108
start_class(HotSpotCompiledCode, jdk_vm_ci_hotspot_HotSpotCompiledCode) \
108109
primarray_field(HotSpotCompiledCode, targetCode, "[B") \

src/hotspot/share/jvmci/jvmciRuntime.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -746,23 +746,28 @@ JVM_END
746746
void JVMCINMethodData::initialize(int nmethod_mirror_index,
747747
int nmethod_entry_patch_offset,
748748
const char* nmethod_mirror_name,
749+
bool is_default,
750+
bool profile_deopt,
749751
FailedSpeculation** failed_speculations)
750752
{
751753
_failed_speculations = failed_speculations;
752754
_nmethod_mirror_index = nmethod_mirror_index;
753755
guarantee(nmethod_entry_patch_offset != -1, "missing entry barrier");
754756
_nmethod_entry_patch_offset = nmethod_entry_patch_offset;
755757
if (nmethod_mirror_name != nullptr) {
756-
_has_name = true;
758+
_properties.bits._has_name = 1;
757759
char* dest = (char*) name();
758760
strcpy(dest, nmethod_mirror_name);
759761
} else {
760-
_has_name = false;
762+
_properties.bits._has_name = 0;
761763
}
764+
_properties.bits._is_default = is_default;
765+
_properties.bits._profile_deopt = profile_deopt;
762766
}
763767

764768
void JVMCINMethodData::copy(JVMCINMethodData* data) {
765-
initialize(data->_nmethod_mirror_index, data->_nmethod_entry_patch_offset, data->name(), data->_failed_speculations);
769+
initialize(data->_nmethod_mirror_index, data->_nmethod_entry_patch_offset, data->name(), data->_properties.bits._is_default,
770+
data->_properties.bits._profile_deopt, data->_failed_speculations);
766771
}
767772

768773
void JVMCINMethodData::add_failed_speculation(nmethod* nm, jlong speculation) {
@@ -2076,6 +2081,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
20762081
char* failure_detail = nullptr;
20772082

20782083
bool install_default = JVMCIENV->get_HotSpotNmethod_isDefault(nmethod_mirror) != 0;
2084+
bool profile_deopt = JVMCIENV->get_HotSpotNmethod_profileDeopt(nmethod_mirror) != 0;
20792085
assert(JVMCIENV->isa_HotSpotNmethod(nmethod_mirror), "must be");
20802086
JVMCIObject name = JVMCIENV->get_InstalledCode_name(nmethod_mirror);
20812087
const char* nmethod_mirror_name = name.is_null() ? nullptr : JVMCIENV->as_utf8_string(name);
@@ -2122,7 +2128,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
21222128
JVMCICompileState* compile_state = JVMCIENV->compile_state();
21232129
bool failing_dep_is_call_site;
21242130
result = validate_compile_task_dependencies(dependencies, compile_state, &failure_detail, failing_dep_is_call_site);
2125-
if (result != JVMCI::ok) {
2131+
if (install_default && result != JVMCI::ok) {
21262132
// While not a true deoptimization, it is a preemptive decompile.
21272133
MethodData* mdp = method()->method_data();
21282134
if (mdp != nullptr && !failing_dep_is_call_site) {
@@ -2143,6 +2149,8 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
21432149
JVMCINMethodData* data = JVMCINMethodData::create(nmethod_mirror_index,
21442150
nmethod_entry_patch_offset,
21452151
nmethod_mirror_name,
2152+
install_default,
2153+
profile_deopt,
21462154
failed_speculations);
21472155
nm = nmethod::new_nmethod(method,
21482156
compile_id,

src/hotspot/share/jvmci/jvmciRuntime.hpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,21 @@ class MetadataHandles;
4848
class JVMCINMethodData : public ResourceObj {
4949
friend class JVMCIVMStructs;
5050

51-
// Is HotSpotNmethod.name non-null? If so, the value is
52-
// embedded in the end of this object.
53-
bool _has_name;
51+
union JVMCINMethodProperties {
52+
uint8_t value;
53+
struct {
54+
// Is HotSpotNmethod.name non-null? If so, the value is
55+
// embedded in the end of this object.
56+
uint8_t _has_name : 1,
57+
// HotSpotNmethod.isDefault (e.g., compilation scheduled by CompileBroker)
58+
_is_default : 1,
59+
// HotSpotNmethod.profileDeopt
60+
_profile_deopt : 1,
61+
: 5;
62+
} bits;
63+
};
64+
65+
JVMCINMethodProperties _properties;
5466

5567
// Index for the HotSpotNmethod mirror in the nmethod's oops table.
5668
// This is -1 if there is no mirror in the oops table.
@@ -76,6 +88,8 @@ class JVMCINMethodData : public ResourceObj {
7688
void initialize(int nmethod_mirror_index,
7789
int nmethod_entry_patch_offset,
7890
const char* nmethod_mirror_name,
91+
bool is_default,
92+
bool profile_deopt,
7993
FailedSpeculation** failed_speculations);
8094

8195
void* operator new(size_t size, const char* nmethod_mirror_name) {
@@ -88,11 +102,15 @@ class JVMCINMethodData : public ResourceObj {
88102
static JVMCINMethodData* create(int nmethod_mirror_index,
89103
int nmethod_entry_patch_offset,
90104
const char* nmethod_mirror_name,
105+
bool is_default,
106+
bool profile_deopt,
91107
FailedSpeculation** failed_speculations) {
92108
JVMCINMethodData* result = new (nmethod_mirror_name) JVMCINMethodData();
93109
result->initialize(nmethod_mirror_index,
94110
nmethod_entry_patch_offset,
95111
nmethod_mirror_name,
112+
is_default,
113+
profile_deopt,
96114
failed_speculations);
97115
return result;
98116
}
@@ -117,7 +135,7 @@ class JVMCINMethodData : public ResourceObj {
117135
void add_failed_speculation(nmethod* nm, jlong speculation);
118136

119137
// Gets the JVMCI name of the nmethod (which may be null).
120-
const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : nullptr; }
138+
const char* name() { return has_name() ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : nullptr; }
121139

122140
// Clears the HotSpotNmethod.address field in the mirror. If nm
123141
// is dead, the HotSpotNmethod.entryPoint field is also cleared.
@@ -132,6 +150,18 @@ class JVMCINMethodData : public ResourceObj {
132150
int nmethod_entry_patch_offset() {
133151
return _nmethod_entry_patch_offset;
134152
}
153+
154+
bool has_name() {
155+
return _properties.bits._has_name;
156+
}
157+
158+
bool is_default() {
159+
return _properties.bits._is_default;
160+
}
161+
162+
bool profile_deopt() {
163+
return _properties.bits._profile_deopt;
164+
}
135165
};
136166

137167
// A top level class that represents an initialized JVMCI runtime.

src/hotspot/share/jvmci/jvmci_globals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
106106
}
107107
if (BootstrapJVMCI && (TieredStopAtLevel < CompLevel_full_optimization)) {
108108
jio_fprintf(defaultStream::error_stream(),
109-
"-XX:+BootstrapJVMCI is not compatible with -XX:TieredStopAtLevel=%d\n", TieredStopAtLevel);
109+
"-XX:+BootstrapJVMCI is not compatible with -XX:TieredStopAtLevel=%zd\n", TieredStopAtLevel);
110110
return false;
111111
}
112112
}

src/hotspot/share/jvmci/vmSymbols_jvmci.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
template(bootstrapFinished_name, "bootstrapFinished") \
103103
template(forPrimitive_name, "forPrimitive") \
104104
template(forPrimitive_signature, "(CJ)Ljdk/vm/ci/meta/PrimitiveConstant;") \
105-
template(method_string_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
105+
template(method_string_bool_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZZJ)V") \
106106

107107
#endif
108108

0 commit comments

Comments
 (0)