Source Code Cross Referenced for Peephole.java in  » Database-DBMS » db4o-6.4 » EDU » purdue » cs » bloat » trans » 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 » Database DBMS » db4o 6.4 » EDU.purdue.cs.bloat.trans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com
002:
003:        This file is part of the db4o open source object database.
004:
005:        db4o is free software; you can redistribute it and/or modify it under
006:        the terms of version 2 of the GNU General Public License as published
007:        by the Free Software Foundation and as clarified by db4objects' GPL 
008:        interpretation policy, available at
009:        http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010:        Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011:        Suite 350, San Mateo, CA 94403, USA.
012:
013:        db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014:        WARRANTY; without even the implied warranty of MERCHANTABILITY or
015:        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
016:        for more details.
017:
018:        You should have received a copy of the GNU General Public License along
019:        with this program; if not, write to the Free Software Foundation, Inc.,
020:        59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */
021:        package EDU.purdue.cs.bloat.trans;
022:
023:        import java.util.*;
024:
025:        import EDU.purdue.cs.bloat.editor.*;
026:        import EDU.purdue.cs.bloat.util.*;
027:
028:        /**
029:         * Performs some peephole optimizations such as loads and stores and removes
030:         * unreachable instructions.
031:         */
032:        public class Peephole implements  Opcode {
033:            public static boolean DEBUG = false;
034:
035:            /**
036:             * Perform peephole optimizations on the bytecodes in a method. Peephole
037:             * optimizations look at two consecutive instructions and try to perform
038:             * some simple optimization. For instance, a push followed by a pop is
039:             * uninteresting, so both of those instructions can be removed.
040:             * 
041:             * <p>
042:             * 
043:             * After the peephole optimizations are performed a final phase removes
044:             * instructions that are not reachable. These instructions reside in basic
045:             * blocks whose starting label is never jumped to.
046:             */
047:            public static void transform(final MethodEditor method) {
048:                if (Peephole.DEBUG) {
049:                    System.out.println("Peephole optimizing " + method);
050:                }
051:
052:                // Map between labels and the instruction that they label
053:                final Map targets = new HashMap();
054:
055:                final LinkedList jumps = new LinkedList(); // Jump instructions
056:
057:                Instruction next = null;
058:                Instruction nextInst = null;
059:
060:                final List code = method.code();
061:
062:                // Go backwards so we can eliminate redundant loads and stores
063:                // in one pass. During the pass collect the locations of labels.
064:
065:                CODE: for (int i = code.size() - 1; i >= 0; i--) {
066:                    final Object ce = code.get(i);
067:
068:                    if (ce instanceof  Label) {
069:                        if (nextInst != null) {
070:                            targets.put(ce, nextInst);
071:                        }
072:
073:                        next = null;
074:
075:                    } else if (ce instanceof  Instruction) {
076:                        final Instruction inst = (Instruction) ce;
077:
078:                        Filter peep = null;
079:
080:                        // Have we seen a label that starts a block? (i.e. is a target)
081:                        boolean seenLabel = false;
082:
083:                        if (inst.isGoto()) {
084:                            // Look at the instructions following the goto. If an
085:                            // instruction follows and no label (that starts a block)
086:                            // has been seen, the instruction is dead and can be
087:                            // removed. If the target of the goto follows the goto
088:                            // instruction, the goto is useless and is removed.
089:
090:                            final Label target = (Label) inst.operand();
091:
092:                            for (int j = i + 1; j < code.size(); j++) {
093:                                final Object t = code.get(j);
094:
095:                                // Replace
096:                                // goto L
097:                                // L: inst
098:                                // with
099:                                // L: inst
100:                                //
101:                                if (t instanceof  Label) {
102:                                    if (((Label) t).startsBlock()) {
103:                                        seenLabel = true;
104:                                    }
105:
106:                                    if (target.equals(t)) {
107:                                        code.remove(i);
108:                                        next = null;
109:                                        nextInst = null;
110:                                        continue CODE;
111:                                    }
112:
113:                                    continue;
114:                                }
115:
116:                                // Replace
117:                                // goto L
118:                                // this is unreachable
119:                                // M: inst (M is a different label from L!)
120:                                // with
121:                                // goto L
122:                                // M: inst
123:                                //
124:                                if (t instanceof  Instruction) {
125:                                    if (seenLabel) {
126:                                        break;
127:                                    }
128:
129:                                    code.remove(j);
130:                                    j--;
131:                                }
132:                            }
133:                        }
134:
135:                        if (inst.isGoto() || inst.isSwitch()) {
136:                            jumps.add(inst);
137:                        }
138:
139:                        // Performs some peephole optimizations using the filter
140:                        // method that returns an instance of the Filter class. The
141:                        // filter method looks at two consecutive instructions and
142:                        // determines whether or not something about them can be
143:                        // changed. For instance, if a push is followed by a pop,
144:                        // both instructions are useless and can be eliminated. The
145:                        // contents of the Filter object represents the effects of the
146:                        // peephole optimization.
147:                        if (next != null) {
148:                            peep = Peephole.filter(inst, next);
149:                        }
150:
151:                        if (peep != null) {
152:                            if (ClassEditor.DEBUG) {
153:                                if (peep.replace.length == 0) {
154:                                    System.out.println("eliminate "
155:                                            + code.get(i) + "-"
156:                                            + code.get(i + 1));
157:
158:                                } else {
159:                                    System.out.println("replace " + code.get(i)
160:                                            + "-" + code.get(i + 1));
161:                                    System.out.println("   with");
162:                                    for (int j = 0; j < peep.replace.length; j++) {
163:                                        System.out.println("   "
164:                                                + peep.replace[j]);
165:                                    }
166:                                }
167:                            }
168:
169:                            // Remove old instructions
170:                            code.remove(i + 1);
171:                            code.remove(i);
172:
173:                            // Add new instructions resulting from peephole
174:                            // optimizations
175:                            for (int j = peep.replace.length - 1; j >= 0; j--) {
176:                                code.add(i, peep.replace[j]);
177:                            }
178:
179:                            if ((i < code.size())
180:                                    && (code.get(i) instanceof  Instruction)) {
181:                                next = (Instruction) code.get(i);
182:
183:                            } else {
184:                                // No more instructions, or next thing is a label
185:                                next = null;
186:                            }
187:
188:                        } else {
189:                            // Filter didn't find any peephole optimizations, skip to
190:                            // next pair of instructions.
191:                            next = inst;
192:                        }
193:
194:                        nextInst = next;
195:                    }
196:                }
197:
198:                // Replace the target of jumps to gotos with the goto target.
199:                // Replace gotos to unconditional jumps with the unconditional jump.
200:                while (!jumps.isEmpty()) {
201:                    final Instruction inst = (Instruction) jumps.removeFirst();
202:
203:                    Instruction target;
204:
205:                    if (inst.isGoto()) {
206:                        target = (Instruction) targets.get(inst.operand());
207:
208:                        if (target != null) {
209:                            if (target.isGoto()
210:                                    && !target.operand().equals(inst.operand())) {
211:
212:                                if (ClassEditor.DEBUG) {
213:                                    System.out.println("replace " + inst);
214:                                }
215:
216:                                inst.setOperand(target.operand());
217:
218:                                if (ClassEditor.DEBUG) {
219:                                    System.out.println("   with " + inst);
220:                                }
221:
222:                                jumps.add(inst);
223:
224:                            } else if (target.isSwitch() || target.isReturn()
225:                                    || target.isThrow()) {
226:
227:                                if (ClassEditor.DEBUG) {
228:                                    System.out.println("replace " + inst);
229:                                }
230:
231:                                inst.setOpcodeClass(target.opcodeClass());
232:                                inst.setOperand(target.operand());
233:
234:                                if (ClassEditor.DEBUG) {
235:                                    System.out.println("   with " + inst);
236:                                }
237:                            }
238:                        }
239:                    }
240:                }
241:
242:                // Remove unreachable code.
243:                Peephole.removeUnreachable(method, code);
244:
245:                if (ClassEditor.DEBUG) {
246:                    System.out
247:                            .println("END PEEPHOLE---------------------------------");
248:                }
249:            }
250:
251:            /**
252:             * Iterate over the code in the method and determine which labels begin
253:             * blocks that are reachable. The code in blocks that are not reachable is
254:             * removed.
255:             */
256:            // TODO: Currently, ALL ret targets are marked reachable from a
257:            // single ret. Correct this by looking at the local variables.
258:            private static void removeUnreachable(final MethodEditor method,
259:                    final List code) {
260:                // Maps Labels to their instruction position
261:                final Map labelPos = new HashMap();
262:
263:                // Collect all the ret targets.
264:                Iterator iter = code.iterator();
265:                int i = 0;
266:
267:                while (iter.hasNext()) {
268:                    final Object ce = iter.next();
269:
270:                    if (ce instanceof  Label) {
271:                        labelPos.put(ce, new Integer(i));
272:                    }
273:
274:                    i++;
275:                }
276:
277:                // Visit the blocks depth-first.
278:
279:                // Stack of Labels that begin blocks that have been visited
280:                final Set visited = new HashSet();
281:
282:                // Stack of Labels that begin blocks that have not been visited
283:                final Stack stack = new Stack();
284:
285:                Label label; // Current label
286:
287:                if (code.size() > 0) {
288:                    // Start with the label of the first block
289:                    label = (Label) code.get(0);
290:                    visited.add(label);
291:                    stack.push(label);
292:                }
293:
294:                final Iterator e = method.tryCatches().iterator();
295:
296:                while (e.hasNext()) {
297:                    // All exception handlers are considered to be live
298:                    final TryCatch tc = (TryCatch) e.next();
299:                    visited.add(tc.handler());
300:                    stack.push(tc.handler());
301:                }
302:
303:                while (!stack.isEmpty()) {
304:                    label = (Label) stack.pop();
305:
306:                    final Integer labelIndex = (Integer) labelPos.get(label);
307:                    Assert.isTrue(labelIndex != null, "Index of " + label
308:                            + " not found");
309:
310:                    i = labelIndex.intValue();
311:                    final ListIterator blockIter = code.listIterator(i + 1);
312:
313:                    while (blockIter.hasNext()) {
314:                        // Iterate over the code in the block. If we encounter
315:                        // instructions that change execution (i.e. go to another
316:                        // block), add the Label of the target of the jump to the
317:                        // stack if it is not already present.
318:
319:                        final Object ce = blockIter.next();
320:                        i++;
321:
322:                        if (ce instanceof  Instruction) {
323:                            final Instruction inst = (Instruction) ce;
324:
325:                            if (inst.isReturn() || inst.isThrow()) {
326:                                // We've reached the end of the block, but we don't know
327:                                // which block will be executed next.
328:                                break;
329:
330:                            } else if (inst.isConditionalJump() || inst.isJsr()) {
331:                                // We've reached the end of the block, add the Label of
332:                                // the next block to be executed to the list. It's a
333:                                // conditional jump, so don't break. The rest of the
334:                                // code
335:                                // in the block is not necessarily dead.
336:
337:                                label = (Label) inst.operand();
338:
339:                                if (!visited.contains(label)) {
340:                                    visited.add(label);
341:                                    stack.push(label);
342:                                }
343:
344:                                // Fall through.
345:
346:                            } else if (inst.isGoto()) {
347:                                // Add next block to work list.
348:
349:                                label = (Label) inst.operand();
350:
351:                                if (!visited.contains(label)) {
352:                                    visited.add(label);
353:                                    stack.push(label);
354:                                }
355:
356:                                break;
357:
358:                            } else if (inst.isRet()) {
359:                                // The ret targets were handled by the jsr.
360:                                break;
361:
362:                            } else if (inst.isSwitch()) {
363:                                // A switch. Add all possible targets of the switch to
364:                                // the worklist.
365:
366:                                final Switch sw = (Switch) inst.operand();
367:
368:                                label = sw.defaultTarget();
369:
370:                                if (!visited.contains(label)) {
371:                                    visited.add(label);
372:                                    stack.push(label);
373:                                }
374:
375:                                final Label[] targets = sw.targets();
376:
377:                                for (int j = 0; j < targets.length; j++) {
378:                                    label = targets[j];
379:
380:                                    if (!visited.contains(label)) {
381:                                        visited.add(label);
382:                                        stack.push(label);
383:                                    }
384:                                }
385:
386:                                break;
387:                            }
388:
389:                        } else if (ce instanceof  Label) {
390:                            label = (Label) ce;
391:                            visited.add(label);
392:                        }
393:                    }
394:                }
395:
396:                boolean reachable = false;
397:
398:                iter = code.iterator();
399:
400:                // Remove unreachable instructions
401:                while (iter.hasNext()) {
402:                    final Object ce = iter.next();
403:
404:                    if (ce instanceof  Label) {
405:                        reachable = visited.contains(ce);
406:                        // Don't remove unreachable labels, only instructions.
407:
408:                    } else if (!reachable) {
409:                        if (ClassEditor.DEBUG) {
410:                            System.out.println("Removing unreachable " + ce);
411:                        }
412:
413:                        iter.remove();
414:                    }
415:                }
416:            }
417:
418:            /**
419:             * Filter represents a set of instructions that result from a peephole
420:             * optimizations. For instance, when uninteresting instructions are removed,
421:             * a Filter object with an empty "replace" array will be returned by the
422:             * below filter method.
423:             */
424:            static class Filter {
425:                Instruction[] replace;
426:
427:                Filter() {
428:                    this .replace = new Instruction[0];
429:                }
430:
431:                Filter(final Instruction replace) {
432:                    this .replace = new Instruction[] { replace };
433:                }
434:
435:                Filter(final Instruction replace1, final Instruction replace2) {
436:                    this .replace = new Instruction[] { replace1, replace2 };
437:                }
438:            }
439:
440:            /**
441:             * Filter a pair of instructions. That is, do a peephole optimization on two
442:             * consecutive instructions. For instance, if a push is followed by a pop,
443:             * both instructions can be eliminated. The <tt>Filter</tt> object that is
444:             * returned specifies what instruction(s), if any, should replace the two
445:             * instructions that are the parameters to this method.
446:             * 
447:             * @param first
448:             *            The first instruction.
449:             * @param second
450:             *            The second instruction.
451:             * @return A list of instructions to replace the two instructions with, or
452:             *         null, if the instructions should be left as is.
453:             */
454:            private static Filter filter(final Instruction first,
455:                    final Instruction second) {
456:                switch (second.opcodeClass()) {
457:
458:                // swap means nothing if it's after a dup.
459:                // (goodbye means nothing when it's all for show
460:                // so stop pretending you've somewhere else to go.)
461:
462:                case opcx_swap:
463:                    // Elminate swap-swap
464:                    if (first.opcodeClass() == Opcode.opcx_swap) {
465:                        return new Filter();
466:                    }
467:                    // swap means nothing if it's after a dup.
468:                    // (goodbye means nothing when it's all for show
469:                    // so stop pretending you've somewhere else to go.)
470:                    if (first.opcodeClass() == Opcode.opcx_dup) {
471:                        return new Filter(first);
472:                    }
473:                    break;
474:
475:                // Eliminate push-pop.
476:                case opcx_pop:
477:                    // Eliminate push-pop.
478:
479:                    switch (first.opcodeClass()) {
480:                    case opcx_ldc:
481:                        // Make sure things being popped off is not wide (we're
482:                        // dealing with a pop not a pop2).
483:                        Assert.isTrue(!(first.operand() instanceof  Long)
484:                                && !(first.operand() instanceof  Double),
485:                                "Cannot pop a 2-word operand");
486:                        // Fall through.
487:
488:                    case opcx_iload:
489:                    case opcx_fload:
490:                    case opcx_aload:
491:                    case opcx_dup:
492:                        // Eliminate the load and the pop.
493:                        return new Filter();
494:
495:                    case opcx_dup_x1:
496:                        // Replace dup_x1-pop with swap
497:                        // (As if this is really likely to happen ;) <-- Nate made a
498:                        // joke!
499:                        return new Filter(new Instruction(Opcode.opcx_swap));
500:                    }
501:                    break;
502:
503:                case opcx_pop2:
504:                    switch (first.opcodeClass()) {
505:                    case opcx_ldc:
506:                        Assert.isTrue((first.operand() instanceof  Long)
507:                                || (first.operand() instanceof  Double),
508:                                "Cannot pop2 a 1-word operand");
509:                        // Fall through.
510:
511:                    case opcx_lload:
512:                    case opcx_dload:
513:                    case opcx_dup2:
514:                        // Eliminate push and pop
515:                        return new Filter();
516:                    }
517:                    break;
518:
519:                case opcx_istore:
520:                    // Eliminate load-store to same location.
521:
522:                    if (first.opcodeClass() == Opcode.opcx_iload) {
523:                        if (first.operand().equals(second.operand())) {
524:                            return new Filter();
525:                        }
526:                    }
527:                    break;
528:
529:                case opcx_fstore:
530:                    if (first.opcodeClass() == Opcode.opcx_fload) {
531:                        if (first.operand().equals(second.operand())) {
532:                            return new Filter();
533:                        }
534:                    }
535:                    break;
536:
537:                case opcx_astore:
538:                    if (first.opcodeClass() == Opcode.opcx_aload) {
539:                        if (first.operand().equals(second.operand())) {
540:                            return new Filter();
541:                        }
542:                    }
543:                    break;
544:
545:                case opcx_lstore:
546:                    if (first.opcodeClass() == Opcode.opcx_lload) {
547:                        if (first.operand().equals(second.operand())) {
548:                            return new Filter();
549:                        }
550:                    }
551:                    break;
552:
553:                case opcx_dstore:
554:                    if (first.opcodeClass() == Opcode.opcx_dload) {
555:                        if (first.operand().equals(second.operand())) {
556:                            return new Filter();
557:                        }
558:                    }
559:                    break;
560:
561:                case opcx_ireturn:
562:                case opcx_freturn:
563:                case opcx_areturn:
564:                case opcx_lreturn:
565:                case opcx_dreturn:
566:                    // Replace store-return with return. Remember that upon return
567:                    // all local variables revert to their pre-call values, so any
568:                    // stores are destroyed.
569:
570:                    switch (first.opcodeClass()) {
571:                    case opcx_istore:
572:                    case opcx_fstore:
573:                    case opcx_astore:
574:                    case opcx_lstore:
575:                    case opcx_dstore:
576:                        return new Filter(second);
577:                    }
578:                    break;
579:
580:                case opcx_iadd:
581:                    // Replace ineg-iadd with isub
582:
583:                    if (first.opcodeClass() == Opcode.opcx_ineg) {
584:                        return new Filter(new Instruction(Opcode.opcx_isub));
585:                    }
586:                    break;
587:
588:                case opcx_isub:
589:                    // Replace ineg-isub with iadd
590:
591:                    if (first.opcodeClass() == Opcode.opcx_ineg) {
592:                        return new Filter(new Instruction(Opcode.opcx_iadd));
593:                    }
594:                    break;
595:
596:                case opcx_ladd:
597:                    // Replace lneg-ladd with lsub
598:
599:                    if (first.opcodeClass() == Opcode.opcx_lneg) {
600:                        return new Filter(new Instruction(Opcode.opcx_lsub));
601:                    }
602:                    break;
603:
604:                case opcx_lsub:
605:                    // Replace lneg-lsub with ladd
606:
607:                    if (first.opcodeClass() == Opcode.opcx_lneg) {
608:                        return new Filter(new Instruction(Opcode.opcx_ladd));
609:                    }
610:                    break;
611:
612:                case opcx_if_icmpeq:
613:                    // Replace ldc 0-if_icmpeq with ifeq
614:
615:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
616:                        final Object op = first.operand();
617:                        if (op instanceof  Integer) {
618:                            if (((Integer) op).intValue() == 0) {
619:                                return new Filter(new Instruction(
620:                                        Opcode.opcx_ifeq, second.operand()));
621:                            }
622:                        }
623:                    }
624:                    break;
625:
626:                case opcx_if_icmpne:
627:                    // Replace ldc 0-if_icmpne with ifne
628:
629:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
630:                        final Object op = first.operand();
631:                        if (op instanceof  Integer) {
632:                            if (((Integer) op).intValue() == 0) {
633:                                return new Filter(new Instruction(
634:                                        Opcode.opcx_ifne, second.operand()));
635:                            }
636:                        }
637:                    }
638:                    break;
639:
640:                case opcx_if_icmplt:
641:                    // Replace ldc 0-if_icmplt with iflt
642:
643:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
644:                        final Object op = first.operand();
645:                        if (op instanceof  Integer) {
646:                            if (((Integer) op).intValue() == 0) {
647:                                return new Filter(new Instruction(
648:                                        Opcode.opcx_iflt, second.operand()));
649:                            }
650:                        }
651:                    }
652:                    break;
653:
654:                case opcx_if_icmpge:
655:                    // Replace ldc 0-if_icmpge with ifge
656:
657:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
658:                        final Object op = first.operand();
659:                        if (op instanceof  Integer) {
660:                            if (((Integer) op).intValue() == 0) {
661:                                return new Filter(new Instruction(
662:                                        Opcode.opcx_ifge, second.operand()));
663:                            }
664:                        }
665:                    }
666:                    break;
667:
668:                case opcx_if_icmpgt:
669:                    // Replace ldc 0-if_icmpgt with ifgt
670:
671:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
672:                        final Object op = first.operand();
673:                        if (op instanceof  Integer) {
674:                            if (((Integer) op).intValue() == 0) {
675:                                return new Filter(new Instruction(
676:                                        Opcode.opcx_ifgt, second.operand()));
677:                            }
678:                        }
679:                    }
680:                    break;
681:
682:                case opcx_if_icmple:
683:                    // Replace ldc 0-if_icmple with ifle
684:
685:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
686:                        final Object op = first.operand();
687:                        if (op instanceof  Integer) {
688:                            if (((Integer) op).intValue() == 0) {
689:                                return new Filter(new Instruction(
690:                                        Opcode.opcx_ifle, second.operand()));
691:                            }
692:                        }
693:                    }
694:                    break;
695:
696:                case opcx_if_acmpeq:
697:                    // Replace ldc null-if_acmpeq with ifnull
698:
699:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
700:                        if (first.operand() == null) {
701:                            return new Filter(new Instruction(
702:                                    Opcode.opcx_ifnull, second.operand()));
703:                        }
704:                    }
705:                    break;
706:
707:                case opcx_if_acmpne:
708:                    // Replace ldc null-if_acmpne with ifnonnull
709:
710:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
711:                        if (first.operand() == null) {
712:                            return new Filter(new Instruction(
713:                                    Opcode.opcx_ifnonnull, second.operand()));
714:                        }
715:                    }
716:                    break;
717:
718:                case opcx_ifeq:
719:                    // Replace ldc 0-ifeq with goto and eliminate ldc !0-ifeq
720:
721:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
722:                        final Object op = first.operand();
723:                        if (op instanceof  Integer) {
724:                            if (((Integer) op).intValue() == 0) {
725:                                return new Filter(new Instruction(
726:                                        Opcode.opcx_goto, second.operand()));
727:                            } else {
728:                                return new Filter();
729:                            }
730:                        }
731:                    }
732:                    break;
733:
734:                case opcx_ifne:
735:                    // Replace ldc !0-ifne with goto and eliminate ldc 0-ifne
736:
737:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
738:                        final Object op = first.operand();
739:                        if (op instanceof  Integer) {
740:                            if (((Integer) op).intValue() != 0) {
741:                                return new Filter(new Instruction(
742:                                        Opcode.opcx_goto, second.operand()));
743:                            } else {
744:                                return new Filter();
745:                            }
746:                        }
747:                    }
748:                    break;
749:
750:                case opcx_iflt:
751:                    // Replace ldc <0-iflt with goto and eliminate ldc >=0-iflt
752:
753:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
754:                        final Object op = first.operand();
755:                        if (op instanceof  Integer) {
756:                            if (((Integer) op).intValue() < 0) {
757:                                return new Filter(new Instruction(
758:                                        Opcode.opcx_goto, second.operand()));
759:                            } else {
760:                                return new Filter();
761:                            }
762:                        }
763:                    }
764:                    break;
765:
766:                case opcx_ifge:
767:                    // Replace ldc >=0-ifge with goto and eliminate ldc <0-ifge
768:
769:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
770:                        final Object op = first.operand();
771:                        if (op instanceof  Integer) {
772:                            if (((Integer) op).intValue() >= 0) {
773:                                return new Filter(new Instruction(
774:                                        Opcode.opcx_goto, second.operand()));
775:                            } else {
776:                                return new Filter();
777:                            }
778:                        }
779:                    }
780:                    break;
781:
782:                case opcx_ifgt:
783:                    // Replace ldc >0-ifgt with goto and eliminate ldc <=0-ifgt
784:
785:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
786:                        final Object op = first.operand();
787:                        if (op instanceof  Integer) {
788:                            if (((Integer) op).intValue() > 0) {
789:                                return new Filter(new Instruction(
790:                                        Opcode.opcx_goto, second.operand()));
791:                            } else {
792:                                return new Filter();
793:                            }
794:                        }
795:                    }
796:                    break;
797:
798:                case opcx_ifle:
799:                    // Replace ldc <=0-ifle with goto and eliminate ldc >0-ifle
800:
801:                    if (first.opcodeClass() == Opcode.opcx_ldc) {
802:                        final Object op = first.operand();
803:                        if (op instanceof  Integer) {
804:                            if (((Integer) op).intValue() <= 0) {
805:                                return new Filter(new Instruction(
806:                                        Opcode.opcx_goto, second.operand()));
807:                            } else {
808:                                return new Filter();
809:                            }
810:                        }
811:                    }
812:                    break;
813:                }
814:
815:                switch (second.opcodeClass()) {
816:                // Replace store-store to same location with pop-store.
817:
818:                case opcx_istore:
819:                case opcx_fstore:
820:                case opcx_astore:
821:                case opcx_lstore:
822:                case opcx_dstore:
823:                    switch (first.opcodeClass()) {
824:                    case opcx_istore:
825:                    case opcx_fstore:
826:                    case opcx_astore:
827:                        if (first.operand().equals(second.operand())) {
828:                            return new Filter(new Instruction(Opcode.opcx_pop),
829:                                    first);
830:                        }
831:                        break;
832:                    case opcx_lstore:
833:                    case opcx_dstore:
834:                        if (first.operand().equals(second.operand())) {
835:                            return new Filter(
836:                                    new Instruction(Opcode.opcx_pop2), first);
837:                        }
838:                        break;
839:                    }
840:                    break;
841:                }
842:
843:                switch (second.opcodeClass()) {
844:                // Replace store-load with dup-store.
845:                // Replace load-load with load-dup.
846:                case opcx_iload:
847:                    if (first.opcodeClass() == Opcode.opcx_istore) {
848:                        if (first.operand().equals(second.operand())) {
849:                            return new Filter(new Instruction(Opcode.opcx_dup),
850:                                    first);
851:                        }
852:                    }
853:                    if (first.opcodeClass() == Opcode.opcx_iload) {
854:                        if (first.operand().equals(second.operand())) {
855:                            return new Filter(first, new Instruction(
856:                                    Opcode.opcx_dup));
857:                        }
858:                    }
859:                    break;
860:
861:                case opcx_fload:
862:                    if (first.opcodeClass() == Opcode.opcx_fstore) {
863:                        if (first.operand().equals(second.operand())) {
864:                            return new Filter(new Instruction(Opcode.opcx_dup),
865:                                    first);
866:                        }
867:                    }
868:                    if (first.opcodeClass() == Opcode.opcx_fload) {
869:                        if (first.operand().equals(second.operand())) {
870:                            return new Filter(first, new Instruction(
871:                                    Opcode.opcx_dup));
872:                        }
873:                    }
874:                    break;
875:
876:                case opcx_aload:
877:                    if (first.opcodeClass() == Opcode.opcx_astore) {
878:                        if (first.operand().equals(second.operand())) {
879:                            return new Filter(new Instruction(Opcode.opcx_dup),
880:                                    first);
881:                        }
882:                    }
883:                    if (first.opcodeClass() == Opcode.opcx_aload) {
884:                        if (first.operand().equals(second.operand())) {
885:                            return new Filter(first, new Instruction(
886:                                    Opcode.opcx_dup));
887:                        }
888:                    }
889:                    break;
890:
891:                case opcx_lload:
892:                    if (first.opcodeClass() == Opcode.opcx_lstore) {
893:                        if (first.operand().equals(second.operand())) {
894:                            return new Filter(
895:                                    new Instruction(Opcode.opcx_dup2), first);
896:                        }
897:                    }
898:                    if (first.opcodeClass() == Opcode.opcx_lload) {
899:                        if (first.operand().equals(second.operand())) {
900:                            return new Filter(first, new Instruction(
901:                                    Opcode.opcx_dup2));
902:                        }
903:                    }
904:                    break;
905:
906:                case opcx_dload:
907:                    if (first.opcodeClass() == Opcode.opcx_dstore) {
908:                        if (first.operand().equals(second.operand())) {
909:                            return new Filter(
910:                                    new Instruction(Opcode.opcx_dup2), first);
911:                        }
912:                    }
913:                    if (first.opcodeClass() == Opcode.opcx_dload) {
914:                        if (first.operand().equals(second.operand())) {
915:                            return new Filter(first, new Instruction(
916:                                    Opcode.opcx_dup2));
917:                        }
918:                    }
919:                    break;
920:                }
921:
922:                return null;
923:            }
924:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.