Skip to content

8361569: [JVMCI] Further refine JVMCI-compiled nmethod that should not collect deoptimization profile #26192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/hotspot/share/code/nmethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1936,10 +1936,7 @@ void nmethod::inc_decompile_count() {
if (!is_compiled_by_c2() && !is_compiled_by_jvmci()) return;
// Could be gated by ProfileTraps, but do not bother...
#if INCLUDE_JVMCI
// Deoptimization count is used by the CompileBroker to reason about compilations
// it requests so do not pollute the count for deoptimizations in non-default (i.e.
// non-CompilerBroker) compilations.
if (is_jvmci_hosted()) {
if (jvmci_skip_profile_deopt()) {
return;
}
#endif
Expand Down Expand Up @@ -4066,7 +4063,7 @@ const char* nmethod::jvmci_name() {
return nullptr;
}

bool nmethod::is_jvmci_hosted() const {
return jvmci_nmethod_data() != nullptr && !jvmci_nmethod_data()->is_default();
bool nmethod::jvmci_skip_profile_deopt() const {
return jvmci_nmethod_data() != nullptr && !jvmci_nmethod_data()->profile_deopt();
}
#endif
6 changes: 3 additions & 3 deletions src/hotspot/share/code/nmethod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,9 @@ class nmethod : public CodeBlob {
return jvmci_data_size() == 0 ? nullptr : (JVMCINMethodData*) jvmci_data_begin();
}

// Returns true if a JVMCI compiled method is non-default,
// i.e., not triggered by CompilerBroker
bool is_jvmci_hosted() const;
// Returns true if the runtime should NOT collect deoptimization profile for a JVMCI
// compiled method
bool jvmci_skip_profile_deopt() const;
#endif

void oops_do(OopClosure* f) { oops_do(f, false); }
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2890,11 +2890,12 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
JVMCIObject methodObject = thisEnv->get_HotSpotNmethod_method(obj);
methodHandle mh(THREAD, thisEnv->asMethod(methodObject));
jboolean isDefault = thisEnv->get_HotSpotNmethod_isDefault(obj);
jboolean profileDeopt = thisEnv->get_HotSpotNmethod_profileDeopt(obj);
jlong compileIdSnapshot = thisEnv->get_HotSpotNmethod_compileIdSnapshot(obj);
JVMCIObject name_string = thisEnv->get_InstalledCode_name(obj);
const char* cstring = name_string.is_null() ? nullptr : thisEnv->as_utf8_string(name_string);
// Create a new HotSpotNmethod instance in the peer runtime
result = PEER_JVMCIENV->new_HotSpotNmethod(mh, cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);
result = PEER_JVMCIENV->new_HotSpotNmethod(mh, cstring, isDefault, profileDeopt, compileIdSnapshot, JVMCI_CHECK_0);
JVMCINMethodHandle nmethod_handle(THREAD);
nmethod* nm = JVMCIENV->get_nmethod(obj, nmethod_handle);
if (result.is_null()) {
Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci,
}
}

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

JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
Expand All @@ -1230,11 +1230,12 @@ JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char*
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
jargs.push_oop(nameStr);
jargs.push_int(isDefault);
jargs.push_int(profileDeopt);
jargs.push_long(compileId);
JavaValue result(T_VOID);
JavaCalls::call_special(&result, ik,
vmSymbols::object_initializer_name(),
vmSymbols::method_string_bool_long_signature(),
vmSymbols::method_string_bool_bool_long_signature(),
&jargs, CHECK_(JVMCIObject()));
return wrap(obj_h());
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/jvmci/jvmciEnv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ class JVMCIEnv : public ResourceObj {
JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS);

JVMCIObject new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS);
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jboolean profileDeopt, jlong compileId, JVMCI_TRAPS);
JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS);
Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/share/jvmci/jvmciJavaClasses.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -100,10 +100,11 @@
end_class \
start_class(HotSpotNmethod, jdk_vm_ci_hotspot_HotSpotNmethod) \
boolean_field(HotSpotNmethod, isDefault) \
boolean_field(HotSpotNmethod, profileDeopt) \
long_field(HotSpotNmethod, compileIdSnapshot) \
object_field(HotSpotNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;") \
int_field(HotSpotNmethod, invalidationReason) \
jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZZJ)V") \
end_class \
start_class(HotSpotCompiledCode, jdk_vm_ci_hotspot_HotSpotCompiledCode) \
primarray_field(HotSpotCompiledCode, targetCode, "[B") \
Expand Down
7 changes: 6 additions & 1 deletion src/hotspot/share/jvmci/jvmciRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@ void JVMCINMethodData::initialize(int nmethod_mirror_index,
int nmethod_entry_patch_offset,
const char* nmethod_mirror_name,
bool is_default,
bool profile_deopt,
FailedSpeculation** failed_speculations)
{
_failed_speculations = failed_speculations;
Expand All @@ -761,10 +762,12 @@ void JVMCINMethodData::initialize(int nmethod_mirror_index,
_properties.bits._has_name = 0;
}
_properties.bits._is_default = is_default;
_properties.bits._profile_deopt = profile_deopt;
}

