< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java
Print this page
rev 56282 : [mq]: graal
*** 1,7 ****
/*
! * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 23,36 ****
--- 23,38 ----
package org.graalvm.compiler.replacements.arraycopy;
import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE;
+ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
+ import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.DEOPT_PROBABILITY;
import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
import java.util.EnumMap;
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
*** 208,218 ****
if (probability(FREQUENT_PROBABILITY, length > 0)) {
Object nonNullSrc = PiNode.asNonNullObject(src);
Object nonNullDest = PiNode.asNonNullObject(dest);
Pointer srcKlass = loadHub(nonNullSrc);
Pointer destKlass = loadHub(nonNullDest);
! if (probability(LIKELY_PROBABILITY, srcKlass == destKlass)) {
// no storecheck required.
counters.objectCheckcastSameTypeCounter.inc();
counters.objectCheckcastSameTypeCopiedCounter.add(length);
ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length, heapWordSize());
} else {
--- 210,220 ----
if (probability(FREQUENT_PROBABILITY, length > 0)) {
Object nonNullSrc = PiNode.asNonNullObject(src);
Object nonNullDest = PiNode.asNonNullObject(dest);
Pointer srcKlass = loadHub(nonNullSrc);
Pointer destKlass = loadHub(nonNullDest);
! if (probability(LIKELY_PROBABILITY, srcKlass == destKlass) || probability(LIKELY_PROBABILITY, nonNullDest.getClass() == Object[].class)) {
// no storecheck required.
counters.objectCheckcastSameTypeCounter.inc();
counters.objectCheckcastSameTypeCopiedCounter.add(length);
ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length, heapWordSize());
} else {
*** 220,238 ****
Word superCheckOffset = getSuperCheckOffset(destElemKlass);
counters.objectCheckcastDifferentTypeCounter.inc();
counters.objectCheckcastDifferentTypeCopiedCounter.add(length);
! int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
! if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
! /*
! * the stub doesn't throw the ArrayStoreException, but returns the number of
! * copied elements (xor'd with -1).
! */
! copiedElements ^= -1;
! System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
! }
}
}
}
@SuppressWarnings("unused")
--- 222,232 ----
Word superCheckOffset = getSuperCheckOffset(destElemKlass);
counters.objectCheckcastDifferentTypeCounter.inc();
counters.objectCheckcastDifferentTypeCopiedCounter.add(length);
! System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
}
}
}
@SuppressWarnings("unused")
*** 259,274 ****
if (!IS_BUILDING_NATIVE_IMAGE) {
counters.lengthHistogram.inc(length);
}
}
private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
! if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) ||
! probability(SLOW_PATH_PROBABILITY, destPos < 0) ||
! probability(SLOW_PATH_PROBABILITY, length < 0) ||
! probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) ||
! probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
counters.checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
counters.checkSuccessCounter.inc();
}
--- 253,283 ----
if (!IS_BUILDING_NATIVE_IMAGE) {
counters.lengthHistogram.inc(length);
}
}
+ /**
+ * Writing this as individual if statements to avoid a merge without a frame state.
+ */
private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
! if (probability(DEOPT_PROBABILITY, srcPos < 0)) {
! counters.checkAIOOBECounter.inc();
! DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
! }
! if (probability(DEOPT_PROBABILITY, destPos < 0)) {
! counters.checkAIOOBECounter.inc();
! DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
! }
! if (probability(DEOPT_PROBABILITY, length < 0)) {
! counters.checkAIOOBECounter.inc();
! DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
! }
! if (probability(DEOPT_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length)) {
! counters.checkAIOOBECounter.inc();
! DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
! }
! if (probability(DEOPT_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
counters.checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
counters.checkSuccessCounter.inc();
}
*** 277,293 ****
if (arrayTypeCheck == ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK) {
// nothing to do
} else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) {
Pointer srcHub = loadHub(nonNullSrc);
Pointer destHub = loadHub(nonNullDest);
! if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
} else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
Pointer srcHub = loadHub(nonNullSrc);
Pointer destHub = loadHub(nonNullDest);
! if (probability(SLOW_PATH_PROBABILITY, getReadLayoutHelper(srcHub) != getReadLayoutHelper(destHub))) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
} else {
ReplacementsUtil.staticAssert(false, "unknown array type check ", arrayTypeCheck);
}
--- 286,302 ----
if (arrayTypeCheck == ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK) {
// nothing to do
} else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) {
Pointer srcHub = loadHub(nonNullSrc);
Pointer destHub = loadHub(nonNullDest);
! if (probability(DEOPT_PROBABILITY, srcHub != destHub)) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
} else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
Pointer srcHub = loadHub(nonNullSrc);
Pointer destHub = loadHub(nonNullDest);
! if (probability(DEOPT_PROBABILITY, getReadLayoutHelper(srcHub) != getReadLayoutHelper(destHub))) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
} else {
ReplacementsUtil.staticAssert(false, "unknown array type check ", arrayTypeCheck);
}
*** 411,420 ****
--- 420,433 ----
} else if (srcComponentType == null && destComponentType == null) {
// we don't know anything about the types - use the generic copying
snippetInfo = arraycopyGenericSnippet;
// no need for additional type check to avoid duplicated work
arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+ } else if (GeneratePIC.getValue(options)) {
+ // use generic copying for AOT compilation
+ snippetInfo = arraycopyGenericSnippet;
+ arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
} else if (srcComponentType != null && destComponentType != null) {
if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
// it depends on the array content if the copy succeeds - we need
// a type check for every store
snippetInfo = arraycopyCheckcastSnippet;
< prev index next >