001/* 002 * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.hotspot; 024 025import static jdk.internal.jvmci.hotspot.HotSpotResolvedObjectTypeImpl.*; 026 027import java.lang.invoke.*; 028 029import jdk.internal.jvmci.meta.*; 030 031/** 032 * Represents a constant non-{@code null} object reference, within the compiler and across the 033 * compiler/runtime interface. 034 */ 035public final class HotSpotObjectConstantImpl extends AbstractValue implements HotSpotObjectConstant, HotSpotProxified { 036 037 public static JavaConstant forObject(Object object) { 038 return forObject(object, false); 039 } 040 041 static JavaConstant forObject(Object object, boolean compressed) { 042 if (object == null) { 043 return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER; 044 } else { 045 return new HotSpotObjectConstantImpl(object, compressed); 046 } 047 } 048 049 static JavaConstant forStableArray(Object object, int stableDimension, boolean isDefaultStable) { 050 if (object == null) { 051 return JavaConstant.NULL_POINTER; 052 } else { 053 assert object.getClass().isArray(); 054 return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable); 055 } 056 } 057 058 public static JavaConstant forBoxedValue(Kind kind, Object value) { 059 if (kind == Kind.Object) { 060 return HotSpotObjectConstantImpl.forObject(value); 061 } else { 062 return JavaConstant.forBoxedPrimitive(value); 063 } 064 } 065 066 static Object asBoxedValue(Constant constant) { 067 if (JavaConstant.isNull(constant)) { 068 return null; 069 } else if (constant instanceof HotSpotObjectConstantImpl) { 070 return ((HotSpotObjectConstantImpl) constant).object; 071 } else { 072 return ((JavaConstant) constant).asBoxedPrimitive(); 073 } 074 } 075 076 private final Object object; 077 private final boolean compressed; 078 private final byte stableDimension; 079 private final boolean isDefaultStable; 080 081 private HotSpotObjectConstantImpl(Object object, boolean compressed, int stableDimension, boolean isDefaultStable) { 082 super(LIRKind.reference(compressed ? Kind.Int : Kind.Object)); 083 this.object = object; 084 this.compressed = compressed; 085 this.stableDimension = (byte) stableDimension; 086 this.isDefaultStable = isDefaultStable; 087 assert object != null; 088 assert stableDimension == 0 || (object != null && object.getClass().isArray()); 089 assert stableDimension >= 0 && stableDimension <= 255; 090 assert !isDefaultStable || stableDimension > 0; 091 } 092 093 private HotSpotObjectConstantImpl(Object object, boolean compressed) { 094 this(object, compressed, 0, false); 095 } 096 097 /** 098 * Package-private accessor for the object represented by this constant. 099 */ 100 Object object() { 101 return object; 102 } 103 104 /** 105 * Determines if the object represented by this constant is {@link Object#equals(Object) equal} 106 * to a given object. 107 */ 108 public boolean isEqualTo(Object obj) { 109 return object.equals(obj); 110 } 111 112 /** 113 * Gets the class of the object represented by this constant. 114 */ 115 public Class<?> getObjectClass() { 116 return object.getClass(); 117 } 118 119 public boolean isCompressed() { 120 return compressed; 121 } 122 123 public JavaConstant compress() { 124 assert !compressed; 125 return new HotSpotObjectConstantImpl(object, true, stableDimension, isDefaultStable); 126 } 127 128 public JavaConstant uncompress() { 129 assert compressed; 130 return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable); 131 } 132 133 public HotSpotResolvedObjectType getType() { 134 return fromObjectClass(object.getClass()); 135 } 136 137 public JavaConstant getClassLoader() { 138 if (object instanceof Class) { 139 /* 140 * This is an intrinsic for getClassLoader0, which occurs after any security checks. We 141 * can't call that directly so just call getClassLoader. 142 */ 143 return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getClassLoader()); 144 } 145 return null; 146 } 147 148 public int getIdentityHashCode() { 149 return System.identityHashCode(object); 150 } 151 152 public JavaConstant getComponentType() { 153 if (object instanceof Class) { 154 return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getComponentType()); 155 } 156 return null; 157 } 158 159 public JavaConstant getSuperclass() { 160 if (object instanceof Class) { 161 return HotSpotObjectConstantImpl.forObject(((Class<?>) object).getSuperclass()); 162 } 163 return null; 164 } 165 166 public JavaConstant getCallSiteTarget(Assumptions assumptions) { 167 if (object instanceof CallSite) { 168 CallSite callSite = (CallSite) object; 169 MethodHandle target = callSite.getTarget(); 170 if (!(callSite instanceof ConstantCallSite)) { 171 if (assumptions == null) { 172 return null; 173 } 174 assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target)); 175 } 176 return HotSpotObjectConstantImpl.forObject(target); 177 } 178 return null; 179 } 180 181 @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want") 182 public boolean isInternedString() { 183 if (object instanceof String) { 184 String s = (String) object; 185 return s.intern() == s; 186 } 187 return false; 188 } 189 190 public <T> T asObject(Class<T> type) { 191 if (type.isInstance(object)) { 192 return type.cast(object); 193 } 194 return null; 195 } 196 197 public Object asObject(ResolvedJavaType type) { 198 if (type.isInstance(this)) { 199 return object; 200 } 201 return null; 202 } 203 204 @Override 205 public boolean isNull() { 206 return false; 207 } 208 209 @Override 210 public boolean isDefaultForKind() { 211 return false; 212 } 213 214 @Override 215 public Object asBoxedPrimitive() { 216 throw new IllegalArgumentException(); 217 } 218 219 @Override 220 public int asInt() { 221 throw new IllegalArgumentException(); 222 } 223 224 @Override 225 public boolean asBoolean() { 226 throw new IllegalArgumentException(); 227 } 228 229 @Override 230 public long asLong() { 231 throw new IllegalArgumentException(); 232 } 233 234 @Override 235 public float asFloat() { 236 throw new IllegalArgumentException(); 237 } 238 239 @Override 240 public double asDouble() { 241 throw new IllegalArgumentException(); 242 } 243 244 @Override 245 public int hashCode() { 246 return System.identityHashCode(object); 247 } 248 249 @Override 250 public boolean equals(Object o) { 251 if (o == this) { 252 return true; 253 } else if (o instanceof HotSpotObjectConstantImpl) { 254 HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o; 255 return super.equals(o) && object == other.object && compressed == other.compressed && stableDimension == other.stableDimension && isDefaultStable == other.isDefaultStable; 256 } 257 return false; 258 } 259 260 @Override 261 public String toValueString() { 262 if (object instanceof String) { 263 return "\"" + (String) object + "\""; 264 } else { 265 return Kind.Object.format(object); 266 } 267 } 268 269 @Override 270 public String toString() { 271 return (compressed ? "NarrowOop" : getKind().getJavaName()) + "[" + Kind.Object.format(object) + "]"; 272 } 273 274 /** 275 * Number of stable dimensions if this constant is a stable array. 276 */ 277 public int getStableDimension() { 278 return stableDimension & 0xff; 279 } 280 281 /** 282 * Returns {@code true} if this is a stable array constant and its elements should be considered 283 * as stable regardless of whether they are default values. 284 */ 285 public boolean isDefaultStable() { 286 return isDefaultStable; 287 } 288}