LoadHubNode.java revision 12651:6ef01bd40ce2
1132718Skan/*
2169689Skan * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3132718Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4132718Skan *
5132718Skan * This code is free software; you can redistribute it and/or modify it
6132718Skan * under the terms of the GNU General Public License version 2 only, as
7132718Skan * published by the Free Software Foundation.
8132718Skan *
9132718Skan * This code is distributed in the hope that it will be useful, but WITHOUT
10132718Skan * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11132718Skan * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12132718Skan * version 2 for more details (a copy is included in the LICENSE file that
13132718Skan * accompanied this code).
14132718Skan *
15132718Skan * You should have received a copy of the GNU General Public License version
16132718Skan * 2 along with this work; if not, write to the Free Software Foundation,
17132718Skan * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18169689Skan *
19169689Skan * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20132718Skan * or visit www.oracle.com if you need additional information or have any
21132718Skan * questions.
22132718Skan */
23132718Skanpackage org.graalvm.compiler.nodes.extended;
24132718Skan
25132718Skanimport static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
26132718Skan
27132718Skanimport static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
28132718Skanimport static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
29132718Skan
30132718Skanimport org.graalvm.compiler.core.common.type.ObjectStamp;
31132718Skanimport org.graalvm.compiler.core.common.type.Stamp;
32132718Skanimport org.graalvm.compiler.core.common.type.TypeReference;
33132718Skanimport org.graalvm.compiler.graph.NodeClass;
34132718Skanimport org.graalvm.compiler.graph.spi.Canonicalizable;
35132718Skanimport org.graalvm.compiler.graph.spi.CanonicalizerTool;
36132718Skanimport org.graalvm.compiler.nodeinfo.NodeInfo;
37169689Skanimport org.graalvm.compiler.nodes.ConstantNode;
38169689Skanimport org.graalvm.compiler.nodes.ValueNode;
39132718Skanimport org.graalvm.compiler.nodes.calc.FloatingNode;
40132718Skanimport org.graalvm.compiler.nodes.spi.Lowerable;
41132718Skanimport org.graalvm.compiler.nodes.spi.LoweringTool;
42169689Skanimport org.graalvm.compiler.nodes.spi.StampProvider;
43132718Skanimport org.graalvm.compiler.nodes.spi.Virtualizable;
44132718Skanimport org.graalvm.compiler.nodes.spi.VirtualizerTool;
45132718Skanimport org.graalvm.compiler.nodes.type.StampTool;
46132718Skan
47132718Skanimport jdk.vm.ci.meta.ConstantReflectionProvider;
48132718Skanimport jdk.vm.ci.meta.MetaAccessProvider;
49132718Skan
50132718Skan/**
51132718Skan * Loads an object's hub. The object is not null-checked by this operation.
52132718Skan */
53132718Skan@NodeInfo(cycles = CYCLES_2, size = SIZE_1)
54132718Skanpublic final class LoadHubNode extends FloatingNode implements Lowerable, Canonicalizable, Virtualizable {
55132718Skan
56132718Skan    public static final NodeClass<LoadHubNode> TYPE = NodeClass.create(LoadHubNode.class);
57132718Skan    @Input ValueNode value;
58132718Skan
59132718Skan    public ValueNode getValue() {
60132718Skan        return value;
61132718Skan    }
62169689Skan
63169689Skan    private static Stamp hubStamp(StampProvider stampProvider, ValueNode value) {
64169689Skan        assert value.stamp() instanceof ObjectStamp;
65169689Skan        return stampProvider.createHubStamp(((ObjectStamp) value.stamp()));
66169689Skan    }
67169689Skan
68169689Skan    public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
69169689Skan        Stamp stamp = hubStamp(stampProvider, value);
70169689Skan        ValueNode synonym = findSynonym(value, stamp, metaAccess, constantReflection);
71169689Skan        if (synonym != null) {
72169689Skan            return synonym;
73169689Skan        }
74132718Skan        return new LoadHubNode(stamp, value);
75132718Skan    }
76132718Skan
77132718Skan    public LoadHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode value) {
78132718Skan        this(hubStamp(stampProvider, value), value);
79132718Skan    }
80132718Skan
81132718Skan    public LoadHubNode(Stamp stamp, ValueNode value) {
82132718Skan        super(TYPE, stamp);
83132718Skan        this.value = value;
84132718Skan    }
85132718Skan
86132718Skan    @Override
87132718Skan    public void lower(LoweringTool tool) {
88132718Skan        tool.getLowerer().lower(this, tool);
89132718Skan    }
90169689Skan
91132718Skan    @Override
92132718Skan    public ValueNode canonical(CanonicalizerTool tool) {
93132718Skan        if (!GeneratePIC.getValue()) {
94132718Skan            MetaAccessProvider metaAccess = tool.getMetaAccess();
95132718Skan            ValueNode curValue = getValue();
96132718Skan            ValueNode newNode = findSynonym(curValue, stamp(), metaAccess, tool.getConstantReflection());
97132718Skan            if (newNode != null) {
98132718Skan                return newNode;
99132718Skan            }
100132718Skan        }
101132718Skan        return this;
102132718Skan    }
103132718Skan
104132718Skan    public static ValueNode findSynonym(ValueNode curValue, Stamp stamp, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
105132718Skan        if (!GeneratePIC.getValue()) {
106132718Skan            TypeReference type = StampTool.typeReferenceOrNull(curValue);
107132718Skan            if (type != null && type.isExact()) {
108132718Skan                return ConstantNode.forConstant(stamp, constantReflection.asObjectHub(type.getType()), metaAccess);
109132718Skan            }
110132718Skan        }
111132718Skan        return null;
112132718Skan    }
113132718Skan
114132718Skan    @Override
115132718Skan    public void virtualize(VirtualizerTool tool) {
116132718Skan        if (!GeneratePIC.getValue()) {
117132718Skan            ValueNode alias = tool.getAlias(getValue());
118132718Skan            TypeReference type = StampTool.typeReferenceOrNull(alias);
119132718Skan            if (type != null && type.isExact()) {
120132718Skan                tool.replaceWithValue(ConstantNode.forConstant(stamp(), tool.getConstantReflectionProvider().asObjectHub(type.getType()), tool.getMetaAccessProvider(), graph()));
121132718Skan            }
122132718Skan        }
123132718Skan    }
124132718Skan}
125132718Skan