From 7ca6a5ce7d389639a194acb1e4e7774d8533b056 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Tue, 2 Dec 2025 16:33:01 -0600 Subject: [PATCH] Stage --- src/hotspot/share/classfile/vmIntrinsics.hpp | 2 +- src/hotspot/share/opto/library_call.cpp | 2 +- .../classes/java/lang/invoke/Invokers.java | 2 +- .../java/lang/invoke/MethodHandleImpl.java | 13 +++++------- .../classes/java/lang/invoke/VarHandle.java | 21 +++++++------------ 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 7bdcf47e388..43198ead573 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -700,7 +700,7 @@ class methodHandle; do_signature(profileBoolean_signature, "(Z[I)Z") \ do_intrinsic(_isCompileConstant, java_lang_invoke_MethodHandleImpl, isCompileConstant_name, isCompileConstant_signature, F_S) \ do_name( isCompileConstant_name, "isCompileConstant") \ - do_alias( isCompileConstant_signature, object_int_signature) \ + do_alias( isCompileConstant_signature, object_boolean_signature) \ \ do_intrinsic(_getObjectSize, sun_instrument_InstrumentationImpl, getObjectSize_name, getObjectSize_signature, F_RN) \ do_name( getObjectSize_name, "getObjectSize0") \ diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 5f7f53b7a2b..7a213102efd 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -8923,7 +8923,7 @@ bool LibraryCallKit::inline_profileBoolean() { bool LibraryCallKit::inline_isCompileConstant() { Node* n = argument(0); - set_result(n->is_Con() ? intcon(1) : intcon(2)); + set_result(n->is_Con() ? intcon(1) : intcon(0)); return true; } diff --git a/src/java.base/share/classes/java/lang/invoke/Invokers.java b/src/java.base/share/classes/java/lang/invoke/Invokers.java index a5347c3458d..bd97307ac27 100644 --- a/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -621,7 +621,7 @@ class Invokers { @ForceInline /*non-public*/ static void checkCustomized(MethodHandle mh) { - if (MethodHandleImpl.isCompileConstant(mh) == MethodHandleImpl.CONSTANT_YES) { + if (MethodHandleImpl.isCompileConstant(mh)) { return; // no need to customize a MH when the instance is known to JIT } if (mh.form.customized == null) { // fast approximate check that the underlying form is already customized diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 772a068d93c..02e3b7e233b 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -621,16 +621,13 @@ abstract class MethodHandleImpl { return result; } - static final int CONSTANT_PENDING = 0; - static final int CONSTANT_YES = 1; - static final int CONSTANT_NO = 2; - - // Intrinsified by C2. Returns 0 if not ready, 1 if obj is a compile-time constant, - // 2 if obj is not a compile-time constant. + // Intrinsified by C2. Returns true if obj is a compile-time constant. + // Note that a non-constant value may be subsequently promoted to a constant, + // so a false return value does not indicate obj is definitely not a constant. @Hidden @jdk.internal.vm.annotation.IntrinsicCandidate - static int isCompileConstant(Object obj) { - return CONSTANT_PENDING; + static boolean isCompileConstant(Object obj) { + return false; } static MethodHandle makeGuardWithTest(MethodHandle test, diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/src/java.base/share/classes/java/lang/invoke/VarHandle.java index a4923e6846a..c7792299359 100644 --- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java +++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -2016,9 +2016,10 @@ public abstract sealed class VarHandle implements Constable final Class returnType; final int type; final int mode; - // The cache for adapted MH if the access site has a constant VH - // that does not match the erased type for. - @Stable MethodHandle adaptedMh; + // The cache for last adapted MH if the access site has a VH that does + // not match the erased type for. It can be safely reused if VH is + // discovered to be a constant during C2 compilation. + @Stable MethodHandle lastAdaption; AccessDescriptor(MethodType symbolicMethodType, int type, int mode) { this.symbolicMethodTypeExact = symbolicMethodType; @@ -2031,21 +2032,15 @@ public abstract sealed class VarHandle implements Constable @ForceInline MethodHandle adaptedMethodHandle(VarHandle vh) { - var constant = MethodHandleImpl.isCompileConstant(vh); - if (constant == MethodHandleImpl.CONSTANT_YES) { - var cache = adaptedMh; + if (MethodHandleImpl.isCompileConstant(vh)) { + var cache = lastAdaption; if (cache != null) { return cache; } } - // This is still a hot path if vh is not constant - in this case, - // asType is the bottleneck for constant folding, unfortunately - var result = vh.getMethodHandle(mode).asType(symbolicMethodTypeInvoker); - if (constant != MethodHandleImpl.CONSTANT_NO) { - adaptedMh = result; - } - return result; + // Keep capturing - vh may suddenly get promoted to a constant by C2 + return lastAdaption = vh.getMethodHandle(mode).asType(symbolicMethodTypeInvoker); } }