src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java
changeset 52956 4b0b796dd581
parent 52910 583fd71c47d6
child 54084 84f10bbf993f
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Tue Dec 11 18:00:17 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Tue Dec 11 16:50:43 2018 -0800
@@ -28,6 +28,7 @@
 import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint;
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.core.common.calc.UnsignedMath.belowThan;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_OPTIONVALUES;
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_ARRAY;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_ARRAY_OR_NULL;
@@ -41,10 +42,14 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocateInstancePrefetchLines;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchDistance;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchLines;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchStepSize;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.allocatePrefetchStyle;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayKlassOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayLengthOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.config;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.initializeObjectHeader;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.instanceHeaderSize;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.isInstanceKlassFullyInitialized;
@@ -151,7 +156,7 @@
     }
 
     @Fold
-    static String createName(String path, String typeContext, OptionValues options) {
+    static String createName(@Fold.InjectedParameter OptionValues options, String path, String typeContext) {
         switch (ProfileAllocationsContext.getValue(options)) {
             case AllocatingMethod:
                 return "";
@@ -168,34 +173,33 @@
     }
 
     @Fold
-    static boolean doProfile(OptionValues options) {
+    static boolean doProfile(@Fold.InjectedParameter OptionValues options) {
         return ProfileAllocations.getValue(options);
     }
 
     @Fold
-    static boolean withContext(OptionValues options) {
+    static boolean withContext(@Fold.InjectedParameter OptionValues options) {
         ProfileContext context = ProfileAllocationsContext.getValue(options);
         return context == ProfileContext.AllocatingMethod || context == ProfileContext.AllocatedTypesInMethod;
     }
 
-    protected static void profileAllocation(String path, long size, String typeContext, OptionValues options) {
-        if (doProfile(options)) {
-            String name = createName(path, typeContext, options);
+    protected static void profileAllocation(String path, long size, String typeContext) {
+        if (doProfile(INJECTED_OPTIONVALUES)) {
+            String name = createName(INJECTED_OPTIONVALUES, path, typeContext);
 
-            boolean context = withContext(options);
+            boolean context = withContext(INJECTED_OPTIONVALUES);
             DynamicCounterNode.counter("number of bytes allocated", name, size, context);
             DynamicCounterNode.counter("number of allocations", name, 1, context);
         }
     }
 
     public static void emitPrefetchAllocate(Word address, boolean isArray) {
-        GraalHotSpotVMConfig config = config(INJECTED_VMCONFIG);
-        if (config.allocatePrefetchStyle > 0) {
+        if (allocatePrefetchStyle(INJECTED_VMCONFIG) > 0) {
             // Insert a prefetch for each allocation only on the fast-path
             // Generate several prefetch instructions.
-            int lines = isArray ? config.allocatePrefetchLines : config.allocateInstancePrefetchLines;
-            int stepSize = config.allocatePrefetchStepSize;
-            int distance = config.allocatePrefetchDistance;
+            int lines = isArray ? allocatePrefetchLines(INJECTED_VMCONFIG) : allocateInstancePrefetchLines(INJECTED_VMCONFIG);
+            int stepSize = allocatePrefetchStepSize(INJECTED_VMCONFIG);
+            int distance = allocatePrefetchDistance(INJECTED_VMCONFIG);
             ExplodeLoopNode.explodeLoop();
             for (int i = 0; i < lines; i++) {
                 PrefetchAllocateNode.prefetch(OffsetAddressNode.address(address, distance));
@@ -206,13 +210,13 @@
 
     @Snippet
     public static Object allocateInstance(@ConstantParameter int size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
-                    @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter OptionValues options,
+                    @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext,
                     @ConstantParameter Counters counters) {
-        return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters));
+        return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, hub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters));
     }
 
     public static Object allocateInstanceHelper(int size, KlassPointer hub, Word prototypeMarkWord, boolean fillContents,
-                    Register threadRegister, boolean constantSize, String typeContext, OptionValues options, Counters counters) {
+                    Register threadRegister, boolean constantSize, String typeContext, Counters counters) {
         Object result;
         Word thread = registerAsWord(threadRegister);
         Word top = readTlabTop(thread);
@@ -223,12 +227,13 @@
             emitPrefetchAllocate(newTop, false);
             result = formatObject(hub, size, top, prototypeMarkWord, fillContents, constantSize, counters);
         } else {
-            if (counters != null && counters.stub != null) {
-                counters.stub.inc();
+            Counters theCounters = counters;
+            if (theCounters != null && theCounters.stub != null) {
+                theCounters.stub.inc();
             }
             result = newInstanceStub(hub);
         }
-        profileAllocation("instance", size, typeContext, options);
+        profileAllocation("instance", size, typeContext);
         return verifyOop(result);
     }
 
@@ -248,18 +253,18 @@
 
     @Snippet
     public static Object allocateInstancePIC(@ConstantParameter int size, KlassPointer hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents,
-                    @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext, @ConstantParameter OptionValues options,
+                    @ConstantParameter Register threadRegister, @ConstantParameter boolean constantSize, @ConstantParameter String typeContext,
                     @ConstantParameter Counters counters) {
         // Klass must be initialized by the time the first instance is allocated, therefore we can
         // just load it from the corresponding cell and avoid the resolution check. We have to use a
         // fixed load though, to prevent it from floating above the initialization.
         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
-        return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, options, counters));
+        return piCastToSnippetReplaceeStamp(allocateInstanceHelper(size, picHub, prototypeMarkWord, fillContents, threadRegister, constantSize, typeContext, counters));
     }
 
     @Snippet
     public static Object allocateInstanceDynamic(Class<?> type, Class<?> classClass, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
-                    @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
+                    @ConstantParameter Counters counters) {
         if (probability(SLOW_PATH_PROBABILITY, type == null)) {
             DeoptimizeNode.deopt(None, RuntimeConstraint);
         }
@@ -269,10 +274,10 @@
             DeoptimizeNode.deopt(None, RuntimeConstraint);
         }
 
-        return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, options, counters, nonNullType));
+        return PiNode.piCastToSnippetReplaceeStamp(allocateInstanceDynamicHelper(type, fillContents, threadRegister, counters, nonNullType));
     }
 
-    private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, OptionValues options, Counters counters, Class<?> nonNullType) {
+    private static Object allocateInstanceDynamicHelper(Class<?> type, boolean fillContents, Register threadRegister, Counters counters, Class<?> nonNullType) {
         KlassPointer hub = ClassGetHubNode.readClass(nonNullType);
         if (probability(FAST_PATH_PROBABILITY, !hub.isNull())) {
             KlassPointer nonNullHub = ClassGetHubNode.piCastNonNull(hub, SnippetAnchorNode.anchor());
@@ -291,7 +296,7 @@
                      * FIXME(je,ds): we should actually pass typeContext instead of "" but late
                      * binding of parameters is not yet supported by the GraphBuilderPlugin system.
                      */
-                    return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", options, counters);
+                    return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", counters);
                 }
             } else {
                 DeoptimizeNode.deopt(None, RuntimeConstraint);
@@ -308,19 +313,19 @@
     @Snippet
     public static Object allocatePrimitiveArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
-                    @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
+                    @ConstantParameter Counters counters) {
         // Primitive array types are eagerly pre-resolved. We can use a floating load.
         KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
-        return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
+        return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, counters);
     }
 
     @Snippet
     public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
                     @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
