# HG changeset patch # User chegar # Date 1371582529 -3600 # Node ID 64f511787fd93edd73d47021bf234a9c79628f7a # Parent db6bf740a578ae2e162260c7c233291e7f87d2a2# Parent 9851071b551a83327f5e292a884f77445ab94890 Merge diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 18 20:08:49 2013 +0100 @@ -110,49 +110,27 @@ } public boolean isNumeric() { - switch (tag) { - case BYTE: case CHAR: - case SHORT: - case INT: case LONG: - case FLOAT: case DOUBLE: - return true; - default: - return false; - } + return tag.isNumeric; } public boolean isPrimitive() { - return (isNumeric() || tag == BOOLEAN); + return tag.isPrimitive; } public boolean isPrimitiveOrVoid() { - return (isPrimitive() || tag == VOID); + return tag.isPrimitiveOrVoid; } public boolean isReference() { - switch (tag) { - case CLASS: - case ARRAY: - case TYPEVAR: - case WILDCARD: - case ERROR: - return true; - default: - return false; - } + return tag.isReference; } public boolean isNullOrReference() { - return (tag == BOT || isReference()); + return (tag.isReference || tag == BOT); } public boolean isPartial() { - switch(tag) { - case ERROR: case UNKNOWN: case UNDETVAR: - return true; - default: - return false; - } + return tag.isPartial; } /** diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/code/TypeTag.java --- a/src/share/classes/com/sun/tools/javac/code/TypeTag.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/code/TypeTag.java Tue Jun 18 20:08:49 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import javax.lang.model.type.TypeKind; +import static com.sun.tools.javac.code.TypeTag.NumericClasses.*; + /** An interface for type tag values, which distinguish between different * sorts of types. * @@ -40,113 +42,170 @@ public enum TypeTag { /** The tag of the basic type `byte'. */ - BYTE(1), + BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `char'. */ - CHAR(2), + CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `short'. */ - SHORT(3), + SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `int'. */ - INT(4), + INT(INT_CLASS, INT_SUPERCLASSES, + TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `long'. */ - LONG(5), + LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `float'. */ - FLOAT(6), + FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `double'. */ - DOUBLE(7), + DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), /** The tag of the basic type `boolean'. */ - BOOLEAN, + BOOLEAN(TypeTagKind.PRIMITIVE), /** The tag of the type `void'. */ - VOID, + VOID(TypeTagKind.VOID), /** The tag of all class and interface types. */ - CLASS, + CLASS(TypeTagKind.REFERENCE), /** The tag of all array types. */ - ARRAY, + ARRAY(TypeTagKind.REFERENCE), /** The tag of all (monomorphic) method types. */ - METHOD, + METHOD(TypeTagKind.OTHER), /** The tag of all package "types". */ - PACKAGE, + PACKAGE(TypeTagKind.OTHER), /** The tag of all (source-level) type variables. */ - TYPEVAR, + TYPEVAR(TypeTagKind.REFERENCE), /** The tag of all type arguments. */ - WILDCARD, + WILDCARD(TypeTagKind.REFERENCE), /** The tag of all polymorphic (method-) types. */ - FORALL, + FORALL(TypeTagKind.OTHER), /** The tag of deferred expression types in method context */ - DEFERRED, + DEFERRED(TypeTagKind.OTHER), /** The tag of the bottom type {@code }. */ - BOT, + BOT(TypeTagKind.OTHER), /** The tag of a missing type. */ - NONE, + NONE(TypeTagKind.OTHER), /** The tag of the error type. */ - ERROR, + ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL), /** The tag of an unknown type */ - UNKNOWN, + UNKNOWN(TypeTagKind.PARTIAL), /** The tag of all instantiatable type variables. */ - UNDETVAR, + UNDETVAR(TypeTagKind.PARTIAL), /** Pseudo-types, these are special tags */ - UNINITIALIZED_THIS, + UNINITIALIZED_THIS(TypeTagKind.OTHER), - UNINITIALIZED_OBJECT; + UNINITIALIZED_OBJECT(TypeTagKind.OTHER); - /** This field will only be used for tags related with numeric types for - * optimization reasons. - */ - private final int order; + final boolean isPrimitive; + final boolean isNumeric; + final boolean isPartial; + final boolean isReference; + final boolean isPrimitiveOrVoid; + final int superClasses; + final int numericClass; - private TypeTag() { - this(0); + private TypeTag(int kind) { + this(0, 0, kind); } - private TypeTag(int order) { - this.order = order; + private TypeTag(int numericClass, int superClasses, int kind) { + isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0; + isNumeric = (kind & TypeTagKind.NUMERIC) != 0; + isPartial = (kind & TypeTagKind.PARTIAL) != 0; + isReference = (kind & TypeTagKind.REFERENCE) != 0; + isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) || + ((kind & TypeTagKind.VOID) != 0); + this.superClasses = superClasses; + this.numericClass = numericClass; + } + + static class TypeTagKind { + static final int PRIMITIVE = 1; + static final int NUMERIC = 2; + static final int REFERENCE = 4; + static final int PARTIAL = 8; + static final int OTHER = 16; + static final int VOID = 32; } - private static final int MIN_NUMERIC_TAG_ORDER = 1; - private static final int MAX_NUMERIC_TAG_ORDER = 7; + public static class NumericClasses { + public static final int BYTE_CLASS = 1; + public static final int CHAR_CLASS = 2; + public static final int SHORT_CLASS = 4; + public static final int INT_CLASS = 8; + public static final int LONG_CLASS = 16; + public static final int FLOAT_CLASS = 32; + public static final int DOUBLE_CLASS = 64; + + static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS | + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; + + static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS | + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; + + static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS | + LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; + + static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; + + static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; + + static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS; + } + + public boolean isStrictSubRangeOf(TypeTag tag) { + /* Please don't change the implementation of this method to call method + * isSubRangeOf. Both methods are called from hotspot code, the current + * implementation is better performance-wise than the commented modification. + */ + return (this.superClasses & tag.numericClass) != 0 && this != tag; + } + + public boolean isSubRangeOf(TypeTag tag) { + return (this.superClasses & tag.numericClass) != 0; + } /** Returns the number of type tags. */ @@ -155,29 +214,6 @@ return (UNDETVAR.ordinal() + 1); } - public boolean isSubRangeOf(TypeTag range) { - return (this == range) || isStrictSubRangeOf(range); - } - - public boolean isStrictSubRangeOf(TypeTag range) { - if (this.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER && - range.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER) { - if (this == range) - return false; - switch (this) { - case BYTE: - return true; - case CHAR: case SHORT: case INT: - case LONG: case FLOAT: - return this.order < range.order && range.order <= MAX_NUMERIC_TAG_ORDER; - default: - return false; - } - } - else - return false; - } - public Kind getKindLiteral() { switch (this) { case INT: diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jun 18 20:08:49 2013 +0100 @@ -1532,21 +1532,23 @@ // If one arm has an integer subrange type (i.e., byte, // short, or char), and the other is an integer constant // that fits into the subrange, return the subrange type. - if (thenUnboxed.getTag().isStrictSubRangeOf(INT) && elseUnboxed.hasTag(INT) && - types.isAssignable(elseUnboxed, thenUnboxed)) + if (thenUnboxed.getTag().isStrictSubRangeOf(INT) && + elseUnboxed.hasTag(INT) && + types.isAssignable(elseUnboxed, thenUnboxed)) { return thenUnboxed.baseType(); - if (elseUnboxed.getTag().isStrictSubRangeOf(INT) && thenUnboxed.hasTag(INT) && - types.isAssignable(thenUnboxed, elseUnboxed)) + } + if (elseUnboxed.getTag().isStrictSubRangeOf(INT) && + thenUnboxed.hasTag(INT) && + types.isAssignable(thenUnboxed, elseUnboxed)) { return elseUnboxed.baseType(); - - for (TypeTag tag : TypeTag.values()) { - if (tag.ordinal() >= TypeTag.getTypeTagCount()) break; + } + + for (TypeTag tag : primitiveTags) { Type candidate = syms.typeOfTag[tag.ordinal()]; - if (candidate != null && - candidate.isPrimitive() && - types.isSubtype(thenUnboxed, candidate) && - types.isSubtype(elseUnboxed, candidate)) + if (types.isSubtype(thenUnboxed, candidate) && + types.isSubtype(elseUnboxed, candidate)) { return candidate; + } } } @@ -1575,6 +1577,17 @@ return types.lub(thentype.baseType(), elsetype.baseType()); } + final static TypeTag[] primitiveTags = new TypeTag[]{ + BYTE, + CHAR, + SHORT, + INT, + LONG, + FLOAT, + DOUBLE, + BOOLEAN, + }; + public void visitIf(JCIf tree) { attribExpr(tree.cond, env, syms.booleanType); attribStat(tree.thenpart, env); diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jun 18 20:08:49 2013 +0100 @@ -544,7 +544,7 @@ if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) { return found; } else { - if (found.getTag().isSubRangeOf(DOUBLE) && req.getTag().isSubRangeOf(DOUBLE)) { + if (found.isNumeric() && req.isNumeric()) { checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req)); return types.createErrorType(found); } @@ -754,7 +754,7 @@ * @param t The type to be checked. */ Type checkNullOrRefType(DiagnosticPosition pos, Type t) { - if (t.isNullOrReference()) + if (t.isReference() || t.hasTag(BOT)) return t; else return typeTagError(pos, @@ -3228,7 +3228,7 @@ void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) { if (operand.constValue() != null && lint.isEnabled(LintCategory.DIVZERO) - && (operand.getTag().isSubRangeOf(LONG)) + && operand.getTag().isSubRangeOf(LONG) && ((Number) (operand.constValue())).longValue() == 0) { int opc = ((OperatorSymbol)operator).opcode; if (opc == ByteCodes.idiv || opc == ByteCodes.imod diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jun 18 20:08:49 2013 +0100 @@ -952,8 +952,9 @@ Type solve(UndetVar uv, InferenceContext inferenceContext) { Infer infer = inferenceContext.infer(); List lobounds = filterBounds(uv, inferenceContext); - Type owntype = infer.types.lub(lobounds); - if (owntype.hasTag(ERROR)) { + //note: lobounds should have at least one element + Type owntype = lobounds.tail.tail == null ? lobounds.head : infer.types.lub(lobounds); + if (owntype.isPrimitive() || owntype.hasTag(ERROR)) { throw infer.inferenceException .setMessage("no.unique.minimal.instance.exists", uv.qtype, lobounds); @@ -971,8 +972,9 @@ Type solve(UndetVar uv, InferenceContext inferenceContext) { Infer infer = inferenceContext.infer(); List hibounds = filterBounds(uv, inferenceContext); - Type owntype = infer.types.glb(hibounds); - if (owntype.isErroneous()) { + //note: lobounds should have at least one element + Type owntype = hibounds.tail.tail == null ? hibounds.head : infer.types.glb(hibounds); + if (owntype.isPrimitive() || owntype.hasTag(ERROR)) { throw infer.inferenceException .setMessage("no.unique.maximal.instance.exists", uv.qtype, hibounds); @@ -1100,10 +1102,11 @@ } } //no progress - throw inferenceException; + throw inferenceException.setMessage(); } } catch (InferenceException ex) { + //did we fail because of interdependent ivars? inferenceContext.rollback(); instantiateAsUninferredVars(varsToSolve, inferenceContext); checkWithinBounds(inferenceContext, warn); diff -r db6bf740a578 -r 64f511787fd9 src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Jun 18 09:36:46 2013 +0100 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Jun 18 20:08:49 2013 +0100 @@ -1435,11 +1435,13 @@ env.tree = transTypes.translateTopLevelClass(env.tree, localMake); compileStates.put(env, CompileState.TRANSTYPES); - if (shouldStop(CompileState.UNLAMBDA)) - return; + if (source.allowLambda()) { + if (shouldStop(CompileState.UNLAMBDA)) + return; - env.tree = lambdaToMethod.translateTopLevelClass(env, env.tree, localMake); - compileStates.put(env, CompileState.UNLAMBDA); + env.tree = lambdaToMethod.translateTopLevelClass(env, env.tree, localMake); + compileStates.put(env, CompileState.UNLAMBDA); + } if (shouldStop(CompileState.LOWER)) return;