EMMA Coverage Report (generated Thu Dec 06 15:52:10 GMT 2007)
[all classes][com.sun.tools.javac.comp]

COVERAGE SUMMARY FOR SOURCE FILE [ConstFold.java]

nameclass, %method, %block, %line, %
ConstFold.java100% (1/1)25%  (3/12)4%   (39/1075)9%   (12/130)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ConstFold100% (1/1)25%  (3/12)4%   (39/1075)9%   (12/130)
b2i (boolean): Integer 0%   (0/1)0%   (0/6)0%   (0/1)
coerce (Type, Type): Type 0%   (0/1)0%   (0/86)0%   (0/13)
doubleValue (Object): double 0%   (0/1)0%   (0/4)0%   (0/1)
floatValue (Object): float 0%   (0/1)0%   (0/4)0%   (0/1)
fold (int, List): Type 0%   (0/1)0%   (0/31)0%   (0/6)
fold1 (int, Type): Type 0%   (0/1)0%   (0/160)0%   (0/19)
fold2 (int, Type, Type): Type 0%   (0/1)0%   (0/737)0%   (0/75)
intValue (Object): int 0%   (0/1)0%   (0/4)0%   (0/1)
longValue (Object): long 0%   (0/1)0%   (0/4)0%   (0/1)
<static initializer> 100% (1/1)100% (14/14)100% (4/4)
ConstFold (Context): void 100% (1/1)100% (11/11)100% (4/4)
instance (Context): ConstFold 100% (1/1)100% (14/14)100% (4/4)

