src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54914 9feb4852536f
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     1 /*
     1 /*
     2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    41 import java.nio.ByteOrder;
    41 import java.nio.ByteOrder;
    42 import java.util.ArrayList;
    42 import java.util.ArrayList;
    43 import java.util.BitSet;
    43 import java.util.BitSet;
    44 import java.util.List;
    44 import java.util.List;
    45 
    45 
       
    46 import jdk.vm.ci.meta.JavaConstant;
    46 import org.graalvm.compiler.api.directives.GraalDirectives;
    47 import org.graalvm.compiler.api.directives.GraalDirectives;
    47 import org.graalvm.compiler.api.replacements.Snippet;
    48 import org.graalvm.compiler.api.replacements.Snippet;
    48 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
    49 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
    49 import org.graalvm.compiler.core.common.LIRKind;
    50 import org.graalvm.compiler.core.common.LIRKind;
    50 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
    51 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
    51 import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
    52 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
    52 import org.graalvm.compiler.core.common.type.IntegerStamp;
    53 import org.graalvm.compiler.core.common.type.IntegerStamp;
    53 import org.graalvm.compiler.core.common.type.ObjectStamp;
    54 import org.graalvm.compiler.core.common.type.ObjectStamp;
    54 import org.graalvm.compiler.core.common.type.Stamp;
    55 import org.graalvm.compiler.core.common.type.Stamp;
    55 import org.graalvm.compiler.core.common.type.StampFactory;
    56 import org.graalvm.compiler.core.common.type.StampFactory;
    56 import org.graalvm.compiler.core.common.type.TypeReference;
    57 import org.graalvm.compiler.core.common.type.TypeReference;
    59 import org.graalvm.compiler.debug.GraalError;
    60 import org.graalvm.compiler.debug.GraalError;
    60 import org.graalvm.compiler.graph.Node;
    61 import org.graalvm.compiler.graph.Node;
    61 import org.graalvm.compiler.nodeinfo.InputType;
    62 import org.graalvm.compiler.nodeinfo.InputType;
    62 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
    63 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
    63 import org.graalvm.compiler.nodes.ConstantNode;
    64 import org.graalvm.compiler.nodes.ConstantNode;
       
    65 import org.graalvm.compiler.nodes.EndNode;
    64 import org.graalvm.compiler.nodes.FieldLocationIdentity;
    66 import org.graalvm.compiler.nodes.FieldLocationIdentity;
    65 import org.graalvm.compiler.nodes.FixedNode;
    67 import org.graalvm.compiler.nodes.FixedNode;
       
    68 import org.graalvm.compiler.nodes.FixedWithNextNode;
       
    69 import org.graalvm.compiler.nodes.IfNode;
    66 import org.graalvm.compiler.nodes.LogicNode;
    70 import org.graalvm.compiler.nodes.LogicNode;
       
    71 import org.graalvm.compiler.nodes.MergeNode;
    67 import org.graalvm.compiler.nodes.NamedLocationIdentity;
    72 import org.graalvm.compiler.nodes.NamedLocationIdentity;
    68 import org.graalvm.compiler.nodes.NodeView;
    73 import org.graalvm.compiler.nodes.NodeView;
       
    74 import org.graalvm.compiler.nodes.PhiNode;
    69 import org.graalvm.compiler.nodes.PiNode;
    75 import org.graalvm.compiler.nodes.PiNode;
    70 import org.graalvm.compiler.nodes.StructuredGraph;
    76 import org.graalvm.compiler.nodes.StructuredGraph;
    71 import org.graalvm.compiler.nodes.ValueNode;
    77 import org.graalvm.compiler.nodes.ValueNode;
       
    78 import org.graalvm.compiler.nodes.ValuePhiNode;
    72 import org.graalvm.compiler.nodes.calc.AddNode;
    79 import org.graalvm.compiler.nodes.calc.AddNode;
    73 import org.graalvm.compiler.nodes.calc.ConditionalNode;
    80 import org.graalvm.compiler.nodes.calc.ConditionalNode;
    74 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
    81 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
    75 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
    82 import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
    76 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
    83 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
    90 import org.graalvm.compiler.nodes.extended.GuardingNode;
    97 import org.graalvm.compiler.nodes.extended.GuardingNode;
    91 import org.graalvm.compiler.nodes.extended.JavaReadNode;
    98 import org.graalvm.compiler.nodes.extended.JavaReadNode;
    92 import org.graalvm.compiler.nodes.extended.JavaWriteNode;
    99 import org.graalvm.compiler.nodes.extended.JavaWriteNode;
    93 import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode;
   100 import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode;
    94 import org.graalvm.compiler.nodes.extended.LoadHubNode;
   101 import org.graalvm.compiler.nodes.extended.LoadHubNode;
       
   102 import org.graalvm.compiler.nodes.extended.LoadHubOrNullNode;
    95 import org.graalvm.compiler.nodes.extended.MembarNode;
   103 import org.graalvm.compiler.nodes.extended.MembarNode;
    96 import org.graalvm.compiler.nodes.extended.RawLoadNode;
   104 import org.graalvm.compiler.nodes.extended.RawLoadNode;
    97 import org.graalvm.compiler.nodes.extended.RawStoreNode;
   105 import org.graalvm.compiler.nodes.extended.RawStoreNode;
    98 import org.graalvm.compiler.nodes.extended.UnboxNode;
   106 import org.graalvm.compiler.nodes.extended.UnboxNode;
    99 import org.graalvm.compiler.nodes.extended.UnsafeMemoryLoadNode;
   107 import org.graalvm.compiler.nodes.extended.UnsafeMemoryLoadNode;
   138 import org.graalvm.compiler.options.OptionValues;
   146 import org.graalvm.compiler.options.OptionValues;
   139 import org.graalvm.compiler.phases.util.Providers;
   147 import org.graalvm.compiler.phases.util.Providers;
   140 import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
   148 import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
   141 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
   149 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
   142 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
   150 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
   143 import org.graalvm.compiler.word.WordTypes;
       
   144 import jdk.internal.vm.compiler.word.LocationIdentity;
   151 import jdk.internal.vm.compiler.word.LocationIdentity;
   145 
   152 
   146 import jdk.vm.ci.code.CodeUtil;
   153 import jdk.vm.ci.code.CodeUtil;
   147 import jdk.vm.ci.code.MemoryBarriers;
   154 import jdk.vm.ci.code.MemoryBarriers;
   148 import jdk.vm.ci.code.TargetDescription;
   155 import jdk.vm.ci.code.TargetDescription;
   164     protected final MetaAccessProvider metaAccess;
   171     protected final MetaAccessProvider metaAccess;
   165     protected final ForeignCallsProvider foreignCalls;
   172     protected final ForeignCallsProvider foreignCalls;
   166     protected final TargetDescription target;
   173     protected final TargetDescription target;
   167     private final boolean useCompressedOops;
   174     private final boolean useCompressedOops;
   168     private final ResolvedJavaType objectArrayType;
   175     private final ResolvedJavaType objectArrayType;
   169     private final WordTypes wordTypes;
       
   170 
   176 
   171     private BoxingSnippets.Templates boxingSnippets;
   177     private BoxingSnippets.Templates boxingSnippets;
   172     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
   178     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
   173 
   179 
   174     public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
   180     public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
   175         this.metaAccess = metaAccess;
   181         this.metaAccess = metaAccess;
   176         this.foreignCalls = foreignCalls;
   182         this.foreignCalls = foreignCalls;
   177         this.target = target;
   183         this.target = target;
   178         this.useCompressedOops = useCompressedOops;
   184         this.useCompressedOops = useCompressedOops;
   179         this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
   185         this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
   180         this.wordTypes = new WordTypes(metaAccess, target.wordJavaKind);
       
   181     }
   186     }
   182 
   187 
   183     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
   188     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
   184         boxingSnippets = new BoxingSnippets.Templates(options, factories, factory, providers, snippetReflection, target);
   189         boxingSnippets = new BoxingSnippets.Templates(options, factories, factory, providers, snippetReflection, target);
   185         indexOfSnippets = new ConstantStringIndexOfSnippets.Templates(options, factories, providers, snippetReflection, target);
   190         indexOfSnippets = new ConstantStringIndexOfSnippets.Templates(options, factories, providers, snippetReflection, target);
   212                 lowerIndexAddressNode((IndexAddressNode) n);
   217                 lowerIndexAddressNode((IndexAddressNode) n);
   213             } else if (n instanceof ArrayLengthNode) {
   218             } else if (n instanceof ArrayLengthNode) {
   214                 lowerArrayLengthNode((ArrayLengthNode) n, tool);
   219                 lowerArrayLengthNode((ArrayLengthNode) n, tool);
   215             } else if (n instanceof LoadHubNode) {
   220             } else if (n instanceof LoadHubNode) {
   216                 lowerLoadHubNode((LoadHubNode) n, tool);
   221                 lowerLoadHubNode((LoadHubNode) n, tool);
       
   222             } else if (n instanceof LoadHubOrNullNode) {
       
   223                 lowerLoadHubOrNullNode((LoadHubOrNullNode) n, tool);
   217             } else if (n instanceof LoadArrayComponentHubNode) {
   224             } else if (n instanceof LoadArrayComponentHubNode) {
   218                 lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);
   225                 lowerLoadArrayComponentHubNode((LoadArrayComponentHubNode) n);
   219             } else if (n instanceof MonitorEnterNode) {
   226             } else if (n instanceof MonitorEnterNode) {
   220                 lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph);
   227                 lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph);
   221             } else if (n instanceof UnsafeCompareAndSwapNode) {
   228             } else if (n instanceof UnsafeCompareAndSwapNode) {
   434         ValueNode positiveIndex = graph.maybeAddOrUnique(PiNode.create(index, POSITIVE_ARRAY_INDEX_STAMP, boundsCheck != null ? boundsCheck.asNode() : null));
   441         ValueNode positiveIndex = graph.maybeAddOrUnique(PiNode.create(index, POSITIVE_ARRAY_INDEX_STAMP, boundsCheck != null ? boundsCheck.asNode() : null));
   435         return createArrayAddress(graph, array, elementKind, positiveIndex);
   442         return createArrayAddress(graph, array, elementKind, positiveIndex);
   436     }
   443     }
   437 
   444 
   438     public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
   445     public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
       
   446         return createArrayAddress(graph, array, elementKind, elementKind, index);
       
   447     }
       
   448 
       
   449     public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind arrayKind, JavaKind elementKind, ValueNode index) {
   439         ValueNode wordIndex;
   450         ValueNode wordIndex;
   440         if (target.wordSize > 4) {
   451         if (target.wordSize > 4) {
   441             wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
   452             wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
   442         } else {
   453         } else {
   443             assert target.wordSize == 4 : "unsupported word size";
   454             assert target.wordSize == 4 : "unsupported word size";
   445         }
   456         }
   446 
   457 
   447         int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
   458         int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
   448         ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
   459         ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
   449 
   460 
   450         int base = metaAccess.getArrayBaseOffset(elementKind);
   461         int base = metaAccess.getArrayBaseOffset(arrayKind);
   451         ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
   462         ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
   452 
   463 
   453         return graph.unique(new OffsetAddressNode(array, offset));
   464         return graph.unique(new OffsetAddressNode(array, offset));
   454     }
   465     }
   455 
   466 
   456     protected void lowerIndexAddressNode(IndexAddressNode indexAddress) {
   467     protected void lowerIndexAddressNode(IndexAddressNode indexAddress) {
   457         AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getElementKind(), indexAddress.getIndex());
   468         AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getArrayKind(), indexAddress.getElementKind(), indexAddress.getIndex());
   458         indexAddress.replaceAndDelete(lowered);
   469         indexAddress.replaceAndDelete(lowered);
   459     }
   470     }
   460 
   471 
   461     protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
   472     protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) {
   462         StructuredGraph graph = loadIndexed.graph();
   473         StructuredGraph graph = loadIndexed.graph();
   515             }
   526             }
   516         }
   527         }
   517 
   528 
   518         AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
   529         AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
   519         WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value),
   530         WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value),
   520                         arrayStoreBarrierType(array, storeIndexed.elementKind())));
   531                         arrayStoreBarrierType(storeIndexed.elementKind())));
   521         memoryWrite.setGuard(boundsCheck);
   532         memoryWrite.setGuard(boundsCheck);
   522         if (condition != null) {
   533         if (condition != null) {
   523             tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
   534             tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
   524         }
   535         }
   525         memoryWrite.setStateAfter(storeIndexed.stateAfter());
   536         memoryWrite.setStateAfter(storeIndexed.stateAfter());
   554         if (graph.getGuardsStage().allowsFloatingGuards()) {
   565         if (graph.getGuardsStage().allowsFloatingGuards()) {
   555             return;
   566             return;
   556         }
   567         }
   557         ValueNode hub = createReadHub(graph, loadHub.getValue(), tool);
   568         ValueNode hub = createReadHub(graph, loadHub.getValue(), tool);
   558         loadHub.replaceAtUsagesAndDelete(hub);
   569         loadHub.replaceAtUsagesAndDelete(hub);
       
   570     }
       
   571 
       
   572     protected void lowerLoadHubOrNullNode(LoadHubOrNullNode loadHubOrNullNode, LoweringTool tool) {
       
   573         StructuredGraph graph = loadHubOrNullNode.graph();
       
   574         if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
       
   575             return;
       
   576         }
       
   577         if (graph.getGuardsStage().allowsFloatingGuards()) {
       
   578             return;
       
   579         }
       
   580         final FixedWithNextNode predecessor = tool.lastFixedNode();
       
   581         final ValueNode value = loadHubOrNullNode.getValue();
       
   582         AbstractPointerStamp stamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT);
       
   583         final LogicNode isNull = graph.addOrUniqueWithInputs(IsNullNode.create(value));
       
   584         final EndNode trueEnd = graph.add(new EndNode());
       
   585         final EndNode falseEnd = graph.add(new EndNode());
       
   586         final IfNode ifNode = graph.add(new IfNode(isNull, trueEnd, falseEnd, 0.5));
       
   587         final MergeNode merge = graph.add(new MergeNode());
       
   588         merge.addForwardEnd(trueEnd);
       
   589         merge.addForwardEnd(falseEnd);
       
   590         final AbstractPointerStamp hubStamp = (AbstractPointerStamp) loadHubOrNullNode.stamp(NodeView.DEFAULT);
       
   591         ValueNode nullHub = ConstantNode.forConstant(hubStamp.asAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), graph);
       
   592         final ValueNode nonNullValue = graph.addOrUniqueWithInputs(PiNode.create(value, stamp.asNonNull(), ifNode.falseSuccessor()));
       
   593         ValueNode hub = createReadHub(graph, nonNullValue, tool);
       
   594         ValueNode[] values = new ValueNode[]{nullHub, hub};
       
   595         final PhiNode hubPhi = graph.unique(new ValuePhiNode(hubStamp, merge, values));
       
   596         final FixedNode oldNext = predecessor.next();
       
   597         predecessor.setNext(ifNode);
       
   598         merge.setNext(oldNext);
       
   599         loadHubOrNullNode.replaceAtUsagesAndDelete(hubPhi);
   559     }
   600     }
   560 
   601 
   561     protected void lowerLoadArrayComponentHubNode(LoadArrayComponentHubNode loadHub) {
   602     protected void lowerLoadArrayComponentHubNode(LoadArrayComponentHubNode loadHub) {
   562         StructuredGraph graph = loadHub.graph();
   603         StructuredGraph graph = loadHub.graph();
   563         ValueNode hub = createReadArrayComponentHub(graph, loadHub.getValue(), loadHub);
   604         ValueNode hub = createReadArrayComponentHub(graph, loadHub.getValue(), loadHub);
   764                     if (virtual instanceof VirtualInstanceNode) {
   805                     if (virtual instanceof VirtualInstanceNode) {
   765                         newObject = graph.add(createNewInstanceFromVirtual(virtual));
   806                         newObject = graph.add(createNewInstanceFromVirtual(virtual));
   766                     } else {
   807                     } else {
   767                         newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
   808                         newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
   768                     }
   809                     }
       
   810                     // The final STORE_STORE barrier will be emitted by finishAllocatedObjects
       
   811                     newObject.clearEmitMemoryBarrier();
   769 
   812 
   770                     recursiveLowerings.add(newObject);
   813                     recursiveLowerings.add(newObject);
   771                     graph.addBeforeFixed(commit, newObject);
   814                     graph.addBeforeFixed(commit, newObject);
   772                     allocations[objIndex] = newObject;
   815                     allocations[objIndex] = newObject;
   773                     for (int i = 0; i < entryCount; i++) {
   816                     for (int i = 0; i < entryCount; i++) {
   790                             if (virtual instanceof VirtualInstanceNode) {
   833                             if (virtual instanceof VirtualInstanceNode) {
   791                                 ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
   834                                 ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
   792                                 long offset = fieldOffset(field);
   835                                 long offset = fieldOffset(field);
   793                                 if (offset >= 0) {
   836                                 if (offset >= 0) {
   794                                     address = createOffsetAddress(graph, newObject, offset);
   837                                     address = createOffsetAddress(graph, newObject, offset);
   795                                     barrierType = fieldInitializationBarrier(field);
   838                                     barrierType = fieldInitializationBarrier(entryKind);
   796                                 }
   839                                 }
   797                             } else {
   840                             } else {
   798                                 address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(entryKind) + i * metaAccess.getArrayIndexScale(entryKind));
   841                                 address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(entryKind) + i * metaAccess.getArrayIndexScale(entryKind));
   799                                 barrierType = arrayInitializationBarrier(newObject, entryKind);
   842                                 barrierType = arrayInitializationBarrier(entryKind);
   800                             }
   843                             }
   801                             if (address != null) {
   844                             if (address != null) {
   802                                 WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
   845                                 WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
   803                                 graph.addAfterFixed(newObject, graph.add(write));
   846                                 graph.addAfterFixed(newObject, graph.add(write));
   804                             }
   847                             }
   827                                     VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
   870                                     VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
   828                                     address = createFieldAddress(graph, newObject, virtualInstance.field(i));
   871                                     address = createFieldAddress(graph, newObject, virtualInstance.field(i));
   829                                     barrierType = fieldStoreBarrierType(virtualInstance.field(i));
   872                                     barrierType = fieldStoreBarrierType(virtualInstance.field(i));
   830                                 } else {
   873                                 } else {
   831                                     address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
   874                                     address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
   832                                     barrierType = arrayStoreBarrierType(newObject, virtual.entryKind(i));
   875                                     barrierType = arrayStoreBarrierType(virtual.entryKind(i));
   833                                 }
   876                                 }
   834                                 if (address != null) {
   877                                 if (address != null) {
   835                                     WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
   878                                     WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
   836                                     graph.addBeforeFixed(commit, graph.add(write));
   879                                     graph.addBeforeFixed(commit, graph.add(write));
   837                                 }
   880                                 }
   941     protected BarrierType fieldLoadBarrierType(ResolvedJavaField field) {
   984     protected BarrierType fieldLoadBarrierType(ResolvedJavaField field) {
   942         return BarrierType.NONE;
   985         return BarrierType.NONE;
   943     }
   986     }
   944 
   987 
   945     protected BarrierType fieldStoreBarrierType(ResolvedJavaField field) {
   988     protected BarrierType fieldStoreBarrierType(ResolvedJavaField field) {
   946         JavaKind fieldKind = wordTypes.asKind(field.getType());
   989         if (getStorageKind(field) == JavaKind.Object) {
   947         if (fieldKind == JavaKind.Object) {
       
   948             return BarrierType.FIELD;
   990             return BarrierType.FIELD;
   949         }
   991         }
   950         return BarrierType.NONE;
   992         return BarrierType.NONE;
   951     }
   993     }
   952 
   994 
   953     /**
   995     protected BarrierType arrayStoreBarrierType(JavaKind elementKind) {
   954      * If the given value is indeed an array, and its elements are of a word type, return the
   996         if (elementKind == JavaKind.Object) {
   955      * correct word kind; in all other cases, return the defaultElementKind. This is needed for
       
   956      * determining the correct write barrier type.
       
   957      *
       
   958      * @param array a value that is expected to have an array stamp
       
   959      * @param defaultElementKind the array's element kind without taking word types into account
       
   960      * @return the element kind of the array taking word types into account
       
   961      */
       
   962     protected JavaKind maybeWordArrayElementKind(ValueNode array, JavaKind defaultElementKind) {
       
   963         JavaKind elementKind = defaultElementKind;
       
   964         Stamp arrayStamp = array.stamp(NodeView.DEFAULT);
       
   965         if (arrayStamp instanceof AbstractObjectStamp && arrayStamp.hasValues()) {
       
   966             ResolvedJavaType arrayType = ((AbstractObjectStamp) arrayStamp).type();
       
   967             if (arrayType != null && arrayType.getComponentType() != null) {
       
   968                 elementKind = wordTypes.asKind(arrayType.getComponentType());
       
   969             }
       
   970         }
       
   971         return elementKind;
       
   972     }
       
   973 
       
   974     protected BarrierType arrayStoreBarrierType(ValueNode array, JavaKind elementKind) {
       
   975         JavaKind kind = maybeWordArrayElementKind(array, elementKind);
       
   976         if (kind == JavaKind.Object) {
       
   977             return BarrierType.ARRAY;
   997             return BarrierType.ARRAY;
   978         }
   998         }
   979         return BarrierType.NONE;
   999         return BarrierType.NONE;
   980     }
  1000     }
   981 
  1001 
   982     public BarrierType fieldInitializationBarrier(ResolvedJavaField field) {
  1002     public BarrierType fieldInitializationBarrier(JavaKind entryKind) {
   983         JavaKind fieldKind = wordTypes.asKind(field.getType());
  1003         return entryKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
   984         return fieldKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
  1004     }
   985     }
  1005 
   986 
  1006     public BarrierType arrayInitializationBarrier(JavaKind entryKind) {
   987     public BarrierType arrayInitializationBarrier(ValueNode array, JavaKind entryKind) {
  1007         return entryKind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
   988         JavaKind kind = maybeWordArrayElementKind(array, entryKind);
       
   989         return kind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
       
   990     }
  1008     }
   991 
  1009 
   992     private BarrierType unsafeStoreBarrierType(RawStoreNode store) {
  1010     private BarrierType unsafeStoreBarrierType(RawStoreNode store) {
   993         if (!store.needsBarrier()) {
  1011         if (!store.needsBarrier()) {
   994             return BarrierType.NONE;
  1012             return BarrierType.NONE;
  1000         if (value.getStackKind() == JavaKind.Object && object.getStackKind() == JavaKind.Object) {
  1018         if (value.getStackKind() == JavaKind.Object && object.getStackKind() == JavaKind.Object) {
  1001             ResolvedJavaType type = StampTool.typeOrNull(object);
  1019             ResolvedJavaType type = StampTool.typeOrNull(object);
  1002             // Array types must use a precise barrier, so if the type is unknown or is a supertype
  1020             // Array types must use a precise barrier, so if the type is unknown or is a supertype
  1003             // of Object[] then treat it as an array.
  1021             // of Object[] then treat it as an array.
  1004             if (type != null && type.isArray()) {
  1022             if (type != null && type.isArray()) {
  1005                 return arrayStoreBarrierType(object, JavaKind.Object);
  1023                 return BarrierType.ARRAY;
  1006             } else if (type != null && wordTypes.isWord(type)) {
       
  1007                 return BarrierType.NONE;
       
  1008             } else if (type == null || type.isAssignableFrom(objectArrayType)) {
  1024             } else if (type == null || type.isAssignableFrom(objectArrayType)) {
  1009                 return BarrierType.UNKNOWN;
  1025                 return BarrierType.UNKNOWN;
  1010             } else {
  1026             } else {
  1011                 return BarrierType.FIELD;
  1027                 return BarrierType.FIELD;
  1012             }
  1028             }