Skip to content

Commit c095c0e

Browse files
committed
8336489: Track scoped accesses in JVMCI compiled code
Reviewed-by: dnsimon, never
1 parent 7e925d7 commit c095c0e

File tree

11 files changed

+72
-6
lines changed

11 files changed

+72
-6
lines changed

src/hotspot/share/jvmci/jvmciCodeInstaller.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,13 +722,15 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,
722722
jint entry_bci = -1;
723723
JVMCICompileState* compile_state = nullptr;
724724
bool has_unsafe_access = false;
725+
bool has_scoped_access = false;
725726
jint id = -1;
726727

727728
if (is_nmethod) {
728729
method = methodHandle(thread, stream->read_method("method"));
729730
entry_bci = is_nmethod ? stream->read_s4("entryBCI") : -1;
730731
compile_state = (JVMCICompileState*) stream->read_u8("compileState");
731732
has_unsafe_access = stream->read_bool("hasUnsafeAccess");
733+
has_scoped_access = stream->read_bool("hasScopedAccess");
732734
id = stream->read_s4("id");
733735
}
734736
stream->set_code_desc(name, method);
@@ -795,6 +797,7 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,
795797
id,
796798
_has_monitors,
797799
has_unsafe_access,
800+
has_scoped_access,
798801
_has_wide_vector,
799802
compiled_code,
800803
mirror,

src/hotspot/share/jvmci/jvmciRuntime.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
20782078
int compile_id,
20792079
bool has_monitors,
20802080
bool has_unsafe_access,
2081+
bool has_scoped_access,
20812082
bool has_wide_vector,
20822083
JVMCIObject compiled_code,
20832084
JVMCIObject nmethod_mirror,
@@ -2183,7 +2184,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,
21832184
nm->set_has_unsafe_access(has_unsafe_access);
21842185
nm->set_has_wide_vectors(has_wide_vector);
21852186
nm->set_has_monitors(has_monitors);
2186-
nm->set_has_scoped_access(true); // conservative
2187+
nm->set_has_scoped_access(has_scoped_access);
21872188

21882189
JVMCINMethodData* data = nm->jvmci_nmethod_data();
21892190
assert(data != nullptr, "must be");

src/hotspot/share/jvmci/jvmciRuntime.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2024, 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
@@ -452,6 +452,7 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
452452
int compile_id,
453453
bool has_monitors,
454454
bool has_unsafe_access,
455+
bool has_scoped_access,
455456
bool has_wide_vector,
456457
JVMCIObject compiled_code,
457458
JVMCIObject nmethod_mirror,

src/hotspot/share/jvmci/vmStructs_jvmci.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@
655655
declare_constant(ConstMethodFlags::_misc_intrinsic_candidate) \
656656
declare_constant(ConstMethodFlags::_misc_reserved_stack_access) \
657657
declare_constant(ConstMethodFlags::_misc_changes_current_thread) \
658+
declare_constant(ConstMethodFlags::_misc_is_scoped) \
658659
\
659660
declare_constant(CounterData::count_off) \
660661
\

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ private String codeDesc() {
563563
writeInt("entryBCI", nmethod.entryBCI);
564564
writeLong("compileState", nmethod.compileState);
565565
writeBoolean("hasUnsafeAccess", nmethod.hasUnsafeAccess);
566+
writeBoolean("hasScopedAccess", nmethod.hasScopedAccess());
566567
writeInt("id", nmethod.id);
567568
}
568569

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2024, 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,4 +100,22 @@ public String toString() {
100100
public String getInstallationFailureMessage() {
101101
return installationFailureMessage;
102102
}
103+
104+
/**
105+
* Determines if {@code methods} contains at least one entry for which {@code HotSpotResolvedJavaMethod.isScoped()} returns true.
106+
*/
107+
public boolean hasScopedAccess() {
108+
if (methods == null) {
109+
return false;
110+
}
111+
for (ResolvedJavaMethod method : methods) {
112+
if (method instanceof HotSpotResolvedJavaMethod hotSpotMethod) {
113+
if (hotSpotMethod.isScoped()) {
114+
return true;
115+
}
116+
}
117+
}
118+
return false;
119+
}
120+
103121
}

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public int hashCode() {
170170
* @return flags of this method
171171
*/
172172
private int getFlags() {
173-
return UNSAFE.getShort(getMethodPointer() + config().methodFlagsOffset);
173+
return UNSAFE.getInt(getMethodPointer() + config().methodFlagsOffset);
174174
}
175175

176176
/**
@@ -179,7 +179,7 @@ private int getFlags() {
179179
* @return flags of this method's ConstMethod
180180
*/
181181
private int getConstMethodFlags() {
182-
return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset);
182+
return UNSAFE.getInt(getConstMethod() + config().constMethodFlagsOffset);
183183
}
184184

