1/*
2 * Copyright (c) 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.nodes.aot;
24
25import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
26import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_20;
27
28import org.graalvm.compiler.core.common.LocationIdentity;
29import org.graalvm.compiler.graph.Node;
30import org.graalvm.compiler.graph.NodeClass;
31import org.graalvm.compiler.graph.spi.Canonicalizable;
32import org.graalvm.compiler.graph.spi.CanonicalizerTool;
33import org.graalvm.compiler.hotspot.HotSpotLIRGenerator;
34import org.graalvm.compiler.hotspot.word.KlassPointer;
35import org.graalvm.compiler.lir.LIRFrameState;
36import org.graalvm.compiler.nodeinfo.InputType;
37import org.graalvm.compiler.nodeinfo.NodeInfo;
38import org.graalvm.compiler.nodes.DeoptimizingNode;
39import org.graalvm.compiler.nodes.FrameState;
40import org.graalvm.compiler.nodes.ValueNode;
41import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
42import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
43import org.graalvm.compiler.nodes.spi.LIRLowerable;
44import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
45import org.graalvm.compiler.nodes.util.GraphUtil;
46
47import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
48import jdk.vm.ci.meta.Constant;
49import jdk.vm.ci.meta.Value;
50
51/**
52 * A call to the VM via a regular stub.
53 */
54@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_UNKNOWN, size = SIZE_20)
55public class InitializeKlassStubCall extends AbstractMemoryCheckpoint implements LIRLowerable, Canonicalizable, DeoptimizingNode.DeoptBefore, MemoryCheckpoint.Single {
56    public static final NodeClass<InitializeKlassStubCall> TYPE = NodeClass.create(InitializeKlassStubCall.class);
57
58    @OptionalInput protected ValueNode value;
59    @Input protected ValueNode string;
60    @OptionalInput(InputType.State) protected FrameState stateBefore;
61    protected Constant constant;
62
63    protected InitializeKlassStubCall(ValueNode value, ValueNode string) {
64        super(TYPE, value.stamp());
65        this.value = value;
66        this.string = string;
67    }
68
69    @NodeIntrinsic
70    public static native KlassPointer initializeKlass(KlassPointer value, Object string);
71
72    @Override
73    public Node canonical(CanonicalizerTool tool) {
74        if (value != null) {
75            constant = GraphUtil.foldIfConstantAndRemove(this, value);
76        }
77        return this;
78    }
79
80    @Override
81    public void generate(NodeLIRBuilderTool gen) {
82        assert constant != null : "Expected the value to fold: " + value;
83        Value stringValue = gen.operand(string);
84        LIRFrameState fs = gen.state(this);
85        assert fs != null : "Frame state should be set";
86        assert constant instanceof HotSpotMetaspaceConstant;
87        Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitKlassInitializationAndRetrieval(constant, stringValue, fs);
88        gen.setResult(this, result);
89    }
90
91    @Override
92    public boolean canDeoptimize() {
93        return true;
94    }
95
96    @Override
97    public LocationIdentity getLocationIdentity() {
98        return LocationIdentity.any();
99    }
100
101    @Override
102    public FrameState stateBefore() {
103        return stateBefore;
104    }
105
106    @Override
107    public void setStateBefore(FrameState f) {
108        updateUsages(stateBefore, f);
109        stateBefore = f;
110    }
111}
112