2424 */
2525package com .oracle .svm .core .genscavenge .graal ;
2626
27+ import static org .graalvm .compiler .nodes .extended .BranchProbabilityNode .SLOW_PATH_PROBABILITY ;
28+ import static org .graalvm .compiler .nodes .extended .BranchProbabilityNode .probability ;
29+
2730import java .util .Map ;
2831
2932import org .graalvm .compiler .api .replacements .Snippet ;
3033import org .graalvm .compiler .api .replacements .Snippet .ConstantParameter ;
3134import org .graalvm .compiler .graph .Node ;
35+ import org .graalvm .compiler .nodes .ConstantNode ;
3236import org .graalvm .compiler .nodes .PiNode ;
3337import org .graalvm .compiler .nodes .SnippetAnchorNode ;
3438import org .graalvm .compiler .nodes .StructuredGraph ;
3539import org .graalvm .compiler .nodes .spi .LoweringTool ;
3640import org .graalvm .compiler .options .OptionValues ;
3741import org .graalvm .compiler .phases .util .Providers ;
38- import org .graalvm .compiler .replacements .ReplacementsUtil ;
3942import org .graalvm .compiler .replacements .SnippetCounter ;
4043import org .graalvm .compiler .replacements .SnippetTemplate ;
4144import org .graalvm .compiler .replacements .SnippetTemplate .Arguments ;
5255import com .oracle .svm .core .genscavenge .graal .nodes .FormatArrayNode ;
5356import com .oracle .svm .core .genscavenge .graal .nodes .FormatObjectNode ;
5457import com .oracle .svm .core .graal .meta .SubstrateForeignCallsProvider ;
58+ import com .oracle .svm .core .graal .nodes .NewStoredContinuationNode ;
5559import com .oracle .svm .core .graal .snippets .NodeLoweringProvider ;
5660import com .oracle .svm .core .graal .snippets .SubstrateAllocationSnippets ;
5761import com .oracle .svm .core .heap .Heap ;
5862import com .oracle .svm .core .heap .StoredContinuation ;
63+ import com .oracle .svm .core .heap .StoredContinuationImpl ;
5964import com .oracle .svm .core .hub .DynamicHub ;
6065import com .oracle .svm .core .hub .LayoutEncoding ;
66+ import com .oracle .svm .core .meta .SharedType ;
67+ import com .oracle .svm .core .meta .SubstrateObjectConstant ;
6168import com .oracle .svm .core .snippets .SnippetRuntime ;
6269import com .oracle .svm .core .snippets .SnippetRuntime .SubstrateForeignCallDescriptor ;
6370import com .oracle .svm .core .thread .Continuation ;
@@ -81,18 +88,13 @@ public static void registerLowering(OptionValues options, Providers providers,
8188 }
8289
8390 @ Snippet
84- public Object formatObjectSnippet (Word memory , DynamicHub hub , UnsignedWord size , boolean rememberedSet , FillContent fillContents ,
85- boolean emitMemoryBarrier , @ ConstantParameter AllocationSnippetCounters snippetCounters ) {
91+ public Object formatObjectSnippet (Word memory , DynamicHub hub , boolean rememberedSet , FillContent fillContents , boolean emitMemoryBarrier ,
92+ @ ConstantParameter AllocationSnippetCounters snippetCounters ) {
8693 DynamicHub hubNonNull = (DynamicHub ) PiNode .piCastNonNull (hub , SnippetAnchorNode .anchor ());
94+ int layoutEncoding = hubNonNull .getLayoutEncoding ();
95+ UnsignedWord size = LayoutEncoding .getInstanceSize (layoutEncoding );
8796 Word objectHeader = encodeAsObjectHeader (hubNonNull , rememberedSet , false );
88- Object obj = formatObject (objectHeader , WordFactory .nullPointer (), size , memory , fillContents , false , false , snippetCounters );
89- if (Continuation .isSupported () && hub == DynamicHub .fromClass (StoredContinuation .class )) {
90- finishFormatStoredContinuation (obj , size .rawValue ());
91- } else {
92- ReplacementsUtil .dynamicAssert (size .equal (LayoutEncoding .getInstanceSize (hubNonNull .getLayoutEncoding ())), "unexpected size" );
93- }
94- emitMemoryBarrierIf (emitMemoryBarrier );
95- return obj ;
97+ return formatObject (objectHeader , WordFactory .nullPointer (), size , memory , fillContents , emitMemoryBarrier , false , snippetCounters );
9698 }
9799
98100 @ Snippet
@@ -102,14 +104,33 @@ public Object formatArraySnippet(Word memory, DynamicHub hub, int length, boolea
102104 int layoutEncoding = hubNonNull .getLayoutEncoding ();
103105 UnsignedWord size = LayoutEncoding .getArraySize (layoutEncoding , length );
104106 Word objectHeader = encodeAsObjectHeader (hubNonNull , rememberedSet , unaligned );
105- return formatArray (objectHeader , WordFactory .nullPointer (), size , length , memory , fillContents , fillStartOffset ,
106- emitMemoryBarrier , false , supportsBulkZeroing , supportsOptimizedFilling , snippetCounters );
107+ Object obj = formatArray (objectHeader , WordFactory .nullPointer (), size , length , memory , fillContents , fillStartOffset ,
108+ false , false , supportsBulkZeroing , supportsOptimizedFilling , snippetCounters );
109+ if (probability (SLOW_PATH_PROBABILITY , Continuation .isSupported () && hub == DynamicHub .fromClass (StoredContinuation .class ))) {
110+ finishFormatStoredContinuation (obj );
111+ }
112+ emitMemoryBarrierIf (emitMemoryBarrier );
113+ return obj ;
107114 }
108115
109116 private static Word encodeAsObjectHeader (DynamicHub hub , boolean rememberedSet , boolean unaligned ) {
110117 return ObjectHeaderImpl .encodeAsObjectHeader (hub , rememberedSet , unaligned );
111118 }
112119
120+ @ Snippet
121+ public Object allocateStoredContinuationInstance (@ Snippet .NonNullParameter DynamicHub hub , int size , @ ConstantParameter AllocationProfilingData profilingData ) {
122+ int baseOffset = StoredContinuationImpl .PAYLOAD_OFFSET ;
123+ Object result = allocateArrayImpl (encodeAsTLABObjectHeader (hub ), WordFactory .nullPointer (), size , baseOffset , 0 ,
124+ FillContent .WITH_GARBAGE_IF_ASSERTIONS_ENABLED , baseOffset , false , false , false , false , profilingData );
125+ finishFormatStoredContinuation (result );
126+ emitMemoryBarrierIf (true );
127+ return PiNode .piCastToSnippetReplaceeStamp (result );
128+ }
129+
130+ private static void finishFormatStoredContinuation (Object obj ) {
131+ StoredContinuationImpl .initializeNewlyAllocated (obj );
132+ }
133+
113134 @ Override
114135 public void initializeObjectHeader (Word memory , Word objectHeader , Word prototypeMarkWord , boolean isArray ) {
115136 Heap .getHeap ().getObjectHeader ().initializeHeaderOfNewObject (memory , objectHeader );
@@ -158,12 +179,14 @@ protected SubstrateForeignCallDescriptor getSlowNewArrayStub() {
158179 public static class Templates extends SubstrateAllocationSnippets .Templates {
159180 private final SnippetInfo formatObject ;
160181 private final SnippetInfo formatArray ;
182+ private final SnippetInfo allocateStoredContinuationInstance ;
161183
162184 Templates (SubstrateAllocationSnippets receiver , OptionValues options , SnippetCounter .Group .Factory groupFactory , Providers providers ) {
163185 super (receiver , options , groupFactory , providers );
164186
165187 formatObject = snippet (GenScavengeAllocationSnippets .class , "formatObjectSnippet" , null , receiver );
166188 formatArray = snippet (GenScavengeAllocationSnippets .class , "formatArraySnippet" , null , receiver );
189+ allocateStoredContinuationInstance = snippet (GenScavengeAllocationSnippets .class , "allocateStoredContinuationInstance" , null , receiver , ALLOCATION_LOCATIONS );
167190 }
168191
169192 @ Override
@@ -175,6 +198,9 @@ public void registerLowerings(Map<Class<? extends Node>, NodeLoweringProvider<?>
175198
176199 FormatArrayLowering formatArrayLowering = new FormatArrayLowering ();
177200 lowerings .put (FormatArrayNode .class , formatArrayLowering );
201+
202+ NewStoredContinuationLowering newStoredContinuationLowering = new NewStoredContinuationLowering ();
203+ lowerings .put (NewStoredContinuationNode .class , newStoredContinuationLowering );
178204 }
179205
180206 private class FormatObjectLowering implements NodeLoweringProvider <FormatObjectNode > {
@@ -187,7 +213,6 @@ public void lower(FormatObjectNode node, LoweringTool tool) {
187213 Arguments args = new Arguments (formatObject , graph .getGuardsStage (), tool .getLoweringStage ());
188214 args .add ("memory" , node .getMemory ());
189215 args .add ("hub" , node .getHub ());
190- args .add ("size" , node .getSize ());
191216 args .add ("rememberedSet" , node .getRememberedSet ());
192217 args .add ("fillContents" , node .getFillContents ());
193218 args .add ("emitMemoryBarrier" , node .getEmitMemoryBarrier ());
@@ -218,5 +243,28 @@ public void lower(FormatArrayNode node, LoweringTool tool) {
218243 template (node , args ).instantiate (providers .getMetaAccess (), node , SnippetTemplate .DEFAULT_REPLACER , args );
219244 }
220245 }
246+
247+ private class NewStoredContinuationLowering implements NodeLoweringProvider <NewStoredContinuationNode > {
248+ @ Override
249+ public void lower (NewStoredContinuationNode node , LoweringTool tool ) {
250+ StructuredGraph graph = node .graph ();
251+
252+ if (graph .getGuardsStage () != StructuredGraph .GuardsStage .AFTER_FSA ) {
253+ return ;
254+ }
255+
256+ DynamicHub hub = ((SharedType ) tool .getMetaAccess ().lookupJavaType (StoredContinuation .class )).getHub ();
257+ assert hub .isStoredContinuationClass ();
258+
259+ ConstantNode hubConstant = ConstantNode .forConstant (SubstrateObjectConstant .forObject (hub ), providers .getMetaAccess (), graph );
260+
261+ Arguments args = new Arguments (allocateStoredContinuationInstance , graph .getGuardsStage (), tool .getLoweringStage ());
262+ args .add ("hub" , hubConstant );
263+ args .add ("size" , node .getSize ());
264+ args .addConst ("profilingData" , getProfilingData (node , null ));
265+
266+ template (node , args ).instantiate (providers .getMetaAccess (), node , SnippetTemplate .DEFAULT_REPLACER , args );
267+ }
268+ }
221269 }
222270}
0 commit comments