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

     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 }

mercurial