src/share/classes/com/sun/tools/javac/code/TypeTag.java

Tue, 18 Jun 2013 19:02:48 +0100

author
vromero
date
Tue, 18 Jun 2013 19:02:48 +0100
changeset 1826
9851071b551a
parent 1442
fcf89720ae71
child 1853
831467c4c6a7
permissions
-rw-r--r--

8016267: javac, TypeTag refactoring has provoked performance issues
Reviewed-by: jjg

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

mercurial