Skip to content

Commit e771b63

Browse files
[GR-60550] Fix registration of VM diagnostics.
PullRequest: graal/19630
2 parents 50736bb + 57e0415 commit e771b63

File tree

1 file changed

+59
-32
lines changed

1 file changed

+59
-32
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
2828
import static com.oracle.svm.core.option.RuntimeOptionKey.RuntimeOptionKeyFlag.RelevantForCompilationIsolates;
2929

30-
import java.util.ArrayList;
3130
import java.util.Arrays;
31+
import java.util.List;
3232

3333
import org.graalvm.collections.EconomicMap;
3434
import org.graalvm.nativeimage.CurrentIsolate;
@@ -46,6 +46,11 @@
4646
import org.graalvm.word.UnsignedWord;
4747
import org.graalvm.word.WordFactory;
4848

49+
import com.oracle.svm.core.SubstrateDiagnostics.DiagnosticThunkRegistry;
50+
import com.oracle.svm.core.SubstrateDiagnostics.DumpCodeCacheHistory;
51+
import com.oracle.svm.core.SubstrateDiagnostics.DumpDeoptStubPointer;
52+
import com.oracle.svm.core.SubstrateDiagnostics.DumpRecentDeoptimizations;
53+
import com.oracle.svm.core.SubstrateDiagnostics.DumpRuntimeCodeInfoMemory;
4954
import com.oracle.svm.core.c.NonmovableArrays;
5055
import com.oracle.svm.core.code.CodeInfo;
5156
import com.oracle.svm.core.code.CodeInfoAccess;
@@ -59,7 +64,9 @@
5964
import com.oracle.svm.core.container.OperatingSystem;
6065
import com.oracle.svm.core.deopt.DeoptimizationSupport;
6166
import com.oracle.svm.core.deopt.Deoptimizer;
67+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
6268
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
69+
import com.oracle.svm.core.feature.InternalFeature;
6370
import com.oracle.svm.core.graal.RuntimeCompilation;
6471
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
6572
import com.oracle.svm.core.heap.Heap;
@@ -88,6 +95,7 @@
8895
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
8996
import com.oracle.svm.core.threadlocal.VMThreadLocalInfos;
9097
import com.oracle.svm.core.util.CounterSupport;
98+
import com.oracle.svm.core.util.ImageHeapList;
9199
import com.oracle.svm.core.util.TimeUtils;
92100
import com.oracle.svm.core.util.VMError;
93101

@@ -679,7 +687,7 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
679687
}
680688
}
681689

