1 /* 2 * Copyright (c) 2009, 2015, 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 */ 23 package jdk.vm.ci.meta; 24 25 /** 26 * Represents a constant (boxed) value, such as an integer, floating point number, or object 27 * reference, within the compiler and across the compiler/runtime interface. Exports a set of 28 * {@code JavaConstant} instances that represent frequently used constant values, such as 29 * {@link #NULL_POINTER}. 30 */ 31 public interface JavaConstant extends Constant, JavaValue { 32 /* 33 * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is 34 * not enough to justify the impact on startup time. 35 */ 36 JavaConstant NULL_POINTER = new NullConstant(); 37 PrimitiveConstant INT_MINUS_1 = new PrimitiveConstant(JavaKind.Int, -1); 38 PrimitiveConstant INT_0 = new PrimitiveConstant(JavaKind.Int, 0); 39 PrimitiveConstant INT_1 = new PrimitiveConstant(JavaKind.Int, 1); 40 PrimitiveConstant INT_2 = new PrimitiveConstant(JavaKind.Int, 2); 41 PrimitiveConstant LONG_0 = new PrimitiveConstant(JavaKind.Long, 0L); 42 PrimitiveConstant LONG_1 = new PrimitiveConstant(JavaKind.Long, 1L); 43 PrimitiveConstant FLOAT_0 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(0.0F)); 44 PrimitiveConstant FLOAT_1 = new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(1.0F)); 45 PrimitiveConstant DOUBLE_0 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(0.0D)); 46 PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(1.0D)); 47 PrimitiveConstant TRUE = new PrimitiveConstant(JavaKind.Boolean, 1L); 48 PrimitiveConstant FALSE = new PrimitiveConstant(JavaKind.Boolean, 0L); 49 50 /** 51 * Returns the Java kind of this constant. 52 */ getJavaKind()53 JavaKind getJavaKind(); 54 55 /** 56 * Checks whether this constant is null. 57 * 58 * @return {@code true} if this constant is the null constant 59 */ isNull()60 boolean isNull(); 61 isNull(Constant c)62 static boolean isNull(Constant c) { 63 if (c instanceof JavaConstant) { 64 return ((JavaConstant) c).isNull(); 65 } else { 66 return false; 67 } 68 } 69 70 /** 71 * Checks whether this constant is non-null. 72 * 73 * @return {@code true} if this constant is a primitive, or an object constant that is not null 74 */ isNonNull()75 default boolean isNonNull() { 76 return !isNull(); 77 } 78 79 /** 80 * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). 81 * 82 * @return {@code true} if this constant is the default value for its kind 83 */ 84 @Override isDefaultForKind()85 boolean isDefaultForKind(); 86 87 /** 88 * Returns the value of this constant as a boxed Java value. 89 * 90 * @return the value of this constant 91 */ asBoxedPrimitive()92 Object asBoxedPrimitive(); 93 94 /** 95 * Returns the primitive int value this constant represents. The constant must have a 96 * {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. 97 * 98 * @return the constant value 99 */ asInt()100 int asInt(); 101 102 /** 103 * Returns the primitive boolean value this constant represents. The constant must have kind 104 * {@link JavaKind#Boolean}. 105 * 106 * @return the constant value 107 */ asBoolean()108 boolean asBoolean(); 109 110 /** 111 * Returns the primitive long value this constant represents. The constant must have kind 112 * {@link JavaKind#Long}, a {@link JavaKind#getStackKind()} of {@link JavaKind#Int}. 113 * 114 * @return the constant value 115 */ asLong()116 long asLong(); 117 118 /** 119 * Returns the primitive float value this constant represents. The constant must have kind 120 * {@link JavaKind#Float}. 121 * 122 * @return the constant value 123 */ asFloat()124 float asFloat(); 125 126 /** 127 * Returns the primitive double value this constant represents. The constant must have kind 128 * {@link JavaKind#Double}. 129 * 130 * @return the constant value 131 */ asDouble()132 double asDouble(); 133 134 @Override toValueString()135 default String toValueString() { 136 if (getJavaKind() == JavaKind.Illegal) { 137 return "illegal"; 138 } else { 139 return getJavaKind().format(asBoxedPrimitive()); 140 } 141 } 142 toString(JavaConstant constant)143 static String toString(JavaConstant constant) { 144 if (constant.getJavaKind() == JavaKind.Illegal) { 145 return "illegal"; 146 } else { 147 return constant.getJavaKind().getJavaName() + "[" + constant.toValueString() + "]"; 148 } 149 } 150 151 /** 152 * Creates a boxed double constant. 153 * 154 * @param d the double value to box 155 * @return a boxed copy of {@code value} 156 */ forDouble(double d)157 static PrimitiveConstant forDouble(double d) { 158 if (Double.compare(0.0D, d) == 0) { 159 return DOUBLE_0; 160 } 161 if (Double.compare(d, 1.0D) == 0) { 162 return DOUBLE_1; 163 } 164 return new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(d)); 165 } 166 167 /** 168 * Creates a boxed float constant. 169 * 170 * @param f the float value to box 171 * @return a boxed copy of {@code value} 172 */ forFloat(float f)173 static PrimitiveConstant forFloat(float f) { 174 if (Float.compare(f, 0.0F) == 0) { 175 return FLOAT_0; 176 } 177 if (Float.compare(f, 1.0F) == 0) { 178 return FLOAT_1; 179 } 180 return new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(f)); 181 } 182 183 /** 184 * Creates a boxed long constant. 185 * 186 * @param i the long value to box 187 * @return a boxed copy of {@code value} 188 */ forLong(long i)189 static PrimitiveConstant forLong(long i) { 190 if (i == 0) { 191 return LONG_0; 192 } else if (i == 1) { 193 return LONG_1; 194 } else { 195 return new PrimitiveConstant(JavaKind.Long, i); 196 } 197 } 198 199 /** 200 * Creates a boxed integer constant. 201 * 202 * @param i the integer value to box 203 * @return a boxed copy of {@code value} 204 */ forInt(int i)205 static PrimitiveConstant forInt(int i) { 206 switch (i) { 207 case -1: 208 return INT_MINUS_1; 209 case 0: 210 return INT_0; 211 case 1: 212 return INT_1; 213 case 2: 214 return INT_2; 215 default: 216 return new PrimitiveConstant(JavaKind.Int, i); 217 } 218 } 219 220 /** 221 * Creates a boxed byte constant. 222 * 223 * @param i the byte value to box 224 * @return a boxed copy of {@code value} 225 */ forByte(byte i)226 static PrimitiveConstant forByte(byte i) { 227 return new PrimitiveConstant(JavaKind.Byte, i); 228 } 229 230 /** 231 * Creates a boxed boolean constant. 232 * 233 * @param i the boolean value to box 234 * @return a boxed copy of {@code value} 235 */ forBoolean(boolean i)236 static PrimitiveConstant forBoolean(boolean i) { 237 return i ? TRUE : FALSE; 238 } 239 240 /** 241 * Creates a boxed char constant. 242 * 243 * @param i the char value to box 244 * @return a boxed copy of {@code value} 245 */ forChar(char i)246 static PrimitiveConstant forChar(char i) { 247 return new PrimitiveConstant(JavaKind.Char, i); 248 } 249 250 /** 251 * Creates a boxed short constant. 252 * 253 * @param i the short value to box 254 * @return a boxed copy of {@code value} 255 */ forShort(short i)256 static PrimitiveConstant forShort(short i) { 257 return new PrimitiveConstant(JavaKind.Short, i); 258 } 259 260 /** 261 * Creates a {@link JavaConstant} from a primitive integer of a certain kind. 262 */ forIntegerKind(JavaKind kind, long i)263 static PrimitiveConstant forIntegerKind(JavaKind kind, long i) { 264 switch (kind) { 265 case Boolean: 266 return forBoolean(i != 0); 267 case Byte: 268 return forByte((byte) i); 269 case Short: 270 return forShort((short) i); 271 case Char: 272 return forChar((char) i); 273 case Int: 274 return forInt((int) i); 275 case Long: 276 return forLong(i); 277 default: 278 throw new IllegalArgumentException("not an integer kind: " + kind); 279 } 280 } 281 282 /** 283 * Creates a {@link JavaConstant} from a primitive integer of a certain width. 284 */ forPrimitiveInt(int bits, long i)285 static PrimitiveConstant forPrimitiveInt(int bits, long i) { 286 assert bits <= 64; 287 switch (bits) { 288 case 1: 289 return forBoolean(i != 0); 290 case 8: 291 return forByte((byte) i); 292 case 16: 293 return forShort((short) i); 294 case 32: 295 return forInt((int) i); 296 case 64: 297 return forLong(i); 298 default: 299 throw new IllegalArgumentException("unsupported integer width: " + bits); 300 } 301 } 302 303 /** 304 * Creates a boxed constant for the given boxed primitive value. 305 * 306 * @param value the Java boxed value 307 * @return the primitive constant holding the {@code value} 308 */ forBoxedPrimitive(Object value)309 static PrimitiveConstant forBoxedPrimitive(Object value) { 310 if (value instanceof Boolean) { 311 return forBoolean((Boolean) value); 312 } else if (value instanceof Byte) { 313 return forByte((Byte) value); 314 } else if (value instanceof Character) { 315 return forChar((Character) value); 316 } else if (value instanceof Short) { 317 return forShort((Short) value); 318 } else if (value instanceof Integer) { 319 return forInt((Integer) value); 320 } else if (value instanceof Long) { 321 return forLong((Long) value); 322 } else if (value instanceof Float) { 323 return forFloat((Float) value); 324 } else if (value instanceof Double) { 325 return forDouble((Double) value); 326 } else { 327 return null; 328 } 329 } 330 forIllegal()331 static PrimitiveConstant forIllegal() { 332 return new PrimitiveConstant(JavaKind.Illegal, 0); 333 } 334 335 /** 336 * Returns a constant with the default value for the given kind. 337 */ defaultForKind(JavaKind kind)338 static JavaConstant defaultForKind(JavaKind kind) { 339 switch (kind) { 340 case Boolean: 341 return FALSE; 342 case Byte: 343 return forByte((byte) 0); 344 case Char: 345 return forChar((char) 0); 346 case Short: 347 return forShort((short) 0); 348 case Int: 349 return INT_0; 350 case Double: 351 return DOUBLE_0; 352 case Float: 353 return FLOAT_0; 354 case Long: 355 return LONG_0; 356 case Object: 357 return NULL_POINTER; 358 default: 359 throw new IllegalArgumentException(kind.toString()); 360 } 361 } 362 } 363