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 import java.lang.reflect.Array;
26
27 //JaCoCo Exclude
28
29 /**
30 * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example,
31 * {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has
32 * a single character short name, a Java name, and a set of flags further describing its behavior.
33 */
34 public enum JavaKind {
35 /** The primitive boolean kind, represented as an int on the stack. */
36 Boolean('z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
37
38 /** The primitive byte kind, represented as an int on the stack. */
39 Byte('b', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
40
41 /** The primitive short kind, represented as an int on the stack. */
42 Short('s', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
43
44 /** The primitive char kind, represented as an int on the stack. */
45 Char('c', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
46
47 /** The primitive int kind, represented as an int on the stack. */
48 Int('i', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
49
50 /** The primitive float kind. */
51 Float('f', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
52
53 /** The primitive long kind. */
54 Long('j', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
55
56 /** The primitive double kind. */
57 Double('d', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
58
59 /** The Object kind, also used for arrays. */
60 Object('a', "Object", 1, false, null, null),
61
62 /** The void float kind. */
63 Void('v', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
64
65 /** The non-type. */
66 Illegal('-', "illegal", 0, false, null, null);
67
68 private final char typeChar;
69 private final String javaName;
70 private final boolean isStackInt;
71 private final Class<?> primitiveJavaClass;
72 private final Class<?> boxedJavaClass;
73 private final int slotCount;
74
75 JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
76 this.typeChar = typeChar;
77 this.javaName = javaName;
78 this.slotCount = slotCount;
79 this.isStackInt = isStackInt;
80 this.primitiveJavaClass = primitiveJavaClass;
81 this.boxedJavaClass = boxedJavaClass;
82 assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName());
83 }
84
85 /**
86 * Returns the number of stack slots occupied by this kind according to the Java bytecodes
87 * specification.
88 */
89 public int getSlotCount() {
90 return this.slotCount;
91 }
92
93 /**
94 * Returns whether this kind occupied two stack slots.
95 */
96 public boolean needsTwoSlots() {
97 return this.slotCount == 2;
98 }
99
100 /**
101 * Returns the name of the kind as a single character.
102 */
103 public char getTypeChar() {
104 return typeChar;
105 }
106
107 /**
108 * Returns the name of this kind which will also be it Java programming language name if it is
109 * {@linkplain #isPrimitive() primitive} or {@code void}.
110 */
111 public String getJavaName() {
112 return javaName;
113 }
114
115 /**
116 * Checks whether this type is a Java primitive type.
117 *
118 * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char},
119 * {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or
120 * {@link #Void}.
121 */
187 }
188
189 /**
190 * Returns the kind of a word given the size of a word in bytes.
191 *
192 * @param wordSizeInBytes the size of a word in bytes
193 * @return the kind representing a word value
194 */
195 public static JavaKind fromWordSize(int wordSizeInBytes) {
196 if (wordSizeInBytes == 8) {
197 return JavaKind.Long;
198 } else {
199 assert wordSizeInBytes == 4 : "Unsupported word size!";
200 return JavaKind.Int;
201 }
202 }
203
204 /**
205 * Returns the kind from the character describing a primitive or void.
206 *
207 * @param ch the character
208 * @return the kind
209 */
210 public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
211 switch (ch) {
212 case 'Z':
213 return Boolean;
214 case 'C':
215 return Char;
216 case 'F':
217 return Float;
218 case 'D':
219 return Double;
220 case 'B':
221 return Byte;
222 case 'S':
223 return Short;
224 case 'I':
225 return Int;
226 case 'J':
227 return Long;
352 int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength);
353 boolean primitive = componentType.isPrimitive();
354 for (int i = 0; i < length; i++) {
355 if (primitive) {
356 buf.append(Array.get(array, i));
357 } else {
358 Object o = ((Object[]) array)[i];
359 buf.append(JavaKind.Object.format(o));
360 }
361 if (i != length - 1) {
362 buf.append(", ");
363 }
364 }
365 if (arrayLength != length) {
366 buf.append(", ...");
367 }
368 return buf.append('}').toString();
369 }
370
371 /**
372 * The minimum value that can be represented as a value of this kind.
373 *
374 * @return the minimum value
375 */
376 public long getMinValue() {
377 switch (this) {
378 case Boolean:
379 return 0;
380 case Byte:
381 return java.lang.Byte.MIN_VALUE;
382 case Char:
383 return java.lang.Character.MIN_VALUE;
384 case Short:
385 return java.lang.Short.MIN_VALUE;
386 case Int:
387 return java.lang.Integer.MIN_VALUE;
388 case Long:
389 return java.lang.Long.MIN_VALUE;
390 default:
391 throw new IllegalArgumentException("illegal call to minValue on " + this);
392 }
393 }
394
395 /**
396 * The maximum value that can be represented as a value of this kind.
397 *
398 * @return the maximum value
399 */
400 public long getMaxValue() {
401 switch (this) {
402 case Boolean:
403 return 1;
404 case Byte:
405 return java.lang.Byte.MAX_VALUE;
406 case Char:
407 return java.lang.Character.MAX_VALUE;
408 case Short:
409 return java.lang.Short.MAX_VALUE;
410 case Int:
411 return java.lang.Integer.MAX_VALUE;
412 case Long:
413 return java.lang.Long.MAX_VALUE;
414 default:
415 throw new IllegalArgumentException("illegal call to maxValue on " + this);
416 }
417 }
418
419 /**
420 * Number of bytes that are necessary to represent a value of this kind.
421 *
422 * @return the number of bytes
423 */
424 public int getByteCount() {
425 if (this == Boolean) {
426 return 1;
427 } else {
428 return getBitCount() >> 3;
429 }
430 }
431
432 /**
433 * Number of bits that are necessary to represent a value of this kind.
|
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 import java.lang.reflect.Array;
26
27 //JaCoCo Exclude
28
29 /**
30 * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example,
31 * {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has
32 * a single character short name, a Java name, and a set of flags further describing its behavior.
33 */
34 public enum JavaKind {
35 /** The primitive boolean kind, represented as an int on the stack. */
36 Boolean('Z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
37
38 /** The primitive byte kind, represented as an int on the stack. */
39 Byte('B', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
40
41 /** The primitive short kind, represented as an int on the stack. */
42 Short('S', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
43
44 /** The primitive char kind, represented as an int on the stack. */
45 Char('C', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
46
47 /** The primitive int kind, represented as an int on the stack. */
48 Int('I', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
49
50 /** The primitive float kind. */
51 Float('F', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
52
53 /** The primitive long kind. */
54 Long('J', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
55
56 /** The primitive double kind. */
57 Double('D', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
58
59 /** The Object kind, also used for arrays. */
60 Object('A', "Object", 1, false, null, null),
61
62 /** The void kind. */
63 Void('V', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
64
65 /** The non-type. */
66 Illegal('-', "illegal", 0, false, null, null);
67
68 private final char typeChar;
69 private final String javaName;
70 private final boolean isStackInt;
71 private final Class<?> primitiveJavaClass;
72 private final Class<?> boxedJavaClass;
73 private final int slotCount;
74
75 JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
76 this.typeChar = typeChar;
77 this.javaName = javaName;
78 this.slotCount = slotCount;
79 this.isStackInt = isStackInt;
80 this.primitiveJavaClass = primitiveJavaClass;
81 this.boxedJavaClass = boxedJavaClass;
82 assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName());
83 }
84
85 /**
86 * Returns the number of stack slots occupied by this kind according to the Java bytecodes
87 * specification.
88 */
89 public int getSlotCount() {
90 return this.slotCount;
91 }
92
93 /**
94 * Returns whether this kind occupied two stack slots.
95 */
96 public boolean needsTwoSlots() {
97 return this.slotCount == 2;
98 }
99
100 /**
101 * Returns the name of the kind as a single upper case character. For the void and primitive
102 * kinds, this is the <i>FieldType</i> term in
103 * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-200">
104 * table 4.3-A</a> of the JVM Specification. For {@link #Object}, the character {@code 'A'} is
105 * returned and for {@link #Illegal}, {@code '-'} is returned.
106 */
107 public char getTypeChar() {
108 return typeChar;
109 }
110
111 /**
112 * Returns the name of this kind which will also be it Java programming language name if it is
113 * {@linkplain #isPrimitive() primitive} or {@code void}.
114 */
115 public String getJavaName() {
116 return javaName;
117 }
118
119 /**
120 * Checks whether this type is a Java primitive type.
121 *
122 * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char},
123 * {@link #Short}, {@link #Int}, {@link #Long}, {@link #Float}, {@link #Double}, or
124 * {@link #Void}.
125 */
191 }
192
193 /**
194 * Returns the kind of a word given the size of a word in bytes.
195 *
196 * @param wordSizeInBytes the size of a word in bytes
197 * @return the kind representing a word value
198 */
199 public static JavaKind fromWordSize(int wordSizeInBytes) {
200 if (wordSizeInBytes == 8) {
201 return JavaKind.Long;
202 } else {
203 assert wordSizeInBytes == 4 : "Unsupported word size!";
204 return JavaKind.Int;
205 }
206 }
207
208 /**
209 * Returns the kind from the character describing a primitive or void.
210 *
211 * @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()}
212 * @return the kind
213 */
214 public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
215 switch (ch) {
216 case 'Z':
217 return Boolean;
218 case 'C':
219 return Char;
220 case 'F':
221 return Float;
222 case 'D':
223 return Double;
224 case 'B':
225 return Byte;
226 case 'S':
227 return Short;
228 case 'I':
229 return Int;
230 case 'J':
231 return Long;
356 int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength);
357 boolean primitive = componentType.isPrimitive();
358 for (int i = 0; i < length; i++) {
359 if (primitive) {
360 buf.append(Array.get(array, i));
361 } else {
362 Object o = ((Object[]) array)[i];
363 buf.append(JavaKind.Object.format(o));
364 }
365 if (i != length - 1) {
366 buf.append(", ");
367 }
368 }
369 if (arrayLength != length) {
370 buf.append(", ...");
371 }
372 return buf.append('}').toString();
373 }
374
375 /**
376 * Gets the minimum value that can be represented as a value of this kind.
377 *
378 * @return the minimum value represented as a {@code long}
379 */
380 public long getMinValue() {
381 switch (this) {
382 case Boolean:
383 return 0;
384 case Byte:
385 return java.lang.Byte.MIN_VALUE;
386 case Char:
387 return java.lang.Character.MIN_VALUE;
388 case Short:
389 return java.lang.Short.MIN_VALUE;
390 case Int:
391 return java.lang.Integer.MIN_VALUE;
392 case Long:
393 return java.lang.Long.MIN_VALUE;
394 case Float:
395 return java.lang.Float.floatToRawIntBits(java.lang.Float.MIN_VALUE);
396 case Double:
397 return java.lang.Double.doubleToRawLongBits(java.lang.Double.MIN_VALUE);
398 default:
399 throw new IllegalArgumentException("illegal call to minValue on " + this);
400 }
401 }
402
403 /**
404 * Gets the maximum value that can be represented as a value of this kind.
405 *
406 * @return the maximum value represented as a {@code long}
407 */
408 public long getMaxValue() {
409 switch (this) {
410 case Boolean:
411 return 1;
412 case Byte:
413 return java.lang.Byte.MAX_VALUE;
414 case Char:
415 return java.lang.Character.MAX_VALUE;
416 case Short:
417 return java.lang.Short.MAX_VALUE;
418 case Int:
419 return java.lang.Integer.MAX_VALUE;
420 case Long:
421 return java.lang.Long.MAX_VALUE;
422 case Float:
423 return java.lang.Float.floatToRawIntBits(java.lang.Float.MAX_VALUE);
424 case Double:
425 return java.lang.Double.doubleToRawLongBits(java.lang.Double.MAX_VALUE);
426 default:
427 throw new IllegalArgumentException("illegal call to maxValue on " + this);
428 }
429 }
430
431 /**
432 * Number of bytes that are necessary to represent a value of this kind.
433 *
434 * @return the number of bytes
435 */
436 public int getByteCount() {
437 if (this == Boolean) {
438 return 1;
439 } else {
440 return getBitCount() >> 3;
441 }
442 }
443
444 /**
445 * Number of bits that are necessary to represent a value of this kind.
|