001/*
002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.hotspot.replacements;
024
025import java.lang.reflect.*;
026import java.util.*;
027
028import jdk.internal.jvmci.common.*;
029import jdk.internal.jvmci.meta.*;
030
031import com.oracle.graal.api.directives.*;
032import com.oracle.graal.hotspot.replacements.arraycopy.*;
033import com.oracle.graal.nodes.java.*;
034import com.oracle.graal.replacements.*;
035
036public class ObjectCloneSnippets implements Snippets {
037
038    public static final EnumMap<Kind, Method> arrayCloneMethods = new EnumMap<>(Kind.class);
039
040    static {
041        arrayCloneMethods.put(Kind.Boolean, getCloneMethod("booleanArrayClone", boolean[].class));
042        arrayCloneMethods.put(Kind.Byte, getCloneMethod("byteArrayClone", byte[].class));
043        arrayCloneMethods.put(Kind.Char, getCloneMethod("charArrayClone", char[].class));
044        arrayCloneMethods.put(Kind.Short, getCloneMethod("shortArrayClone", short[].class));
045        arrayCloneMethods.put(Kind.Int, getCloneMethod("intArrayClone", int[].class));
046        arrayCloneMethods.put(Kind.Float, getCloneMethod("floatArrayClone", float[].class));
047        arrayCloneMethods.put(Kind.Long, getCloneMethod("longArrayClone", long[].class));
048        arrayCloneMethods.put(Kind.Double, getCloneMethod("doubleArrayClone", double[].class));
049        arrayCloneMethods.put(Kind.Object, getCloneMethod("objectArrayClone", Object[].class));
050    }
051
052    private static Method getCloneMethod(String name, Class<?> param) {
053        try {
054            return ObjectCloneSnippets.class.getDeclaredMethod(name, param);
055        } catch (SecurityException | NoSuchMethodException e) {
056            throw new JVMCIError(e);
057        }
058    }
059
060    @Snippet
061    public static boolean[] booleanArrayClone(boolean[] src) {
062        boolean[] result = (boolean[]) NewArrayNode.newUninitializedArray(Boolean.TYPE, src.length);
063        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Boolean);
064        return result;
065    }
066
067    @Snippet
068    public static byte[] byteArrayClone(byte[] src) {
069        byte[] result = (byte[]) NewArrayNode.newUninitializedArray(Byte.TYPE, src.length);
070        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Byte);
071        return result;
072    }
073
074    @Snippet
075    public static short[] shortArrayClone(short[] src) {
076        short[] result = (short[]) NewArrayNode.newUninitializedArray(Short.TYPE, src.length);
077        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Short);
078        return result;
079    }
080
081    @Snippet
082    public static char[] charArrayClone(char[] src) {
083        char[] result = (char[]) NewArrayNode.newUninitializedArray(Character.TYPE, src.length);
084        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Char);
085        return result;
086    }
087
088    @Snippet
089    public static int[] intArrayClone(int[] src) {
090        int[] result = (int[]) NewArrayNode.newUninitializedArray(Integer.TYPE, src.length);
091        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Int);
092        return result;
093    }
094
095    @Snippet
096    public static float[] floatArrayClone(float[] src) {
097        float[] result = (float[]) NewArrayNode.newUninitializedArray(Float.TYPE, src.length);
098        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Float);
099        return result;
100    }
101
102    @Snippet
103    public static long[] longArrayClone(long[] src) {
104        long[] result = (long[]) NewArrayNode.newUninitializedArray(Long.TYPE, src.length);
105        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Long);
106        return result;
107    }
108
109    @Snippet
110    public static double[] doubleArrayClone(double[] src) {
111        double[] result = (double[]) NewArrayNode.newUninitializedArray(Double.TYPE, src.length);
112        ArrayCopyCallNode.disjointArraycopy(src, 0, result, 0, src.length, Kind.Double);
113        return result;
114    }
115
116    @Snippet
117    public static Object[] objectArrayClone(Object[] src) {
118        /* Since this snippet is lowered early the array must be initialized */
119        Object[] result = (Object[]) DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(src.getClass().getComponentType()), src.length, Kind.Object);
120        ArrayCopyCallNode.disjointUninitializedArraycopy(src, 0, result, 0, src.length, Kind.Object);
121        return result;
122    }
123}