1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.hotspot.replacements.arraycopy;
24
25import jdk.vm.ci.code.BytecodeFrame;
26import jdk.vm.ci.meta.JavaKind;
27
28import static org.graalvm.compiler.core.common.LocationIdentity.any;
29
30import org.graalvm.compiler.core.common.LocationIdentity;
31import org.graalvm.compiler.graph.NodeClass;
32import org.graalvm.compiler.hotspot.word.KlassPointer;
33import org.graalvm.compiler.nodeinfo.InputType;
34import org.graalvm.compiler.nodeinfo.NodeInfo;
35import org.graalvm.compiler.nodes.NamedLocationIdentity;
36import org.graalvm.compiler.nodes.ValueNode;
37import org.graalvm.compiler.nodes.type.StampTool;
38import org.graalvm.compiler.replacements.SnippetTemplate;
39import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
40
41@NodeInfo(allowedUsageTypes = InputType.Memory)
42public final class ArrayCopySlowPathNode extends BasicArrayCopyNode {
43
44    public static final NodeClass<ArrayCopySlowPathNode> TYPE = NodeClass.create(ArrayCopySlowPathNode.class);
45
46    private final SnippetTemplate.SnippetInfo snippet;
47
48    /**
49     * Extra context for the slow path snippet.
50     */
51    private final Object argument;
52
53    /**
54     * AOT compilation requires klass constants to be exposed after the first lowering to be handled
55     * automatically. Lowering for {@link ArrayCopySlowPathNode}, with snippet ==
56     * {@link ArrayCopySnippets#arraycopyPredictedObjectWork}, requires a klass of Object[]. For
57     * other snippets {@link #predictedKlass} is a null constant.
58     */
59    @Input protected ValueNode predictedKlass;
60
61    public ArrayCopySlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode predictedKlass, JavaKind elementKind,
62                    SnippetTemplate.SnippetInfo snippet, Object argument) {
63        super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
64        assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
65        this.snippet = snippet;
66        this.argument = argument;
67        this.predictedKlass = predictedKlass;
68    }
69
70    @NodeIntrinsic
71    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer predictedKlass,
72                    @ConstantNodeParameter JavaKind elementKind, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet, @ConstantNodeParameter Object argument);
73
74    public SnippetTemplate.SnippetInfo getSnippet() {
75        return snippet;
76    }
77
78    public Object getArgument() {
79        return argument;
80    }
81
82    @Override
83    public LocationIdentity getLocationIdentity() {
84        if (elementKind != null) {
85            return NamedLocationIdentity.getArrayLocation(elementKind);
86        }
87        return any();
88    }
89
90    public void setBci(int bci) {
91        this.bci = bci;
92    }
93
94    public ValueNode getPredictedKlass() {
95        return predictedKlass;
96    }
97}
98