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}