1.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeTag.java Tue Jun 18 18:57:52 2013 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeTag.java Tue Jun 18 19:02:48 2013 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -29,6 +29,8 @@ 1.11 1.12 import javax.lang.model.type.TypeKind; 1.13 1.14 +import static com.sun.tools.javac.code.TypeTag.NumericClasses.*; 1.15 + 1.16 /** An interface for type tag values, which distinguish between different 1.17 * sorts of types. 1.18 * 1.19 @@ -40,113 +42,170 @@ 1.20 public enum TypeTag { 1.21 /** The tag of the basic type `byte'. 1.22 */ 1.23 - BYTE(1), 1.24 + BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, 1.25 + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.26 1.27 /** The tag of the basic type `char'. 1.28 */ 1.29 - CHAR(2), 1.30 + CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, 1.31 + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.32 1.33 /** The tag of the basic type `short'. 1.34 */ 1.35 - SHORT(3), 1.36 + SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, 1.37 + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.38 1.39 /** The tag of the basic type `int'. 1.40 */ 1.41 - INT(4), 1.42 + INT(INT_CLASS, INT_SUPERCLASSES, 1.43 + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.44 1.45 /** The tag of the basic type `long'. 1.46 */ 1.47 - LONG(5), 1.48 + LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.49 1.50 /** The tag of the basic type `float'. 1.51 */ 1.52 - FLOAT(6), 1.53 + FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.54 1.55 /** The tag of the basic type `double'. 1.56 */ 1.57 - DOUBLE(7), 1.58 + DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), 1.59 1.60 /** The tag of the basic type `boolean'. 1.61 */ 1.62 - BOOLEAN, 1.63 + BOOLEAN(TypeTagKind.PRIMITIVE), 1.64 1.65 /** The tag of the type `void'. 1.66 */ 1.67 - VOID, 1.68 + VOID(TypeTagKind.VOID), 1.69 1.70 /** The tag of all class and interface types. 1.71 */ 1.72 - CLASS, 1.73 + CLASS(TypeTagKind.REFERENCE), 1.74 1.75 /** The tag of all array types. 1.76 */ 1.77 - ARRAY, 1.78 + ARRAY(TypeTagKind.REFERENCE), 1.79 1.80 /** The tag of all (monomorphic) method types. 1.81 */ 1.82 - METHOD, 1.83 + METHOD(TypeTagKind.OTHER), 1.84 1.85 /** The tag of all package "types". 1.86 */ 1.87 - PACKAGE, 1.88 + PACKAGE(TypeTagKind.OTHER), 1.89 1.90 /** The tag of all (source-level) type variables. 1.91 */ 1.92 - TYPEVAR, 1.93 + TYPEVAR(TypeTagKind.REFERENCE), 1.94 1.95 /** The tag of all type arguments. 1.96 */ 1.97 - WILDCARD, 1.98 + WILDCARD(TypeTagKind.REFERENCE), 1.99 1.100 /** The tag of all polymorphic (method-) types. 1.101 */ 1.102 - FORALL, 1.103 + FORALL(TypeTagKind.OTHER), 1.104 1.105 /** The tag of deferred expression types in method context 1.106 */ 1.107 - DEFERRED, 1.108 + DEFERRED(TypeTagKind.OTHER), 1.109 1.110 /** The tag of the bottom type {@code <null>}. 1.111 */ 1.112 - BOT, 1.113 + BOT(TypeTagKind.OTHER), 1.114 1.115 /** The tag of a missing type. 1.116 */ 1.117 - NONE, 1.118 + NONE(TypeTagKind.OTHER), 1.119 1.120 /** The tag of the error type. 1.121 */ 1.122 - ERROR, 1.123 + ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL), 1.124 1.125 /** The tag of an unknown type 1.126 */ 1.127 - UNKNOWN, 1.128 + UNKNOWN(TypeTagKind.PARTIAL), 1.129 1.130 /** The tag of all instantiatable type variables. 1.131 */ 1.132 - UNDETVAR, 1.133 + UNDETVAR(TypeTagKind.PARTIAL), 1.134 1.135 /** Pseudo-types, these are special tags 1.136 */ 1.137 - UNINITIALIZED_THIS, 1.138 + UNINITIALIZED_THIS(TypeTagKind.OTHER), 1.139 1.140 - UNINITIALIZED_OBJECT; 1.141 + UNINITIALIZED_OBJECT(TypeTagKind.OTHER); 1.142 1.143 - /** This field will only be used for tags related with numeric types for 1.144 - * optimization reasons. 1.145 - */ 1.146 - private final int order; 1.147 + final boolean isPrimitive; 1.148 + final boolean isNumeric; 1.149 + final boolean isPartial; 1.150 + final boolean isReference; 1.151 + final boolean isPrimitiveOrVoid; 1.152 + final int superClasses; 1.153 + final int numericClass; 1.154 1.155 - private TypeTag() { 1.156 - this(0); 1.157 + private TypeTag(int kind) { 1.158 + this(0, 0, kind); 1.159 } 1.160 1.161 - private TypeTag(int order) { 1.162 - this.order = order; 1.163 + private TypeTag(int numericClass, int superClasses, int kind) { 1.164 + isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0; 1.165 + isNumeric = (kind & TypeTagKind.NUMERIC) != 0; 1.166 + isPartial = (kind & TypeTagKind.PARTIAL) != 0; 1.167 + isReference = (kind & TypeTagKind.REFERENCE) != 0; 1.168 + isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) || 1.169 + ((kind & TypeTagKind.VOID) != 0); 1.170 + this.superClasses = superClasses; 1.171 + this.numericClass = numericClass; 1.172 + } 1.173 + 1.174 + static class TypeTagKind { 1.175 + static final int PRIMITIVE = 1; 1.176 + static final int NUMERIC = 2; 1.177 + static final int REFERENCE = 4; 1.178 + static final int PARTIAL = 8; 1.179 + static final int OTHER = 16; 1.180 + static final int VOID = 32; 1.181 } 1.182 1.183 - private static final int MIN_NUMERIC_TAG_ORDER = 1; 1.184 - private static final int MAX_NUMERIC_TAG_ORDER = 7; 1.185 + public static class NumericClasses { 1.186 + public static final int BYTE_CLASS = 1; 1.187 + public static final int CHAR_CLASS = 2; 1.188 + public static final int SHORT_CLASS = 4; 1.189 + public static final int INT_CLASS = 8; 1.190 + public static final int LONG_CLASS = 16; 1.191 + public static final int FLOAT_CLASS = 32; 1.192 + public static final int DOUBLE_CLASS = 64; 1.193 + 1.194 + static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS | 1.195 + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 1.196 + 1.197 + static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS | 1.198 + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 1.199 + 1.200 + static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS | 1.201 + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 1.202 + 1.203 + static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 1.204 + 1.205 + static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 1.206 + 1.207 + static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS; 1.208 + } 1.209 + 1.210 + public boolean isStrictSubRangeOf(TypeTag tag) { 1.211 + /* Please don't change the implementation of this method to call method 1.212 + * isSubRangeOf. Both methods are called from hotspot code, the current 1.213 + * implementation is better performance-wise than the commented modification. 1.214 + */ 1.215 + return (this.superClasses & tag.numericClass) != 0 && this != tag; 1.216 + } 1.217 + 1.218 + public boolean isSubRangeOf(TypeTag tag) { 1.219 + return (this.superClasses & tag.numericClass) != 0; 1.220 + } 1.221 1.222 /** Returns the number of type tags. 1.223 */ 1.224 @@ -155,29 +214,6 @@ 1.225 return (UNDETVAR.ordinal() + 1); 1.226 } 1.227 1.228 - public boolean isSubRangeOf(TypeTag range) { 1.229 - return (this == range) || isStrictSubRangeOf(range); 1.230 - } 1.231 - 1.232 - public boolean isStrictSubRangeOf(TypeTag range) { 1.233 - if (this.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER && 1.234 - range.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER) { 1.235 - if (this == range) 1.236 - return false; 1.237 - switch (this) { 1.238 - case BYTE: 1.239 - return true; 1.240 - case CHAR: case SHORT: case INT: 1.241 - case LONG: case FLOAT: 1.242 - return this.order < range.order && range.order <= MAX_NUMERIC_TAG_ORDER; 1.243 - default: 1.244 - return false; 1.245 - } 1.246 - } 1.247 - else 1.248 - return false; 1.249 - } 1.250 - 1.251 public Kind getKindLiteral() { 1.252 switch (this) { 1.253 case INT: