--- old/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2016-02-29 20:05:42.196475821 +0300 +++ new/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2016-02-29 20:05:42.072475825 +0300 @@ -765,6 +765,59 @@ public native Object allocateInstance(Class cls) throws InstantiationException; + /** + * Allocates an array of a given type, but does not do zeroing. + *

+ * This method should only be used in the very rare cases where a high-performance code + * overwrites the destination array completely, and compilers cannot assist in zeroing elimination. + * In an overwhelming majority of cases, a normal Java allocation should be used instead. + *

+ * Users of this method are required to overwrite the initial (garbage) array contents + * before allowing untrusted code, or code in other threads, to observe the reference + * to the newly allocated array. In addition, the publication of the array reference must be + * safe according to the Java Memory Model requirements. + *

+ * The safest approach to deal with an uninitialized array is to keep the reference to it in local + * variable at least until the initialization is complete, and then publish it once, either + * by writing it to a volatile field, or storing it into a final field in constructor, + * or issuing a {@link #storeFence} before publishing the reference. + *

+ * @implnote This method can only allocate primitive arrays, to avoid garbage reference + * elements that could break heap integrity. + * + * @param componentType array component type to allocate + * @param length array size to allocate + * @throws IllegalArgumentException if component type is null, or not a primitive class; + * or the length is negative + */ + public Object allocateUninitializedArray(Class componentType, int length) { + if (componentType == null) { + throw new IllegalArgumentException("Component type is null"); + } + if (!componentType.isPrimitive()) { + throw new IllegalArgumentException("Component type is not primitive"); + } + if (length < 0) { + throw new IllegalArgumentException("Negative length"); + } + return allocateUninitializedArray0(componentType, length); + } + + @HotSpotIntrinsicCandidate + private Object allocateUninitializedArray0(Class componentType, int length) { + // These fallbacks provide zeroed arrays, but intrinsic is not required to + // return the zeroed arrays. + if (componentType == byte.class) return new byte[length]; + if (componentType == boolean.class) return new boolean[length]; + if (componentType == short.class) return new short[length]; + if (componentType == char.class) return new char[length]; + if (componentType == int.class) return new int[length]; + if (componentType == float.class) return new float[length]; + if (componentType == long.class) return new long[length]; + if (componentType == double.class) return new double[length]; + return null; + } + /** Throws the exception without telling the verifier. */ public native void throwException(Throwable ee);