Tue, 18 Jun 2013 19:02:48 +0100
8016267: javac, TypeTag refactoring has provoked performance issues
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1999, 2013, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import com.sun.source.tree.Tree.Kind;
30 import javax.lang.model.type.TypeKind;
32 import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
34 /** An interface for type tag values, which distinguish between different
35 * sorts of types.
36 *
37 * <p><b>This is NOT part of any supported API.
38 * If you write code that depends on this, you do so at your own risk.
39 * This code and its internal interfaces are subject to change or
40 * deletion without notice.</b>
41 */
42 public enum TypeTag {
43 /** The tag of the basic type `byte'.
44 */
45 BYTE(BYTE_CLASS, BYTE_SUPERCLASSES,
46 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
48 /** The tag of the basic type `char'.
49 */
50 CHAR(CHAR_CLASS, CHAR_SUPERCLASSES,
51 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
53 /** The tag of the basic type `short'.
54 */
55 SHORT(SHORT_CLASS, SHORT_SUPERCLASSES,
56 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
58 /** The tag of the basic type `int'.
59 */
60 INT(INT_CLASS, INT_SUPERCLASSES,
61 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
63 /** The tag of the basic type `long'.
64 */
65 LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
67 /** The tag of the basic type `float'.
68 */
69 FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
71 /** The tag of the basic type `double'.
72 */
73 DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
75 /** The tag of the basic type `boolean'.
76 */
77 BOOLEAN(TypeTagKind.PRIMITIVE),
79 /** The tag of the type `void'.
80 */
81 VOID(TypeTagKind.VOID),
83 /** The tag of all class and interface types.
84 */
85 CLASS(TypeTagKind.REFERENCE),
87 /** The tag of all array types.
88 */
89 ARRAY(TypeTagKind.REFERENCE),
91 /** The tag of all (monomorphic) method types.
92 */
93 METHOD(TypeTagKind.OTHER),
95 /** The tag of all package "types".
96 */
97 PACKAGE(TypeTagKind.OTHER),
99 /** The tag of all (source-level) type variables.
100 */
101 TYPEVAR(TypeTagKind.REFERENCE),
103 /** The tag of all type arguments.
104 */
105 WILDCARD(TypeTagKind.REFERENCE),
107 /** The tag of all polymorphic (method-) types.
108 */
109 FORALL(TypeTagKind.OTHER),
111 /** The tag of deferred expression types in method context
112 */
113 DEFERRED(TypeTagKind.OTHER),
115 /** The tag of the bottom type {@code <null>}.
116 */
117 BOT(TypeTagKind.OTHER),
119 /** The tag of a missing type.
120 */
121 NONE(TypeTagKind.OTHER),
123 /** The tag of the error type.
124 */
125 ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL),
127 /** The tag of an unknown type
128 */
129 UNKNOWN(TypeTagKind.PARTIAL),
131 /** The tag of all instantiatable type variables.
132 */
133 UNDETVAR(TypeTagKind.PARTIAL),
135 /** Pseudo-types, these are special tags
136 */
137 UNINITIALIZED_THIS(TypeTagKind.OTHER),
139 UNINITIALIZED_OBJECT(TypeTagKind.OTHER);
141 final boolean isPrimitive;
142 final boolean isNumeric;
143 final boolean isPartial;
144 final boolean isReference;
145 final boolean isPrimitiveOrVoid;
146 final int superClasses;
147 final int numericClass;
149 private TypeTag(int kind) {
150 this(0, 0, kind);
151 }
153 private TypeTag(int numericClass, int superClasses, int kind) {
154 isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0;
155 isNumeric = (kind & TypeTagKind.NUMERIC) != 0;
156 isPartial = (kind & TypeTagKind.PARTIAL) != 0;
157 isReference = (kind & TypeTagKind.REFERENCE) != 0;
158 isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) ||
159 ((kind & TypeTagKind.VOID) != 0);
160 this.superClasses = superClasses;
161 this.numericClass = numericClass;
162 }
164 static class TypeTagKind {
165 static final int PRIMITIVE = 1;
166 static final int NUMERIC = 2;
167 static final int REFERENCE = 4;
168 static final int PARTIAL = 8;
169 static final int OTHER = 16;
170 static final int VOID = 32;
171 }
173 public static class NumericClasses {
174 public static final int BYTE_CLASS = 1;
175 public static final int CHAR_CLASS = 2;
176 public static final int SHORT_CLASS = 4;
177 public static final int INT_CLASS = 8;
178 public static final int LONG_CLASS = 16;
179 public static final int FLOAT_CLASS = 32;
180 public static final int DOUBLE_CLASS = 64;
182 static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS |
183 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
185 static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS |
186 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
188 static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS |
189 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
191 static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
193 static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
195 static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS;
196 }
198 public boolean isStrictSubRangeOf(TypeTag tag) {
199 /* Please don't change the implementation of this method to call method
200 * isSubRangeOf. Both methods are called from hotspot code, the current
201 * implementation is better performance-wise than the commented modification.
202 */
203 return (this.superClasses & tag.numericClass) != 0 && this != tag;
204 }
206 public boolean isSubRangeOf(TypeTag tag) {
207 return (this.superClasses & tag.numericClass) != 0;
208 }
210 /** Returns the number of type tags.
211 */
212 public static int getTypeTagCount() {
213 // last two tags are not included in the total as long as they are pseudo-types
214 return (UNDETVAR.ordinal() + 1);
215 }
217 public Kind getKindLiteral() {
218 switch (this) {
219 case INT:
220 return Kind.INT_LITERAL;
221 case LONG:
222 return Kind.LONG_LITERAL;
223 case FLOAT:
224 return Kind.FLOAT_LITERAL;
225 case DOUBLE:
226 return Kind.DOUBLE_LITERAL;
227 case BOOLEAN:
228 return Kind.BOOLEAN_LITERAL;
229 case CHAR:
230 return Kind.CHAR_LITERAL;
231 case CLASS:
232 return Kind.STRING_LITERAL;
233 case BOT:
234 return Kind.NULL_LITERAL;
235 default:
236 throw new AssertionError("unknown literal kind " + this);
237 }
238 }
240 public TypeKind getPrimitiveTypeKind() {
241 switch (this) {
242 case BOOLEAN:
243 return TypeKind.BOOLEAN;
244 case BYTE:
245 return TypeKind.BYTE;
246 case SHORT:
247 return TypeKind.SHORT;
248 case INT:
249 return TypeKind.INT;
250 case LONG:
251 return TypeKind.LONG;
252 case CHAR:
253 return TypeKind.CHAR;
254 case FLOAT:
255 return TypeKind.FLOAT;
256 case DOUBLE:
257 return TypeKind.DOUBLE;
258 case VOID:
259 return TypeKind.VOID;
260 default:
261 throw new AssertionError("unknown primitive type " + this);
262 }
263 }
264 }