< prev index next >

src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java

Print this page




  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.


< prev index next >