comparison jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java @ 22672:1bbd4a7c274b

Rename jdk.internal.jvmci to jdk.vm.ci
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Oct 2015 17:28:41 -0700
parents jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JavaConstant.java@dc1aeef79e7e
children 1d4ce2d19e52
comparison
equal deleted inserted replaced
22671:97f30e4d0e95 22672:1bbd4a7c274b
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 */
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 */
60 boolean isNull();
61
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 */
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 boolean isDefaultForKind();
85
86 /**
87 * Returns the value of this constant as a boxed Java value.
88 *
89 * @return the value of this constant
90 */
91 Object asBoxedPrimitive();
92
93 /**
94 * Returns the primitive int value this constant represents. The constant must have a
95 * {@link JavaKind#getStackKind()} of {@link JavaKind#Int}.
96 *
97 * @return the constant value
98 */
99 int asInt();
100
101 /**
102 * Returns the primitive boolean value this constant represents. The constant must have kind
103 * {@link JavaKind#Boolean}.
104 *
105 * @return the constant value
106 */
107 boolean asBoolean();
108
109 /**
110 * Returns the primitive long value this constant represents. The constant must have kind
111 * {@link JavaKind#Long}, a {@link JavaKind#getStackKind()} of {@link JavaKind#Int}.
112 *
113 * @return the constant value
114 */
115 long asLong();
116
117 /**
118 * Returns the primitive float value this constant represents. The constant must have kind
119 * {@link JavaKind#Float}.
120 *
121 * @return the constant value
122 */
123 float asFloat();
124
125 /**
126 * Returns the primitive double value this constant represents. The constant must have kind
127 * {@link JavaKind#Double}.
128 *
129 * @return the constant value
130 */
131 double asDouble();
132
133 default String toValueString() {
134 if (getJavaKind() == JavaKind.Illegal) {
135 return "illegal";
136 } else {
137 return getJavaKind().format(asBoxedPrimitive());
138 }
139 }
140
141 static String toString(JavaConstant constant) {
142 if (constant.getJavaKind() == JavaKind.Illegal) {
143 return "illegal";
144 } else {
145 return constant.getJavaKind().getJavaName() + "[" + constant.toValueString() + "]";
146 }
147 }
148
149 /**
150 * Creates a boxed double constant.
151 *
152 * @param d the double value to box
153 * @return a boxed copy of {@code value}
154 */
155 static PrimitiveConstant forDouble(double d) {
156 if (Double.compare(0.0D, d) == 0) {
157 return DOUBLE_0;
158 }
159 if (Double.compare(d, 1.0D) == 0) {
160 return DOUBLE_1;
161 }
162 return new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(d));
163 }
164
165 /**
166 * Creates a boxed float constant.
167 *
168 * @param f the float value to box
169 * @return a boxed copy of {@code value}
170 */
171 static PrimitiveConstant forFloat(float f) {
172 if (Float.compare(f, 0.0F) == 0) {
173 return FLOAT_0;
174 }
175 if (Float.compare(f, 1.0F) == 0) {
176 return FLOAT_1;
177 }
178 return new PrimitiveConstant(JavaKind.Float, Float.floatToRawIntBits(f));
179 }
180
181 /**
182 * Creates a boxed long constant.
183 *
184 * @param i the long value to box
185 * @return a boxed copy of {@code value}
186 */
187 static PrimitiveConstant forLong(long i) {
188 if (i == 0) {
189 return LONG_0;
190 } else if (i == 1) {
191 return LONG_1;
192 } else {
193 return new PrimitiveConstant(JavaKind.Long, i);
194 }
195 }
196
197 /**
198 * Creates a boxed integer constant.
199 *
200 * @param i the integer value to box
201 * @return a boxed copy of {@code value}
202 */
203 static PrimitiveConstant forInt(int i) {
204 switch (i) {
205 case -1:
206 return INT_MINUS_1;
207 case 0:
208 return INT_0;
209 case 1:
210 return INT_1;
211 case 2:
212 return INT_2;
213 default:
214 return new PrimitiveConstant(JavaKind.Int, i);
215 }
216 }
217
218 /**
219 * Creates a boxed byte constant.
220 *
221 * @param i the byte value to box
222 * @return a boxed copy of {@code value}
223 */
224 static PrimitiveConstant forByte(byte i) {
225 return new PrimitiveConstant(JavaKind.Byte, i);
226 }
227
228 /**
229 * Creates a boxed boolean constant.
230 *
231 * @param i the boolean value to box
232 * @return a boxed copy of {@code value}
233 */
234 static PrimitiveConstant forBoolean(boolean i) {
235 return i ? TRUE : FALSE;
236 }
237
238 /**
239 * Creates a boxed char constant.
240 *
241 * @param i the char value to box
242 * @return a boxed copy of {@code value}
243 */
244 static PrimitiveConstant forChar(char i) {
245 return new PrimitiveConstant(JavaKind.Char, i);
246 }
247
248 /**
249 * Creates a boxed short constant.
250 *
251 * @param i the short value to box
252 * @return a boxed copy of {@code value}
253 */
254 static PrimitiveConstant forShort(short i) {
255 return new PrimitiveConstant(JavaKind.Short, i);
256 }
257
258 /**
259 * Creates a {@link JavaConstant} from a primitive integer of a certain kind.
260 */
261 static PrimitiveConstant forIntegerKind(JavaKind kind, long i) {
262 switch (kind) {
263 case Boolean:
264 return forBoolean(i != 0);
265 case Byte:
266 return forByte((byte) i);
267 case Short:
268 return forShort((short) i);
269 case Char:
270 return forChar((char) i);
271 case Int:
272 return forInt((int) i);
273 case Long:
274 return forLong(i);
275 default:
276 throw new IllegalArgumentException("not an integer kind: " + kind);
277 }
278 }
279
280 /**
281 * Creates a {@link JavaConstant} from a primitive integer of a certain width.
282 */
283 static PrimitiveConstant forPrimitiveInt(int bits, long i) {
284 assert bits <= 64;
285 switch (bits) {
286 case 1:
287 return forBoolean(i != 0);
288 case 8:
289 return forByte((byte) i);
290 case 16:
291 return forShort((short) i);
292 case 32:
293 return forInt((int) i);
294 case 64:
295 return forLong(i);
296 default:
297 throw new IllegalArgumentException("unsupported integer width: " + bits);
298 }
299 }
300
301 /**
302 * Creates a boxed constant for the given boxed primitive value.
303 *
304 * @param value the Java boxed value
305 * @return the primitive constant holding the {@code value}
306 */
307 static PrimitiveConstant forBoxedPrimitive(Object value) {
308 if (value instanceof Boolean) {
309 return forBoolean((Boolean) value);
310 } else if (value instanceof Byte) {
311 return forByte((Byte) value);
312 } else if (value instanceof Character) {
313 return forChar((Character) value);
314 } else if (value instanceof Short) {
315 return forShort((Short) value);
316 } else if (value instanceof Integer) {
317 return forInt((Integer) value);
318 } else if (value instanceof Long) {
319 return forLong((Long) value);
320 } else if (value instanceof Float) {
321 return forFloat((Float) value);
322 } else if (value instanceof Double) {
323 return forDouble((Double) value);
324 } else {
325 return null;
326 }
327 }
328
329 static PrimitiveConstant forIllegal() {
330 return new PrimitiveConstant(JavaKind.Illegal, 0);
331 }
332
333 /**
334 * Returns a constant with the default value for the given kind.
335 */
336 static JavaConstant defaultForKind(JavaKind kind) {
337 switch (kind) {
338 case Boolean:
339 return FALSE;
340 case Byte:
341 return forByte((byte) 0);
342 case Char:
343 return forChar((char) 0);
344 case Short:
345 return forShort((short) 0);
346 case Int:
347 return INT_0;
348 case Double:
349 return DOUBLE_0;
350 case Float:
351 return FLOAT_0;
352 case Long:
353 return LONG_0;
354 case Object:
355 return NULL_POINTER;
356 default:
357 throw new IllegalArgumentException(kind.toString());
358 }
359 }
360
361 /**
362 * Returns the zero value for a given numeric kind.
363 */
364 static JavaConstant zero(JavaKind kind) {
365 switch (kind) {
366 case Boolean:
367 return FALSE;
368 case Byte:
369 return forByte((byte) 0);
370 case Char:
371 return forChar((char) 0);
372 case Double:
373 return DOUBLE_0;
374 case Float:
375 return FLOAT_0;
376 case Int:
377 return INT_0;
378 case Long:
379 return LONG_0;
380 case Short:
381 return forShort((short) 0);
382 default:
383 throw new IllegalArgumentException(kind.toString());
384 }
385 }
386
387 /**
388 * Returns the one value for a given numeric kind.
389 */
390 static JavaConstant one(JavaKind kind) {
391 switch (kind) {
392 case Boolean:
393 return TRUE;
394 case Byte:
395 return forByte((byte) 1);
396 case Char:
397 return forChar((char) 1);
398 case Double:
399 return DOUBLE_1;
400 case Float:
401 return FLOAT_1;
402 case Int:
403 return INT_1;
404 case Long:
405 return LONG_1;
406 case Short:
407 return forShort((short) 1);
408 default:
409 throw new IllegalArgumentException(kind.toString());
410 }
411 }
412
413 /**
414 * Adds two numeric constants.
415 */
416 static JavaConstant add(JavaConstant x, JavaConstant y) {
417 assert x.getJavaKind() == y.getJavaKind();
418 switch (x.getJavaKind()) {
419 case Byte:
420 return forByte((byte) (x.asInt() + y.asInt()));
421 case Char:
422 return forChar((char) (x.asInt() + y.asInt()));
423 case Double:
424 return forDouble(x.asDouble() + y.asDouble());
425 case Float:
426 return forFloat(x.asFloat() + y.asFloat());
427 case Int:
428 return forInt(x.asInt() + y.asInt());
429 case Long:
430 return forLong(x.asLong() + y.asLong());
431 case Short:
432 return forShort((short) (x.asInt() + y.asInt()));
433 default:
434 throw new IllegalArgumentException(x.getJavaKind().toString());
435 }
436 }
437
438 /**
439 * Multiplies two numeric constants.
440 */
441 static PrimitiveConstant mul(JavaConstant x, JavaConstant y) {
442 assert x.getJavaKind() == y.getJavaKind();
443 switch (x.getJavaKind()) {
444 case Byte:
445 return forByte((byte) (x.asInt() * y.asInt()));
446 case Char:
447 return forChar((char) (x.asInt() * y.asInt()));
448 case Double:
449 return forDouble(x.asDouble() * y.asDouble());
450 case Float:
451 return forFloat(x.asFloat() * y.asFloat());
452 case Int:
453 return forInt(x.asInt() * y.asInt());
454 case Long:
455 return forLong(x.asLong() * y.asLong());
456 case Short:
457 return forShort((short) (x.asInt() * y.asInt()));
458 default:
459 throw new IllegalArgumentException(x.getJavaKind().toString());
460 }
461 }
462 }