1/*
2 * Copyright 1999-2006 Sun Microsystems, Inc.  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.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 
26package com.sun.tools.javac.comp;
27 
28import com.sun.tools.javac.code.*;
29import com.sun.tools.javac.jvm.*;
30import com.sun.tools.javac.util.*;
31 
32import com.sun.tools.javac.code.Type.*;
33 
34import static com.sun.tools.javac.code.TypeTags.*;
35import static com.sun.tools.javac.jvm.ByteCodes.*;
36 
37/** Helper class for constant folding, used by the attribution phase.
38 *  This class is marked strictfp as mandated by JLS 15.4.
39 *
40 *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
41 *  you write code that depends on this, you do so at your own risk.
42 *  This code and its internal interfaces are subject to change or
43 *  deletion without notice.</b>
44 */
45strictfp class ConstFold {
46    protected static final Context.Key<ConstFold> constFoldKey =
47        new Context.Key<ConstFold>();
48 
49    private Symtab syms;
50 
51    public static ConstFold instance(Context context) {
52        ConstFold instance = context.get(constFoldKey);
53        if (instance == null)
54            instance = new ConstFold(context);
55        return instance;
56    }
57 
58    private ConstFold(Context context) {
59        context.put(constFoldKey, this);
60 
61        syms = Symtab.instance(context);
62    }
63 
64    static Integer minusOne = -1;
65    static Integer zero     = 0;
66    static Integer one      = 1;
67 
68   /** Convert boolean to integer (true = 1, false = 0).
69    */
70    private static Integer b2i(boolean b) {
71        return b ? one : zero;
72    }
73    private static int intValue(Object x) { return ((Number)x).intValue(); }
74    private static long longValue(Object x) { return ((Number)x).longValue(); }
75    private static float floatValue(Object x) { return ((Number)x).floatValue(); }
76    private static double doubleValue(Object x) { return ((Number)x).doubleValue(); }
77 
78    /** Fold binary or unary operation, returning constant type reflecting the
79     *  operations result. Return null if fold failed due to an
80     *  arithmetic exception.
81     *  @param opcode    The operation's opcode instruction (usually a byte code),
82     *                   as entered by class Symtab.
83     *  @param argtypes  The operation's argument types (a list of length 1 or 2).
84     *                   Argument types are assumed to have non-null constValue's.
85     */
86    Type fold(int opcode, List<Type> argtypes) {
87        int argCount = argtypes.length();
88        if (argCount == 1)
89            return fold1(opcode, argtypes.head);
90        else if (argCount == 2)
91            return fold2(opcode, argtypes.head, argtypes.tail.head);
92        else
93            throw new AssertionError();
94    }
95 
96    /** Fold unary operation.
97     *  @param opcode    The operation's opcode instruction (usually a byte code),
98     *                   as entered by class Symtab.
99     *                   opcode's ifeq to ifge are for postprocessing
100     *                   xcmp; ifxx pairs of instructions.
101     *  @param operand   The operation's operand type.
102     *                   Argument types are assumed to have non-null constValue's.
103     */
104    Type fold1(int opcode, Type operand) {
105        try {
106            Object od = operand.constValue();
107            switch (opcode) {
108            case nop:
109                return operand;
110            case ineg: // unary -
111                return syms.intType.constType(-intValue(od));
112            case ixor: // ~
113                return syms.intType.constType(~intValue(od));
114            case bool_not: // !
115                return syms.booleanType.constType(b2i(intValue(od) == 0));
116            case ifeq:
117                return syms.booleanType.constType(b2i(intValue(od) == 0));
118            case ifne:
119                return syms.booleanType.constType(b2i(intValue(od) != 0));
120            case iflt:
121                return syms.booleanType.constType(b2i(intValue(od) < 0));
122            case ifgt:
123                return syms.booleanType.constType(b2i(intValue(od) > 0));
124            case ifle:
125                return syms.booleanType.constType(b2i(intValue(od) <= 0));
126            case ifge:
127                return syms.booleanType.constType(b2i(intValue(od) >= 0));
128 
129            case lneg: // unary -
130                return syms.longType.constType(new Long(-longValue(od)));
131            case lxor: // ~
132                return syms.longType.constType(new Long(~longValue(od)));
133 
134            case fneg: // unary -
135                return syms.floatType.constType(new Float(-floatValue(od)));
136 
137            case dneg: // ~
138                return syms.doubleType.constType(new Double(-doubleValue(od)));
139 
140            default:
141                return null;
142            }
143        } catch (ArithmeticException e) {
144            return null;
145        }
146    }
147 
148    /** Fold binary operation.
149     *  @param opcode    The operation's opcode instruction (usually a byte code),
150     *                   as entered by class Symtab.
151     *                   opcode's ifeq to ifge are for postprocessing
152     *                   xcmp; ifxx pairs of instructions.
153     *  @param left      The type of the operation's left operand.
154     *  @param right     The type of the operation's right operand.
155     */
156    Type fold2(int opcode, Type left, Type right) {
157        try {
158            if (opcode > ByteCodes.preMask) {
159                // we are seeing a composite instruction of the form xcmp; ifxx.
160                // In this case fold both instructions separately.
161                Type t1 = fold2(opcode >> ByteCodes.preShift, left, right);
162                return (t1.constValue() == null) ? t1
163                    : fold1(opcode & ByteCodes.preMask, t1);
164            } else {
165                Object l = left.constValue();
166                Object r = right.constValue();
167                switch (opcode) {
168                case iadd:
169                    return syms.intType.constType(intValue(l) + intValue(r));
170                case isub:
171                    return syms.intType.constType(intValue(l) - intValue(r));
172                case imul:
173                    return syms.intType.constType(intValue(l) * intValue(r));
174                case idiv:
175                    return syms.intType.constType(intValue(l) / intValue(r));
176                case imod:
177                    return syms.intType.constType(intValue(l) % intValue(r));
178                case iand:
179                    return (left.tag == BOOLEAN
180                      ? syms.booleanType : syms.intType)
181                      .constType(intValue(l) & intValue(r));
182                case bool_and:
183                    return syms.booleanType.constType(b2i((intValue(l) & intValue(r)) != 0));
184                case ior:
185                    return (left.tag == BOOLEAN
186                      ? syms.booleanType : syms.intType)
187                      .constType(intValue(l) | intValue(r));
188                case bool_or:
189                    return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
190                case ixor:
191                    return (left.tag == BOOLEAN
192                      ? syms.booleanType : syms.intType)
193                      .constType(intValue(l) ^ intValue(r));
194                case ishl: case ishll:
195                    return syms.intType.constType(intValue(l) << intValue(r));
196                case ishr: case ishrl:
197                    return syms.intType.constType(intValue(l) >> intValue(r));
198                case iushr: case iushrl:
199                    return syms.intType.constType(intValue(l) >>> intValue(r));
200                case if_icmpeq:
201                    return syms.booleanType.constType(
202                        b2i(intValue(l) == intValue(r)));
203                case if_icmpne:
204                    return syms.booleanType.constType(
205                        b2i(intValue(l) != intValue(r)));
206                case if_icmplt:
207                    return syms.booleanType.constType(
208                        b2i(intValue(l) < intValue(r)));
209                case if_icmpgt:
210                    return syms.booleanType.constType(
211                        b2i(intValue(l) > intValue(r)));
212                case if_icmple:
213                    return syms.booleanType.constType(
214                        b2i(intValue(l) <= intValue(r)));
215                case if_icmpge:
216                    return syms.booleanType.constType(
217                        b2i(intValue(l) >= intValue(r)));
218 
219                case ladd:
220                    return syms.longType.constType(
221                        new Long(longValue(l) + longValue(r)));
222                case lsub:
223                    return syms.longType.constType(
224                        new Long(longValue(l) - longValue(r)));
225                case lmul:
226                    return syms.longType.constType(
227                        new Long(longValue(l) * longValue(r)));
228                case ldiv:
229                    return syms.longType.constType(
230                        new Long(longValue(l) / longValue(r)));
231                case lmod:
232                    return syms.longType.constType(
233                        new Long(longValue(l) % longValue(r)));
234                case land:
235                    return syms.longType.constType(
236                        new Long(longValue(l) & longValue(r)));
237                case lor:
238                    return syms.longType.constType(
239                        new Long(longValue(l) | longValue(r)));
240                case lxor:
241                    return syms.longType.constType(
242                        new Long(longValue(l) ^ longValue(r)));
243                case lshl: case lshll:
244                    return syms.longType.constType(
245                        new Long(longValue(l) << intValue(r)));
246                case lshr: case lshrl:
247                    return syms.longType.constType(
248                        new Long(longValue(l) >> intValue(r)));
249                case lushr:
250                    return syms.longType.constType(
251                        new Long(longValue(l) >>> intValue(r)));
252                case lcmp:
253                    if (longValue(l) < longValue(r))
254                        return syms.intType.constType(minusOne);
255                    else if (longValue(l) > longValue(r))
256                        return syms.intType.constType(one);
257                    else
258                        return syms.intType.constType(zero);
259                case fadd:
260                    return syms.floatType.constType(
261                        new Float(floatValue(l) + floatValue(r)));
262                case fsub:
263                    return syms.floatType.constType(
264                        new Float(floatValue(l) - floatValue(r)));
265                case fmul:
266                    return syms.floatType.constType(
267                        new Float(floatValue(l) * floatValue(r)));
268                case fdiv:
269                    return syms.floatType.constType(
270                        new Float(floatValue(l) / floatValue(r)));
271                case fmod:
272                    return syms.floatType.constType(
273                        new Float(floatValue(l) % floatValue(r)));
274                case fcmpg: case fcmpl:
275                    if (floatValue(l) < floatValue(r))
276                        return syms.intType.constType(minusOne);
277                    else if (floatValue(l) > floatValue(r))
278                        return syms.intType.constType(one);
279                    else if (floatValue(l) == floatValue(r))
280                        return syms.intType.constType(zero);
281                    else if (opcode == fcmpg)
282                        return syms.intType.constType(one);
283                    else
284                        return syms.intType.constType(minusOne);
285                case dadd:
286                    return syms.doubleType.constType(
287                        new Double(doubleValue(l) + doubleValue(r)));
288                case dsub:
289                    return syms.doubleType.constType(
290                        new Double(doubleValue(l) - doubleValue(r)));
291                case dmul:
292                    return syms.doubleType.constType(
293                        new Double(doubleValue(l) * doubleValue(r)));
294                case ddiv:
295                    return syms.doubleType.constType(
296                        new Double(doubleValue(l) / doubleValue(r)));
297                case dmod:
298                    return syms.doubleType.constType(
299                        new Double(doubleValue(l) % doubleValue(r)));
300                case dcmpg: case dcmpl:
301                    if (doubleValue(l) < doubleValue(r))
302                        return syms.intType.constType(minusOne);
303                    else if (doubleValue(l) > doubleValue(r))
304                        return syms.intType.constType(one);
305                    else if (doubleValue(l) == doubleValue(r))
306                        return syms.intType.constType(zero);
307                    else if (opcode == dcmpg)
308                        return syms.intType.constType(one);
309                    else
310                        return syms.intType.constType(minusOne);
311                case if_acmpeq:
312                    return syms.booleanType.constType(b2i(l.equals(r)));
313                case if_acmpne:
314                    return syms.booleanType.constType(b2i(!l.equals(r)));
315                case string_add:
316                    return syms.stringType.constType(
317                        left.stringValue() + right.stringValue());
318                default:
319                    return null;
320                }
321            }
322        } catch (ArithmeticException e) {
323            return null;
324        }
325    }
326 
327    /** Coerce constant type to target type.
328     *  @param etype      The source type of the coercion,
329     *                    which is assumed to be a constant type compatble with
330     *                    ttype.
331     *  @param ttype      The target type of the coercion.
332     */
333     Type coerce(Type etype, Type ttype) {
334         // WAS if (etype.baseType() == ttype.baseType())
335         if (etype.tsym.type == ttype.tsym.type)
336             return etype;
337         if (etype.tag <= DOUBLE) {
338             Object n = etype.constValue();
339             switch (ttype.tag) {
340             case BYTE:
341                 return syms.byteType.constType(0 + (byte)intValue(n));
342             case CHAR:
343                 return syms.charType.constType(0 + (char)intValue(n));
344             case SHORT:
345                 return syms.shortType.constType(0 + (short)intValue(n));
346             case INT:
347                 return syms.intType.constType(intValue(n));
348             case LONG:
349                 return syms.longType.constType(longValue(n));
350             case FLOAT:
351                 return syms.floatType.constType(floatValue(n));
352             case DOUBLE:
353                 return syms.doubleType.constType(doubleValue(n));
354             }
355         }
356         return ttype;
357     }
358}

[all classes][com.sun.tools.javac.comp]
EMMA 2.0.5312 (C) Vladimir Roubtsov