@Snippet public static void arraycopyGeneric( Object src, int srcPos, Object dest, int destPos, int length) { Object nonNullSrc = GraalDirectives.guardingNonNull(src); Object nonNullDest = GraalDirectives.guardingNonNull(dest); KlassPointer srcHub = loadHub(nonNullSrc); KlassPointer destHub = loadHub(nonNullDest); if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) { int layoutHelper = checkArrayType(srcHub); final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace(INJECTED_VMCONFIG)) == 0); checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); if (probability(FAST_PATH_PROBABILITY, isObjectArray)) { genericObjectExactCallCounter.inc(); genericObjectExactCallCopiedCounter.add(length); ArrayCopyCallNode.disjointArraycopy( nonNullSrc, srcPos, nonNullDest, destPos, length, JavaKind.Object); } else { genericPrimitiveCallCounter.inc(); genericPrimitiveCallCopiedCounter.add(length); UnsafeArrayCopyNode.arraycopyPrimitive( nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper); } } else { SystemArraycopyCounter.inc(); SystemArraycopyCopiedCounter.add(length); System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length); } }
/** * This is the basic template for the full arraycopy checks, including a check that the underlying * type is really an array type. */ @Snippet public static void arraycopySlowPathIntrinsic( Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetInfo slowPath, @ConstantParameter Object slowPathArgument) { Object nonNullSrc = GraalDirectives.guardingNonNull(src); Object nonNullDest = GraalDirectives.guardingNonNull(dest); KlassPointer srcHub = loadHub(nonNullSrc); KlassPointer destHub = loadHub(nonNullDest); checkArrayType(srcHub); checkArrayType(destHub); checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); if (length == 0) { zeroLengthDynamicCounter.inc(); } else { nonZeroLengthDynamicCounter.inc(); nonZeroLengthDynamicCopiedCounter.add(length); } ArrayCopySlowPathNode.arraycopy( nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind, slowPath, slowPathArgument); }
/** * This intrinsic is useful for the case where we know something statically about one of the * inputs but not the other. */ @Snippet public static void arraycopyPredictedExactIntrinsic( Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter) { Object nonNullSrc = GraalDirectives.guardingNonNull(src); Object nonNullDest = GraalDirectives.guardingNonNull(dest); KlassPointer srcHub = loadHub(nonNullSrc); KlassPointer destHub = loadHub(nonNullDest); if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); counter.inc(); copiedCounter.add(length); ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind); if (length == 0) { zeroLengthDynamicCounter.inc(); } else { nonZeroLengthDynamicCounter.inc(); nonZeroLengthDynamicCopiedCounter.add(length); } }
@Snippet public static void arraycopyZeroLengthIntrinsic( Object src, int srcPos, Object dest, int destPos, int length) { Object nonNullSrc = GraalDirectives.guardingNonNull(src); Object nonNullDest = GraalDirectives.guardingNonNull(dest); KlassPointer srcHub = loadHub(nonNullSrc); KlassPointer destHub = loadHub(nonNullDest); checkArrayType(srcHub); checkArrayType(destHub); checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); zeroLengthStaticCounter.inc(); }
/** Here the read should float after the loop. */ public static int testLoop9Snippet(int a, int b) { container.a = b; for (int i = 0; i < a; i++) { container.a = i; } GraalDirectives.controlFlowAnchor(); return container.a; }
/** Snippet for unrolled arraycopy. */ @Snippet public static void arraycopyUnrolledIntrinsic( Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter int unrolledLength, @ConstantParameter JavaKind elementKind) { Object nonNullSrc = GraalDirectives.guardingNonNull(src); Object nonNullDest = GraalDirectives.guardingNonNull(dest); checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); if (length == 0) { zeroLengthDynamicCounter.inc(); } else { nonZeroLengthDynamicCounter.inc(); nonZeroLengthDynamicCopiedCounter.add(length); } ArrayCopyUnrollNode.arraycopy( nonNullSrc, srcPos, nonNullDest, destPos, length, unrolledLength, elementKind); }
/** Here the read should not float to the end. */ public static int testLoop8Snippet(int a, int b) { int result = container.a; for (int i = 0; i < a; i++) { if (b < 0) { container.b = 10; break; } else { for (int j = 0; j < b; j++) { container.a = 0; } } } GraalDirectives.controlFlowAnchor(); return result; }