682-
private static class DumpDeoptStubPointer extends DiagnosticThunk {
690+
static class DumpDeoptStubPointer extends DiagnosticThunk {
683691
@Override
684692
public int maxInvocationCount() {
685693
return 1;
@@ -796,7 +804,7 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
796804
}
797805
}
798806

799-
private static class DumpCodeCacheHistory extends DiagnosticThunk {
807+
static class DumpCodeCacheHistory extends DiagnosticThunk {
800808
@Override
801809
public int maxInvocationCount() {
802810
return 2;
@@ -810,7 +818,7 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
810818
}
811819
}
812820

813-
private static class DumpRuntimeCodeInfoMemory extends DiagnosticThunk {
821+
static class DumpRuntimeCodeInfoMemory extends DiagnosticThunk {
814822
@Override
815823
public int maxInvocationCount() {
816824
return 3;
@@ -825,7 +833,7 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
825833
}
826834
}
827835

828-
private static class DumpRecentDeoptimizations extends DiagnosticThunk {
836+
static class DumpRecentDeoptimizations extends DiagnosticThunk {
829837
@Override
830838
public int maxInvocationCount() {
831839
return 1;
@@ -1239,11 +1247,15 @@ public abstract static class DiagnosticThunk {
12391247
}
12401248

12411249
public static class DiagnosticThunkRegistry {
1242-
private DiagnosticThunk[] diagnosticThunks;
1250+
@Platforms(Platform.HOSTED_ONLY.class) //
1251+
final int runtimeCompilationPosition;
1252+
1253+
private final List<DiagnosticThunk> thunks = ImageHeapList.create(DiagnosticThunk.class);
12431254
private int[] initialInvocationCount;
12441255

12451256
@Fold
12461257
public static synchronized DiagnosticThunkRegistry singleton() {
1258+
/* The registry is already used very early during the image build. */
12471259
if (!ImageSingletons.contains(DiagnosticThunkRegistry.class)) {
12481260
ImageSingletons.add(DiagnosticThunkRegistry.class, new DiagnosticThunkRegistry());
12491261
}
@@ -1252,7 +1264,6 @@ public static synchronized DiagnosticThunkRegistry singleton() {
12521264

12531265
@Platforms(Platform.HOSTED_ONLY.class)
12541266
DiagnosticThunkRegistry() {
1255-
ArrayList<DiagnosticThunk> thunks = new ArrayList<>();
12561267
thunks.add(new DumpRegisters());
12571268
thunks.add(new DumpInstructions());
12581269
thunks.add(new DumpTopOfCurrentThreadStack());
@@ -1272,45 +1283,43 @@ public static synchronized DiagnosticThunkRegistry singleton() {
12721283
if (CounterSupport.isEnabled()) {
12731284
thunks.add(new DumpCounters());
12741285
}
1275-
if (RuntimeCompilation.isEnabled()) {
1276-
thunks.add(new DumpCodeCacheHistory());
1277-
thunks.add(new DumpRuntimeCodeInfoMemory());
1278-
thunks.add(new DumpDeoptStubPointer());
1279-
thunks.add(new DumpRecentDeoptimizations());
1280-
}
12811286

1282-
this.diagnosticThunks = thunks.toArray(new DiagnosticThunk[0]);
1283-
this.initialInvocationCount = new int[diagnosticThunks.length];
1284-
Arrays.fill(initialInvocationCount, 1);
1287+
resizeInitialInvocationCount();
1288+
this.runtimeCompilationPosition = thunks.size();
12851289
}
12861290

12871291
@Platforms(Platform.HOSTED_ONLY.class)
12881292
public synchronized void add(DiagnosticThunk thunk) {
1289-
diagnosticThunks = Arrays.copyOf(diagnosticThunks, diagnosticThunks.length + 1);
1290-
diagnosticThunks[diagnosticThunks.length - 1] = thunk;
1293+
thunks.add(thunk);
1294+
resizeInitialInvocationCount();
1295+
}
12911296

1292-
initialInvocationCount = Arrays.copyOf(initialInvocationCount, initialInvocationCount.length + 1);
1293-
initialInvocationCount[initialInvocationCount.length - 1] = 1;
1297+
@Platforms(Platform.HOSTED_ONLY.class)
1298+
public synchronized void add(int insertPos, DiagnosticThunk... extraThunks) {
1299+
for (int i = 0; i < extraThunks.length; i++) {
1300+
thunks.add(insertPos + i, extraThunks[i]);
1301+
}
1302+
resizeInitialInvocationCount();
12941303
}
12951304

12961305
@Platforms(Platform.HOSTED_ONLY.class)
12971306
public synchronized void addAfter(DiagnosticThunk thunk, Class<? extends DiagnosticThunk> before) {
12981307
int insertPos = indexOf(before) + 1;
1308+
assert insertPos > 0;
1309+
thunks.add(insertPos, thunk);
1310+
resizeInitialInvocationCount();
1311+
}
12991312

1300-
DiagnosticThunk[] newThunks = new DiagnosticThunk[diagnosticThunks.length + 1];
1301-
System.arraycopy(diagnosticThunks, 0, newThunks, 0, insertPos);
1302-
newThunks[insertPos] = thunk;
1303-
System.arraycopy(diagnosticThunks, insertPos, newThunks, insertPos + 1, diagnosticThunks.length - insertPos);
1304-
diagnosticThunks = newThunks;
1305-
1306-
initialInvocationCount = Arrays.copyOf(initialInvocationCount, initialInvocationCount.length + 1);
1307-
initialInvocationCount[initialInvocationCount.length - 1] = 1;
1313+
@Platforms(Platform.HOSTED_ONLY.class)
1314+
private void resizeInitialInvocationCount() {
1315+
initialInvocationCount = new int[thunks.size()];
1316+
Arrays.fill(initialInvocationCount, 1);
13081317
}
13091318

13101319
@Platforms(Platform.HOSTED_ONLY.class)
13111320
private int indexOf(Class<? extends DiagnosticThunk> clazz) {
1312-
for (int i = 0; i < diagnosticThunks.length; i++) {
1313-
if (diagnosticThunks[i].getClass() == clazz) {
1321+
for (int i = 0; i < thunks.size(); i++) {
1322+
if (thunks.get(i).getClass() == clazz) {
13141323
return i;
13151324
}
13161325
}
@@ -1319,11 +1328,11 @@ private int indexOf(Class<? extends DiagnosticThunk> clazz) {
13191328

13201329
@Fold
13211330
int size() {
1322-
return diagnosticThunks.length;
1331+
return thunks.size();
13231332
}
13241333

13251334
DiagnosticThunk getThunk(int index) {
1326-
return diagnosticThunks[index];
1335+
return thunks.get(index);
13271336
}
13281337

13291338
int getInitialInvocationCount(int index) {
@@ -1394,3 +1403,21 @@ public static boolean implicitExceptionWithoutStacktraceIsFatal() {
13941403
}
13951404
}
13961405
}
1406+
1407+
@AutomaticallyRegisteredFeature
1408+
class SubstrateDiagnosticsFeature implements InternalFeature {
1409+
/**
1410+
* {@link RuntimeCompilation#isEnabled()} can't be executed in the
1411+
* {@link DiagnosticThunkRegistry} constructor because the feature registration is not
1412+
* necessarily finished. So, we need to do it at a later point in time.
1413+
*/
1414+
@Override
1415+
public void afterRegistration(AfterRegistrationAccess access) {
1416+
DiagnosticThunkRegistry registry = DiagnosticThunkRegistry.singleton();
1417+
if (RuntimeCompilation.isEnabled()) {
1418+
int pos = registry.runtimeCompilationPosition;
1419+
SubstrateDiagnostics.DiagnosticThunk[] thunks = {new DumpCodeCacheHistory(), new DumpRuntimeCodeInfoMemory(), new DumpDeoptStubPointer(), new DumpRecentDeoptimizations()};
1420+
registry.add(pos, thunks);
1421+
}
1422+
}
1423+
}

0 commit comments

Comments
 (0)