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