Source Code Cross Referenced for BytecodeCollector.java in  » Test-Coverage » Quilt » org » quilt » cl » 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 » Test Coverage » Quilt » org.quilt.cl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* BytecodeCollector.java */
002:
003:        package org.quilt.cl;
004:
005:        import java.util.HashMap;
006:        import java.util.HashSet;
007:        import java.util.Iterator;
008:        import java.util.List;
009:        import java.util.Map;
010:        import java.util.Set;
011:        import java.util.Vector;
012:
013:        import org.apache.bcel.classfile.*;
014:        import org.apache.bcel.generic.*;
015:
016:        import org.quilt.graph.*;
017:
018:        /**
019:         * Collects the bytecode for a method while walking the method
020:         * control flow graph.
021:         *
022:         * Inspired by Quilt 0.5's BytecodeLayout,
023:         * @author <a href="mailto:ddp@apache.org">David Dixon-Peugh</a> and the
024:         * rest of the Quilt development team.
025:         *
026:         * However, errors and omissions in this version are entirely due to
027:         * @author <a href="mailto:jddixon@users.sourceforge.net">Jim Dixon</a>
028:         */
029:
030:        public class BytecodeCollector implements  org.quilt.graph.Visitor {
031:
032:            private ControlFlowGraph graph = null;
033:
034:            private Map startHandles = null;
035:            private Map endHandles = null;
036:            private Map gotoFixMeUps = null;
037:            private InstructionList ilist = null;
038:
039:            /** No-arg constructor. */
040:            public BytecodeCollector() {
041:            }
042:
043:            /**
044:             * Action taken upon beginning to visit the graph.
045:             * @param g Directed graph to be visited.
046:             */
047:            public void discoverGraph(Directed g) {
048:                graph = (ControlFlowGraph) g;
049:                ilist = graph.getInstructionList();
050:                startHandles = graph.getStartHandles();
051:                endHandles = graph.getEndHandles();
052:                gotoFixMeUps = graph.getGotoFixMeUps();
053:            }
054:
055:            /**
056:             * Action taken upon beginning to visit a graph vertex.  Unless
057:             * this is an Entry or Exit vertex, save the starting position in
058:             * the bytecode to give a offset for edges with this vertex as target.
059:             * Save the end instruction in the bytecode so that we can insert any
060:             * connector code their later, in finishVertex.
061:             *
062:             * Entry and Exit vertices carry no bytecode and never have a
063:             * connecting instruction, so they can be ignored when collecting
064:             * code.
065:             *
066:             * @param v The vertex; carries a block of code and a final
067:             *          instruction in its Connector.
068:             */
069:            public void discoverVertex(Vertex vtx) {
070:                if (vtx == null) {
071:                    throw new IllegalArgumentException("null vertex");
072:                }
073:                // no code in Entry or Exit vertices
074:                if (!(vtx instanceof  Entry || vtx instanceof  Exit)) {
075:                    CodeVertex v = (CodeVertex) vtx;
076:                    InstructionList vIList = v.getInstructionList();
077:                    InstructionHandle vStart = null;
078:
079:                    if (vIList.size() == 0) {
080:                        vIList = new InstructionList(new NOP());
081:                    }
082:                    vStart = ilist.append(vIList); // consumes vIList
083:                    if (vStart == null) {
084:                        System.out
085:                                .println("discoverVertex INTERNAL ERROR: vertex "
086:                                        + v
087:                                        + " has null position in bytecode\n");
088:                    }
089:                    // DEBUG
090:                    // System.out.println("discoverVertex " + v + " - adding vStart");
091:                    if (vStart == null) {
092:                        System.out.println("    ** vStart is null **");
093:                    }
094:                    // END
095:                    startHandles.put(v, vStart); // v a CodeVertex
096:
097:                    Instruction inst = v.getConnInst();
098:                    if (inst != null) {
099:                        // CONSOLIDATE THESE ////////////////////////////////
100:                        if (inst instanceof  GotoInstruction) {
101:                            BranchHandle bh = ilist
102:                                    .append((GotoInstruction) inst);
103:                            endHandles.put(v, bh);
104:                        } else if (inst instanceof  IfInstruction) {
105:                            BranchHandle bh = ilist
106:                                    .append((IfInstruction) inst);
107:                            endHandles.put(v, bh);
108:                        } else if (inst instanceof  JsrInstruction) {
109:                            BranchHandle bh = ilist
110:                                    .append((JsrInstruction) inst);
111:                            endHandles.put(v, bh);
112:                        } else if (inst instanceof  Select) {
113:                            BranchHandle bh = ilist.append((Select) inst);
114:                            endHandles.put(v, bh);
115:                        } else if ((inst instanceof  ExceptionThrower)
116:                                || (inst instanceof  ReturnInstruction)
117:                                || (inst instanceof  RET)
118:                                || (inst instanceof  InvokeInstruction)) {
119:                            InstructionHandle ih = ilist.append(inst);
120:                            endHandles.put(v, ih);
121:                        } else {
122:                            ilist.append(inst);
123:                        }
124:                    }
125:                }
126:            }
127:
128:            /**
129:             * Action taken upon first encountering an edge.
130:             * @param e A FlowControlEdge, a weighted, directed edge.
131:             */
132:            public void discoverEdge(Edge e) {
133:            }
134:
135:            /**
136:             * Action taken before departing an edge.
137:             *
138:             * @param e The control flow graph edge.
139:             */
140:            public void finishEdge(Edge e) {
141:            }
142:
143:            /**
144:             * Where the immediate target of an edge is an Entry or Exit,
145:             * determine the ultimate target.  That is, follow preferred
146:             * edges until a code Vertex (neither Entry nor Exit) is found
147:             * and return that.  XXX Should throw exception if target becomes
148:             * null.
149:             *
150:             * @param e Edge we are searching along.
151:             * @return  Ultimate target of the edge.
152:             */
153:            private CodeVertex getEffectiveTarget(final Edge e) {
154:                Vertex target = e.getTarget();
155:                // DEBUG
156:                //System.out.println (
157:                //            "getEffectiveTarget: initially target is " + target);
158:                // END
159:                while (target != null
160:                        && (target instanceof  Entry || target instanceof  Exit)) {
161:                    // DEBUG
162:                    // System.out.print ("    replacing " + target + " with");
163:                    // END
164:
165:                    target = target.getTarget();
166:
167:                    //System.out.println (" " + target );   // DEBUG too ;-)
168:                }
169:                // DEBUG
170:                // System.out.println ("    returning: " + target);
171:                // END
172:                return (CodeVertex) target;
173:            }
174:
175:            /**
176:             * Action taken before leaving a vertex in the graph.  The
177:             * connection instruction, if any, is fixed up by setting
178:             * its target(s).
179:             *
180:             * If the connection instruction is a goto, which might jump
181:             * into another graph, fixup is delayed until the user asks
182:             * for the instruction list, when the processing of all graphs
183:             * has been completed.
184:             *
185:             * @see CodeVertex.getInstructionList
186:             * @param v The vertex, either an Entry or Exit vertex, or a
187:             *          code vertex.
188:             */
189:            public void finishVertex(Vertex vtx) {
190:                if (vtx instanceof  CodeVertex) {
191:                    CodeVertex v = (CodeVertex) vtx;
192:                    Instruction inst = v.getConnInst();
193:                    if (inst != null) {
194:                        if (inst instanceof  GotoInstruction) {
195:                            //                  // DEBUG
196:                            //                  Connector conn = v.getConnector();
197:                            //                  System.out.println("GotoInstruction in vertex " + v);
198:                            //                  if (conn instanceof UnaryConnector) {
199:                            //                      System.out.println("  has unary connector!!");
200:                            //                  } else if (conn instanceof BinaryConnector) {
201:                            //                      System.out.println("  has binary connector");
202:                            //                      System.out.println ("  'other' edge: "
203:                            //                          + ((BinaryConnector)conn).getOtherEdge());
204:                            //                  }
205:                            //                  // END
206:                            CodeVertex effTarget = getEffectiveTarget(((BinaryConnector) v
207:                                    .getConnector()).getOtherEdge());
208:                            InstructionHandle target = (InstructionHandle) startHandles
209:                                    .get(effTarget);
210:                            gotoFixMeUps.put(v, effTarget); // delayed fixup
211:
212:                        } else if (inst instanceof  IfInstruction) {
213:                            Edge workingEdge = ((BinaryConnector) v
214:                                    .getConnector()).getOtherEdge();
215:                            InstructionHandle target = (InstructionHandle) startHandles
216:                                    .get(getEffectiveTarget(workingEdge));
217:                            BranchHandle bh = (BranchHandle) endHandles.get(v);
218:                            bh.setTarget(target);
219:
220:                        } else if (inst instanceof  JsrInstruction) {
221:                            InstructionHandle target = (InstructionHandle) startHandles
222:                                    .get(getEffectiveTarget(v.getEdge()));
223:                            BranchHandle bh = (BranchHandle) endHandles.get(v);
224:                            bh.setTarget(target);
225:
226:                        } else if (inst instanceof  Select) {
227:                            // has a complex connector - deal with default edge
228:                            InstructionHandle target = (InstructionHandle) startHandles
229:                                    .get(getEffectiveTarget(v.getEdge()));
230:                            // DEBUG
231:                            //              if (target == null) {
232:                            //                  System.out.println(
233:                            //                      "BytecodeCollector.finishVertex "
234:                            //                      + v + " INTERNAL ERROR: \n"
235:                            //                      + "    " + inst + " has null default target");
236:                            //              }
237:                            // END
238:                            BranchHandle bh = (BranchHandle) endHandles.get(v);
239:                            bh.setTarget(target);
240:
241:                            // now take care of the other edges
242:                            ComplexConnector conn = (ComplexConnector) v
243:                                    .getConnector();
244:                            int edgeCount = conn.size();
245:                            InstructionHandle[] targets = new InstructionHandle[edgeCount];
246:                            for (int i = 0; i < edgeCount; i++) {
247:                                target = (InstructionHandle) startHandles
248:                                        .get(getEffectiveTarget(conn.getEdge(i)));
249:                                // DEBUG
250:                                if (target == null) {
251:                                    System.out
252:                                            .println("BytecodeCollector.finishVertex "
253:                                                    + v
254:                                                    + " INTERNAL ERROR: \n"
255:                                                    + "    "
256:                                                    + inst
257:                                                    + " has null target " + i);
258:                                }
259:                                // END
260:                                ((Select) bh.getInstruction()).setTarget(i,
261:                                        target);
262:                            }
263:                        }
264:                    }
265:                }
266:            }
267:
268:            /**
269:             * Dump the instruction list.  Debug method.
270:             */
271:            private void dumpIList(String where) {
272:                System.out.println("BytecodeCollector." + where
273:                        + " instruction list:");
274:                int i = 0;
275:                for (InstructionHandle ih = ilist.getStart(); ih != null; ih = ih
276:                        .getNext()) {
277:                    System.out.println("  " + (i++) + "  "
278:                            + ih.getInstruction());
279:                }
280:            }
281:
282:            /**
283:             * Finish the graph.
284:             *
285:             * @param g The control flow graph - ignored.
286:             */
287:            public void finishGraph(Directed g) {
288:
289:            }
290:
291:            /**
292:             * Get the instruction list after completing walking the graph,
293:             * that is, after calling visit.
294:             *
295:             * @return A reference to the bytecode generated by walking
296:             *         the control flow graph.
297:             */
298:            public InstructionList getInstructionList() {
299:                // maps vertices with gotos to their effective target vertices
300:                Iterator k = gotoFixMeUps.keySet().iterator();
301:                while (k.hasNext()) {
302:                    CodeVertex v = (CodeVertex) k.next();
303:                    // maps vertices to the handles on their connecting instructions
304:                    BranchHandle bh = (BranchHandle) endHandles.get(v);
305:                    // gets the handle on the first instruction in the target vertex
306:                    InstructionHandle target = (InstructionHandle) startHandles
307:                            .get(gotoFixMeUps.get(v));
308:                    bh.setTarget(target); // sets the goto target
309:                }
310:                // dumpIList("BytecodeCollector.getInstructions, before update");
311:                ilist.update();
312:                // dumpIList("BytecodeCollector.getInstructions, after update");
313:                return ilist;
314:            }
315:
316:            /**
317:             * Given an array of exception handler descriptions, return an
318:             * array of CodeExceptionGen.  The array may be empty.
319:             *
320:             * XXX This method has not been thoroughly tested.
321:             *
322:             * @param cd Array of exception handler descriptions in terms of vertices
323:             * @return   Array of BCEL exception handler structures.
324:             */
325:            public CodeExceptionGen[] getCEGs(CatchData[] cd) {
326:                CodeExceptionGen[] ceg;
327:                if (cd == null) {
328:                    ceg = new CodeExceptionGen[0];
329:                } else {
330:                    ceg = new CodeExceptionGen[cd.length];
331:                    for (int i = 0; i < cd.length; i++) {
332:                        InstructionHandle start = (InstructionHandle) startHandles
333:                                .get(cd[i].tryStart);
334:                        InstructionHandle end = (InstructionHandle) startHandles
335:                                .get(cd[i].tryEnd);
336:                        InstructionHandle handler = (InstructionHandle) startHandles
337:                                .get(cd[i].handlerPC);
338:                        if (start == null || end == null || handler == null) {
339:                            System.out
340:                                    .println("BytecodeCollector.getCEGs: INTERNAL ERROR - null handler\n"
341:                                            + "    CatchData["
342:                                            + i
343:                                            + "] start: "
344:                                            + cd[i].tryStart
345:                                            + " end: "
346:                                            + cd[i].tryEnd
347:                                            + " handler at: " + cd[i].handlerPC);
348:                        }
349:                        ceg[i] = new CodeExceptionGen(start, end, handler,
350:                                cd[i].exception);
351:                    }
352:                }
353:                return ceg;
354:            }
355:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.