public void lower(ArrayCopyUnrollNode arraycopy, LoweringTool tool) { StructuredGraph graph = arraycopy.graph(); if (!graph.getGuardsStage().areFrameStatesAtDeopts()) { // Can't be lowered yet return; } SnippetInfo snippetInfo = arraycopyUnrolledWorkSnippet; Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage()); args.add("nonNullSrc", arraycopy.getSource()); args.add("srcPos", arraycopy.getSourcePosition()); args.add("nonNullDest", arraycopy.getDestination()); args.add("destPos", arraycopy.getDestinationPosition()); args.addConst("length", arraycopy.getUnrollLength()); args.addConst("elementKind", arraycopy.getElementKind()); template(args) .instantiate( providers.getMetaAccess(), arraycopy, SnippetTemplate.DEFAULT_REPLACER, args); }
public void lower(ArrayCopySlowPathNode arraycopy, LoweringTool tool) { StructuredGraph graph = arraycopy.graph(); if (!graph.getGuardsStage().areFrameStatesAtDeopts()) { // Can't be lowered yet return; } SnippetInfo snippetInfo = arraycopy.getSnippet(); Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage()); args.add("nonNullSrc", arraycopy.getSource()); args.add("srcPos", arraycopy.getSourcePosition()); args.add("nonNullDest", arraycopy.getDestination()); args.add("destPos", arraycopy.getDestinationPosition()); if (snippetInfo == arraycopyUnrolledWorkSnippet) { args.addConst("length", ((Integer) arraycopy.getArgument()).intValue()); args.addConst("elementKind", arraycopy.getElementKind()); } else { args.add("length", arraycopy.getLength()); } if (snippetInfo == arraycopyPredictedObjectWorkSnippet) { HotSpotResolvedObjectType arrayKlass = (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(Object[].class); ValueNode objectArrayKlass = ConstantNode.forConstant( KlassPointerStamp.klassNonNull(), arrayKlass.klass(), tool.getMetaAccess(), arraycopy.graph()); args.add("objectArrayKlass", objectArrayKlass); args.addConst("counter", arraycopyCallCounters.get(JavaKind.Object)); args.addConst("copiedCounter", arraycopyCallCopiedCounters.get(JavaKind.Object)); } instantiate(args, arraycopy); }
public void lower(ArrayCopyNode arraycopy, LoweringTool tool) { JavaKind componentKind = selectComponentKind(arraycopy); SnippetInfo snippetInfo = null; SnippetInfo slowPathSnippetInfo = null; Object slowPathArgument = null; if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) { snippetInfo = arraycopyZeroLengthIntrinsicSnippet; } else if (arraycopy.isExact()) { snippetInfo = arraycopyExactIntrinsicSnippet; if (shouldUnroll(arraycopy.getLength())) { snippetInfo = arraycopyUnrolledIntrinsicSnippet; } } else { if (componentKind == JavaKind.Object) { ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp()); ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp()); ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType(); ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType(); if (srcComponentType != null && destComponentType != null && !srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) { snippetInfo = arraycopySlowPathIntrinsicSnippet; slowPathSnippetInfo = checkcastArraycopyWorkSnippet; slowPathArgument = LocationIdentity.any(); /* * Because this snippet has to use Sysytem.arraycopy as a slow path, we must * pretend to kill any() so clear the componentKind. */ componentKind = null; } } if (componentKind == null && snippetInfo == null) { JavaKind predictedKind = selectComponentKind(arraycopy, false); if (predictedKind != null) { /* * At least one array is of a known type requiring no store checks, so * assume the other is of the same type. Generally this is working around * deficiencies in our propagation of type information. */ componentKind = predictedKind; if (predictedKind == JavaKind.Object) { snippetInfo = arraycopySlowPathIntrinsicSnippet; slowPathSnippetInfo = arraycopyPredictedObjectWorkSnippet; slowPathArgument = predictedKind; componentKind = null; } else { snippetInfo = arraycopyPredictedExactIntrinsicSnippet; } } } if (snippetInfo == null) { snippetInfo = arraycopyGenericSnippet; } } Arguments args = new Arguments(snippetInfo, arraycopy.graph().getGuardsStage(), tool.getLoweringStage()); args.add("src", arraycopy.getSource()); args.add("srcPos", arraycopy.getSourcePosition()); args.add("dest", arraycopy.getDestination()); args.add("destPos", arraycopy.getDestinationPosition()); args.add("length", arraycopy.getLength()); if (snippetInfo == arraycopyUnrolledIntrinsicSnippet) { args.addConst("unrolledLength", arraycopy.getLength().asJavaConstant().asInt()); args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal); } else if (snippetInfo == arraycopySlowPathIntrinsicSnippet) { args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal); args.addConst("slowPath", slowPathSnippetInfo); assert slowPathArgument != null; args.addConst("slowPathArgument", slowPathArgument); } else if (snippetInfo == arraycopyExactIntrinsicSnippet || snippetInfo == arraycopyPredictedExactIntrinsicSnippet) { assert componentKind != null; args.addConst("elementKind", componentKind); args.addConst("counter", arraycopyCallCounters.get(componentKind)); args.addConst("copiedCounter", arraycopyCallCopiedCounters.get(componentKind)); } instantiate(args, arraycopy); }