28
28
import java .util .ArrayList ;
29
29
import java .util .List ;
30
30
31
+ import com .oracle .svm .core .hub .LayoutEncoding ;
31
32
import org .graalvm .nativeimage .CurrentIsolate ;
32
33
import org .graalvm .nativeimage .IsolateThread ;
33
34
import org .graalvm .nativeimage .Platform ;
54
55
import com .oracle .svm .core .genscavenge .ThreadLocalAllocation .Descriptor ;
55
56
import com .oracle .svm .core .genscavenge .UnalignedHeapChunk .UnalignedHeader ;
56
57
import com .oracle .svm .core .genscavenge .graal .ForcedSerialPostWriteBarrier ;
58
+ import com .oracle .svm .core .genscavenge .graal .nodes .FormatArrayNode ;
57
59
import com .oracle .svm .core .graal .snippets .SubstrateAllocationSnippets ;
58
60
import com .oracle .svm .core .heap .GC ;
59
61
import com .oracle .svm .core .heap .GCCause ;
66
68
import com .oracle .svm .core .heap .ReferenceInternals ;
67
69
import com .oracle .svm .core .heap .RestrictHeapAccess ;
68
70
import com .oracle .svm .core .heap .RuntimeCodeInfoGCSupport ;
71
+ import com .oracle .svm .core .heap .VMOperationInfos ;
69
72
import com .oracle .svm .core .hub .DynamicHub ;
70
73
import com .oracle .svm .core .imagelayer .ImageLayerBuildingSupport ;
71
74
import com .oracle .svm .core .jdk .UninterruptibleUtils .AtomicReference ;
80
83
import com .oracle .svm .core .option .RuntimeOptionKey ;
81
84
import com .oracle .svm .core .os .ImageHeapProvider ;
82
85
import com .oracle .svm .core .snippets .KnownIntrinsics ;
86
+ import com .oracle .svm .core .thread .JavaVMOperation ;
83
87
import com .oracle .svm .core .thread .PlatformThreads ;
84
88
import com .oracle .svm .core .thread .ThreadStatus ;
85
89
import com .oracle .svm .core .thread .VMOperation ;
95
99
import jdk .graal .compiler .core .common .SuppressFBWarnings ;
96
100
import jdk .graal .compiler .nodes .extended .MembarNode ;
97
101
import jdk .graal .compiler .nodes .memory .address .OffsetAddressNode ;
102
+ import jdk .graal .compiler .replacements .AllocationSnippets ;
98
103
import jdk .graal .compiler .word .Word ;
99
104
100
105
public final class HeapImpl extends Heap {
@@ -111,6 +116,8 @@ public final class HeapImpl extends Heap {
111
116
private final RuntimeCodeInfoGCSupportImpl runtimeCodeInfoGcSupport ;
112
117
private final HeapAccounting accounting = new HeapAccounting ();
113
118
119
+ private AlignedHeader lastDynamicHubChunk ;
120
+
114
121
/** Head of the linked list of currently pending (ready to be enqueued) {@link Reference}s. */
115
122
private Reference <?> refPendingList ;
116
123
/** Total number of times when a new pending reference list became available. */
@@ -933,6 +940,83 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
933
940
log .indent (false );
934
941
}
935
942
}
943
+
944
+ public static DynamicHub allocateDynamicHub (int vTableSlots ) {
945
+ AllocateDynamicHubOp vmOp = new AllocateDynamicHubOp (vTableSlots );
946
+ vmOp .enqueue ();
947
+ return vmOp .result ;
948
+ }
949
+
950
+ private static class AllocateDynamicHubOp extends JavaVMOperation {
951
+ int vTableSlots ;
952
+ DynamicHub result ;
953
+
954
+ AllocateDynamicHubOp (int vTableSlots ) {
955
+ super (VMOperationInfos .get (AllocateDynamicHubOp .class , "Allocate DynamicHub" , SystemEffect .SAFEPOINT ));
956
+ this .vTableSlots = vTableSlots ;
957
+ }
958
+
959
+ @ Override
960
+ @ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
961
+ public boolean isGC () {
962
+ /* needs to append chunks into oldGen */
963
+ return true ;
964
+ }
965
+
966
+ @ Override
967
+ protected void operate () {
968
+ DynamicHub hubOfDynamicHub = DynamicHub .fromClass (Class .class );
969
+ /*
970
+ * Note that layoutEncoding already encodes the size of a DynamicHub and it is aware of
971
+ * its hybrid nature, including the size required for a VTable slot.
972
+ *
973
+ * Also note that inlined fields like `closedTypeWorldTypeCheckSlots` are not relevant
974
+ * here, as they are not available in the open type world configuration.
975
+ */
976
+ UnsignedWord size = LayoutEncoding .getArrayAllocationSize (hubOfDynamicHub .getLayoutEncoding (), vTableSlots );
977
+
978
+ Pointer memory = WordFactory .nullPointer ();
979
+ if (getHeapImpl ().lastDynamicHubChunk .isNonNull ()) {
980
+ /*
981
+ * GR-57355: move this fast-path out of vmOp. Needs some locking (it's not
982
+ * thread-local)
983
+ */
984
+ memory = AlignedHeapChunk .allocateMemory (getHeapImpl ().lastDynamicHubChunk , size );
985
+ }
986
+
987
+ if (memory .isNull ()) {
988
+ /* Either no storage for DynamicHubs yet or we are out of memory */
989
+ allocateNewDynamicHubChunk ();
990
+
991
+ memory = AlignedHeapChunk .allocateMemory (getHeapImpl ().lastDynamicHubChunk , size );
992
+ }
993
+
994
+ VMError .guarantee (memory .isNonNull (), "failed to allocate DynamicHub" );
995
+
996
+ /* DynamicHubs live allocated on aligned heap chunks */
997
+ boolean unaligned = false ;
998
+ result = (DynamicHub ) FormatArrayNode .formatArray (memory , DynamicHub .class , vTableSlots , true , unaligned , AllocationSnippets .FillContent .WITH_ZEROES , true );
999
+ }
1000
+
1001
+ private static void allocateNewDynamicHubChunk () {
1002
+ /*
1003
+ * GR-60085: Should be a dedicated generation. Make sure that those chunks are close to
1004
+ * the heap base. The hub is stored as offset relative to the heap base. There are 5
1005
+ * status bits in the header and in addition, compressed references use a three-bit
1006
+ * shift that word-aligns objects. This results in a 35-bit address range of 32 GB, of
1007
+ * which DynamicHubs must reside in the lowest 1 GB.
1008
+ */
1009
+ OldGeneration oldGeneration = getHeapImpl ().getOldGeneration ();
1010
+
1011
+ /*
1012
+ * GR-60085: DynamicHub objects must never be be moved. Pin them either by (1) pinning
1013
+ * each DynamicHub, or (2) mark the whole chunk as pinned (not supported yet).
1014
+ */
1015
+ getHeapImpl ().lastDynamicHubChunk = oldGeneration .requestAlignedChunk ();
1016
+
1017
+ oldGeneration .appendChunk (getHeapImpl ().lastDynamicHubChunk );
1018
+ }
1019
+ }
936
1020
}
937
1021
938
1022
@ TargetClass (value = java .lang .Runtime .class , onlyWith = UseSerialOrEpsilonGC .class )
0 commit comments