History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/tree/AddExpression.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/tree/AddExpression.java+253−0
@@ -0,0 +1,253 @@
1+/*
2+ * Copyright (c) 1994, 2003, 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+ */
25+
26+package sun.tools.tree;
27+
28+import sun.tools.java.*;
29+import sun.tools.asm.Assembler;
30+
31+/**
32+ * WARNING: The contents of this source file are not part of any
33+ * supported API. Code that depends on them does so at its own risk:
34+ * they are subject to change or removal without notice.
35+ */
36+public
37+class AddExpression extends BinaryArithmeticExpression {
38+ /**
39+ * constructor
40+ */
41+ public AddExpression(long where, Expression left, Expression right) {
42+ super(ADD, where, left, right);
43+ }
44+
45+ /**
46+ * Select the type
47+ */
48+ void selectType(Environment env, Context ctx, int tm) {
49+ if ((left.type == Type.tString) && !right.type.isType(TC_VOID)) {
50+ type = Type.tString;
51+ return;
52+ } else if ((right.type == Type.tString) && !left.type.isType(TC_VOID)) {
53+ type = Type.tString;
54+ return;
55+ }
56+ super.selectType(env, ctx, tm);
57+ }
58+
59+ public boolean isNonNull() {
60+ // an addition expression cannot yield a null reference as a result
61+ return true;
62+ }
63+
64+ /**
65+ * Evaluate
66+ */
67+ Expression eval(int a, int b) {
68+ return new IntExpression(where, a + b);
69+ }
70+ Expression eval(long a, long b) {
71+ return new LongExpression(where, a + b);
72+ }
73+ Expression eval(float a, float b) {
74+ return new FloatExpression(where, a + b);
75+ }
76+ Expression eval(double a, double b) {
77+ return new DoubleExpression(where, a + b);
78+ }
79+ Expression eval(String a, String b) {
80+ return new StringExpression(where, a + b);
81+ }
82+
83+ /**
84+ * Inline the value of an AddExpression. If this AddExpression
85+ * represents a concatenation of compile-time constant strings,
86+ * dispatch to the special method inlineValueSB, which handles
87+ * the inlining more efficiently.
88+ */
89+ public Expression inlineValue(Environment env, Context ctx) {
90+ if (type == Type.tString && isConstant()) {
91+ StringBuffer buffer = inlineValueSB(env, ctx, new StringBuffer());
92+ if (buffer != null) {
93+ // We were able to evaluate the String concatenation.
94+ return new StringExpression(where, buffer.toString());
95+ }
96+ }
97+ // For some reason inlinValueSB() failed to produce a value.
98+ // Use the older, less efficient, inlining mechanism.
99+ return super.inlineValue(env, ctx);
100+ }
101+
102+ /**
103+ * Attempt to evaluate this expression. If this expression
104+ * yields a value, append it to the StringBuffer `buffer'.
105+ * If this expression cannot be evaluated at this time (for
106+ * example if it contains a division by zero, a non-constant
107+ * subexpression, or a subexpression which "refuses" to evaluate)
108+ * then return `null' to indicate failure.
109+ *
110+ * It is anticipated that this method will be called to evaluate
111+ * concatenations of compile-time constant strings. The call
112+ * originates from AddExpression#inlineValue().
113+ *
114+ * This method does not use associativity to good effect in
115+ * folding string concatenations. This is room for improvement.
116+ *
117+ * -------------
118+ *
119+ * A bit of history: this method was added because an
120+ * expression like...
121+ *
122+ * "a" + "b" + "c" + "d"
123+ *
124+ * ...was evaluated at compile-time as...
125+ *
126+ * (new StringBuffer((new StringBuffer("a")).append("b").toString())).
127+ * append((new StringBuffer("c")).append("d").toString()).toString()
128+ *
129+ * Alex Garthwaite, in profiling the memory allocation of the
130+ * compiler, noticed this and suggested that the method inlineValueSB()
131+ * be added to evaluate constant string concatenations in a more
132+ * efficient manner. The compiler now builds the string in a
133+ * top-down fashion, by accumulating the result in a StringBuffer
134+ * which is allocated once and passed in as a parameter. The new
135+ * evaluation scheme is equivalent to...
136+ *
137+ * (new StringBuffer("a")).append("b").append("c").append("d")
138+ * .toString()
139+ *
140+ * ...which is more efficient. Since then, the code has been modified
141+ * to fix certain problems. Now, for example, it can return `null'
142+ * when it encounters a concatenation which it is not able to
143+ * evaluate.
144+ *
145+ * See also Expression#inlineValueSB() and ExprExpression#inlineValueSB().
146+ */
147+ protected StringBuffer inlineValueSB(Environment env,
148+ Context ctx,
149+ StringBuffer buffer) {
150+ if (type != Type.tString) {
151+ // This isn't a concatenation. It is actually an addition
152+ // of some sort. Call the generic inlineValueSB()
153+ return super.inlineValueSB(env, ctx, buffer);
154+ }
155+
156+ buffer = left.inlineValueSB(env, ctx, buffer);
157+ if (buffer != null) {
158+ buffer = right.inlineValueSB(env, ctx, buffer);
159+ }
160+ return buffer;
161+ }
162+
163+ /**
164+ * Simplify
165+ */
166+ Expression simplify() {
167+ if (!type.isType(TC_CLASS)) {
168+ // Can't simplify floating point add because of -0.0 strangeness
169+ if (type.inMask(TM_INTEGER)) {
170+ if (left.equals(0)) {
171+ return right;
172+ }
173+ if (right.equals(0)) {
174+ return left;
175+ }
176+ }
177+ } else if (right.type.isType(TC_NULL)) {
178+ right = new StringExpression(right.where, "null");
179+ } else if (left.type.isType(TC_NULL)) {
180+ left = new StringExpression(left.where, "null");
181+ }
182+ return this;
183+ }
184+
185+ /**
186+ * The cost of inlining this expression
187+ */
188+ public int costInline(int thresh, Environment env, Context ctx) {
189+ return (type.isType(TC_CLASS) ? 12 : 1)
190+ + left.costInline(thresh, env, ctx)
191+ + right.costInline(thresh, env, ctx);
192+ }
193+
194+ /**
195+ * Code
196+ */
197+ void codeOperation(Environment env, Context ctx, Assembler asm) {
198+ asm.add(where, opc_iadd + type.getTypeCodeOffset());
199+ }
200+
201+ /**
202+ * Convert this expression to a string and append it to the string
203+ * buffer on the top of the stack.
204+ * If the needBuffer argument is true, the string buffer needs to be
205+ * created, initialized, and pushed on the stack, first.
206+ */
207+ void codeAppend(Environment env, Context ctx, Assembler asm,
208+ ClassDeclaration sbClass, boolean needBuffer)
209+ throws ClassNotFound, AmbiguousMember {
210+ if (type.isType(TC_CLASS)) {
211+ left.codeAppend(env, ctx, asm, sbClass, needBuffer);
212+ right.codeAppend(env, ctx, asm, sbClass, false);
213+ } else {
214+ super.codeAppend(env, ctx, asm, sbClass, needBuffer);
215+ }
216+ }
217+
218+ public void codeValue(Environment env, Context ctx, Assembler asm) {
219+ if (type.isType(TC_CLASS)) {
220+ try {
221+ // optimize (""+foo) or (foo+"") to String.valueOf(foo)
222+ if (left.equals("")) {
223+ right.codeValue(env, ctx, asm);
224+ right.ensureString(env, ctx, asm);
225+ return;
226+ }
227+ if (right.equals("")) {
228+ left.codeValue(env, ctx, asm);
229+ left.ensureString(env, ctx, asm);
230+ return;
231+ }
232+
233+ ClassDeclaration sbClass =
234+ env.getClassDeclaration(idJavaLangStringBuffer);
235+ ClassDefinition sourceClass = ctx.field.getClassDefinition();
236+ // Create the string buffer and append to it.
237+ codeAppend(env, ctx, asm, sbClass, true);
238+ // Convert the string buffer to a string
239+ MemberDefinition f =
240+ sbClass.getClassDefinition(env).matchMethod(env,
241+ sourceClass,
242+ idToString);
243+ asm.add(where, opc_invokevirtual, f);
244+ } catch (ClassNotFound e) {
245+ throw new CompilerError(e);
246+ } catch (AmbiguousMember e) {
247+ throw new CompilerError(e);
248+ }
249+ } else {
250+ super.codeValue(env, ctx, asm);
251+ }
252+ }
253+}