Source Code Cross Referenced for MethodInliner.java in  » Development » proguard » proguard » optimize » peephole » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » proguard » proguard.optimize.peephole 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * ProGuard -- shrinking, optimization, obfuscation, and preverification
003:         *             of Java bytecode.
004:         *
005:         * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006:         *
007:         * This library is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU General Public License as published by the Free
009:         * Software Foundation; either version 2 of the License, or (at your option)
010:         * any later version.
011:         *
012:         * This library is distributed in the hope that it will be useful, but WITHOUT
013:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014:         * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
015:         * for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public License
018:         * along with this library; if not, write to the Free Software Foundation,
019:         * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020:         */
021:        package proguard.optimize.peephole;
022:
023:        import proguard.classfile.*;
024:        import proguard.classfile.attribute.*;
025:        import proguard.classfile.attribute.visitor.*;
026:        import proguard.classfile.constant.*;
027:        import proguard.classfile.constant.visitor.ConstantVisitor;
028:        import proguard.classfile.editor.*;
029:        import proguard.classfile.instruction.*;
030:        import proguard.classfile.instruction.visitor.InstructionVisitor;
031:        import proguard.classfile.util.*;
032:        import proguard.classfile.visitor.MemberVisitor;
033:        import proguard.optimize.info.*;
034:
035:        import java.util.Stack;
036:
037:        /**
038:         * This AttributeVisitor inlines short methods or methods that are only invoked
039:         * once, in the code attributes that it visits.
040:         *
041:         * @author Eric Lafortune
042:         */
043:        public class MethodInliner extends SimplifiedVisitor implements 
044:                AttributeVisitor, InstructionVisitor, ExceptionInfoVisitor,
045:                ConstantVisitor, MemberVisitor {
046:            private static final int MAXIMUM_INLINED_CODE_LENGTH = Integer
047:                    .parseInt(System.getProperty("maximum.inlined.code.length",
048:                            "8"));
049:            private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer
050:                    .parseInt(System.getProperty(
051:                            "maximum.resulting.code.length", "8000"));
052:            private static final int MAXIMUM_RESULTING_CODE_LENGTH_JME = Integer
053:                    .parseInt(System.getProperty(
054:                            "maximum.resulting.code.length", "2000"));
055:            private static final int MAXIMUM_CODE_EXPANSION = 2;
056:            private static final int MAXIMUM_EXTRA_CODE_LENGTH = 128;
057:
058:            //*
059:            private static final boolean DEBUG = false;
060:            /*/
061:            private static       boolean DEBUG = true;
062:            //*/
063:
064:            private final boolean microEdition;
065:            private final boolean allowAccessModification;
066:            private final boolean inlineSingleInvocations;
067:            private final InstructionVisitor extraInlinedInvocationVisitor;
068:
069:            private final CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();
070:            private final AccessMethodMarker accessMethodMarker = new AccessMethodMarker();
071:            private final CatchExceptionMarker catchExceptionMarker = new CatchExceptionMarker();
072:            private final ConstantAdder constantAdder = new ConstantAdder();
073:            private final StackSizeComputer stackSizeComputer = new StackSizeComputer();
074:
075:            private ProgramClass targetClass;
076:            private ProgramMethod targetMethod;
077:            private int estimatedResultingCodeLength;
078:            private boolean inlining;
079:            private Stack inliningMethods = new Stack();
080:            private boolean emptyInvokingStack;
081:            private int uninitializedObjectCount;
082:            private int variableOffset;
083:            private boolean inlined;
084:            private boolean inlinedAny;
085:
086:            /**
087:             * Creates a new MethodInliner.
088:             * @param microEdition            indicates whether the resulting code is
089:             *                                targeted at Java Micro Edition.
090:             * @param allowAccessModification indicates whether the access modifiers of
091:             *                                classes and class members can be changed
092:             *                                in order to inline methods.
093:             * @param inlineSingleInvocations indicates whether the single invocations
094:             *                                should be inlined, or, alternatively,
095:             *                                short methods.
096:             */
097:            public MethodInliner(boolean microEdition,
098:                    boolean allowAccessModification,
099:                    boolean inlineSingleInvocations) {
100:                this (microEdition, allowAccessModification,
101:                        inlineSingleInvocations, null);
102:            }
103:
104:            /**
105:             * Creates a new MethodInliner.
106:             * @param microEdition            indicates whether the resulting code is
107:             *                                targeted at Java Micro Edition.
108:             * @param allowAccessModification indicates whether the access modifiers of
109:             *                                classes and class members can be changed
110:             *                                in order to inline methods.
111:             * @param inlineSingleInvocations indicates whether the single invocations
112:             *                                should be inlined, or, alternatively,
113:             *                                short methods.
114:             * @param extraInlinedInvocationVisitor an optional extra visitor for all
115:             *                                      inlined invocation instructions.
116:             */
117:            public MethodInliner(boolean microEdition,
118:                    boolean allowAccessModification,
119:                    boolean inlineSingleInvocations,
120:                    InstructionVisitor extraInlinedInvocationVisitor) {
121:                this .microEdition = microEdition;
122:                this .allowAccessModification = allowAccessModification;
123:                this .inlineSingleInvocations = inlineSingleInvocations;
124:                this .extraInlinedInvocationVisitor = extraInlinedInvocationVisitor;
125:            }
126:
127:            // Implementations for AttributeVisitor.
128:
129:            public void visitAnyAttribute(Clazz clazz, Attribute attribute) {
130:            }
131:
132:            public void visitCodeAttribute(Clazz clazz, Method method,
133:                    CodeAttribute codeAttribute) {
134:                if (!inlining) {
135:                    //            codeAttributeComposer.DEBUG = DEBUG =
136:                    //                clazz.getName().equals("abc/Def") &&
137:                    //                method.getName(clazz).equals("abc");
138:
139:                    targetClass = (ProgramClass) clazz;
140:                    targetMethod = (ProgramMethod) method;
141:                    estimatedResultingCodeLength = codeAttribute.u4codeLength;
142:                    inliningMethods.clear();
143:                    uninitializedObjectCount = method.getName(clazz).equals(
144:                            ClassConstants.INTERNAL_METHOD_NAME_INIT) ? 1 : 0;
145:                    inlinedAny = false;
146:                    codeAttributeComposer.reset();
147:                    constantAdder.setTargetClass(targetClass);
148:                    stackSizeComputer.visitCodeAttribute(clazz, method,
149:                            codeAttribute);
150:
151:                    // Append the body of the code.
152:                    copyCode(clazz, method, codeAttribute);
153:
154:                    targetClass = null;
155:                    targetMethod = null;
156:                    constantAdder.setTargetClass(null);
157:
158:                    // Update the code attribute if any code has been inlined.
159:                    if (inlinedAny) {
160:                        codeAttributeComposer.visitCodeAttribute(clazz, method,
161:                                codeAttribute);
162:
163:                        // Update the accessing flags.
164:                        codeAttribute.instructionsAccept(clazz, method,
165:                                accessMethodMarker);
166:
167:                        // Update the exception catching flags.
168:                        catchExceptionMarker.visitCodeAttribute(clazz, method,
169:                                codeAttribute);
170:                    }
171:                }
172:
173:                // Only inline the method if it is invoked once or if it is short.
174:                else if ((inlineSingleInvocations ? MethodInvocationMarker
175:                        .getInvocationCount(method) == 1
176:                        : codeAttribute.u4codeLength <= MAXIMUM_INLINED_CODE_LENGTH)
177:                        && estimatedResultingCodeLength
178:                                + codeAttribute.u4codeLength < (microEdition ? MAXIMUM_RESULTING_CODE_LENGTH_JME
179:                                : MAXIMUM_RESULTING_CODE_LENGTH_JSE)) {
180:                    if (DEBUG) {
181:                        System.out
182:                                .println("MethodInliner: inlining ["
183:                                        + clazz.getName()
184:                                        + "."
185:                                        + method.getName(clazz)
186:                                        + method.getDescriptor(clazz)
187:                                        + "] in ["
188:                                        + targetClass.getName()
189:                                        + "."
190:                                        + targetMethod.getName(targetClass)
191:                                        + targetMethod
192:                                                .getDescriptor(targetClass)
193:                                        + "]");
194:                    }
195:
196:                    // Ignore the removal of the original method invocation,
197:                    // the addition of the parameter setup, and
198:                    // the modification of a few inlined instructions.
199:                    estimatedResultingCodeLength += codeAttribute.u4codeLength;
200:
201:                    // Append instructions to store the parameters.
202:                    storeParameters(clazz, method);
203:
204:                    // Inline the body of the code.
205:                    copyCode(clazz, method, codeAttribute);
206:
207:                    inlined = true;
208:                    inlinedAny = true;
209:                }
210:            }
211:
212:            /**
213:             * Appends instructions to pop the parameters for the given method, storing
214:             * them in new local variables.
215:             */
216:            private void storeParameters(Clazz clazz, Method method) {
217:
218:                String descriptor = method.getDescriptor(clazz);
219:
220:                boolean isStatic = (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;
221:
222:                // Count the number of parameters, taking into account their categories.
223:                int parameterCount = ClassUtil
224:                        .internalMethodParameterCount(descriptor);
225:                int parameterSize = ClassUtil
226:                        .internalMethodParameterSize(descriptor);
227:                int parameterOffset = isStatic ? 0 : 1;
228:
229:                // Store the parameter types.
230:                String[] parameterTypes = new String[parameterSize];
231:
232:                InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(
233:                        descriptor);
234:
235:                for (int parameterIndex = 0; parameterIndex < parameterSize; parameterIndex++) {
236:                    String parameterType = internalTypeEnumeration.nextType();
237:                    parameterTypes[parameterIndex] = parameterType;
238:                    if (ClassUtil.internalTypeSize(parameterType) == 2) {
239:                        parameterIndex++;
240:                    }
241:                }
242:
243:                codeAttributeComposer
244:                        .beginCodeFragment((parameterOffset + parameterCount) * 4);
245:
246:                // Go over the parameter types backward, storing the stack entries
247:                // in their corresponding variables.
248:                for (int parameterIndex = parameterSize - 1; parameterIndex >= 0; parameterIndex--) {
249:                    String parameterType = parameterTypes[parameterIndex];
250:                    if (parameterType != null) {
251:                        byte opcode;
252:                        switch (parameterType.charAt(0)) {
253:                        case ClassConstants.INTERNAL_TYPE_BOOLEAN:
254:                        case ClassConstants.INTERNAL_TYPE_BYTE:
255:                        case ClassConstants.INTERNAL_TYPE_CHAR:
256:                        case ClassConstants.INTERNAL_TYPE_SHORT:
257:                        case ClassConstants.INTERNAL_TYPE_INT:
258:                            opcode = InstructionConstants.OP_ISTORE;
259:                            break;
260:
261:                        case ClassConstants.INTERNAL_TYPE_LONG:
262:                            opcode = InstructionConstants.OP_LSTORE;
263:                            break;
264:
265:                        case ClassConstants.INTERNAL_TYPE_FLOAT:
266:                            opcode = InstructionConstants.OP_FSTORE;
267:                            break;
268:
269:                        case ClassConstants.INTERNAL_TYPE_DOUBLE:
270:                            opcode = InstructionConstants.OP_DSTORE;
271:                            break;
272:
273:                        default:
274:                            opcode = InstructionConstants.OP_ASTORE;
275:                            break;
276:                        }
277:
278:                        codeAttributeComposer.appendInstruction(parameterSize
279:                                - parameterIndex - 1, new VariableInstruction(
280:                                opcode, variableOffset + parameterOffset
281:                                        + parameterIndex).shrink());
282:                    }
283:                }
284:
285:                // Put the 'this' reference in variable 0 (plus offset).
286:                if (!isStatic) {
287:                    codeAttributeComposer.appendInstruction(parameterSize,
288:                            new VariableInstruction(
289:                                    InstructionConstants.OP_ASTORE,
290:                                    variableOffset).shrink());
291:                }
292:
293:                codeAttributeComposer.endCodeFragment();
294:            }
295:
296:            /**
297:             * Appends the code of the given code attribute.
298:             */
299:            private void copyCode(Clazz clazz, Method method,
300:                    CodeAttribute codeAttribute) {
301:                // The code may expand, due to expanding constant and variable
302:                // instructions.
303:                codeAttributeComposer
304:                        .beginCodeFragment(codeAttribute.u4codeLength
305:                                * MAXIMUM_CODE_EXPANSION
306:                                + MAXIMUM_EXTRA_CODE_LENGTH);
307:
308:                // Copy the instructions.
309:                codeAttribute.instructionsAccept(clazz, method, this );
310:
311:                // Copy the exceptions.
312:                codeAttribute.exceptionsAccept(clazz, method, this );
313:
314:                // Append a label just after the code.
315:                codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
316:
317:                codeAttributeComposer.endCodeFragment();
318:            }
319:
320:            // Implementations for InstructionVisitor.
321:
322:            public void visitAnyInstruction(Clazz clazz, Method method,
323:                    CodeAttribute codeAttribute, int offset,
324:                    Instruction instruction) {
325:                codeAttributeComposer.appendInstruction(offset, instruction
326:                        .shrink());
327:            }
328:
329:            public void visitSimpleInstruction(Clazz clazz, Method method,
330:                    CodeAttribute codeAttribute, int offset,
331:                    SimpleInstruction simpleInstruction) {
332:                // Are we inlining this instruction?
333:                if (inlining) {
334:                    // Replace any return instructions by branches to the end of the code.
335:                    switch (simpleInstruction.opcode) {
336:                    case InstructionConstants.OP_IRETURN:
337:                    case InstructionConstants.OP_LRETURN:
338:                    case InstructionConstants.OP_FRETURN:
339:                    case InstructionConstants.OP_DRETURN:
340:                    case InstructionConstants.OP_ARETURN:
341:                    case InstructionConstants.OP_RETURN:
342:                        // Are we not at the last instruction?
343:                        if (offset < codeAttribute.u4codeLength - 1) {
344:                            // Replace the return instruction by a branch instruction.
345:                            Instruction branchInstruction = new BranchInstruction(
346:                                    InstructionConstants.OP_GOTO_W,
347:                                    codeAttribute.u4codeLength - offset);
348:
349:                            codeAttributeComposer.appendInstruction(offset,
350:                                    branchInstruction.shrink());
351:                        } else {
352:                            // Just leave out the instruction, but put in a label,
353:                            // for the sake of any other branch instructions.
354:                            codeAttributeComposer.appendLabel(offset);
355:                        }
356:
357:                        return;
358:                    }
359:                }
360:
361:                codeAttributeComposer.appendInstruction(offset,
362:                        simpleInstruction.shrink());
363:            }
364:
365:            public void visitVariableInstruction(Clazz clazz, Method method,
366:                    CodeAttribute codeAttribute, int offset,
367:                    VariableInstruction variableInstruction) {
368:                // Are we inlining this instruction?
369:                if (inlining) {
370:                    // Update the variable index.
371:                    variableInstruction.variableIndex += variableOffset;
372:                }
373:
374:                codeAttributeComposer.appendInstruction(offset,
375:                        variableInstruction.shrink());
376:            }
377:
378:            public void visitConstantInstruction(Clazz clazz, Method method,
379:                    CodeAttribute codeAttribute, int offset,
380:                    ConstantInstruction constantInstruction) {
381:                // Is it a method invocation?
382:                switch (constantInstruction.opcode) {
383:                case InstructionConstants.OP_NEW:
384:                    uninitializedObjectCount++;
385:                    break;
386:
387:                case InstructionConstants.OP_INVOKEVIRTUAL:
388:                case InstructionConstants.OP_INVOKESPECIAL:
389:                case InstructionConstants.OP_INVOKESTATIC:
390:                case InstructionConstants.OP_INVOKEINTERFACE:
391:                    // See if we can inline it.
392:                    inlined = false;
393:
394:                    // Append a label, in case the invocation will be inlined.
395:                    codeAttributeComposer.appendLabel(offset);
396:
397:                    emptyInvokingStack = !inlining
398:                            && stackSizeComputer.isReachable(offset)
399:                            && stackSizeComputer.getStackSize(offset) == 0;
400:
401:                    variableOffset += codeAttribute.u2maxLocals;
402:
403:                    clazz.constantPoolEntryAccept(
404:                            constantInstruction.constantIndex, this );
405:
406:                    variableOffset -= codeAttribute.u2maxLocals;
407:
408:                    // Was the method inlined?
409:                    if (inlined) {
410:                        if (extraInlinedInvocationVisitor != null) {
411:                            extraInlinedInvocationVisitor
412:                                    .visitConstantInstruction(clazz, method,
413:                                            codeAttribute, offset,
414:                                            constantInstruction);
415:                        }
416:
417:                        // The invocation itself is no longer necessary.
418:                        return;
419:                    }
420:
421:                    break;
422:                }
423:
424:                // Are we inlining this instruction?
425:                if (inlining) {
426:                    // Make sure the constant is present in the constant pool of the
427:                    // target class.
428:                    clazz.constantPoolEntryAccept(
429:                            constantInstruction.constantIndex, constantAdder);
430:
431:                    // Let the instruction point to this constant.
432:                    constantInstruction.constantIndex = constantAdder
433:                            .getConstantIndex();
434:                }
435:
436:                codeAttributeComposer.appendInstruction(offset,
437:                        constantInstruction.shrink());
438:            }
439:
440:            // Implementations for ExceptionInfoVisitor.
441:
442:            public void visitExceptionInfo(Clazz clazz, Method method,
443:                    CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) {
444:                int catchType = exceptionInfo.u2catchType;
445:
446:                if (inlining && catchType != 0) {
447:                    // Make sure the constant is present in the constant pool of the
448:                    // target class.
449:                    clazz.constantPoolEntryAccept(catchType, constantAdder);
450:
451:                    // Let the exception point to this constant.
452:                    catchType = constantAdder.getConstantIndex();
453:                }
454:
455:                codeAttributeComposer.appendException(new ExceptionInfo(
456:                        exceptionInfo.u2startPC, exceptionInfo.u2endPC,
457:                        exceptionInfo.u2handlerPC, catchType));
458:            }
459:
460:            // Implementations for ConstantVisitor.
461:
462:            public void visitInterfaceMethodrefConstant(Clazz clazz,
463:                    InterfaceMethodrefConstant interfaceMethodrefConstant) {
464:            }
465:
466:            public void visitMethodrefConstant(Clazz clazz,
467:                    MethodrefConstant methodrefConstant) {
468:                methodrefConstant.referencedMemberAccept(this );
469:            }
470:
471:            // Implementations for MemberVisitor.
472:
473:            public void visitAnyMember(Clazz Clazz, Member member) {
474:            }
475:
476:            public void visitProgramMethod(ProgramClass programClass,
477:                    ProgramMethod programMethod) {
478:                int accessFlags = programMethod.getAccessFlags();
479:
480:                if (// Only inline the method if it is private, static, or final.
481:                (accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE
482:                        | ClassConstants.INTERNAL_ACC_STATIC | ClassConstants.INTERNAL_ACC_FINAL)) != 0
483:                        &&
484:
485:                        // Only inline the method if it is not synchronized, etc.
486:                        (accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED
487:                                | ClassConstants.INTERNAL_ACC_NATIVE
488:                                | ClassConstants.INTERNAL_ACC_INTERFACE | ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0
489:                        &&
490:
491:                        // Don't inline an <init> method, except in an <init> method in the
492:                        // same class.
493:                        //            (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ||
494:                        //             (programClass.equals(targetClass) &&
495:                        //              targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) &&
496:                        !programMethod.getName(programClass).equals(
497:                                ClassConstants.INTERNAL_METHOD_NAME_INIT)
498:                        &&
499:
500:                        // Don't inline a method into itself.
501:                        (!programMethod.equals(targetMethod) || !programClass
502:                                .equals(targetClass))
503:                        &&
504:
505:                        // Only inline the method if it isn't recursing.
506:                        !inliningMethods.contains(programMethod)
507:                        &&
508:
509:                        // Only inline the method if its target class has at least the
510:                        // same version number as the source class, in order to avoid
511:                        // introducing incompatible constructs.
512:                        targetClass.u4version >= programClass.u4version
513:                        &&
514:
515:                        // Only inline the method if it doesn't invoke a super method, or if
516:                        // it is in the same class.
517:                        (!SuperInvocationMarker
518:                                .invokesSuperMethods(programMethod) || programClass
519:                                .equals(targetClass))
520:                        &&
521:
522:                        // Only inline the method if it doesn't branch backward while there
523:                        // are uninitialized objects.
524:                        (!BackwardBranchMarker.branchesBackward(programMethod) || uninitializedObjectCount == 0)
525:                        &&
526:
527:                        // Only inline if the code access of the inlined method allows it.
528:                        (allowAccessModification || ((!AccessMethodMarker
529:                                .accessesPrivateCode(programMethod) || programClass
530:                                .equals(targetClass)) &&
531:
532:                        (!AccessMethodMarker.accessesPackageCode(programMethod) || ClassUtil
533:                                .internalPackageName(programClass.getName())
534:                                .equals(
535:                                        ClassUtil
536:                                                .internalPackageName(targetClass
537:                                                        .getName())))))
538:                        &&
539:
540:                        //               (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
541:                        //                targetClass.extends_(programClass) ||
542:                        //                targetClass.implements_(programClass)) ||
543:                        (!AccessMethodMarker
544:                                .accessesProtectedCode(programMethod) || programClass
545:                                .equals(targetClass))
546:                        &&
547:
548:                        // Only inline the method if it doesn't catch exceptions, or if it
549:                        // is invoked with an empty stack.
550:                        (!CatchExceptionMarker.catchesExceptions(programMethod) || emptyInvokingStack)
551:                        &&
552:
553:                        // Only inline the method if it comes from the same class or from
554:                        // a class with a static initializer.
555:                        (programClass.equals(targetClass) || programClass
556:                                .findMethod(
557:                                        ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
558:                                        ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) == null)) {
559:                    //            System.out.print("MethodInliner: inlining ");
560:                    //            programMethod.accept(programClass, new SimpleClassPrinter(true));
561:                    //            System.out.print("               in       ");
562:                    //            targetMethod.accept(targetClass, new SimpleClassPrinter(true));
563:                    //
564:                    //            System.out.println("  Private:   "+
565:                    //                               (!AccessMethodMarker.accessesPrivateCode(programMethod) ||
566:                    //                                programClass.equals(targetClass)));
567:                    //
568:                    //            System.out.println("  Package:   "+
569:                    //                               (!AccessMethodMarker.accessesPackageCode(programMethod) ||
570:                    //                                ClassUtil.internalPackageName(programClass.getName()).equals(
571:                    //                                ClassUtil.internalPackageName(targetClass.getName()))));
572:                    //
573:                    //            System.out.println("  Protected: "+
574:                    //                               ((!AccessMethodMarker.accessesProtectedCode(programMethod) ||
575:                    //                                 targetClass.extends_(programClass) ||
576:                    //                                 targetClass.implements_(programClass)) ||
577:                    //                                ClassUtil.internalPackageName(programClass.getName()).equals(
578:                    //                                ClassUtil.internalPackageName(targetClass.getName()))));
579:
580:                    boolean oldInlining = inlining;
581:                    inlining = true;
582:                    inliningMethods.push(programMethod);
583:
584:                    // Inline the method body.
585:                    programMethod.attributesAccept(programClass, this);
586:
587:                    inlining = oldInlining;
588:                    inliningMethods.pop();
589:                } else if (programMethod.getName(programClass).equals(
590:                        ClassConstants.INTERNAL_METHOD_NAME_INIT)) {
591:                    uninitializedObjectCount--;
592:                }
593:            }
594:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.