KlassPointerStamp.java revision 12651:6ef01bd40ce2
1130803Smarcel/*
2130803Smarcel * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3130803Smarcel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4130803Smarcel *
5130803Smarcel * This code is free software; you can redistribute it and/or modify it
6130803Smarcel * under the terms of the GNU General Public License version 2 only, as
7130803Smarcel * published by the Free Software Foundation.
8130803Smarcel *
9130803Smarcel * This code is distributed in the hope that it will be useful, but WITHOUT
10130803Smarcel * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11130803Smarcel * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12130803Smarcel * version 2 for more details (a copy is included in the LICENSE file that
13130803Smarcel * accompanied this code).
14130803Smarcel *
15130803Smarcel * You should have received a copy of the GNU General Public License version
16130803Smarcel * 2 along with this work; if not, write to the Free Software Foundation,
17130803Smarcel * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18130803Smarcel *
19130803Smarcel * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20130803Smarcel * or visit www.oracle.com if you need additional information or have any
21130803Smarcel * questions.
22130803Smarcel */
23130803Smarcelpackage org.graalvm.compiler.hotspot.nodes.type;
24130803Smarcel
25130803Smarcelimport java.util.Objects;
26130803Smarcel
27130803Smarcelimport org.graalvm.compiler.core.common.LIRKind;
28130803Smarcelimport org.graalvm.compiler.core.common.spi.LIRKindTool;
29130803Smarcelimport org.graalvm.compiler.core.common.type.AbstractPointerStamp;
30130803Smarcelimport org.graalvm.compiler.core.common.type.Stamp;
31130803Smarcelimport org.graalvm.compiler.hotspot.CompressEncoding;
32130803Smarcel
33130803Smarcelimport jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
34130803Smarcelimport jdk.vm.ci.hotspot.HotSpotMemoryAccessProvider;
35130803Smarcelimport jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
36130803Smarcelimport jdk.vm.ci.meta.Constant;
37130803Smarcelimport jdk.vm.ci.meta.JavaConstant;
38130803Smarcelimport jdk.vm.ci.meta.MemoryAccessProvider;
39130803Smarcelimport jdk.vm.ci.meta.MetaAccessProvider;
40130803Smarcel
41130803Smarcelpublic final class KlassPointerStamp extends MetaspacePointerStamp {
42130803Smarcel
43130803Smarcel    private static final KlassPointerStamp KLASS = new KlassPointerStamp(false, false);
44130803Smarcel
45130803Smarcel    private static final KlassPointerStamp KLASS_NON_NULL = new KlassPointerStamp(true, false);
46130803Smarcel
47130803Smarcel    private static final KlassPointerStamp KLASS_ALWAYS_NULL = new KlassPointerStamp(false, true);
48130803Smarcel
49130803Smarcel    private final CompressEncoding encoding;
50130803Smarcel
51130803Smarcel    public static KlassPointerStamp klass() {
52130803Smarcel        return KLASS;
53130803Smarcel    }
54130803Smarcel
55130803Smarcel    public static KlassPointerStamp klassNonNull() {
56130803Smarcel        return KLASS_NON_NULL;
57130803Smarcel    }
58130803Smarcel
59130803Smarcel    public static KlassPointerStamp klassAlwaysNull() {
60130803Smarcel        return KLASS_ALWAYS_NULL;
61130803Smarcel    }
62130803Smarcel
63130803Smarcel    private KlassPointerStamp(boolean nonNull, boolean alwaysNull) {
64130803Smarcel        this(nonNull, alwaysNull, null);
65130803Smarcel    }
66130803Smarcel
67130803Smarcel    private KlassPointerStamp(boolean nonNull, boolean alwaysNull, CompressEncoding encoding) {
68130803Smarcel        super(nonNull, alwaysNull);
69130803Smarcel        this.encoding = encoding;
70130803Smarcel    }
71130803Smarcel
72130803Smarcel    @Override
73130803Smarcel    protected AbstractPointerStamp copyWith(boolean newNonNull, boolean newAlwaysNull) {
74130803Smarcel        return new KlassPointerStamp(newNonNull, newAlwaysNull, encoding);
75130803Smarcel    }
76130803Smarcel
77130803Smarcel    @Override
78130803Smarcel    public boolean isCompatible(Stamp otherStamp) {
79130803Smarcel        if (this == otherStamp) {
80130803Smarcel            return true;
81130803Smarcel        }
82130803Smarcel        if (otherStamp instanceof KlassPointerStamp) {
83130803Smarcel            KlassPointerStamp other = (KlassPointerStamp) otherStamp;
84130803Smarcel            return Objects.equals(this.encoding, other.encoding);
85130803Smarcel        }
86130803Smarcel        return false;
87130803Smarcel    }
88130803Smarcel
89130803Smarcel    @Override
90130803Smarcel    public boolean isCompatible(Constant constant) {
91130803Smarcel        if (constant instanceof HotSpotMetaspaceConstant) {
92130803Smarcel            return ((HotSpotMetaspaceConstant) constant).asResolvedJavaType() != null;
93130803Smarcel        } else {
94130803Smarcel            return super.isCompatible(constant);
95130803Smarcel        }
96130803Smarcel    }
97130803Smarcel
98130803Smarcel    @Override
99130803Smarcel    public Stamp constant(Constant c, MetaAccessProvider meta) {
100130803Smarcel        if (isCompressed()) {
101130803Smarcel            if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
102130803Smarcel                return new KlassPointerStamp(false, true, encoding);
103130803Smarcel            }
104130803Smarcel        } else {
105130803Smarcel            if (JavaConstant.NULL_POINTER.equals(c)) {
106130803Smarcel                return KLASS_ALWAYS_NULL;
107130803Smarcel            }
108130803Smarcel        }
109130803Smarcel
110130803Smarcel        assert c instanceof HotSpotMetaspaceConstant;
111130803Smarcel        assert ((HotSpotMetaspaceConstant) c).isCompressed() == isCompressed();
112130803Smarcel        if (nonNull()) {
113130803Smarcel            return this;
114130803Smarcel        }
115130803Smarcel        if (isCompressed()) {
116130803Smarcel            return new KlassPointerStamp(true, false, encoding);
117130803Smarcel        } else {
118130803Smarcel            return KLASS_NON_NULL;
119130803Smarcel        }
120130803Smarcel    }
121130803Smarcel
122130803Smarcel    @Override
123130803Smarcel    public Constant asConstant() {
124130803Smarcel        if (alwaysNull() && isCompressed()) {
125130803Smarcel            return HotSpotCompressedNullConstant.COMPRESSED_NULL;
126130803Smarcel        } else {
127130803Smarcel            return super.asConstant();
128130803Smarcel        }
129130803Smarcel    }
130130803Smarcel
131130803Smarcel    @Override
132130803Smarcel    public LIRKind getLIRKind(LIRKindTool tool) {
133130803Smarcel        if (isCompressed()) {
134130803Smarcel            return ((HotSpotLIRKindTool) tool).getNarrowPointerKind();
135130803Smarcel        } else {
136130803Smarcel            return super.getLIRKind(tool);
137130803Smarcel        }
138130803Smarcel    }
139130803Smarcel
140130803Smarcel    public boolean isCompressed() {
141130803Smarcel        return encoding != null;
142130803Smarcel    }
143130803Smarcel
144130803Smarcel    public CompressEncoding getEncoding() {
145130803Smarcel        return encoding;
146130803Smarcel    }
147130803Smarcel
148130803Smarcel    public KlassPointerStamp compressed(CompressEncoding newEncoding) {
149130803Smarcel        assert !isCompressed();
150130803Smarcel        return new KlassPointerStamp(nonNull(), alwaysNull(), newEncoding);
151130803Smarcel    }
152130803Smarcel
153130803Smarcel    public KlassPointerStamp uncompressed() {
154130803Smarcel        assert isCompressed();
155130803Smarcel        return new KlassPointerStamp(nonNull(), alwaysNull());
156130803Smarcel    }
157130803Smarcel
158130803Smarcel    @Override
159130803Smarcel    public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) {
160130803Smarcel        HotSpotMemoryAccessProvider hsProvider = (HotSpotMemoryAccessProvider) provider;
161130803Smarcel        if (isCompressed()) {
162130803Smarcel            return hsProvider.readNarrowKlassPointerConstant(base, displacement);
163130803Smarcel        } else {
164130803Smarcel            return hsProvider.readKlassPointerConstant(base, displacement);
165130803Smarcel        }
166130803Smarcel    }
167130803Smarcel
168130803Smarcel    @Override
169130803Smarcel    public int hashCode() {
170130803Smarcel        final int prime = 31;
171130803Smarcel        int result = super.hashCode();
172130803Smarcel        result = prime * result + ((encoding == null) ? 0 : encoding.hashCode());
173130803Smarcel        return result;
174130803Smarcel    }
175130803Smarcel
176130803Smarcel    @Override
177130803Smarcel    public boolean equals(Object obj) {
178130803Smarcel        if (this == obj) {
179130803Smarcel            return true;
180130803Smarcel        }
181130803Smarcel        if (!super.equals(obj)) {
182130803Smarcel            return false;
183130803Smarcel        }
184130803Smarcel        if (!(obj instanceof KlassPointerStamp)) {
185130803Smarcel            return false;
186130803Smarcel        }
187130803Smarcel        KlassPointerStamp other = (KlassPointerStamp) obj;
188130803Smarcel        return Objects.equals(this.encoding, other.encoding);
189130803Smarcel    }
190130803Smarcel
191130803Smarcel    @Override
192130803Smarcel    public String toString() {
193130803Smarcel        StringBuilder ret = new StringBuilder("Klass*");
194130803Smarcel        appendString(ret);
195130803Smarcel        if (isCompressed()) {
196130803Smarcel            ret.append("(compressed ").append(encoding).append(")");
197130803Smarcel        }
198130803Smarcel        return ret.toString();
199130803Smarcel    }
200130803Smarcel}
201130803Smarcel