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}