void JVMCINMethodData::copy(JVMCINMethodData* data) {
initialize(data->_nmethod_mirror_index, data->_nmethod_entry_patch_offset, data->name(), data->_properties.bits._is_default, data->_failed_speculations);
initialize(data->_nmethod_mirror_index, data->_nmethod_entry_patch_offset, data->name(), data->_properties.bits._is_default,
data->_properties.bits._profile_deopt, data->_failed_speculations);
}

void JVMCINMethodData::add_failed_speculation(nmethod* nm, jlong speculation) {
Expand Down Expand Up @@ -2086,6 +2089,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
char* failure_detail = nullptr;

bool install_default = JVMCIENV->get_HotSpotNmethod_isDefault(nmethod_mirror) != 0;
bool profile_deopt = JVMCIENV->get_HotSpotNmethod_profileDeopt(nmethod_mirror) != 0;
assert(JVMCIENV->isa_HotSpotNmethod(nmethod_mirror), "must be");
JVMCIObject name = JVMCIENV->get_InstalledCode_name(nmethod_mirror);
const char* nmethod_mirror_name = name.is_null() ? nullptr : JVMCIENV->as_utf8_string(name);
Expand Down Expand Up @@ -2154,6 +2158,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
nmethod_entry_patch_offset,
nmethod_mirror_name,
install_default,
profile_deopt,
failed_speculations);
nm = nmethod::new_nmethod(method,
compile_id,
Expand Down
15 changes: 12 additions & 3 deletions src/hotspot/share/jvmci/jvmciRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ class JVMCINMethodData : public ResourceObj {
struct {
// Is HotSpotNmethod.name non-null? If so, the value is
// embedded in the end of this object.
uint8_t _has_name : 1,
uint8_t _has_name : 1,
// HotSpotNmethod.isDefault (e.g., compilation scheduled by CompileBroker)
_is_default : 1,
: 6;
_is_default : 1,
// HotSpotNmethod.profileDeopt
_profile_deopt : 1,
: 5;
} bits;
};

Expand Down Expand Up @@ -87,6 +89,7 @@ class JVMCINMethodData : public ResourceObj {
int nmethod_entry_patch_offset,
const char* nmethod_mirror_name,
bool is_default,
bool profile_deopt,
FailedSpeculation** failed_speculations);

void* operator new(size_t size, const char* nmethod_mirror_name) {
Expand All @@ -100,12 +103,14 @@ class JVMCINMethodData : public ResourceObj {
int nmethod_entry_patch_offset,
const char* nmethod_mirror_name,
bool is_default,
bool profile_deopt,
FailedSpeculation** failed_speculations) {
JVMCINMethodData* result = new (nmethod_mirror_name) JVMCINMethodData();
result->initialize(nmethod_mirror_index,
nmethod_entry_patch_offset,
nmethod_mirror_name,
is_default,
profile_deopt,
failed_speculations);
return result;
}
Expand Down Expand Up @@ -153,6 +158,10 @@ class JVMCINMethodData : public ResourceObj {
bool is_default() {
return _properties.bits._is_default;
}

bool profile_deopt() {
return _properties.bits._profile_deopt;
}
};

// A top level class that represents an initialized JVMCI runtime.
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/jvmci/vmSymbols_jvmci.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
template(bootstrapFinished_name, "bootstrapFinished") \
template(forPrimitive_name, "forPrimitive") \
template(forPrimitive_signature, "(CJ)Ljdk/vm/ci/meta/PrimitiveConstant;") \
template(method_string_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
template(method_string_bool_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZZJ)V") \

#endif

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/deoptimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2367,7 +2367,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
// Deoptimization count is used by the CompileBroker to reason about compilations
// it requests so do not pollute the count for deoptimizations in non-default (i.e.
// non-CompilerBroker) compilations.
if (nm->is_jvmci_hosted()) {
if (nm->jvmci_skip_profile_deopt()) {
update_trap_state = false;
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -42,13 +42,15 @@ public interface CodeCacheProvider {
* @param installedCode a predefined {@link InstalledCode} object to use as a reference to the
* installed code. If {@code null}, a new {@link InstalledCode} object will be
* created.
* @param profileDeopt specifies if HotSpot should profile deoptimizations for the
* {@code nmethod} associated with this object.
* @return a reference to the ready-to-run code
* @throws BailoutException if the code installation failed
* @throws IllegalArgumentException if {@code installedCode != null} and this object does not
* support a predefined {@link InstalledCode} object
*/
default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCode, SpeculationLog log, InstalledCode installedCode) {
return installCode(method, compiledCode, installedCode, log, false);
default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCode, SpeculationLog log, InstalledCode installedCode, boolean profileDeopt) {
return installCode(method, compiledCode, installedCode, log, false, profileDeopt);
}

/**
Expand All @@ -64,7 +66,7 @@ default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCo
* support a predefined {@link InstalledCode} object
*/
default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompiledCode compiledCode) {
return installCode(method, compiledCode, null, null, true);
return installCode(method, compiledCode, null, null, true, true);
}

/**
Expand All @@ -81,10 +83,12 @@ default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompiledCode com
* {@code compRequest.getMethod()}. The default implementation for a method is the
* code executed for standard calls to the method. This argument is ignored if
* {@code compRequest == null}.
* @param profileDeopt specifies if HotSpot should profile deoptimizations for the
* {@code nmethod} associated with this object.
* @return a reference to the compiled and ready-to-run installed code
* @throws BailoutException if the code installation failed
*/
InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault);
InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault, boolean profileDeopt);

/**
* Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,8 +23,6 @@
/**
* Package that defines the interface between a Java application that wants to install code and the
* runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
* interface. The method
* {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
* can be used to install code.
* interface. The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode} can be used to install code.
*/
package jdk.vm.ci.code;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -101,7 +101,7 @@ private InstalledCode logOrDump(InstalledCode installedCode, CompiledCode compil
}

@Override
public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault) {
public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault, boolean profileDeopt) {
InstalledCode resultInstalledCode;
if (installedCode != null) {
throw new IllegalArgumentException("InstalledCode argument must be null");
Expand Down Expand Up @@ -131,7 +131,7 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile
} else {
hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode;
HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method;
HotSpotNmethod nmethod = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id);
HotSpotNmethod nmethod = new HotSpotNmethod(hsMethod, name, isDefault, profileDeopt, hsCompiledNmethod.id);
nmethod.setSpeculationLog(speculationLog);
resultInstalledCode = nmethod;
}
Expand Down
Loading