Source Code Cross Referenced for CVMMethodInfo.java in  » 6.0-JDK-Modules » j2me » vm » 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 » 6.0 JDK Modules » j2me » vm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)CVMMethodInfo.java	1.25 06/10/10
0003:         *
0004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
0006:         *   
0007:         * This program is free software; you can redistribute it and/or  
0008:         * modify it under the terms of the GNU General Public License version  
0009:         * 2 only, as published by the Free Software Foundation.   
0010:         *   
0011:         * This program is distributed in the hope that it will be useful, but  
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
0014:         * General Public License version 2 for more details (a copy is  
0015:         * included at /legal/license.txt).   
0016:         *   
0017:         * You should have received a copy of the GNU General Public License  
0018:         * version 2 along with this work; if not, write to the Free Software  
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
0020:         * 02110-1301 USA   
0021:         *   
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
0024:         * information or have any questions. 
0025:         *
0026:         */
0027:
0028:        package vm;
0029:
0030:        /*
0031:         * VM-specific internal representation of
0032:         * a method. Target-machine independent.
0033:         *
0034:         * See also CVMClass for VM-specific info associated with each class.
0035:         * See also CVMVM for VM-specific info not associated directly with any class.
0036:         */
0037:        import components.*;
0038:        import vm.VMMethodInfo;
0039:        import consts.Const;
0040:        import consts.CVMConst;
0041:        import util.DataFormatException;
0042:        import java.util.Enumeration;
0043:        import java.util.Vector;
0044:        import java.util.Hashtable;
0045:        import java.util.StringTokenizer;
0046:
0047:        public class CVMMethodInfo extends VMMethodInfo implements  Const,
0048:                CVMConst {
0049:            private boolean impureCode = false;
0050:            private boolean mustAlign = false;
0051:            private boolean hasJsr = false;
0052:            private boolean isStrictFP;
0053:            private boolean codeExamined = false;
0054:            public MethodInfo method;
0055:            public CVMMethodType sigType;
0056:
0057:            private String myNativeName;
0058:
0059:            public CVMMethodStats.Entry statsEntry;
0060:
0061:            private int inlining;
0062:            static final int NO_INLINE_FLAG = (0x1 << 24);
0063:            static final int SAME_CLASS_FLAG = (0x1 << 25);
0064:            static final int REDO_INLINING_FLAG = (0x1 << 26);
0065:
0066:            /**
0067:             * Flag used in quickenCode() to save old methodblock info so we can
0068:             * use it here for inlining.  This affects invokevirtual_quick which
0069:             * typically overwrites the methodblock info with <methodtable offset>
0070:             * and <nargs>.
0071:             */
0072:            public static final boolean SAVE_TARGET_METHODS = true;
0073:
0074:            public CVMMethodInfo(MethodInfo m) {
0075:                method = m;
0076:                method.vmMethodInfo = this ;
0077:                sigType = CVMMethodType.parseSignature(m.type.string);
0078:                this .isStrictFP = ((m.access & Const.ACC_STRICT) != 0);
0079:            }
0080:
0081:            private void examineCode() throws DataFormatException {
0082:                ConstantPool cp = method.parent.getConstantPool();
0083:                boolean needsTypeTable = false;
0084:                impureCode = false;
0085:                mustAlign = false;
0086:                hasJsr = false;
0087:                if (method.code == null) {
0088:                    codeExamined = true;
0089:                    return;
0090:                }
0091:                byte[] code = method.code;
0092:                int ncode = code.length;
0093:                int opcode;
0094:                for (int i = 0; i < ncode; i += method.opcodeLength(i)) {
0095:                    switch (opcode = (int) code[i] & 0xff) {
0096:
0097:                    case opc_tableswitch:
0098:                    case opc_lookupswitch:
0099:                        mustAlign = true;
0100:                        break;
0101:
0102:                    case opc_jsr:
0103:                    case opc_jsr_w:
0104:                        hasJsr = true;
0105:                        break;
0106:
0107:                    case opc_ldc2_w:
0108:                    case opc_getstatic:
0109:                    case opc_putstatic:
0110:                    case opc_getfield:
0111:                    case opc_putfield:
0112:                    case opc_invokevirtual:
0113:                    case opc_invokespecial:
0114:                    case opc_invokestatic:
0115:                    case opc_invokeinterface:
0116:                    case opc_new:
0117:                    case opc_anewarray:
0118:                    case opc_checkcast:
0119:                    case opc_instanceof :
0120:                    case opc_multianewarray:
0121:                        impureCode = true; // all get quicked.
0122:                        break;
0123:
0124:                    // We don't currently quicken ldc of a Class constant
0125:                    case opc_ldc: {
0126:                        ConstantObject co = cp
0127:                                .elementAt((int) code[i + 1] & 0xff);
0128:                        if (!(co instanceof  ClassConstant)) {
0129:                            impureCode = true; // all the rest get quickened.
0130:                        } else {
0131:                            needsTypeTable = true;
0132:                        }
0133:                        break;
0134:                    }
0135:                    case opc_ldc_w: {
0136:                        int index = method.getUnsignedShort(i + 1);
0137:                        ConstantObject co = cp.elementAt(index);
0138:                        if (!(co instanceof  ClassConstant)) {
0139:                            impureCode = true; // all the rest get quickened.
0140:                        } else {
0141:                            needsTypeTable = true;
0142:                        }
0143:                        break;
0144:                    }
0145:                    }
0146:                }
0147:                if (impureCode || needsTypeTable) {
0148:                    cp.setNeedsTypeTable();
0149:                }
0150:                codeExamined = true;
0151:            }
0152:
0153:            public boolean isCodePure() throws DataFormatException {
0154:                if (!codeExamined) {
0155:                    examineCode(); // may throw exception without setting codeExamined
0156:                }
0157:                return !impureCode;
0158:            }
0159:
0160:            public int alignment() throws DataFormatException {
0161:                if (!codeExamined) {
0162:                    examineCode(); // may throw exception without setting codeExamined
0163:                }
0164:                return mustAlign ? 4 : 1;
0165:            }
0166:
0167:            public boolean codeHasJsr() throws DataFormatException {
0168:                if (!codeExamined) {
0169:                    examineCode(); // may throw exception without setting codeExamined
0170:                }
0171:                return hasJsr;
0172:            }
0173:
0174:            public boolean isStrictFP() {
0175:                return isStrictFP;
0176:            }
0177:
0178:            private static int methodNumber = 0;
0179:
0180:            public String getNativeName() {
0181:                if (myNativeName == null) {
0182:                    myNativeName = ((CVMClass) (method.parent.vmClass))
0183:                            .getNativeName()
0184:                            + methodNumber;
0185:                    methodNumber += 1;
0186:                }
0187:                return myNativeName;
0188:            }
0189:
0190:            public boolean hasBody() {
0191:                return ((method.access & (ACC_ABSTRACT | ACC_NATIVE)) == 0);
0192:            }
0193:
0194:            public int CVMflags() {
0195:                int flagval = 0;
0196:                int a = method.access;
0197:                if ((a & ACC_PUBLIC) != 0)
0198:                    flagval |= CVM_METHOD_ACC_PUBLIC;
0199:                if ((a & ACC_PRIVATE) != 0)
0200:                    flagval |= CVM_METHOD_ACC_PRIVATE;
0201:                if ((a & ACC_PROTECTED) != 0)
0202:                    flagval |= CVM_METHOD_ACC_PROTECTED;
0203:                if ((a & ACC_STATIC) != 0)
0204:                    flagval |= CVM_METHOD_ACC_STATIC;
0205:                if ((a & ACC_FINAL) != 0)
0206:                    flagval |= CVM_METHOD_ACC_FINAL;
0207:                if ((a & ACC_SYNCHRONIZED) != 0)
0208:                    flagval |= CVM_METHOD_ACC_SYNCHRONIZED;
0209:                if ((a & ACC_NATIVE) != 0)
0210:                    flagval |= CVM_METHOD_ACC_NATIVE;
0211:                if ((a & ACC_ABSTRACT) != 0)
0212:                    flagval |= CVM_METHOD_ACC_ABSTRACT;
0213:                return flagval;
0214:
0215:            }
0216:
0217:            public int methodOffset() {
0218:                int off = method.methodTableIndex;
0219:                if (off < 0) {
0220:                    /*
0221:                     * off < 0 means that we do not have a methodtable or
0222:                     * imethodtable entry for this method. This is ok if it is:
0223:                     * - private, or
0224:                     * - static, or
0225:                     * - <init>
0226:                     * Otherwise, this is an error.
0227:                     */
0228:                    if (method.isStaticMember() || method.isPrivateMember()
0229:                            || method.name.string.equals("<init>")) {
0230:                        return 0;
0231:                    } else {
0232:                        throw new Error("Bad method offset for "
0233:                                + method.qualifiedName());
0234:                    }
0235:                }
0236:                return off;
0237:            }
0238:
0239:            /** Attempt to inline the code of this method */
0240:            final static int inline_NOT_DONE = 0;
0241:            final static int inline_IN_PROGRESS = 1;
0242:            final static int inline_DONE = 2;
0243:
0244:            private int inlineState = inline_NOT_DONE;
0245:
0246:            public void inlineCode() {
0247:                boolean isRewritten = false;
0248:                if (inlineState == inline_NOT_DONE) {
0249:                    inlineState = inline_IN_PROGRESS;
0250:                } else {
0251:                    return;
0252:                }
0253:                ConstantObject[] cp = method.parent.getConstantPool()
0254:                        .getConstants();
0255:                byte[] code = method.code;
0256:                byte[] rewrite;
0257:                int tmi = 0; // target method index
0258:
0259:                for (int pc = 0; pc < code.length;) {
0260:                    int opcode = code[pc] & 0xff;
0261:
0262:                    switch (opcode) {
0263:                    case opc_invokevirtual_quick:
0264:                    case opc_ainvokevirtual_quick:
0265:                    case opc_dinvokevirtual_quick:
0266:                    case opc_vinvokevirtual_quick:
0267:                    case opc_invokevirtualobject_quick: {
0268:                        // Target method is stored in array instead of code
0269:                        VMMethodInfo targetMethod = method.targetMethods[tmi++].vmMethodInfo;
0270:                        rewrite = MethodCallInline(pc,
0271:                                (CVMMethodInfo) targetMethod);
0272:                        if (rewrite != null) {
0273:                            isRewritten = true;
0274:                            System.arraycopy(rewrite, 0, code, pc, 3);
0275:                        }
0276:                        pc += 3;
0277:                        break;
0278:                    }
0279:                    case opc_invokevirtual_quick_w:
0280:                    case opc_invokenonvirtual_quick:
0281:                    case opc_invokesuper _quick: // not currently used by JavaCodeCompact
0282:                    case opc_invokestatic_quick: {
0283:                        int index = method.getUnsignedShort(pc + 1);
0284:                        MethodConstant mc = (MethodConstant) cp[index];
0285:                        VMMethodInfo targetMethod = mc.find().vmMethodInfo;
0286:                        rewrite = MethodCallInline(pc,
0287:                                (CVMMethodInfo) targetMethod);
0288:                        if (rewrite != null) {
0289:                            isRewritten = true;
0290:                            System.arraycopy(rewrite, 0, code, pc, 3);
0291:                        }
0292:                        pc += 3;
0293:                        break;
0294:                    }
0295:
0296:                    default:
0297:                        pc += method.opcodeLength(pc);
0298:                        break;
0299:                    }
0300:                }
0301:                if (isRewritten)
0302:                    compress();
0303:                inlineState = inline_DONE;
0304:            }
0305:
0306:            /* This method is called to determine whether the method "mb" called at
0307:             * from instruction "pc" can be inlined.  If not, the value null is
0308:             * returned.  If so, an array of three bytes, which should overwrite the
0309:             * method invocation, is returned
0310:             */
0311:            private byte[] MethodCallInline(int pc, CVMMethodInfo mb) {
0312:                byte code[] = method.code;
0313:                int opcode = code[pc] & 0xff;
0314:
0315:                if (opcode == opc_invokevirtual_quick
0316:                        || opcode == opc_ainvokevirtual_quick
0317:                        || opcode == opc_dinvokevirtual_quick
0318:                        || opcode == opc_vinvokevirtual_quick
0319:                        || opcode == opc_invokevirtual_quick_w)
0320:                    /* This is a virtual method call.  No use even bother trying to
0321:                     * inline the method, unless its final
0322:                     */
0323:                    if (((mb.method.access & ACC_FINAL) == 0)
0324:                            && ((mb.method.parent.access & ACC_FINAL) == 0))
0325:                        return null;
0326:
0327:                int mbInlining = mb.getInlining();
0328:                if ((mbInlining & NO_INLINE_FLAG) != 0)
0329:                    return null;
0330:                /* Does this inlining have a dependency on the constant pool, and so
0331:                 * can only be used on a method in the same class. */
0332:                if ((mbInlining & SAME_CLASS_FLAG) != 0) {
0333:                    if (this .method.parent != mb.method.parent)
0334:                        return null;
0335:                }
0336:                /* There is a inlining.  Copy that value into "result" */
0337:                byte[] result = new byte[3];
0338:                result[0] = INLINING_WORD1(mbInlining);
0339:                result[1] = INLINING_WORD2(mbInlining);
0340:                result[2] = INLINING_WORD3(mbInlining);
0341:                return result;
0342:            }
0343:
0344:            public int getInlining() {
0345:                MethodInfo mi = this .method;
0346:                if (inlining == 0) {
0347:                    if (((mi.access & (ACC_ABSTRACT | ACC_NATIVE | ACC_SYNCHRONIZED)) != 0)
0348:                            || (mi.exceptionTable.length > 0)) {
0349:                        inlining = NO_INLINE_FLAG;
0350:                    } else {
0351:                        inlineCode();
0352:                        inlining = calculateInlining();
0353:
0354:                        /*******
0355:                        if (inlining != NO_INLINE_FLAG) { 
0356:                            String sameClass = 
0357:                        	((inlining & SAME_CLASS_FLAG) != 0) ? "*" : "";
0358:                            System.out.print("get: " + this + " =>" + sameClass);
0359:                            System.out.println(" " + disassembleInlining());
0360:                        }
0361:                         ********/
0362:                    }
0363:                }
0364:                return inlining;
0365:            }
0366:
0367:            /* Given a method, determine if it can be "inlined" into three or fewer
0368:             * bytes.
0369:             */
0370:            private int calculateInlining() {
0371:                MethodInfo mb = this .method;
0372:                byte[] code = mb.code;
0373:
0374:                /* The checkThis flag indicates that the resulting code must 
0375:                 * throw a NullPointerException if the first argument is null
0376:                 */
0377:                boolean checkThis = ((mb.access & ACC_STATIC) == 0)
0378:                        && !method.name.string.equals("<init>");
0379:
0380:                boolean redoInlining = false;
0381:                int stackSize, stackBase;
0382:                OpcodeInfoType opPtr;
0383:
0384:                stackSize = 0;
0385:                stackBase = 0; // Prevent javac warning
0386:                for (int pc = 0;; pc++) {
0387:                    /* At this point in our simulation of the execution of the
0388:                     * method, registers stackBase .. stackBase+stackSize - 1 are
0389:                     * pushed onto the the stack.  pc points to the next
0390:                     * instruction to look at.
0391:                     */
0392:                    int opcode = code[pc] & 0xff;
0393:                    int opcode2;
0394:                    int reg, regSize, nextReg;
0395:
0396:                    if (stackSize == 0)
0397:                        stackBase = 0;
0398:                    nextReg = stackBase + stackSize;
0399:                    opPtr = OpcodeInfo[opcode];
0400:
0401:                    switch (opPtr.opcode) {
0402:
0403:                    case opc_iload_0: /* register load.  regnum from opcode */
0404:                    case opc_iload: /* register load.  regnum from pc[1] */
0405:                        if (opPtr.opcode == opc_iload_0) {
0406:                            reg = REGNUM(opPtr);
0407:                        } else {
0408:                            reg = code[pc + 1] & 0xff;
0409:                            pc++;
0410:                        }
0411:                        regSize = REGSIZE(opPtr);
0412:                        if (stackSize == 0) /* stack is currently empty */
0413:                            stackBase = reg;
0414:                        else if (nextReg != reg)
0415:                            return NO_INLINE_FLAG;
0416:                        stackSize += regSize;
0417:                        continue;
0418:
0419:                    case opc_pop: /* pop stack, or nop */
0420:                        stackSize -= REGSIZE(opPtr);
0421:                        continue;
0422:
0423:                    case opc_nonnull_quick: /* special instruction */
0424:                        if (nextReg == 1) {
0425:                            /* We're checking register 0 to ensure that it isn't null */
0426:                            stackSize = 0;
0427:                            checkThis = true;
0428:                            continue;
0429:                        }
0430:                        return NO_INLINE_FLAG;
0431:
0432:                    case opc_invokeignored_quick: /* special instruction */
0433:                    {
0434:                        int popCount = code[pc + 1] & 0xff;
0435:                        if (code[pc + 2] != 0) {
0436:                            /* We only know how to check register 0 for non-null ness */
0437:                            if (nextReg != popCount)
0438:                                return NO_INLINE_FLAG;
0439:                            checkThis = true;
0440:                            stackSize -= popCount;
0441:                        } else {
0442:                            stackSize -= popCount;
0443:                        }
0444:                        pc += 2;
0445:                        continue;
0446:                    }
0447:
0448:                    case opc_return: /* return void or value */
0449:                        return makeReturnResult(checkThis, nextReg,
0450:                                REGSIZE(opPtr));
0451:
0452:                    case opc_getfield_quick_w: /* or putfield_quick_w */
0453:                        opcode2 = code[pc + 3] & 0xff;
0454:                        if (!((opcode == opc_getfield_quick_w) ? isXreturn(opcode2)
0455:                                : opcode2 == opc_return)) {
0456:                            return NO_INLINE_FLAG;
0457:                        }
0458:                        /* FALLTHROUGH */
0459:
0460:                    case opc_iadd: { /* any simple instruction */
0461:                        int ilength = opcLengths[opcode];
0462:                        int result;
0463:                        if (opcode != opc_athrow) {
0464:                            // We are not inlinable unless we have athrow
0465:                            // as the last instruction, or we are returning
0466:                            if (pc + ilength >= code.length) {
0467:                                return NO_INLINE_FLAG;
0468:                            } else {
0469:                                opcode2 = code[pc + ilength] & 0xff;
0470:                                if (!isXreturn(opcode2)
0471:                                        && (opcode2 != opc_return)) {
0472:                                    return NO_INLINE_FLAG;
0473:                                }
0474:                            }
0475:                        }
0476:
0477:                        if ((opPtr.flags & OpcodeInfoType.NULL_CHECK) != 0
0478:                                && (stackBase == 0)) {
0479:                            /* We don't need to generate code to check for null, since
0480:                             * the instruction already does it.
0481:                             */
0482:                            checkThis = false;
0483:                        }
0484:                        switch (ilength) {
0485:                        case 1:
0486:                            result = makeOpcodeResult(checkThis, nextReg,
0487:                                    opPtr.inStack, 1, opcode, 0, 0);
0488:                            break;
0489:                        case 2:
0490:                            result = makeOpcodeResult(checkThis, nextReg,
0491:                                    opPtr.inStack, 2, opcode,
0492:                                    code[pc + 1] & 0xff, 0);
0493:                            break;
0494:                        case 3:
0495:                            result = makeOpcodeResult(checkThis, nextReg,
0496:                                    opPtr.inStack, 3, opcode,
0497:                                    code[pc + 1] & 0xff, code[pc + 2] & 0xff);
0498:                            break;
0499:                        default:
0500:                            throw new RuntimeException("sysAssert(FALSE);");
0501:                            // result = NO_INLINE_FLAG; // not reached
0502:                            // break;			// not reached
0503:                        }
0504:                        if ((result & NO_INLINE_FLAG) == 0) {
0505:                            if ((opPtr.flags & OpcodeInfoType.CONSTANT_POOL) != 0)
0506:                                result |= SAME_CLASS_FLAG;
0507:                            if (redoInlining)
0508:                                result |= REDO_INLINING_FLAG;
0509:                        }
0510:                        return result;
0511:                    }
0512:
0513:                    default:
0514:                        throw new RuntimeException("sysAssert(FALSE);");
0515:                    case 255: /* random instruction */
0516:                        return NO_INLINE_FLAG;
0517:
0518:                    } /* of switch statement */
0519:                } /* end of for loop */
0520:            }
0521:
0522:            /* This method is called to create the code that is actually going to
0523:             * replace the indicated method, when the method does nothing, or when
0524:             * it simply returns one of its arguments.
0525:             *
0526:             * It takes the following arguments:
0527:             *   mb:          Method we are examining
0528:             *   checkThis:   If true,  We must specially check that the first argument
0529:             *                "this" isn't null. 
0530:             *   highReg,     One greater than the highest register on the stack when
0531:             *                the return or Xreturn is called.
0532:             *   returnSize   Size of the return (0 for return, 1 for ireturn, 
0533:             *                 2 for lreturn, etc);
0534:             *
0535:             * We have to emulate the method call in 3 bytes.  At the time the
0536:             * method is called, the arguments reg[0] . . . reg[mb->args_size - 1]
0537:             * are pushed on the stack.
0538:             */
0539:            static int[] poppers = { opc_nop, opc_pop, opc_pop2 };
0540:
0541:            private int makeReturnResult(boolean checkThis, int highReg,
0542:                    int returnSize) {
0543:                MethodInfo mb = method;
0544:                int argsSize = mb.argsSize;
0545:                if (returnSize == 0) {
0546:                    /* Return void */
0547:                    return MAKE_INLINING(opc_invokeignored_quick, argsSize,
0548:                            (checkThis ? 1 : 0));
0549:                } else {
0550:                    /* Return some value from the stack */
0551:                    int returnReg = highReg - returnSize;
0552:                    int excessArgs = argsSize - returnSize - returnReg;
0553:                    // sysAssert(returnReg >= 0 && returnSize >= 0);
0554:                    if (returnReg == 0) {
0555:                        /* Returning reg0 or reg0/reg1 */
0556:                        if (checkThis) {
0557:                            /* Must be returning reg0, which is also checked. We
0558:                             * require argsSize >= 2 (which is the same thing as
0559:                             * excessArgs >= 1), because otherwise the "dup" might
0560:                             * overflow the stack.  More sophisticated inliners
0561:                             * might see if there is space on the caller's stack.
0562:                             */
0563:                            // sysAssert(returnSize == 1);
0564:                            if (argsSize < 2) {
0565:                                return NO_INLINE_FLAG;
0566:                            } else if (excessArgs > 2) {
0567:                                return NO_INLINE_FLAG;
0568:                            } else {
0569:                                return MAKE_INLINING(poppers[excessArgs],
0570:                                        opc_dup, opc_nonnull_quick);
0571:                            }
0572:                        } else {
0573:                            /* We're returning reg0 or reg0/reg1 which isn't null
0574:                             * checked.  We just pop extraneous stuff off the stack
0575:                             * */
0576:                            return MAKE_INLINING(opc_invokeignored_quick,
0577:                                    excessArgs, 0);
0578:                        }
0579:                    } else {
0580:                        /* At this point, returnReg > 0.  We're returning something
0581:                         * other than the bottom of the stack.
0582:                         */
0583:                        if (returnSize == 1 && returnReg == 1) {
0584:                            if (excessArgs > 2) {
0585:                                return NO_INLINE_FLAG;
0586:                            }
0587:                            return MAKE_INLINING(poppers[excessArgs], opc_swap,
0588:                                    checkThis ? opc_nonnull_quick : opc_pop);
0589:                        }
0590:                        return NO_INLINE_FLAG;
0591:                    }
0592:                }
0593:            }
0594:
0595:            /* This method is called to create the code that is actually going to
0596:             * replace the indicated method
0597:             * 
0598:             * makeOpcodeResult is used to create a inlining that can be used anywhere
0599:             * It takes the following arguments:
0600:             *
0601:             *   mb:          Method we are examining
0602:             *   checkThis:   If true,  We must specially check that the first argument
0603:             *                "this" isn't null.  This condition is >>NOT<< tested by 
0604:             *                the generated code.
0605:             *   nextReg:     In the emulation, the highest register on the stack is
0606:             *                reg[nextReg - 1].
0607:             *   icount       The number of bytes of instructions that follow.
0608:             *   opcode, op1, op2
0609:             *                The bytes of instruction.
0610:             *
0611:             * We have to emulate the method call in 3 bytes.  At the time the
0612:             * method is called, the arguments reg[0] . . . reg[mb->args_size - 1]
0613:             * are pushed on the stack.  So in three bytes, we have to:
0614:             *     Remove any excess arguments from the stack.
0615:             *     Perform the operation on the indicated stack registers
0616:             *     Remove any objects lower down on the stack (this is hard!)
0617:             *     Make sure that reg[0] is checked for being non-null, if necessary.
0618:             */
0619:            private int makeOpcodeResult(boolean checkThis, int nextReg,
0620:                    int opcodeArgCount, int icount, int opcode, int op1, int op2) {
0621:                MethodInfo mb = method;
0622:                int firstReg = (opcodeArgCount == 0) ? 0 : nextReg
0623:                        - opcodeArgCount;
0624:                // sysAssert(firstReg >= 0 && opcodeArgCount >= 0 && icount > 0);
0625:
0626:                if (firstReg > 0) {
0627:                    /* There are extra registers at the bottom of the stack */
0628:                    return makePoppingResult(checkThis, firstReg,
0629:                            opcodeArgCount, icount, opcode, op1, op2);
0630:                } else {
0631:                    /* No extra registers at bottom of stack */
0632:                    int argsSize = mb.argsSize;
0633:                    int excessArgs = argsSize - opcodeArgCount; /* extra at top */
0634:                    int popSpace = 3 - icount; /* space to pop args at top */
0635:
0636:                    int result = 0;
0637:                    int i;
0638:
0639:                    if (checkThis) {
0640:                        /* Unless this is a constant method that ignores all of its
0641:                         * arguments, we don't really have any way of checking
0642:                         * register 0 if the instructions doesn't.  If it is a
0643:                         * constant instruction, deduct one from both popSpace and
0644:                         * from excessArgs, since we are popping that last argument
0645:                         * when an opc_nonnull_quick;
0646:                         */
0647:                        if (opcodeArgCount > 0 || popSpace == 0)
0648:                            return NO_INLINE_FLAG;
0649:                        popSpace--;
0650:                        excessArgs--;
0651:                        // sysAssert(excessArgs >= 0);
0652:                    }
0653:                    if (excessArgs > 2 * popSpace)
0654:                        return NO_INLINE_FLAG;
0655:                    for (i = 0; i < popSpace; i++) {
0656:                        /* If excessArgs <= popSpace, the following generates excessArgs
0657:                         * "pops" followed by nops.  Otherwise, it generates 
0658:                         * excessArgs - popSpace pop2's followed by pop's.
0659:                         */
0660:                        int opcodeTmp = (excessArgs <= i) ? opc_nop
0661:                                : (excessArgs <= popSpace + i) ? opc_pop
0662:                                        : opc_pop2;
0663:                        result |= (opcodeTmp << (i << 3));
0664:                    }
0665:                    if (checkThis)
0666:                        result |= opc_nonnull_quick << ((i++) << 3);
0667:                    // sysAssert(i + icount == 3);
0668:                    switch (icount) {
0669:                    case 3:
0670:                        result |= op2 << ((i + 2) << 3);
0671:                    case 2:
0672:                        result |= op1 << ((i + 1) << 3);
0673:                    case 1:
0674:                        result |= opcode << ((i + 0) << 3);
0675:                    }
0676:                    return result;
0677:                }
0678:            }
0679:
0680:            /* 
0681:             * Called by makeOpcodeResult.  
0682:             * Same arguments.  But there are extra arguments on the bottom to pop.
0683:             */
0684:            private int makePoppingResult(boolean checkThis, int firstReg,
0685:                    int opcodeArgCount, int icount, int opcode, int op1, int op2) {
0686:                MethodInfo mb = method;
0687:                int argsSize = mb.argsSize;
0688:                int excessArgs = argsSize - opcodeArgCount - firstReg; /* extra on top*/
0689:
0690:                if (icount > 1)
0691:                    /* We're just not prepared to deal with this. */
0692:                    return NO_INLINE_FLAG;
0693:
0694:                if (OpcodeInfo[opcode].outStack == 0) {
0695:                    int result = 0;
0696:                    /* Something like an array store, that leaves no value on the
0697:                           stack */
0698:                    int i = 0;
0699:                    /* We can't deal with checkThis, since it might reverse the order of
0700:                     * an exception.  We have a total of two instructions to do all the 
0701:                     * pre and post popping.
0702:                     */
0703:                    if (checkThis
0704:                            || ((excessArgs + 1) / 2 + (firstReg + 1) / 2) > 2)
0705:                        return NO_INLINE_FLAG;
0706:                    for (; excessArgs > 0; excessArgs -= 2)
0707:                        /* pre popping */
0708:                        result |= (excessArgs == 1 ? opc_pop : opc_pop2) << ((i++) << 3);
0709:                    result |= opcode << ((i++) << 3);
0710:                    for (; firstReg > 0; firstReg -= 2)
0711:                        /* post popping */
0712:                        result |= (firstReg == 1 ? opc_pop : opc_pop2) << ((i++) << 3);
0713:                    while (i < 3)
0714:                        result |= opc_nop << ((i++) << 3);
0715:                    return result;
0716:                }
0717:
0718:                if (excessArgs > 0 || firstReg > 1)
0719:                    /* We can't both do useful work and remove more than this many 
0720:                     * items from the stack. */
0721:                    return NO_INLINE_FLAG;
0722:
0723:                if (opcodeArgCount == 1) {
0724:                    return MAKE_INLINING(opc_swap,
0725:                            checkThis ? opc_nonnull_quick : opc_pop, opcode);
0726:                }
0727:                if (((OpcodeInfo[opcode].flags & (OpcodeInfoType.NULL_CHECK | OpcodeInfoType.CAN_ERROR)) == 0)
0728:                        && (OpcodeInfo[opcode].outStack == 1)) {
0729:                    /* The result creates one thing on the stack, and it can't error */
0730:                    return MAKE_INLINING(opcode, opc_swap,
0731:                            checkThis ? opc_nonnull_quick : opc_pop);
0732:                }
0733:                return NO_INLINE_FLAG;
0734:            }
0735:
0736:            private static boolean isXreturn(int opcode) {
0737:                return (opcode >= opc_ireturn) && (opcode <= opc_areturn);
0738:            }
0739:
0740:            private static byte INLINING_WORD1(int simp) {
0741:                return (byte) (simp & 0xFF);
0742:            }
0743:
0744:            private static byte INLINING_WORD2(int simp) {
0745:                return (byte) ((simp >> 8) & 0xFF);
0746:            }
0747:
0748:            private static byte INLINING_WORD3(int simp) {
0749:                return (byte) ((simp >> 16) & 0xFF);
0750:            }
0751:
0752:            private static int MAKE_INLINING(int op1, int op2, int op3) {
0753:                return (op1 << 0) + (op2 << 8) + (op3 << 16);
0754:            }
0755:
0756:            private static int REGSIZE(OpcodeInfoType ptr) {
0757:                return (ptr.inStack);
0758:            }
0759:
0760:            private static int REGNUM(OpcodeInfoType ptr) {
0761:                return (ptr.outStack);
0762:            }
0763:
0764:            static OpcodeInfoType[] OpcodeInfo = new OpcodeInfoType[256];
0765:            static {
0766:                /*  { opc_pop  <number of words to pop from stack> } 
0767:                 *  { opc_iadd <words popped from stack> <words pushed to stack> }
0768:                 *  { opc_iload <words pushed to stack> } 
0769:                 *  { opc_iload_0 <words pushed to stack> <implicit register> } 
0770:                 *  { opc_return  <words returned> } 
0771:                 *    255 indicates opcode that we can't inline
0772:                 *  other values are special opcodes that must be handled specially
0773:                 */
0774:
0775:                OpcodeInfo[opc_nop] = new OpcodeInfoType(opc_pop, 0);
0776:                OpcodeInfo[opc_aconst_null] = new OpcodeInfoType(opc_iadd, 0, 1);
0777:                OpcodeInfo[opc_iconst_m1] = new OpcodeInfoType(opc_iadd, 0, 1);
0778:                OpcodeInfo[opc_iconst_0] = new OpcodeInfoType(opc_iadd, 0, 1);
0779:                OpcodeInfo[opc_iconst_1] = new OpcodeInfoType(opc_iadd, 0, 1);
0780:                OpcodeInfo[opc_iconst_2] = new OpcodeInfoType(opc_iadd, 0, 1);
0781:                OpcodeInfo[opc_iconst_3] = new OpcodeInfoType(opc_iadd, 0, 1);
0782:                OpcodeInfo[opc_iconst_4] = new OpcodeInfoType(opc_iadd, 0, 1);
0783:                OpcodeInfo[opc_iconst_5] = new OpcodeInfoType(opc_iadd, 0, 1);
0784:                OpcodeInfo[opc_lconst_0] = new OpcodeInfoType(opc_iadd, 0, 2);
0785:                OpcodeInfo[opc_lconst_1] = new OpcodeInfoType(opc_iadd, 0, 2);
0786:                OpcodeInfo[opc_fconst_0] = new OpcodeInfoType(opc_iadd, 0, 1);
0787:                OpcodeInfo[opc_fconst_1] = new OpcodeInfoType(opc_iadd, 0, 1);
0788:                OpcodeInfo[opc_fconst_2] = new OpcodeInfoType(opc_iadd, 0, 1);
0789:                OpcodeInfo[opc_dconst_0] = new OpcodeInfoType(opc_iadd, 0, 2);
0790:                OpcodeInfo[opc_dconst_1] = new OpcodeInfoType(opc_iadd, 0, 2);
0791:                OpcodeInfo[opc_bipush] = new OpcodeInfoType(opc_iadd, 0, 1);
0792:                OpcodeInfo[opc_sipush] = new OpcodeInfoType(opc_iadd, 0, 1);
0793:                OpcodeInfo[opc_ldc] = new OpcodeInfoType(255);
0794:                OpcodeInfo[opc_ldc_w] = new OpcodeInfoType(255);
0795:                OpcodeInfo[opc_ldc2_w] = new OpcodeInfoType(255);
0796:                OpcodeInfo[opc_iload] = new OpcodeInfoType(opc_iload, 1);
0797:                OpcodeInfo[opc_lload] = new OpcodeInfoType(opc_iload, 2);
0798:                OpcodeInfo[opc_fload] = new OpcodeInfoType(opc_iload, 1);
0799:                OpcodeInfo[opc_dload] = new OpcodeInfoType(opc_iload, 2);
0800:                OpcodeInfo[opc_aload] = new OpcodeInfoType(opc_iload, 1);
0801:                OpcodeInfo[opc_iload_0] = new OpcodeInfoType(opc_iload_0, 1, 0);
0802:                OpcodeInfo[opc_iload_1] = new OpcodeInfoType(opc_iload_0, 1, 1);
0803:                OpcodeInfo[opc_iload_2] = new OpcodeInfoType(opc_iload_0, 1, 2);
0804:                OpcodeInfo[opc_iload_3] = new OpcodeInfoType(opc_iload_0, 1, 3);
0805:                OpcodeInfo[opc_lload_0] = new OpcodeInfoType(opc_iload_0, 2, 0);
0806:                OpcodeInfo[opc_lload_1] = new OpcodeInfoType(opc_iload_0, 2, 1);
0807:                OpcodeInfo[opc_lload_2] = new OpcodeInfoType(opc_iload_0, 2, 2);
0808:                OpcodeInfo[opc_lload_3] = new OpcodeInfoType(opc_iload_0, 2, 3);
0809:                OpcodeInfo[opc_fload_0] = new OpcodeInfoType(opc_iload_0, 1, 0);
0810:                OpcodeInfo[opc_fload_1] = new OpcodeInfoType(opc_iload_0, 1, 1);
0811:                OpcodeInfo[opc_fload_2] = new OpcodeInfoType(opc_iload_0, 1, 2);
0812:                OpcodeInfo[opc_fload_3] = new OpcodeInfoType(opc_iload_0, 1, 3);
0813:                OpcodeInfo[opc_dload_0] = new OpcodeInfoType(opc_iload_0, 2, 0);
0814:                OpcodeInfo[opc_dload_1] = new OpcodeInfoType(opc_iload_0, 2, 1);
0815:                OpcodeInfo[opc_dload_2] = new OpcodeInfoType(opc_iload_0, 2, 2);
0816:                OpcodeInfo[opc_dload_3] = new OpcodeInfoType(opc_iload_0, 2, 3);
0817:                OpcodeInfo[opc_aload_0] = new OpcodeInfoType(opc_iload_0, 1, 0);
0818:                OpcodeInfo[opc_aload_1] = new OpcodeInfoType(opc_iload_0, 1, 1);
0819:                OpcodeInfo[opc_aload_2] = new OpcodeInfoType(opc_iload_0, 1, 2);
0820:                OpcodeInfo[opc_aload_3] = new OpcodeInfoType(opc_iload_0, 1, 3);
0821:                OpcodeInfo[opc_iaload] = new OpcodeInfoType(opc_iadd, 2, 1,
0822:                        OpcodeInfoType.NULL_CHECK);
0823:                OpcodeInfo[opc_laload] = new OpcodeInfoType(opc_iadd, 2, 2,
0824:                        OpcodeInfoType.NULL_CHECK);
0825:                OpcodeInfo[opc_faload] = new OpcodeInfoType(opc_iadd, 2, 1,
0826:                        OpcodeInfoType.NULL_CHECK);
0827:                OpcodeInfo[opc_daload] = new OpcodeInfoType(opc_iadd, 2, 2,
0828:                        OpcodeInfoType.NULL_CHECK);
0829:                OpcodeInfo[opc_aaload] = new OpcodeInfoType(opc_iadd, 2, 1,
0830:                        OpcodeInfoType.NULL_CHECK);
0831:                OpcodeInfo[opc_baload] = new OpcodeInfoType(opc_iadd, 2, 1,
0832:                        OpcodeInfoType.NULL_CHECK);
0833:                OpcodeInfo[opc_caload] = new OpcodeInfoType(opc_iadd, 2, 1,
0834:                        OpcodeInfoType.NULL_CHECK);
0835:                OpcodeInfo[opc_saload] = new OpcodeInfoType(opc_iadd, 2, 1,
0836:                        OpcodeInfoType.NULL_CHECK);
0837:                OpcodeInfo[opc_istore] = new OpcodeInfoType(255);
0838:                OpcodeInfo[opc_lstore] = new OpcodeInfoType(255);
0839:                OpcodeInfo[opc_fstore] = new OpcodeInfoType(255);
0840:                OpcodeInfo[opc_dstore] = new OpcodeInfoType(255);
0841:                OpcodeInfo[opc_astore] = new OpcodeInfoType(255);
0842:                OpcodeInfo[opc_istore_0] = new OpcodeInfoType(255);
0843:                OpcodeInfo[opc_istore_1] = new OpcodeInfoType(255);
0844:                OpcodeInfo[opc_istore_2] = new OpcodeInfoType(255);
0845:                OpcodeInfo[opc_istore_3] = new OpcodeInfoType(255);
0846:                OpcodeInfo[opc_lstore_0] = new OpcodeInfoType(255);
0847:                OpcodeInfo[opc_lstore_1] = new OpcodeInfoType(255);
0848:                OpcodeInfo[opc_lstore_2] = new OpcodeInfoType(255);
0849:                OpcodeInfo[opc_lstore_3] = new OpcodeInfoType(255);
0850:                OpcodeInfo[opc_fstore_0] = new OpcodeInfoType(255);
0851:                OpcodeInfo[opc_fstore_1] = new OpcodeInfoType(255);
0852:                OpcodeInfo[opc_fstore_2] = new OpcodeInfoType(255);
0853:                OpcodeInfo[opc_fstore_3] = new OpcodeInfoType(255);
0854:                OpcodeInfo[opc_dstore_0] = new OpcodeInfoType(255);
0855:                OpcodeInfo[opc_dstore_1] = new OpcodeInfoType(255);
0856:                OpcodeInfo[opc_dstore_2] = new OpcodeInfoType(255);
0857:                OpcodeInfo[opc_dstore_3] = new OpcodeInfoType(255);
0858:                OpcodeInfo[opc_astore_0] = new OpcodeInfoType(255);
0859:                OpcodeInfo[opc_astore_1] = new OpcodeInfoType(255);
0860:                OpcodeInfo[opc_astore_2] = new OpcodeInfoType(255);
0861:                OpcodeInfo[opc_astore_3] = new OpcodeInfoType(255);
0862:                OpcodeInfo[opc_iastore] = new OpcodeInfoType(opc_iadd, 3, 0,
0863:                        OpcodeInfoType.NULL_CHECK);
0864:                OpcodeInfo[opc_lastore] = new OpcodeInfoType(opc_iadd, 4, 0,
0865:                        OpcodeInfoType.NULL_CHECK);
0866:                OpcodeInfo[opc_fastore] = new OpcodeInfoType(opc_iadd, 3, 0,
0867:                        OpcodeInfoType.NULL_CHECK);
0868:                OpcodeInfo[opc_dastore] = new OpcodeInfoType(opc_iadd, 4, 0,
0869:                        OpcodeInfoType.NULL_CHECK);
0870:                OpcodeInfo[opc_aastore] = new OpcodeInfoType(opc_iadd, 3, 0,
0871:                        OpcodeInfoType.NULL_CHECK);
0872:                OpcodeInfo[opc_bastore] = new OpcodeInfoType(opc_iadd, 3, 0,
0873:                        OpcodeInfoType.NULL_CHECK);
0874:                OpcodeInfo[opc_castore] = new OpcodeInfoType(opc_iadd, 3, 0,
0875:                        OpcodeInfoType.NULL_CHECK);
0876:                OpcodeInfo[opc_sastore] = new OpcodeInfoType(opc_iadd, 3, 0,
0877:                        OpcodeInfoType.NULL_CHECK);
0878:                OpcodeInfo[opc_pop] = new OpcodeInfoType(opc_pop, 1);
0879:                OpcodeInfo[opc_pop2] = new OpcodeInfoType(opc_pop, 2);
0880:                OpcodeInfo[opc_dup] = new OpcodeInfoType(255);
0881:                OpcodeInfo[opc_dup_x1] = new OpcodeInfoType(255);
0882:                OpcodeInfo[opc_dup_x2] = new OpcodeInfoType(255);
0883:                OpcodeInfo[opc_dup2] = new OpcodeInfoType(255);
0884:                OpcodeInfo[opc_dup2_x1] = new OpcodeInfoType(255);
0885:                OpcodeInfo[opc_dup2_x2] = new OpcodeInfoType(255);
0886:                OpcodeInfo[opc_swap] = new OpcodeInfoType(255);
0887:                OpcodeInfo[opc_iadd] = new OpcodeInfoType(opc_iadd, 2, 1);
0888:                OpcodeInfo[opc_ladd] = new OpcodeInfoType(opc_iadd, 4, 2);
0889:                OpcodeInfo[opc_fadd] = new OpcodeInfoType(opc_iadd, 2, 1);
0890:                OpcodeInfo[opc_dadd] = new OpcodeInfoType(opc_iadd, 4, 2);
0891:                OpcodeInfo[opc_isub] = new OpcodeInfoType(opc_iadd, 2, 1);
0892:                OpcodeInfo[opc_lsub] = new OpcodeInfoType(opc_iadd, 4, 2);
0893:                OpcodeInfo[opc_fsub] = new OpcodeInfoType(opc_iadd, 2, 1);
0894:                OpcodeInfo[opc_dsub] = new OpcodeInfoType(opc_iadd, 4, 2);
0895:                OpcodeInfo[opc_imul] = new OpcodeInfoType(opc_iadd, 2, 1);
0896:                OpcodeInfo[opc_lmul] = new OpcodeInfoType(opc_iadd, 4, 2);
0897:                OpcodeInfo[opc_fmul] = new OpcodeInfoType(opc_iadd, 2, 1);
0898:                OpcodeInfo[opc_dmul] = new OpcodeInfoType(opc_iadd, 4, 2);
0899:                OpcodeInfo[opc_idiv] = new OpcodeInfoType(opc_iadd, 2, 1,
0900:                        OpcodeInfoType.CAN_ERROR);
0901:                OpcodeInfo[opc_ldiv] = new OpcodeInfoType(opc_iadd, 4, 2,
0902:                        OpcodeInfoType.CAN_ERROR);
0903:                OpcodeInfo[opc_fdiv] = new OpcodeInfoType(opc_iadd, 2, 1);
0904:                OpcodeInfo[opc_ddiv] = new OpcodeInfoType(opc_iadd, 4, 2);
0905:                OpcodeInfo[opc_irem] = new OpcodeInfoType(opc_iadd, 2, 1,
0906:                        OpcodeInfoType.CAN_ERROR);
0907:                OpcodeInfo[opc_lrem] = new OpcodeInfoType(opc_iadd, 4, 2,
0908:                        OpcodeInfoType.CAN_ERROR);
0909:                OpcodeInfo[opc_frem] = new OpcodeInfoType(opc_iadd, 2, 1);
0910:                OpcodeInfo[opc_drem] = new OpcodeInfoType(opc_iadd, 4, 2);
0911:                OpcodeInfo[opc_ineg] = new OpcodeInfoType(opc_iadd, 1, 1);
0912:                OpcodeInfo[opc_lneg] = new OpcodeInfoType(opc_iadd, 2, 2);
0913:                OpcodeInfo[opc_fneg] = new OpcodeInfoType(opc_iadd, 1, 1);
0914:                OpcodeInfo[opc_dneg] = new OpcodeInfoType(opc_iadd, 2, 2);
0915:                OpcodeInfo[opc_ishl] = new OpcodeInfoType(opc_iadd, 2, 1);
0916:                OpcodeInfo[opc_lshl] = new OpcodeInfoType(opc_iadd, 3, 2);
0917:                OpcodeInfo[opc_ishr] = new OpcodeInfoType(opc_iadd, 2, 1);
0918:                OpcodeInfo[opc_lshr] = new OpcodeInfoType(opc_iadd, 3, 2);
0919:                OpcodeInfo[opc_iushr] = new OpcodeInfoType(opc_iadd, 2, 1);
0920:                OpcodeInfo[opc_lushr] = new OpcodeInfoType(opc_iadd, 3, 2);
0921:                OpcodeInfo[opc_iand] = new OpcodeInfoType(opc_iadd, 2, 1);
0922:                OpcodeInfo[opc_land] = new OpcodeInfoType(opc_iadd, 4, 2);
0923:                OpcodeInfo[opc_ior] = new OpcodeInfoType(opc_iadd, 2, 1);
0924:                OpcodeInfo[opc_lor] = new OpcodeInfoType(opc_iadd, 4, 2);
0925:                OpcodeInfo[opc_ixor] = new OpcodeInfoType(opc_iadd, 2, 1);
0926:                OpcodeInfo[opc_lxor] = new OpcodeInfoType(opc_iadd, 4, 2);
0927:                OpcodeInfo[opc_iinc] = new OpcodeInfoType(255);
0928:                OpcodeInfo[opc_i2l] = new OpcodeInfoType(opc_iadd, 1, 2);
0929:                OpcodeInfo[opc_i2f] = new OpcodeInfoType(opc_iadd, 1, 1);
0930:                OpcodeInfo[opc_i2d] = new OpcodeInfoType(opc_iadd, 1, 2);
0931:                OpcodeInfo[opc_l2i] = new OpcodeInfoType(opc_iadd, 2, 1);
0932:                OpcodeInfo[opc_l2f] = new OpcodeInfoType(opc_iadd, 2, 1);
0933:                OpcodeInfo[opc_l2d] = new OpcodeInfoType(opc_iadd, 2, 2);
0934:                OpcodeInfo[opc_f2i] = new OpcodeInfoType(opc_iadd, 1, 1);
0935:                OpcodeInfo[opc_f2l] = new OpcodeInfoType(opc_iadd, 1, 2);
0936:                OpcodeInfo[opc_f2d] = new OpcodeInfoType(opc_iadd, 1, 2);
0937:                OpcodeInfo[opc_d2i] = new OpcodeInfoType(opc_iadd, 2, 1);
0938:                OpcodeInfo[opc_d2l] = new OpcodeInfoType(opc_iadd, 2, 2);
0939:                OpcodeInfo[opc_d2f] = new OpcodeInfoType(opc_iadd, 2, 1);
0940:                OpcodeInfo[opc_i2b] = new OpcodeInfoType(opc_iadd, 1, 1);
0941:                OpcodeInfo[opc_i2c] = new OpcodeInfoType(opc_iadd, 1, 1);
0942:                OpcodeInfo[opc_i2s] = new OpcodeInfoType(opc_iadd, 1, 1);
0943:                OpcodeInfo[opc_lcmp] = new OpcodeInfoType(opc_iadd, 4, 1);
0944:                OpcodeInfo[opc_fcmpl] = new OpcodeInfoType(opc_iadd, 2, 1);
0945:                OpcodeInfo[opc_fcmpg] = new OpcodeInfoType(opc_iadd, 2, 1);
0946:                OpcodeInfo[opc_dcmpl] = new OpcodeInfoType(opc_iadd, 4, 1);
0947:                OpcodeInfo[opc_dcmpg] = new OpcodeInfoType(opc_iadd, 4, 1);
0948:                OpcodeInfo[opc_ifeq] = new OpcodeInfoType(255);
0949:                OpcodeInfo[opc_ifne] = new OpcodeInfoType(255);
0950:                OpcodeInfo[opc_iflt] = new OpcodeInfoType(255);
0951:                OpcodeInfo[opc_ifge] = new OpcodeInfoType(255);
0952:                OpcodeInfo[opc_ifgt] = new OpcodeInfoType(255);
0953:                OpcodeInfo[opc_ifle] = new OpcodeInfoType(255);
0954:                OpcodeInfo[opc_if_icmpeq] = new OpcodeInfoType(255);
0955:                OpcodeInfo[opc_if_icmpne] = new OpcodeInfoType(255);
0956:                OpcodeInfo[opc_if_icmplt] = new OpcodeInfoType(255);
0957:                OpcodeInfo[opc_if_icmpge] = new OpcodeInfoType(255);
0958:                OpcodeInfo[opc_if_icmpgt] = new OpcodeInfoType(255);
0959:                OpcodeInfo[opc_if_icmple] = new OpcodeInfoType(255);
0960:                OpcodeInfo[opc_if_acmpeq] = new OpcodeInfoType(255);
0961:                OpcodeInfo[opc_if_acmpne] = new OpcodeInfoType(255);
0962:                OpcodeInfo[opc_goto] = new OpcodeInfoType(255);
0963:                OpcodeInfo[opc_jsr] = new OpcodeInfoType(255);
0964:                OpcodeInfo[opc_ret] = new OpcodeInfoType(255);
0965:                OpcodeInfo[opc_tableswitch] = new OpcodeInfoType(255);
0966:                OpcodeInfo[opc_lookupswitch] = new OpcodeInfoType(255);
0967:                OpcodeInfo[opc_ireturn] = new OpcodeInfoType(opc_return, 1);
0968:                OpcodeInfo[opc_lreturn] = new OpcodeInfoType(opc_return, 2);
0969:                OpcodeInfo[opc_freturn] = new OpcodeInfoType(opc_return, 1);
0970:                OpcodeInfo[opc_dreturn] = new OpcodeInfoType(opc_return, 2);
0971:                OpcodeInfo[opc_areturn] = new OpcodeInfoType(opc_return, 1);
0972:                OpcodeInfo[opc_return] = new OpcodeInfoType(opc_return, 0);
0973:                OpcodeInfo[opc_getstatic] = new OpcodeInfoType(255);
0974:                OpcodeInfo[opc_putstatic] = new OpcodeInfoType(255);
0975:                OpcodeInfo[opc_getfield] = new OpcodeInfoType(255);
0976:                OpcodeInfo[opc_putfield] = new OpcodeInfoType(255);
0977:                OpcodeInfo[opc_invokevirtual] = new OpcodeInfoType(255);
0978:                OpcodeInfo[opc_invokespecial] = new OpcodeInfoType(255);
0979:                OpcodeInfo[opc_invokestatic] = new OpcodeInfoType(255);
0980:                OpcodeInfo[opc_invokeinterface] = new OpcodeInfoType(255);
0981:                OpcodeInfo[opc_xxxunusedxxx] = new OpcodeInfoType(255);
0982:                OpcodeInfo[opc_new] = new OpcodeInfoType(255);
0983:                OpcodeInfo[opc_newarray] = new OpcodeInfoType(opc_iadd, 1, 1,
0984:                        OpcodeInfoType.CAN_ERROR);
0985:                OpcodeInfo[opc_anewarray] = new OpcodeInfoType(255);
0986:                OpcodeInfo[opc_arraylength] = new OpcodeInfoType(opc_iadd, 1,
0987:                        1, OpcodeInfoType.NULL_CHECK);
0988:                OpcodeInfo[opc_athrow] = new OpcodeInfoType(opc_iadd, 1, 0,
0989:                        OpcodeInfoType.NULL_CHECK | OpcodeInfoType.CAN_ERROR);
0990:                OpcodeInfo[opc_checkcast] = new OpcodeInfoType(255);
0991:                OpcodeInfo[opc_instanceof ] = new OpcodeInfoType(255);
0992:                OpcodeInfo[opc_monitorenter] = new OpcodeInfoType(opc_iadd, 1,
0993:                        0, OpcodeInfoType.NULL_CHECK | OpcodeInfoType.CAN_ERROR);
0994:                OpcodeInfo[opc_monitorexit] = new OpcodeInfoType(opc_iadd, 1,
0995:                        0, OpcodeInfoType.NULL_CHECK | OpcodeInfoType.CAN_ERROR);
0996:                OpcodeInfo[opc_wide] = new OpcodeInfoType(255);
0997:                OpcodeInfo[opc_multianewarray] = new OpcodeInfoType(255);
0998:                OpcodeInfo[opc_ifnull] = new OpcodeInfoType(255);
0999:                OpcodeInfo[opc_ifnonnull] = new OpcodeInfoType(255);
1000:                OpcodeInfo[opc_goto_w] = new OpcodeInfoType(255);
1001:                OpcodeInfo[opc_jsr_w] = new OpcodeInfoType(255);
1002:                OpcodeInfo[opc_breakpoint] = new OpcodeInfoType(255);
1003:                OpcodeInfo[opc_aldc_quick] = new OpcodeInfoType(opc_iadd, 0, 1,
1004:                        OpcodeInfoType.CONSTANT_POOL);
1005:                OpcodeInfo[opc_aldc_w_quick] = new OpcodeInfoType(opc_iadd, 0,
1006:                        1, OpcodeInfoType.CONSTANT_POOL);
1007:                OpcodeInfo[opc_aldc_ind_quick] = new OpcodeInfoType(opc_iadd,
1008:                        0, 1, OpcodeInfoType.CONSTANT_POOL);
1009:                OpcodeInfo[opc_aldc_ind_w_quick] = new OpcodeInfoType(opc_iadd,
1010:                        0, 1, OpcodeInfoType.CONSTANT_POOL);
1011:                OpcodeInfo[opc_ldc_quick] = new OpcodeInfoType(opc_iadd, 0, 1,
1012:                        OpcodeInfoType.CONSTANT_POOL);
1013:                OpcodeInfo[opc_ldc_w_quick] = new OpcodeInfoType(opc_iadd, 0,
1014:                        1, OpcodeInfoType.CONSTANT_POOL);
1015:                OpcodeInfo[opc_ldc2_w_quick] = new OpcodeInfoType(opc_iadd, 0,
1016:                        2, OpcodeInfoType.CONSTANT_POOL);
1017:                OpcodeInfo[opc_getfield_quick] = new OpcodeInfoType(opc_iadd,
1018:                        1, 1, OpcodeInfoType.NULL_CHECK);
1019:                OpcodeInfo[opc_putfield_quick] = new OpcodeInfoType(opc_iadd,
1020:                        2, 0, OpcodeInfoType.NULL_CHECK);
1021:                OpcodeInfo[opc_getfield2_quick] = new OpcodeInfoType(opc_iadd,
1022:                        1, 2, OpcodeInfoType.NULL_CHECK);
1023:                OpcodeInfo[opc_putfield2_quick] = new OpcodeInfoType(opc_iadd,
1024:                        3, 0, OpcodeInfoType.NULL_CHECK);
1025:                OpcodeInfo[opc_getstatic_quick] = new OpcodeInfoType(opc_iadd,
1026:                        0, 1, OpcodeInfoType.CONSTANT_POOL);
1027:                OpcodeInfo[opc_putstatic_quick] = new OpcodeInfoType(opc_iadd,
1028:                        1, 0, OpcodeInfoType.CONSTANT_POOL);
1029:                OpcodeInfo[opc_agetstatic_quick] = new OpcodeInfoType(opc_iadd,
1030:                        0, 1, OpcodeInfoType.CONSTANT_POOL);
1031:                OpcodeInfo[opc_aputstatic_quick] = new OpcodeInfoType(opc_iadd,
1032:                        1, 0, OpcodeInfoType.CONSTANT_POOL);
1033:                OpcodeInfo[opc_getstatic2_quick] = new OpcodeInfoType(opc_iadd,
1034:                        0, 2, OpcodeInfoType.CONSTANT_POOL);
1035:                OpcodeInfo[opc_putstatic2_quick] = new OpcodeInfoType(opc_iadd,
1036:                        2, 0, OpcodeInfoType.CONSTANT_POOL);
1037:                OpcodeInfo[opc_invokevirtual_quick] = new OpcodeInfoType(255);
1038:                OpcodeInfo[opc_ainvokevirtual_quick] = new OpcodeInfoType(255);
1039:                OpcodeInfo[opc_dinvokevirtual_quick] = new OpcodeInfoType(255);
1040:                OpcodeInfo[opc_vinvokevirtual_quick] = new OpcodeInfoType(255);
1041:                OpcodeInfo[opc_invokenonvirtual_quick] = new OpcodeInfoType(255);
1042:                OpcodeInfo[opc_invokesuper _quick] = new OpcodeInfoType(255);
1043:                OpcodeInfo[opc_invokestatic_quick] = new OpcodeInfoType(255);
1044:                OpcodeInfo[opc_invokeinterface_quick] = new OpcodeInfoType(255);
1045:                OpcodeInfo[opc_invokevirtualobject_quick] = new OpcodeInfoType(
1046:                        255);
1047:                OpcodeInfo[opc_invokeignored_quick] = new OpcodeInfoType(
1048:                        opc_invokeignored_quick);
1049:                OpcodeInfo[opc_new_quick] = new OpcodeInfoType(opc_iadd, 0, 1,
1050:                        OpcodeInfoType.CAN_ERROR | OpcodeInfoType.CONSTANT_POOL);
1051:                OpcodeInfo[opc_anewarray_quick] = new OpcodeInfoType(opc_iadd,
1052:                        1, 1, OpcodeInfoType.CAN_ERROR
1053:                                | OpcodeInfoType.CONSTANT_POOL);
1054:                OpcodeInfo[opc_multianewarray_quick] = new OpcodeInfoType(255);
1055:                OpcodeInfo[opc_checkcast_quick] = new OpcodeInfoType(opc_iadd,
1056:                        1, 1, OpcodeInfoType.CAN_ERROR
1057:                                | OpcodeInfoType.CONSTANT_POOL);
1058:                OpcodeInfo[opc_instanceof _quick] = new OpcodeInfoType(opc_iadd,
1059:                        1, 1, OpcodeInfoType.CONSTANT_POOL);
1060:                OpcodeInfo[opc_invokevirtual_quick_w] = new OpcodeInfoType(255);
1061:                OpcodeInfo[opc_getfield_quick_w] = new OpcodeInfoType(
1062:                        opc_getfield_quick_w);
1063:                OpcodeInfo[opc_putfield_quick_w] = new OpcodeInfoType(
1064:                        opc_getfield_quick_w);
1065:                OpcodeInfo[opc_nonnull_quick] = new OpcodeInfoType(
1066:                        opc_nonnull_quick);
1067:                OpcodeInfo[opc_agetfield_quick] = new OpcodeInfoType(opc_iadd,
1068:                        1, 1, OpcodeInfoType.NULL_CHECK);
1069:                OpcodeInfo[opc_aputfield_quick] = new OpcodeInfoType(opc_iadd,
1070:                        2, 0, OpcodeInfoType.NULL_CHECK);
1071:                OpcodeInfo[opc_invokestatic_checkinit_quick] = new OpcodeInfoType(
1072:                        255);
1073:                OpcodeInfo[opc_getstatic_checkinit_quick] = new OpcodeInfoType(
1074:                        255);
1075:                OpcodeInfo[opc_putstatic_checkinit_quick] = new OpcodeInfoType(
1076:                        255);
1077:                OpcodeInfo[opc_agetstatic_checkinit_quick] = new OpcodeInfoType(
1078:                        255);
1079:                OpcodeInfo[opc_aputstatic_checkinit_quick] = new OpcodeInfoType(
1080:                        255);
1081:                OpcodeInfo[opc_getstatic2_checkinit_quick] = new OpcodeInfoType(
1082:                        255);
1083:                OpcodeInfo[opc_putstatic2_checkinit_quick] = new OpcodeInfoType(
1084:                        255);
1085:                OpcodeInfo[opc_new_checkinit_quick] = new OpcodeInfoType(255);
1086:                OpcodeInfo[opc_exittransition] = new OpcodeInfoType(255);
1087:            };
1088:
1089:            static OpcodeInfoType[] OpcodeInfoSpecial = {
1090:                    /* getfield_quick    */new OpcodeInfoType(opc_iadd, 1, 1,
1091:                            OpcodeInfoType.NULL_CHECK
1092:                                    | OpcodeInfoType.CONSTANT_POOL),
1093:                    /* putfield_quick    */new OpcodeInfoType(opc_iadd, 2, 0,
1094:                            OpcodeInfoType.NULL_CHECK
1095:                                    | OpcodeInfoType.CONSTANT_POOL),
1096:                    /* getfield2_quick   */new OpcodeInfoType(opc_iadd, 1, 2,
1097:                            OpcodeInfoType.NULL_CHECK
1098:                                    | OpcodeInfoType.CONSTANT_POOL),
1099:                    /* putfield2_quick   */new OpcodeInfoType(opc_iadd, 3, 0,
1100:                            OpcodeInfoType.NULL_CHECK
1101:                                    | OpcodeInfoType.CONSTANT_POOL) };
1102:
1103:            /**
1104:             * Print the code as Java assembly language instructions
1105:             */
1106:            String disassembleInlining() {
1107:                byte codeBytes[] = new byte[3];
1108:                // Copy inlining into codeBytes[] buffer
1109:                codeBytes[0] = (byte) (inlining & 0xff);
1110:                codeBytes[1] = (byte) ((inlining >> 8) & 0xff);
1111:                codeBytes[2] = (byte) ((inlining >> 16) & 0xff);
1112:                return MethodInfo.disassemble(codeBytes, 0, 3);
1113:            }
1114:
1115:            private String myName;
1116:
1117:            public String toString() {
1118:                if (myName == null) {
1119:                    myName = method.parent.className + "." + method.name.string
1120:                            + method.type.string;
1121:                }
1122:                return myName;
1123:            }
1124:
1125:            static int total = 0;
1126:
1127:            // After inlining some code, we try to see if we can remove code.  For
1128:            // example, the frequent case of opc_aload_0 invokeingored_quick #1 T can
1129:            // simply "go away"
1130:
1131:            final boolean compress() {
1132:                MethodInfo mb = method;
1133:                boolean rewritten = false;
1134:                byte[] code = mb.code;
1135:                int[] stack = new int[mb.stack + 1];
1136:                int stackHeight = 0;
1137:                int nextpc;
1138:                java.util.BitSet targets = mb.getLabelTargets();
1139:
1140:                for (int pc = 0; pc < code.length; pc = nextpc) {
1141:                    nextpc = pc + mb.opcodeLength(pc);
1142:                    int opcode = code[pc] & 0xff;
1143:                    int popping = 0;
1144:                    boolean checkThis = false;
1145:
1146:                    if (targets.get(pc)) {
1147:                        stackHeight = 0;
1148:                    }
1149:                    stack[stackHeight] = pc;
1150:
1151:                    // Invariant.  the stackheight at this point is stackHeight or less.
1152:                    // 
1153:                    // We can pop n items from the stack (where n <= stackHeight) by
1154:                    // simply deleting all the code from stackHeight[n] to this point
1155:                    // in the code.  No side effects are removed.
1156:                    // 
1157:                    // Note that instructions that have a side effect should set
1158:                    // stackHeight = 0, to indicate that it can't be deleted.
1159:
1160:                    switch (opcode) {
1161:                    case opc_nop:
1162:                    case opc_ineg:
1163:                    case opc_fneg:
1164:                    case opc_i2f:
1165:                    case opc_f2i:
1166:                    case opc_i2b:
1167:                    case opc_i2c:
1168:                    case opc_i2s:
1169:                    case opc_newarray:
1170:                    case opc_anewarray_quick:
1171:                    case opc_instanceof _quick:
1172:                    case opc_lneg:
1173:                    case opc_dneg:
1174:                    case opc_l2d:
1175:                    case opc_d2l:
1176:                        // these don't change stack height, and we know as much about
1177:                        // the stack before as we do after.
1178:                        break;
1179:
1180:                    case opc_aconst_null:
1181:                    case opc_iconst_m1:
1182:                    case opc_iconst_0:
1183:                    case opc_iconst_1:
1184:                    case opc_iconst_2:
1185:                    case opc_iconst_3:
1186:                    case opc_iconst_4:
1187:                    case opc_iconst_5:
1188:                    case opc_fconst_0:
1189:                    case opc_fconst_1:
1190:                    case opc_fconst_2:
1191:                    case opc_bipush:
1192:                    case opc_sipush:
1193:                    case opc_iload:
1194:                    case opc_fload:
1195:                    case opc_aload:
1196:                    case opc_iload_0:
1197:                    case opc_iload_1:
1198:                    case opc_iload_2:
1199:                    case opc_iload_3:
1200:                    case opc_fload_0:
1201:                    case opc_fload_1:
1202:                    case opc_fload_2:
1203:                    case opc_fload_3:
1204:                    case opc_aload_0:
1205:                    case opc_aload_1:
1206:                    case opc_aload_2:
1207:                    case opc_aload_3:
1208:                    case opc_ldc_quick:
1209:                    case opc_ldc_w_quick:
1210:                    case opc_aldc_quick:
1211:                    case opc_aldc_w_quick:
1212:                    case opc_aldc_ind_quick:
1213:                    case opc_aldc_ind_w_quick:
1214:                    case opc_getstatic_quick:
1215:                    case opc_agetstatic_quick:
1216:                    case opc_dup:
1217:                        // These push some value onto the stack, no matter what was
1218:                        // there before
1219:                        stackHeight += 1;
1220:                        break;
1221:
1222:                    case opc_lconst_0:
1223:                    case opc_lconst_1:
1224:                    case opc_dconst_0:
1225:                    case opc_dconst_1:
1226:                    case opc_lload:
1227:                    case opc_dload:
1228:                    case opc_lload_0:
1229:                    case opc_lload_1:
1230:                    case opc_lload_2:
1231:                    case opc_lload_3:
1232:                    case opc_dload_0:
1233:                    case opc_dload_1:
1234:                    case opc_dload_2:
1235:                    case opc_dload_3:
1236:                    case opc_ldc2_w_quick:
1237:                    case opc_getstatic2_quick:
1238:                        // These push two values onto the stack, no matter what was 
1239:                        // there before.
1240:                        stackHeight += 2;
1241:                        break;
1242:
1243:                    case opc_i2l:
1244:                    case opc_i2d:
1245:                    case opc_f2l:
1246:                    case opc_f2d:
1247:                        // if we knew the top element of the stack, we know more
1248:                        stackHeight = (stackHeight < 1) ? 0 : stackHeight + 1;
1249:                        break;
1250:
1251:                    case opc_iadd:
1252:                    case opc_fadd:
1253:                    case opc_isub:
1254:                    case opc_fsub:
1255:                    case opc_imul:
1256:                    case opc_fmul:
1257:                    case opc_fdiv:
1258:                    case opc_frem:
1259:                    case opc_ishl:
1260:                    case opc_ishr:
1261:                    case opc_iushr:
1262:                    case opc_iand:
1263:                    case opc_ior:
1264:                    case opc_ixor:
1265:                    case opc_l2i:
1266:                    case opc_l2f:
1267:                    case opc_d2i:
1268:                    case opc_d2f:
1269:                    case opc_fcmpl:
1270:                    case opc_fcmpg:
1271:                        // if we knew the top two elements of the stack, the stack
1272:                        // has just shrunk
1273:                        stackHeight = (stackHeight < 2) ? 0 : stackHeight - 1;
1274:                        break;
1275:
1276:                    case opc_lshl:
1277:                    case opc_lshr:
1278:                    case opc_lushr:
1279:                        // if we knew the top three elements of the stack, we now
1280:                        // know the top two
1281:                        stackHeight = (stackHeight < 3) ? 0 : stackHeight - 1;
1282:                        break;
1283:
1284:                    case opc_lcmp:
1285:                    case opc_dcmpl:
1286:                    case opc_dcmpg:
1287:                        // if we knew the top 4 elements of the stack, we now
1288:                        // know the top element
1289:                        stackHeight = (stackHeight < 4) ? 0 : stackHeight - 3;
1290:                        break;
1291:
1292:                    case opc_ladd:
1293:                    case opc_dadd:
1294:                    case opc_lsub:
1295:                    case opc_dsub:
1296:                    case opc_lmul:
1297:                    case opc_dmul:
1298:                    case opc_ddiv:
1299:                    case opc_drem:
1300:                    case opc_land:
1301:                    case opc_lor:
1302:                    case opc_lxor:
1303:                        // if we knew the top 4 elements of the stack, we now
1304:                        // know the top 2
1305:                        stackHeight = (stackHeight < 4) ? 0 : stackHeight - 2;
1306:                        break;
1307:
1308:                    // The dup's (other than opc_dup) deal with the stack in 
1309:                    // a way that's not worth the hassle of dealing with.
1310:
1311:                    case opc_getfield_quick:
1312:                    case opc_agetfield_quick:
1313:                    case opc_arraylength:
1314:                        // If we throw away the result, then we just need to check that
1315:                        // the value is non-null.
1316:                        if (code[nextpc] == (byte) (opc_pop)) {
1317:                            checkThis = true;
1318:                            nextpc += 1;
1319:                        } else {
1320:                            stackHeight = 0;
1321:                        }
1322:                        break;
1323:
1324:                    case opc_pop2:
1325:                        popping++; // fall thru
1326:                    case opc_pop:
1327:                        // We have to be careful.  The inliner may produce code that
1328:                        // does correspond to the stack.  For example, it might 
1329:                        // produce "pop pop2" to remove a double then an int.  We need
1330:                        // to deal with series of them at once.
1331:                        if (stackHeight > 0) {
1332:                            popping++;
1333:                            for (;;) {
1334:                                opcode = code[++pc] & 0xFF;
1335:                                if (opcode == opc_pop)
1336:                                    popping++;
1337:                                else if (opcode == opc_pop2)
1338:                                    popping += 2;
1339:                                else
1340:                                    break;
1341:                            }
1342:                            nextpc = pc;
1343:                        }
1344:                        break;
1345:
1346:                    case opc_invokeignored_quick:
1347:                        popping = code[pc + 1] & 0xff;
1348:                        if (code[pc + 2] != 0) {
1349:                            checkThis = true;
1350:                            popping--;
1351:                        }
1352:                        break;
1353:
1354:                    default:
1355:                        stackHeight = 0;
1356:                    }
1357:
1358:                    if (checkThis || (popping > 0 && stackHeight > 0)) {
1359:                        rewritten = true;
1360:                        if (stackHeight >= popping) {
1361:                            stackHeight -= popping;
1362:                            popping = 0;
1363:                        } else {
1364:                            popping -= stackHeight;
1365:                            stackHeight = 0;
1366:                        }
1367:                        int start = stack[stackHeight];
1368:
1369:                        if (checkThis) {
1370:                            if (popping == 0 && (nextpc - start != 3)) {
1371:                                mb
1372:                                        .replaceCode(start, nextpc,
1373:                                                opc_nonnull_quick);
1374:                            } else {
1375:                                mb
1376:                                        .replaceCode(start, nextpc,
1377:                                                opc_invokeignored_quick,
1378:                                                popping + 1, 1);
1379:                            }
1380:                            stackHeight = 0;
1381:                        } else {
1382:                            switch (popping) {
1383:                            case 0:
1384:                                mb.replaceCode(start, nextpc);
1385:                                break;
1386:                            case 1:
1387:                                mb.replaceCode(start, nextpc, opc_pop);
1388:                                break;
1389:                            case 2:
1390:                                mb.replaceCode(start, nextpc, opc_pop2);
1391:                                break;
1392:                            default:
1393:                                mb.replaceCode(start, nextpc,
1394:                                        opc_invokeignored_quick, popping, 0);
1395:                                break;
1396:                            }
1397:                        }
1398:                    }
1399:                }
1400:                return rewritten;
1401:            }
1402:        }
1403:
1404:        /**
1405:         * Class used for inlining info.  See inlining code in MethodInfo
1406:         */
1407:        class OpcodeInfoType {
1408:            int opcode; // really the opcode type
1409:            int inStack;
1410:            int outStack;
1411:
1412:            static final int CAN_ERROR = 0x01; /* can give error in addition to
1413:            				   NULL_CHECK */
1414:            static final int NULL_CHECK = 0x02; /* checks that first arg isn't null */
1415:            static final int CONSTANT_POOL = 0x04; /* uses the constant pool */
1416:            int flags;
1417:
1418:            OpcodeInfoType(int opcode, int inStack, int outStack, int flags) {
1419:                this .opcode = opcode;
1420:                this .inStack = inStack;
1421:                this .outStack = outStack;
1422:                this .flags = flags;
1423:            }
1424:
1425:            OpcodeInfoType(int opcode, int inStack, int outStack) {
1426:                this (opcode, inStack, outStack, 0);
1427:            }
1428:
1429:            OpcodeInfoType(int opcode, int inStack) {
1430:                this (opcode, inStack, 0, 0);
1431:            }
1432:
1433:            OpcodeInfoType(int opcode) {
1434:                this (opcode, 0, 0, 0);
1435:            }
1436:        };
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.