001/* 002 * Copyright (c) 2013, 2015, 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.arraycopy; 024 025import jdk.internal.jvmci.meta.*; 026import static jdk.internal.jvmci.meta.LocationIdentity.*; 027 028import com.oracle.graal.compiler.common.type.*; 029import com.oracle.graal.graph.*; 030import com.oracle.graal.nodeinfo.*; 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.nodes.extended.*; 033import com.oracle.graal.nodes.memory.*; 034import com.oracle.graal.nodes.spi.*; 035import com.oracle.graal.replacements.SnippetTemplate.Arguments; 036 037@NodeInfo(allowedUsageTypes = {InputType.Memory}) 038public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single, MemoryAccess { 039 040 public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class); 041 @Input ValueNode src; 042 @Input ValueNode srcPos; 043 @Input ValueNode dest; 044 @Input ValueNode destPos; 045 @Input ValueNode length; 046 @OptionalInput ValueNode layoutHelper; 047 048 @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess; 049 050 protected Kind elementKind; 051 052 public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, Kind elementKind) { 053 super(TYPE, StampFactory.forVoid()); 054 assert layoutHelper == null || elementKind == null; 055 this.src = src; 056 this.srcPos = srcPos; 057 this.dest = dest; 058 this.destPos = destPos; 059 this.length = length; 060 this.layoutHelper = layoutHelper; 061 this.elementKind = elementKind; 062 } 063 064 public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind) { 065 this(src, srcPos, dest, destPos, length, null, elementKind); 066 } 067 068 public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) { 069 this(src, srcPos, dest, destPos, length, layoutHelper, null); 070 } 071 072 @Override 073 public ValueNode getArray() { 074 return dest; 075 } 076 077 @Override 078 public ValueNode getIndex() { 079 return destPos; 080 } 081 082 @Override 083 public ValueNode getLength() { 084 return length; 085 } 086 087 @Override 088 public boolean isObjectArray() { 089 return elementKind == Kind.Object; 090 } 091 092 @Override 093 public boolean isInitialization() { 094 return false; 095 } 096 097 public Kind getElementKind() { 098 return elementKind; 099 } 100 101 @Override 102 public void lower(LoweringTool tool) { 103 if (graph().getGuardsStage().areFrameStatesAtDeopts()) { 104 UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class); 105 templates.lower(this, tool); 106 } 107 } 108 109 public void addSnippetArguments(Arguments args) { 110 args.add("src", src); 111 args.add("srcPos", srcPos); 112 args.add("dest", dest); 113 args.add("destPos", destPos); 114 args.add("length", length); 115 if (layoutHelper != null) { 116 args.add("layoutHelper", layoutHelper); 117 } 118 } 119 120 @Override 121 public LocationIdentity getLocationIdentity() { 122 if (elementKind != null) { 123 return NamedLocationIdentity.getArrayLocation(elementKind); 124 } 125 return any(); 126 } 127 128 public MemoryNode getLastLocationAccess() { 129 return lastLocationAccess; 130 } 131 132 public void setLastLocationAccess(MemoryNode lla) { 133 updateUsagesInterface(lastLocationAccess, lla); 134 lastLocationAccess = lla; 135 } 136 137 @NodeIntrinsic 138 public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter Kind elementKind); 139 140 @NodeIntrinsic 141 public static native void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper); 142}