-                    @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
+                    @ConstantParameter Counters counters) {
         // Array type would be resolved by dominating resolution.
         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
-        return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
+        return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, counters);
     }
 
     @Snippet
@@ -333,9 +338,19 @@
                     @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean maybeUnroll,
                     @ConstantParameter String typeContext,
-                    @ConstantParameter OptionValues options,
                     @ConstantParameter Counters counters) {
-        Object result = allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, false, options, counters);
+        Object result = allocateArrayImpl(hub,
+                        length,
+                        prototypeMarkWord,
+                        headerSize,
+                        log2ElementSize,
+                        fillContents,
+                        threadRegister,
+                        maybeUnroll,
+                        typeContext,
+                        false,
+
+                        counters);
         return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
     }
 
@@ -349,7 +364,7 @@
     }
 
     private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister,
-                    boolean maybeUnroll, String typeContext, boolean skipNegativeCheck, OptionValues options, Counters counters) {
+                    boolean maybeUnroll, String typeContext, boolean skipNegativeCheck, Counters counters) {
         Object result;
         int allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize);
         Word thread = registerAsWord(threadRegister);
@@ -360,14 +375,15 @@
                         probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) {
             writeTlabTop(thread, newTop);
             emitPrefetchAllocate(newTop, true);
-            if (counters != null && counters.arrayLoopInit != null) {
-                counters.arrayLoopInit.inc();
+            Counters theCounters = counters;
+            if (theCounters != null && theCounters.arrayLoopInit != null) {
+                theCounters.arrayLoopInit.inc();
             }
             result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, counters);
         } else {
             result = newArrayStub(hub, length);
         }
