diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index 79bc97f53ac..6bca2aa644e 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -722,6 +722,7 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, jint entry_bci = -1; JVMCICompileState* compile_state = nullptr; bool has_unsafe_access = false; + bool has_scoped_access = false; jint id = -1; if (is_nmethod) { @@ -729,6 +730,7 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, entry_bci = is_nmethod ? stream->read_s4("entryBCI") : -1; compile_state = (JVMCICompileState*) stream->read_u8("compileState"); has_unsafe_access = stream->read_bool("hasUnsafeAccess"); + has_scoped_access = stream->read_bool("hasScopedAccess"); id = stream->read_s4("id"); } stream->set_code_desc(name, method); @@ -795,6 +797,7 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, id, _has_monitors, has_unsafe_access, + has_scoped_access, _has_wide_vector, compiled_code, mirror, diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index ad0430787aa..8241fc2498c 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -2078,6 +2078,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, int compile_id, bool has_monitors, bool has_unsafe_access, + bool has_scoped_access, bool has_wide_vector, JVMCIObject compiled_code, JVMCIObject nmethod_mirror, @@ -2183,7 +2184,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, nm->set_has_unsafe_access(has_unsafe_access); nm->set_has_wide_vectors(has_wide_vector); nm->set_has_monitors(has_monitors); - nm->set_has_scoped_access(true); // conservative + nm->set_has_scoped_access(has_scoped_access); JVMCINMethodData* data = nm->jvmci_nmethod_data(); assert(data != nullptr, "must be"); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index bc5bee4edeb..99738393b5b 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -452,6 +452,7 @@ class JVMCIRuntime: public CHeapObj { int compile_id, bool has_monitors, bool has_unsafe_access, + bool has_scoped_access, bool has_wide_vector, JVMCIObject compiled_code, JVMCIObject nmethod_mirror, diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 1e2ca0e990e..ac895cc93f2 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -655,6 +655,7 @@ declare_constant(ConstMethodFlags::_misc_intrinsic_candidate) \ declare_constant(ConstMethodFlags::_misc_reserved_stack_access) \ declare_constant(ConstMethodFlags::_misc_changes_current_thread) \ + declare_constant(ConstMethodFlags::_misc_is_scoped) \ \ declare_constant(CounterData::count_off) \ \ diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCodeStream.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCodeStream.java index 87c6ecde07b..ab7a57f2759 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCodeStream.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledCodeStream.java @@ -563,6 +563,7 @@ final class HotSpotCompiledCodeStream implements AutoCloseable { writeInt("entryBCI", nmethod.entryBCI); writeLong("compileState", nmethod.compileState); writeBoolean("hasUnsafeAccess", nmethod.hasUnsafeAccess); + writeBoolean("hasScopedAccess", nmethod.hasScopedAccess()); writeInt("id", nmethod.id); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java index c364af7ad41..b1be3dee25c 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -100,4 +100,22 @@ public final class HotSpotCompiledNmethod extends HotSpotCompiledCode { public String getInstallationFailureMessage() { return installationFailureMessage; } + + /** + * Determines if {@code methods} contains at least one entry for which {@code HotSpotResolvedJavaMethod.isScoped()} returns true. + */ + public boolean hasScopedAccess() { + if (methods == null) { + return false; + } + for (ResolvedJavaMethod method : methods) { + if (method instanceof HotSpotResolvedJavaMethod hotSpotMethod) { + if (hotSpotMethod.isScoped()) { + return true; + } + } + } + return false; + } + } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java index 4c9dc509ce1..4fbd4796024 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java @@ -170,7 +170,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp * @return flags of this method */ private int getFlags() { - return UNSAFE.getShort(getMethodPointer() + config().methodFlagsOffset); + return UNSAFE.getInt(getMethodPointer() + config().methodFlagsOffset); } /** @@ -179,7 +179,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp * @return flags of this method's ConstMethod */ private int getConstMethodFlags() { - return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset); + return UNSAFE.getInt(getConstMethod() + config().constMethodFlagsOffset); } @Override @@ -324,6 +324,17 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp return (getConstMethodFlags() & config().constMethodFlagsReservedStackAccess) != 0; } + /** + * Returns true if this method has a + * {@code jdk.internal.misc.ScopedMemoryAccess.Scoped} annotation. + * + * @return true if Scoped annotation present, false otherwise + */ + @Override + public boolean isScoped() { + return (getConstMethodFlags() & config().constMethodFlagsIsScoped) != 0; + } + /** * Sets flags on {@code method} indicating that it should never be inlined or compiled by the * VM. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 57f9473c902..954e1f6b201 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -194,6 +194,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int constMethodFlagsReservedStackAccess = getConstant("ConstMethodFlags::_misc_reserved_stack_access", Integer.class); final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class); final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class); + final int constMethodFlagsIsScoped = getConstant("ConstMethodFlags::_misc_is_scoped", Integer.class); final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class); final int constMethodHasLocalVariableTable = getConstant("ConstMethodFlags::_misc_has_localvariable_table", Integer.class); final int constMethodHasMethodAnnotations = getConstant("ConstMethodFlags::_misc_has_method_annotations", Integer.class); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java index 41eccc9d1c6..fa42dc26ac8 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java @@ -463,6 +463,16 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP return getDeclaringClass().isJavaLangObject() && getName().equals(""); } + /** + * Returns true if this method has a + * {@code jdk.internal.misc.ScopedMemoryAccess.Scoped} annotation. + * + * @return true if Scoped annotation present, false otherwise. + */ + default boolean isScoped() { + throw new UnsupportedOperationException(); + } + /** * Gets a speculation log that can be used when compiling this method to make new speculations * and query previously failed speculations. The implementation may return a new diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java index 00973fd78c2..98d7d168ba7 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java @@ -475,6 +475,24 @@ public class TestResolvedJavaMethod extends MethodUniverse { } } + @Test + public void isScopedTest() throws NoSuchMethodException, ClassNotFoundException { + // Must use reflection as ScopedMemoryAccess$Scoped is package-private + Class scopedAnnotationClass = Class.forName("jdk.internal.misc.ScopedMemoryAccess$Scoped").asSubclass(Annotation.class); + boolean scopedMethodFound = false; + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + Method key = e.getKey(); + boolean expect = key.isAnnotationPresent(scopedAnnotationClass); + boolean actual = m.isScoped(); + assertEquals(m.toString(), expect, actual); + if (expect) { + scopedMethodFound = true; + } + } + assertTrue("At least one scoped method must be present", scopedMethodFound); + } + abstract static class UnlinkedType { abstract void abstractMethod(); diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java index 2420a133b63..13003095ee6 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java @@ -51,6 +51,7 @@ import java.util.stream.Collectors; import org.junit.Test; import jdk.internal.misc.Unsafe; +import jdk.internal.misc.ScopedMemoryAccess; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.MetaAccessProvider; @@ -115,7 +116,7 @@ public class TypeUniverse { byte[][].class, short[][].class, char[][].class, int[][].class, float[][].class, long[][].class, double[][].class, Object[][].class, Class[][].class, List[][].class, ClassLoader.class, String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class, HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, InnerClass.class, InnerStaticClass.class, - InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class}; + InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class, ScopedMemoryAccess.class}; for (Class c : initialClasses) { addClass(c); }