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.meta; 024 025/** 026 * Represents a constant (boxed) value, such as an integer, floating point number, or object 027 * reference, within the compiler and across the compiler/runtime interface. Exports a set of 028 * {@code JavaConstant} instances that represent frequently used constant values, such as 029 * {@link #NULL_POINTER}. 030 */ 031public interface JavaConstant extends Constant, JavaValue, Value { 032 033 /* 034 * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is 035 * not enough to justify the impact on startup time. 036 */ 037 JavaConstant NULL_POINTER = new NullConstant(); 038 PrimitiveConstant INT_MINUS_1 = new PrimitiveConstant(Kind.Int, -1); 039 PrimitiveConstant INT_0 = new PrimitiveConstant(Kind.Int, 0); 040 PrimitiveConstant INT_1 = new PrimitiveConstant(Kind.Int, 1); 041 PrimitiveConstant INT_2 = new PrimitiveConstant(Kind.Int, 2); 042 PrimitiveConstant LONG_0 = new PrimitiveConstant(Kind.Long, 0L); 043 PrimitiveConstant LONG_1 = new PrimitiveConstant(Kind.Long, 1L); 044 PrimitiveConstant FLOAT_0 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(0.0F)); 045 PrimitiveConstant FLOAT_1 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(1.0F)); 046 PrimitiveConstant DOUBLE_0 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(0.0D)); 047 PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(1.0D)); 048 PrimitiveConstant TRUE = new PrimitiveConstant(Kind.Boolean, 1L); 049 PrimitiveConstant FALSE = new PrimitiveConstant(Kind.Boolean, 0L); 050 051 /** 052 * Checks whether this constant is null. 053 * 054 * @return {@code true} if this constant is the null constant 055 */ 056 boolean isNull(); 057 058 static boolean isNull(Constant c) { 059 if (c instanceof JavaConstant) { 060 return ((JavaConstant) c).isNull(); 061 } else { 062 return false; 063 } 064 } 065 066 /** 067 * Checks whether this constant is non-null. 068 * 069 * @return {@code true} if this constant is a primitive, or an object constant that is not null 070 */ 071 default boolean isNonNull() { 072 return !isNull(); 073 } 074 075 /** 076 * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). 077 * 078 * @return {@code true} if this constant is the default value for its kind 079 */ 080 boolean isDefaultForKind(); 081 082 /** 083 * Returns the value of this constant as a boxed Java value. 084 * 085 * @return the value of this constant 086 */ 087 Object asBoxedPrimitive(); 088 089 /** 090 * Returns the primitive int value this constant represents. The constant must have a 091 * {@link Kind#getStackKind()} of {@link Kind#Int}. 092 * 093 * @return the constant value 094 */ 095 int asInt(); 096 097 /** 098 * Returns the primitive boolean value this constant represents. The constant must have kind 099 * {@link Kind#Boolean}. 100 * 101 * @return the constant value 102 */ 103 boolean asBoolean(); 104 105 /** 106 * Returns the primitive long value this constant represents. The constant must have kind 107 * {@link Kind#Long}, a {@link Kind#getStackKind()} of {@link Kind#Int}. 108 * 109 * @return the constant value 110 */ 111 long asLong(); 112 113 /** 114 * Returns the primitive float value this constant represents. The constant must have kind 115 * {@link Kind#Float}. 116 * 117 * @return the constant value 118 */ 119 float asFloat(); 120 121 /** 122 * Returns the primitive double value this constant represents. The constant must have kind 123 * {@link Kind#Double}. 124 * 125 * @return the constant value 126 */ 127 double asDouble(); 128 129 default String toValueString() { 130 if (getKind() == Kind.Illegal) { 131 return "illegal"; 132 } else { 133 return getKind().format(asBoxedPrimitive()); 134 } 135 } 136 137 static String toString(JavaConstant constant) { 138 if (constant.getKind() == Kind.Illegal) { 139 return "illegal"; 140 } else { 141 return constant.getKind().getJavaName() + "[" + constant.toValueString() + "]"; 142 } 143 } 144 145 /** 146 * Creates a boxed double constant. 147 * 148 * @param d the double value to box 149 * @return a boxed copy of {@code value} 150 */ 151 static PrimitiveConstant forDouble(double d) { 152 if (Double.compare(0.0D, d) == 0) { 153 return DOUBLE_0; 154 } 155 if (Double.compare(d, 1.0D) == 0) { 156 return DOUBLE_1; 157 } 158 return new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(d)); 159 } 160 161 /** 162 * Creates a boxed float constant. 163 * 164 * @param f the float value to box 165 * @return a boxed copy of {@code value} 166 */ 167 static PrimitiveConstant forFloat(float f) { 168 if (Float.compare(f, 0.0F) == 0) { 169 return FLOAT_0; 170 } 171 if (Float.compare(f, 1.0F) == 0) { 172 return FLOAT_1; 173 } 174 return new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(f)); 175 } 176 177 /** 178 * Creates a boxed long constant. 179 * 180 * @param i the long value to box 181 * @return a boxed copy of {@code value} 182 */ 183 static PrimitiveConstant forLong(long i) { 184 if (i == 0) { 185 return LONG_0; 186 } else if (i == 1) { 187 return LONG_1; 188 } else { 189 return new PrimitiveConstant(Kind.Long, i); 190 } 191 } 192 193 /** 194 * Creates a boxed integer constant. 195 * 196 * @param i the integer value to box 197 * @return a boxed copy of {@code value} 198 */ 199 static PrimitiveConstant forInt(int i) { 200 switch (i) { 201 case -1: 202 return INT_MINUS_1; 203 case 0: 204 return INT_0; 205 case 1: 206 return INT_1; 207 case 2: 208 return INT_2; 209 default: 210 return new PrimitiveConstant(Kind.Int, i); 211 } 212 } 213 214 /** 215 * Creates a boxed byte constant. 216 * 217 * @param i the byte value to box 218 * @return a boxed copy of {@code value} 219 */ 220 static PrimitiveConstant forByte(byte i) { 221 return new PrimitiveConstant(Kind.Byte, i); 222 } 223 224 /** 225 * Creates a boxed boolean constant. 226 * 227 * @param i the boolean value to box 228 * @return a boxed copy of {@code value} 229 */ 230 static PrimitiveConstant forBoolean(boolean i) { 231 return i ? TRUE : FALSE; 232 } 233 234 /** 235 * Creates a boxed char constant. 236 * 237 * @param i the char value to box 238 * @return a boxed copy of {@code value} 239 */ 240 static PrimitiveConstant forChar(char i) { 241 return new PrimitiveConstant(Kind.Char, i); 242 } 243 244 /** 245 * Creates a boxed short constant. 246 * 247 * @param i the short value to box 248 * @return a boxed copy of {@code value} 249 */ 250 static PrimitiveConstant forShort(short i) { 251 return new PrimitiveConstant(Kind.Short, i); 252 } 253 254 /** 255 * Creates a {@link JavaConstant} from a primitive integer of a certain kind. 256 */ 257 static PrimitiveConstant forIntegerKind(Kind kind, long i) { 258 switch (kind) { 259 case Boolean: 260 return forBoolean(i != 0); 261 case Byte: 262 return forByte((byte) i); 263 case Short: 264 return forShort((short) i); 265 case Char: 266 return forChar((char) i); 267 case Int: 268 return forInt((int) i); 269 case Long: 270 return forLong(i); 271 default: 272 throw new IllegalArgumentException("not an integer kind: " + kind); 273 } 274 } 275 276 /** 277 * Creates a {@link JavaConstant} from a primitive integer of a certain width. 278 */ 279 static PrimitiveConstant forPrimitiveInt(int bits, long i) { 280 assert bits <= 64; 281 switch (bits) { 282 case 1: 283 return forBoolean(i != 0); 284 case 8: 285 return forByte((byte) i); 286 case 16: 287 return forShort((short) i); 288 case 32: 289 return forInt((int) i); 290 case 64: 291 return forLong(i); 292 default: 293 throw new IllegalArgumentException("unsupported integer width: " + bits); 294 } 295 } 296 297 /** 298 * Creates a boxed constant for the given boxed primitive value. 299 * 300 * @param value the Java boxed value 301 * @return the primitive constant holding the {@code value} 302 */ 303 static PrimitiveConstant forBoxedPrimitive(Object value) { 304 if (value instanceof Boolean) { 305 return forBoolean((Boolean) value); 306 } else if (value instanceof Byte) { 307 return forByte((Byte) value); 308 } else if (value instanceof Character) { 309 return forChar((Character) value); 310 } else if (value instanceof Short) { 311 return forShort((Short) value); 312 } else if (value instanceof Integer) { 313 return forInt((Integer) value); 314 } else if (value instanceof Long) { 315 return forLong((Long) value); 316 } else if (value instanceof Float) { 317 return forFloat((Float) value); 318 } else if (value instanceof Double) { 319 return forDouble((Double) value); 320 } else { 321 return null; 322 } 323 } 324 325 static PrimitiveConstant forIllegal() { 326 return new PrimitiveConstant(Kind.Illegal, 0); 327 } 328 329 /** 330 * Returns a constant with the default value for the given kind. 331 */ 332 static JavaConstant defaultForKind(Kind kind) { 333 switch (kind) { 334 case Boolean: 335 return FALSE; 336 case Byte: 337 return forByte((byte) 0); 338 case Char: 339 return forChar((char) 0); 340 case Short: 341 return forShort((short) 0); 342 case Int: 343 return INT_0; 344 case Double: 345 return DOUBLE_0; 346 case Float: 347 return FLOAT_0; 348 case Long: 349 return LONG_0; 350 case Object: 351 return NULL_POINTER; 352 default: 353 throw new IllegalArgumentException(kind.toString()); 354 } 355 } 356 357 /** 358 * Returns the zero value for a given numeric kind. 359 */ 360 static JavaConstant zero(Kind kind) { 361 switch (kind) { 362 case Boolean: 363 return FALSE; 364 case Byte: 365 return forByte((byte) 0); 366 case Char: 367 return forChar((char) 0); 368 case Double: 369 return DOUBLE_0; 370 case Float: 371 return FLOAT_0; 372 case Int: 373 return INT_0; 374 case Long: 375 return LONG_0; 376 case Short: 377 return forShort((short) 0); 378 default: 379 throw new IllegalArgumentException(kind.toString()); 380 } 381 } 382 383 /** 384 * Returns the one value for a given numeric kind. 385 */ 386 static JavaConstant one(Kind kind) { 387 switch (kind) { 388 case Boolean: 389 return TRUE; 390 case Byte: 391 return forByte((byte) 1); 392 case Char: 393 return forChar((char) 1); 394 case Double: 395 return DOUBLE_1; 396 case Float: 397 return FLOAT_1; 398 case Int: 399 return INT_1; 400 case Long: 401 return LONG_1; 402 case Short: 403 return forShort((short) 1); 404 default: 405 throw new IllegalArgumentException(kind.toString()); 406 } 407 } 408 409 /** 410 * Adds two numeric constants. 411 */ 412 static JavaConstant add(JavaConstant x, JavaConstant y) { 413 assert x.getKind() == y.getKind(); 414 switch (x.getKind()) { 415 case Byte: 416 return forByte((byte) (x.asInt() + y.asInt())); 417 case Char: 418 return forChar((char) (x.asInt() + y.asInt())); 419 case Double: 420 return forDouble(x.asDouble() + y.asDouble()); 421 case Float: 422 return forFloat(x.asFloat() + y.asFloat()); 423 case Int: 424 return forInt(x.asInt() + y.asInt()); 425 case Long: 426 return forLong(x.asLong() + y.asLong()); 427 case Short: 428 return forShort((short) (x.asInt() + y.asInt())); 429 default: 430 throw new IllegalArgumentException(x.getKind().toString()); 431 } 432 } 433 434 /** 435 * Multiplies two numeric constants. 436 */ 437 static PrimitiveConstant mul(JavaConstant x, JavaConstant y) { 438 assert x.getKind() == y.getKind(); 439 switch (x.getKind()) { 440 case Byte: 441 return forByte((byte) (x.asInt() * y.asInt())); 442 case Char: 443 return forChar((char) (x.asInt() * y.asInt())); 444 case Double: 445 return forDouble(x.asDouble() * y.asDouble()); 446 case Float: 447 return forFloat(x.asFloat() * y.asFloat()); 448 case Int: 449 return forInt(x.asInt() * y.asInt()); 450 case Long: 451 return forLong(x.asLong() * y.asLong()); 452 case Short: 453 return forShort((short) (x.asInt() * y.asInt())); 454 default: 455 throw new IllegalArgumentException(x.getKind().toString()); 456 } 457 } 458}