-        profileAllocation("array", allocationSize, typeContext, options);
+        profileAllocation("array", allocationSize, typeContext);
         return result;
     }
 
@@ -421,14 +437,14 @@
 
     @Snippet
     public static Object allocateArrayDynamic(Class<?> elementType, Class<?> voidClass, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
-                    @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord, @ConstantParameter OptionValues options,
+                    @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord,
                     @ConstantParameter Counters counters) {
-        Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord, options, counters);
+        Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord, counters);
         return result;
     }
 
     private static Object allocateArrayDynamicImpl(Class<?> elementType, Class<?> voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind,
-                    int knownLayoutHelper, Word prototypeMarkWord, OptionValues options, Counters counters) {
+                    int knownLayoutHelper, Word prototypeMarkWord, Counters counters) {
         /*
          * We only need the dynamic check for void when we have no static information from
          * knownElementKind.
@@ -470,7 +486,7 @@
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
 
-        Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true, options, counters);
+        Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", true, counters);
         return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
     }
 
@@ -536,13 +552,14 @@
             offset += 4;
         }
         ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset");
+        Counters theCounters = counters;
         if (manualUnroll && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
             ReplacementsUtil.staticAssert(!constantSize, "size shouldn't be constant at instantiation time");
             // This case handles arrays of constant length. Instead of having a snippet variant for
             // each length, generate a chain of stores of maximum length. Once it's inlined the
             // break statement will trim excess stores.
-            if (counters != null && counters.instanceSeqInit != null) {
-                counters.instanceSeqInit.inc();
+            if (theCounters != null && theCounters.instanceSeqInit != null) {
+                theCounters.instanceSeqInit.inc();
             }
 
             explodeLoop();
@@ -556,13 +573,13 @@
             // Use Word instead of int to avoid extension to long in generated code
             Word off = WordFactory.signed(offset);
             if (constantSize && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
-                if (counters != null && counters.instanceSeqInit != null) {
-                    counters.instanceSeqInit.inc();
+                if (theCounters != null && theCounters.instanceSeqInit != null) {
+                    theCounters.instanceSeqInit.inc();
                 }
                 explodeLoop();
             } else {
-                if (counters != null && counters.instanceLoopInit != null) {
-                    counters.instanceLoopInit.inc();
+                if (theCounters != null && theCounters.instanceLoopInit != null) {
+                    theCounters.instanceLoopInit.inc();
                 }
             }
             for (; off.rawValue() < size; off = off.add(8)) {
@@ -694,7 +711,6 @@
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("constantSize", true);
             args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? type.toJavaName(false) : "");
-            args.addConst("options", localOptions);
             args.addConst("counters", counters);
 
             SnippetTemplate template = template(newInstanceNode, args);
@@ -738,7 +754,6 @@
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("maybeUnroll", length.isConstant());
             args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : "");
-            args.addConst("options", localOptions);
             args.addConst("counters", counters);
             SnippetTemplate template = template(newArrayNode, args);
             graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
@@ -747,14 +762,12 @@
 
         public void lower(DynamicNewInstanceNode newInstanceNode, HotSpotRegistersProvider registers, LoweringTool tool) {
             Arguments args = new Arguments(allocateInstanceDynamic, newInstanceNode.graph().getGuardsStage(), tool.getLoweringStage());
-            OptionValues localOptions = newInstanceNode.getOptions();
             args.add("type", newInstanceNode.getInstanceType());
             ValueNode classClass = newInstanceNode.getClassClass();
             assert classClass != null;
             args.add("classClass", classClass);
             args.addConst("fillContents", newInstanceNode.fillContents());
             args.addConst("threadRegister", registers.getThreadRegister());
-            args.addConst("options", localOptions);
             args.addConst("counters", counters);
 
             SnippetTemplate template = template(newInstanceNode, args);
@@ -763,7 +776,6 @@
 
         public void lower(DynamicNewArrayNode newArrayNode, HotSpotRegistersProvider registers, LoweringTool tool) {
             StructuredGraph graph = newArrayNode.graph();
-            OptionValues localOptions = graph.getOptions();
             Arguments args = new Arguments(allocateArrayDynamic, newArrayNode.graph().getGuardsStage(), tool.getLoweringStage());
             args.add("elementType", newArrayNode.getElementType());
             ValueNode voidClass = newArrayNode.getVoidClass();
@@ -784,7 +796,6 @@
                 args.addConst("knownLayoutHelper", 0);
             }
             args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord());
-            args.addConst("options", localOptions);
             args.addConst("counters", counters);
             SnippetTemplate template = template(newArrayNode, args);
             template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);