185185
@Override
@@ -324,6 +324,17 @@ public boolean hasReservedStackAccess() {
324324
return (getConstMethodFlags() & config().constMethodFlagsReservedStackAccess) != 0;
325325
}
326326

327+
/**
328+
* Returns true if this method has a
329+
* {@code jdk.internal.misc.ScopedMemoryAccess.Scoped} annotation.
330+
*
331+
* @return true if Scoped annotation present, false otherwise
332+
*/
333+
@Override
334+
public boolean isScoped() {
335+
return (getConstMethodFlags() & config().constMethodFlagsIsScoped) != 0;
336+
}
337+
327338
/**
328339
* Sets flags on {@code method} indicating that it should never be inlined or compiled by the
329340
* VM.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ long prototypeMarkWord() {
194194
final int constMethodFlagsReservedStackAccess = getConstant("ConstMethodFlags::_misc_reserved_stack_access", Integer.class);
195195
final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class);
196196
final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class);
197+
final int constMethodFlagsIsScoped = getConstant("ConstMethodFlags::_misc_is_scoped", Integer.class);
197198
final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class);
198199
final int constMethodHasLocalVariableTable = getConstant("ConstMethodFlags::_misc_has_localvariable_table", Integer.class);
199200
final int constMethodHasMethodAnnotations = getConstant("ConstMethodFlags::_misc_has_method_annotations", Integer.class);

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,16 @@ default boolean isJavaLangObjectInit() {
463463
return getDeclaringClass().isJavaLangObject() && getName().equals("<init>");
464464
}
465465

466+
/**
467+
* Returns true if this method has a
468+
* {@code jdk.internal.misc.ScopedMemoryAccess.Scoped} annotation.
469+
*
470+
* @return true if Scoped annotation present, false otherwise.
471+
*/
472+
default boolean isScoped() {
473+
throw new UnsupportedOperationException();
474+
}
475+
466476
/**
467477
* Gets a speculation log that can be used when compiling this method to make new speculations
468478
* and query previously failed speculations. The implementation may return a new

test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,24 @@ public void isJavaLangObjectInitTest() throws NoSuchMethodException {
475475
}
476476
}
477477

478+
@Test
479+
public void isScopedTest() throws NoSuchMethodException, ClassNotFoundException {
480+
// Must use reflection as ScopedMemoryAccess$Scoped is package-private
481+
Class<? extends Annotation> scopedAnnotationClass = Class.forName("jdk.internal.misc.ScopedMemoryAccess$Scoped").asSubclass(Annotation.class);
482+
boolean scopedMethodFound = false;
483+
for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
484+
ResolvedJavaMethod m = e.getValue();
485+
Method key = e.getKey();
486+
boolean expect = key.isAnnotationPresent(scopedAnnotationClass);
487+
boolean actual = m.isScoped();
488+
assertEquals(m.toString(), expect, actual);
489+
if (expect) {
490+
scopedMethodFound = true;
491+
}
492+
}
493+
assertTrue("At least one scoped method must be present", scopedMethodFound);
494+
}
495+
478496
abstract static class UnlinkedType {
479497
abstract void abstractMethod();
480498

0 commit comments

Comments
 (0)