Skip to content

Commit 25a8d34

Browse files
committed
Refactor PerfCounter substitutions and ensure LambdaForm.LF_FAILED is initialized and folded.
1 parent 8a65629 commit 25a8d34

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jvmstat/Target_jdk_internal_perf_PerfCounter.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,30 @@
2929
import com.oracle.svm.core.annotate.Delete;
3030
import com.oracle.svm.core.annotate.Substitute;
3131
import com.oracle.svm.core.annotate.TargetClass;
32+
import com.oracle.svm.core.util.VMError;
3233

3334
/**
34-
* PerfCounter objects that end up in the image heap reference an invalid buffer (see
35-
* PerfCounter.lb). Accessing this buffer would result in a segfault, so we substitute all methods
36-
* that may access this buffer.
35+
* {@code PerfCounter} objects created at build time and written in the image heap reference an
36+
* invalid buffer via the {@code PerfCounter.lb} field. Accessing this buffer would result in a
37+
* segfault, so we substitute all methods that may access this buffer. Moreover, we delete the
38+
* buffer field since it should never be reachable and make the factory methods that would
39+
* initialize it throw an {@link VMError#unsupportedFeature(String)} at run time.
3740
*/
3841
@TargetClass(className = "jdk.internal.perf.PerfCounter")
3942
final class Target_jdk_internal_perf_PerfCounter {
4043
@Delete //
4144
private LongBuffer lb;
4245

46+
@Substitute //
47+
public static Target_jdk_internal_perf_PerfCounter newPerfCounter(@SuppressWarnings("unused") String name) {
48+
throw VMError.unsupportedFeature("Creating a new jdk.internal.perf.PerfCounter at run time is currently not supported.");
49+
}
50+
51+
@Substitute //
52+
public static Target_jdk_internal_perf_PerfCounter newConstantPerfCounter(@SuppressWarnings("unused") String name) {
53+
throw VMError.unsupportedFeature("Creating a new jdk.internal.perf.PerfCounter at run time is currently not supported.");
54+
}
55+
4356
@Substitute
4457
@SuppressWarnings("static-method")
4558
public long get() {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/methodhandles/MethodHandleFeature.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,17 @@ public Object transform(Object receiver, Object originalValue) {
301301
} catch (ReflectiveOperationException e) {
302302
VMError.shouldNotReachHere("Can not invoke createFormsForm method to register base types from the java.lang.invoke.LambdaForm$BasicType class.");
303303
}
304+
305+
/*
306+
* Allocating PerfCounter objects at run-time is not supported. For more details see the
307+
* Target_jdk_internal_perf_PerfCounter substitutions. Here we ensure that the @Stable field
308+
* java.lang.invoke.LambdaForm.LF_FAILED is initialized and is allowed to be folded before
309+
* analysis to eliminate any code paths that would try initializing it.
310+
*/
311+
Method failedCompilationCounterMethod = ReflectionUtil.lookupMethod(lambdaFormClass, "failedCompilationCounter");
312+
ReflectionUtil.invokeMethod(failedCompilationCounterMethod, null);
313+
access.allowStableFieldFoldingBeforeAnalysis(access.findField(lambdaFormClass, "LF_FAILED"));
314+
304315
// The following call sites produce side effects by generating BoundMethodHandle
305316
// species, which are subsequently referenced by java.lang.invoke.LambdaForm$Holder.
306317
MethodHandles.constant(long.class, 0L);

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/CremaFeature.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import static com.oracle.graal.pointsto.ObjectScanner.ScanReason;
2929

3030
import java.lang.reflect.Field;
31-
import java.lang.reflect.Method;
3231
import java.util.Arrays;
3332
import java.util.List;
3433

@@ -94,7 +93,6 @@ private static boolean assertionsEnabled() {
9493

9594
@Override
9695
public void beforeAnalysis(BeforeAnalysisAccess access) {
97-
methodHandleSetup();
9896
FeatureImpl.BeforeAnalysisAccessImpl accessImpl = (FeatureImpl.BeforeAnalysisAccessImpl) access;
9997
try {
10098
AnalysisType declaringClass = accessImpl.getMetaAccess().lookupJavaType(InterpreterStubSection.class);
@@ -106,16 +104,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
106104
}
107105
}
108106

109-
private static void methodHandleSetup() {
110-
/*
111-
* Get java.lang.invoke.LambdaForm.LF_FAILED initialized since we don't support perf counter
112-
* creation at run-time. See Target_jdk_internal_perf_PerfCounter.
113-
*/
114-
Class<?> lfClass = ReflectionUtil.lookupClass("java.lang.invoke.LambdaForm");
115-
Method failedCompilationCounterMethod = ReflectionUtil.lookupMethod(lfClass, "failedCompilationCounter");
116-
ReflectionUtil.invokeMethod(failedCompilationCounterMethod, null);
117-
}
118-
119107
@Override
120108
public void afterAnalysis(AfterAnalysisAccess access) {
121109
AnalysisUniverse aUniverse = ((FeatureImpl.AfterAnalysisAccessImpl) access).getUniverse();

0 commit comments

Comments
 (0)