History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

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

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

Unified · Split

java/pkg/sun/tools/asm/Assembler.java+955−0
@@ -0,0 +1,955 @@
1+/*
2+ * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.tools.asm;
27+
28+import sun.tools.java.*;
29+import java.util.Enumeration;
30+import java.io.IOException;
31+import java.io.DataOutputStream;
32+import java.io.PrintStream;
33+import java.util.Vector;
34+// JCOV
35+import sun.tools.javac.*;
36+import java.io.File;
37+import java.io.BufferedInputStream;
38+import java.io.DataInputStream;
39+import java.io.FileInputStream;
40+import java.io.FileNotFoundException;
41+import java.io.FileOutputStream;
42+import java.lang.String;
43+// end JCOV
44+
45+/**
46+ * This class is used to assemble the bytecode instructions for a method.
47+ *
48+ * WARNING: The contents of this source file are not part of any
49+ * supported API. Code that depends on them does so at its own risk:
50+ * they are subject to change or removal without notice.
51+ *
52+ * @author Arthur van Hoff
53+ */
54+public final
55+class Assembler implements Constants {
56+ static final int NOTREACHED = 0;
57+ static final int REACHED = 1;
58+ static final int NEEDED = 2;
59+
60+ Label first = new Label();
61+ Instruction last = first;
62+ int maxdepth;
63+ int maxvar;
64+ int maxpc;
65+
66+ /**
67+ * Add an instruction
68+ */
69+ public void add(Instruction inst) {
70+ if (inst != null) {
71+ last.next = inst;
72+ last = inst;
73+ }
74+ }
75+ public void add(long where, int opc) {
76+ add(new Instruction(where, opc, null));
77+ }
78+ public void add(long where, int opc, Object obj) {
79+ add(new Instruction(where, opc, obj));
80+ }
81+// JCOV
82+ public void add(long where, int opc, Object obj, boolean flagCondInverted) {
83+ add(new Instruction(where, opc, obj, flagCondInverted));
84+ }
85+
86+ public void add(boolean flagNoCovered, long where, int opc, Object obj) {
87+ add(new Instruction(flagNoCovered, where, opc, obj));
88+ }
89+
90+ public void add(long where, int opc, boolean flagNoCovered) {
91+ add(new Instruction(where, opc, flagNoCovered));
92+ }
93+
94+ static Vector SourceClassList = new Vector();
95+
96+ static Vector TmpCovTable = new Vector();
97+
98+ static int[] JcovClassCountArray = new int[CT_LAST_KIND + 1];
99+
100+ static String JcovMagicLine = "JCOV-DATA-FILE-VERSION: 2.0";
101+ static String JcovClassLine = "CLASS: ";
102+ static String JcovSrcfileLine = "SRCFILE: ";
103+ static String JcovTimestampLine = "TIMESTAMP: ";
104+ static String JcovDataLine = "DATA: ";
105+ static String JcovHeadingLine = "#kind\tcount";
106+
107+ static int[] arrayModifiers =
108+ {M_PUBLIC, M_PRIVATE, M_PROTECTED, M_ABSTRACT, M_FINAL, M_INTERFACE};
109+ static int[] arrayModifiersOpc =
110+ {PUBLIC, PRIVATE, PROTECTED, ABSTRACT, FINAL, INTERFACE};
111+//end JCOV
112+
113+ /**
114+ * Optimize instructions and mark those that can be reached
115+ */
116+ void optimize(Environment env, Label lbl) {
117+ lbl.pc = REACHED;
118+
119+ for (Instruction inst = lbl.next ; inst != null ; inst = inst.next) {
120+ switch (inst.pc) {
121+ case NOTREACHED:
122+ inst.optimize(env);
123+ inst.pc = REACHED;
124+ break;
125+ case REACHED:
126+ return;
127+ case NEEDED:
128+ break;
129+ }
130+
131+ switch (inst.opc) {
132+ case opc_label:
133+ case opc_dead:
134+ if (inst.pc == REACHED) {
135+ inst.pc = NOTREACHED;
136+ }
137+ break;
138+
139+ case opc_ifeq:
140+ case opc_ifne:
141+ case opc_ifgt:
142+ case opc_ifge:
143+ case opc_iflt:
144+ case opc_ifle:
145+ case opc_if_icmpeq:
146+ case opc_if_icmpne:
147+ case opc_if_icmpgt:
148+ case opc_if_icmpge:
149+ case opc_if_icmplt:
150+ case opc_if_icmple:
151+ case opc_if_acmpeq:
152+ case opc_if_acmpne:
153+ case opc_ifnull:
154+ case opc_ifnonnull:
155+ optimize(env, (Label)inst.value);
156+ break;
157+
158+ case opc_goto:
159+ optimize(env, (Label)inst.value);
160+ return;
161+
162+ case opc_jsr:
163+ optimize(env, (Label)inst.value);
164+ break;
165+
166+ case opc_ret:
167+ case opc_return:
168+ case opc_ireturn:
169+ case opc_lreturn:
170+ case opc_freturn:
171+ case opc_dreturn:
172+ case opc_areturn:
173+ case opc_athrow:
174+ return;
175+
176+ case opc_tableswitch:
177+ case opc_lookupswitch: {
178+ SwitchData sw = (SwitchData)inst.value;
179+ optimize(env, sw.defaultLabel);
180+ for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) {
181+ optimize(env, (Label)e.nextElement());
182+ }
183+ return;
184+ }
185+
186+ case opc_try: {
187+ TryData td = (TryData)inst.value;
188+ td.getEndLabel().pc = NEEDED;
189+ for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) {
190+ CatchData cd = (CatchData)e.nextElement();
191+ optimize(env, cd.getLabel());
192+ }
193+ break;
194+ }
195+ }
196+ }
197+ }
198+
199+ /**
200+ * Eliminate instructions that are not reached
201+ */
202+ boolean eliminate() {
203+ boolean change = false;
204+ Instruction prev = first;
205+
206+ for (Instruction inst = first.next ; inst != null ; inst = inst.next) {
207+ if (inst.pc != NOTREACHED) {
208+ prev.next = inst;
209+ prev = inst;
210+ inst.pc = NOTREACHED;
211+ } else {
212+ change = true;
213+ }
214+ }
215+ first.pc = NOTREACHED;
216+ prev.next = null;
217+ return change;
218+ }
219+
220+ /**
221+ * Optimize the byte codes
222+ */
223+ public void optimize(Environment env) {
224+ //listing(System.out);
225+ do {
226+ // Figure out which instructions are reached
227+ optimize(env, first);
228+
229+ // Eliminate instructions that are not reached
230+ } while (eliminate() && env.opt());
231+ }
232+
233+ /**
234+ * Collect all constants into the constant table
235+ */
236+ public void collect(Environment env, MemberDefinition field, ConstantPool tab) {
237+ // Collect constants for arguments only
238+ // if a local variable table is generated
239+ if ((field != null) && env.debug_vars()) {
240+ if (field.getArguments() != null) {
241+ for (Enumeration e = field.getArguments().elements() ; e.hasMoreElements() ;) {
242+ MemberDefinition f = (MemberDefinition)e.nextElement();
243+ tab.put(f.getName().toString());
244+ tab.put(f.getType().getTypeSignature());
245+ }
246+ }
247+ }
248+
249+ // Collect constants from the instructions
250+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
251+ inst.collect(tab);
252+ }
253+ }
254+
255+ /**
256+ * Determine stack size, count local variables
257+ */
258+ void balance(Label lbl, int depth) {
259+ for (Instruction inst = lbl ; inst != null ; inst = inst.next) {
260+ //Environment.debugOutput(inst.toString() + ": " + depth + " => " +
261+ // (depth + inst.balance()));
262+ depth += inst.balance();
263+ if (depth < 0) {
264+ throw new CompilerError("stack under flow: " + inst.toString() + " = " + depth);
265+ }
266+ if (depth > maxdepth) {
267+ maxdepth = depth;
268+ }
269+ switch (inst.opc) {
270+ case opc_label:
271+ lbl = (Label)inst;
272+ if (inst.pc == REACHED) {
273+ if (lbl.depth != depth) {
274+ throw new CompilerError("stack depth error " +
275+ depth + "/" + lbl.depth +
276+ ": " + inst.toString());
277+ }
278+ return;
279+ }
280+ lbl.pc = REACHED;
281+ lbl.depth = depth;
282+ break;
283+
284+ case opc_ifeq:
285+ case opc_ifne:
286+ case opc_ifgt:
287+ case opc_ifge:
288+ case opc_iflt:
289+ case opc_ifle:
290+ case opc_if_icmpeq:
291+ case opc_if_icmpne:
292+ case opc_if_icmpgt:
293+ case opc_if_icmpge:
294+ case opc_if_icmplt:
295+ case opc_if_icmple:
296+ case opc_if_acmpeq:
297+ case opc_if_acmpne:
298+ case opc_ifnull:
299+ case opc_ifnonnull:
300+ balance((Label)inst.value, depth);
301+ break;
302+
303+ case opc_goto:
304+ balance((Label)inst.value, depth);
305+ return;
306+
307+ case opc_jsr:
308+ balance((Label)inst.value, depth + 1);
309+ break;
310+
311+ case opc_ret:
312+ case opc_return:
313+ case opc_ireturn:
314+ case opc_lreturn:
315+ case opc_freturn:
316+ case opc_dreturn:
317+ case opc_areturn:
318+ case opc_athrow:
319+ return;
320+
321+ case opc_iload:
322+ case opc_fload:
323+ case opc_aload:
324+ case opc_istore:
325+ case opc_fstore:
326+ case opc_astore: {
327+ int v = ((inst.value instanceof Number)
328+ ? ((Number)inst.value).intValue()
329+ : ((LocalVariable)inst.value).slot) + 1;
330+ if (v > maxvar)
331+ maxvar = v;
332+ break;
333+ }
334+
335+ case opc_lload:
336+ case opc_dload:
337+ case opc_lstore:
338+ case opc_dstore: {
339+ int v = ((inst.value instanceof Number)
340+ ? ((Number)inst.value).intValue()
341+ : ((LocalVariable)inst.value).slot) + 2;
342+ if (v > maxvar)
343+ maxvar = v;
344+ break;
345+ }
346+
347+ case opc_iinc: {
348+ int v = ((int[])inst.value)[0] + 1;
349+ if (v > maxvar)
350+ maxvar = v + 1;
351+ break;
352+ }
353+
354+ case opc_tableswitch:
355+ case opc_lookupswitch: {
356+ SwitchData sw = (SwitchData)inst.value;
357+ balance(sw.defaultLabel, depth);
358+ for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) {
359+ balance((Label)e.nextElement(), depth);
360+ }
361+ return;
362+ }
363+
364+ case opc_try: {
365+ TryData td = (TryData)inst.value;
366+ for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) {
367+ CatchData cd = (CatchData)e.nextElement();
368+ balance(cd.getLabel(), depth + 1);
369+ }
370+ break;
371+ }
372+ }
373+ }
374+ }
375+
376+ /**
377+ * Generate code
378+ */
379+ public void write(Environment env, DataOutputStream out,
380+ MemberDefinition field, ConstantPool tab)
381+ throws IOException {
382+ //listing(System.out);
383+
384+ if ((field != null) && field.getArguments() != null) {
385+ int sum = 0;
386+ Vector v = field.getArguments();
387+ for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
388+ MemberDefinition f = ((MemberDefinition)e.nextElement());
389+ sum += f.getType().stackSize();
390+ }
391+ maxvar = sum;
392+ }
393+
394+ // Make sure the stack balances. Also calculate maxvar and maxstack
395+ try {
396+ balance(first, 0);
397+ } catch (CompilerError e) {
398+ System.out.println("ERROR: " + e);
399+ listing(System.out);
400+ throw e;
401+ }
402+
403+ // Assign PCs
404+ int pc = 0, nexceptions = 0;
405+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
406+ inst.pc = pc;
407+ int sz = inst.size(tab);
408+ if (pc<65536 && (pc+sz)>=65536) {
409+ env.error(inst.where, "warn.method.too.long");
410+ }
411+ pc += sz;
412+
413+ if (inst.opc == opc_try) {
414+ nexceptions += ((TryData)inst.value).catches.size();
415+ }
416+ }
417+
418+ // Write header
419+ out.writeShort(maxdepth);
420+ out.writeShort(maxvar);
421+ out.writeInt(maxpc = pc);
422+
423+ // Generate code
424+ for (Instruction inst = first.next ; inst != null ; inst = inst.next) {
425+ inst.write(out, tab);
426+ }
427+
428+ // write exceptions
429+ out.writeShort(nexceptions);
430+ if (nexceptions > 0) {
431+ //listing(System.out);
432+ writeExceptions(env, out, tab, first, last);
433+ }
434+ }
435+
436+ /**
437+ * Write the exceptions table
438+ */
439+ void writeExceptions(Environment env, DataOutputStream out, ConstantPool tab, Instruction first, Instruction last) throws IOException {
440+ for (Instruction inst = first ; inst != last.next ; inst = inst.next) {
441+ if (inst.opc == opc_try) {
442+ TryData td = (TryData)inst.value;
443+ writeExceptions(env, out, tab, inst.next, td.getEndLabel());
444+ for (Enumeration e = td.catches.elements() ; e.hasMoreElements();) {
445+ CatchData cd = (CatchData)e.nextElement();
446+ //System.out.println("EXCEPTION: " + env.getSource() + ", pc=" + inst.pc + ", end=" + td.getEndLabel().pc + ", hdl=" + cd.getLabel().pc + ", tp=" + cd.getType());
447+ out.writeShort(inst.pc);
448+ out.writeShort(td.getEndLabel().pc);
449+ out.writeShort(cd.getLabel().pc);
450+ if (cd.getType() != null) {
451+ out.writeShort(tab.index(cd.getType()));
452+ } else {
453+ out.writeShort(0);
454+ }
455+ }
456+ inst = td.getEndLabel();
457+ }
458+ }
459+ }
460+
461+//JCOV
462+ /**
463+ * Write the coverage table
464+ */
465+ public void writeCoverageTable(Environment env, ClassDefinition c, DataOutputStream out, ConstantPool tab, long whereField) throws IOException {
466+ Vector TableLot = new Vector(); /* Coverage table */
467+ boolean begseg = false;
468+ boolean begmeth = false;
469+ long whereClass = ((SourceClass)c).getWhere();
470+ Vector whereTry = new Vector();
471+ int numberTry = 0;
472+ int count = 0;
473+
474+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
475+ long n = (inst.where >> WHEREOFFSETBITS);
476+ if (n > 0 && inst.opc != opc_label) {
477+ if (!begmeth) {
478+ if ( whereClass == inst.where)
479+ TableLot.addElement(new Cover(CT_FIKT_METHOD, whereField, inst.pc));
480+ else
481+ TableLot.addElement(new Cover(CT_METHOD, whereField, inst.pc));
482+ count++;
483+ begmeth = true;
484+ }
485+ if (!begseg && !inst.flagNoCovered ) {
486+ boolean findTry = false;
487+ for (Enumeration e = whereTry.elements(); e.hasMoreElements();) {
488+ if ( ((Long)(e.nextElement())).longValue() == inst.where) {
489+ findTry = true;
490+ break;
491+ }
492+ }
493+ if (!findTry) {
494+ TableLot.addElement(new Cover(CT_BLOCK, inst.where, inst.pc));
495+ count++;
496+ begseg = true;
497+ }
498+ }
499+ }
500+ switch (inst.opc) {
501+ case opc_label:
502+ begseg = false;
503+ break;
504+ case opc_ifeq:
505+ case opc_ifne:
506+ case opc_ifnull:
507+ case opc_ifnonnull:
508+ case opc_ifgt:
509+ case opc_ifge:
510+ case opc_iflt:
511+ case opc_ifle:
512+ case opc_if_icmpeq:
513+ case opc_if_icmpne:
514+ case opc_if_icmpgt:
515+ case opc_if_icmpge:
516+ case opc_if_icmplt:
517+ case opc_if_icmple:
518+ case opc_if_acmpeq:
519+ case opc_if_acmpne: {
520+ if ( inst.flagCondInverted ) {
521+ TableLot.addElement(new Cover(CT_BRANCH_TRUE, inst.where, inst.pc));
522+ TableLot.addElement(new Cover(CT_BRANCH_FALSE, inst.where, inst.pc));
523+ } else {
524+ TableLot.addElement(new Cover(CT_BRANCH_FALSE, inst.where, inst.pc));
525+ TableLot.addElement(new Cover(CT_BRANCH_TRUE, inst.where, inst.pc));
526+ }
527+ count += 2;
528+ begseg = false;
529+ break;
530+ }
531+
532+ case opc_goto: {
533+ begseg = false;
534+ break;
535+ }
536+
537+ case opc_ret:
538+ case opc_return:
539+ case opc_ireturn:
540+ case opc_lreturn:
541+ case opc_freturn:
542+ case opc_dreturn:
543+ case opc_areturn:
544+ case opc_athrow: {
545+ break;
546+ }
547+
548+ case opc_try: {
549+ whereTry.addElement(new Long(inst.where));
550+ begseg = false;
551+ break;
552+ }
553+
554+ case opc_tableswitch: {
555+ SwitchData sw = (SwitchData)inst.value;
556+ for (int i = sw.minValue; i <= sw.maxValue; i++) {
557+ TableLot.addElement(new Cover(CT_CASE, sw.whereCase(new Integer(i)), inst.pc));
558+ count++;
559+ }
560+ if (!sw.getDefault()) {
561+ TableLot.addElement(new Cover(CT_SWITH_WO_DEF, inst.where, inst.pc));
562+ count++;
563+ } else {
564+ TableLot.addElement(new Cover(CT_CASE, sw.whereCase("default"), inst.pc));
565+ count++;
566+ }
567+ begseg = false;
568+ break;
569+ }
570+ case opc_lookupswitch: {
571+ SwitchData sw = (SwitchData)inst.value;
572+ for (Enumeration e = sw.sortedKeys(); e.hasMoreElements() ; ) {
573+ Integer v = (Integer)e.nextElement();
574+ TableLot.addElement(new Cover(CT_CASE, sw.whereCase(v), inst.pc));
575+ count++;
576+ }
577+ if (!sw.getDefault()) {
578+ TableLot.addElement(new Cover(CT_SWITH_WO_DEF, inst.where, inst.pc));
579+ count++;
580+ } else {
581+ TableLot.addElement(new Cover(CT_CASE, sw.whereCase("default"), inst.pc));
582+ count++;
583+ }
584+ begseg = false;
585+ break;
586+ }
587+ }
588+ }
589+ Cover Lot;
590+ long ln, pos;
591+
592+ out.writeShort(count);
593+ for (int i = 0; i < count; i++) {
594+ Lot = (Cover)TableLot.elementAt(i);
595+ ln = (Lot.Addr >> WHEREOFFSETBITS);
596+ pos = (Lot.Addr << (64 - WHEREOFFSETBITS)) >> (64 - WHEREOFFSETBITS);
597+ out.writeShort(Lot.NumCommand);
598+ out.writeShort(Lot.Type);
599+ out.writeInt((int)ln);
600+ out.writeInt((int)pos);
601+
602+ if ( !(Lot.Type == CT_CASE && Lot.Addr == 0) ) {
603+ JcovClassCountArray[Lot.Type]++;
604+ }
605+ }
606+
607+ }
608+
609+/*
610+ * Increase count of methods for native methods
611+ */
612+
613+public void addNativeToJcovTab(Environment env, ClassDefinition c) {
614+ JcovClassCountArray[CT_METHOD]++;
615+}
616+
617+/*
618+ * Create class jcov element
619+ */
620+
621+private String createClassJcovElement(Environment env, ClassDefinition c) {
622+ String SourceClass = (Type.mangleInnerType((c.getClassDeclaration()).getName())).toString();
623+ String ConvSourceClass;
624+ String classJcovLine;
625+
626+ SourceClassList.addElement(SourceClass);
627+ ConvSourceClass = SourceClass.replace('.', '/');
628+ classJcovLine = JcovClassLine + ConvSourceClass;
629+
630+ classJcovLine = classJcovLine + " [";
631+ String blank = "";
632+
633+ for (int i = 0; i < arrayModifiers.length; i++ ) {
634+ if ((c.getModifiers() & arrayModifiers[i]) != 0) {
635+ classJcovLine = classJcovLine + blank + opNames[arrayModifiersOpc[i]];
636+ blank = " ";
637+ }
638+ }
639+ classJcovLine = classJcovLine + "]";
640+
641+ return classJcovLine;
642+}
643+
644+/*
645+ * generate coverage data
646+ */
647+
648+public void GenVecJCov(Environment env, ClassDefinition c, long Time) {
649+ String SourceFile = ((SourceClass)c).getAbsoluteName();
650+
651+ TmpCovTable.addElement(createClassJcovElement(env, c));
652+ TmpCovTable.addElement(JcovSrcfileLine + SourceFile);
653+ TmpCovTable.addElement(JcovTimestampLine + Time);
654+ TmpCovTable.addElement(JcovDataLine + "A"); // data format
655+ TmpCovTable.addElement(JcovHeadingLine);
656+
657+ for (int i = CT_FIRST_KIND; i <= CT_LAST_KIND; i++) {
658+ if (JcovClassCountArray[i] != 0) {
659+ TmpCovTable.addElement(new String(i + "\t" + JcovClassCountArray[i]));
660+ JcovClassCountArray[i] = 0;
661+ }
662+ }
663+}
664+
665+
666+/*
667+ * generate file of coverage data
668+ */
669+
670+public void GenJCov(Environment env) {
671+
672+ try {
673+ File outFile = env.getcovFile();
674+ if( outFile.exists()) {
675+ DataInputStream JCovd = new DataInputStream(
676+ new BufferedInputStream(
677+ new FileInputStream(outFile)));
678+ String CurrLine = null;
679+ boolean first = true;
680+ String Class;
681+
682+ CurrLine = JCovd.readLine();
683+ if ((CurrLine != null) && CurrLine.startsWith(JcovMagicLine)) {
684+ // this is a good Jcov file
685+
686+ while((CurrLine = JCovd.readLine()) != null ) {
687+ if ( CurrLine.startsWith(JcovClassLine) ) {
688+ first = true;
689+ for(Enumeration e = SourceClassList.elements(); e.hasMoreElements();) {
690+ String clsName = CurrLine.substring(JcovClassLine.length());
691+ int idx = clsName.indexOf(' ');
692+
693+ if (idx != -1) {
694+ clsName = clsName.substring(0, idx);
695+ }
696+ Class = (String)e.nextElement();
697+ if ( Class.compareTo(clsName) == 0) {
698+ first = false;
699+ break;
700+ }
701+ }
702+ }
703+ if (first) // re-write old class
704+ TmpCovTable.addElement(CurrLine);
705+ }
706+ }
707+ JCovd.close();
708+ }
709+ PrintStream CovFile = new PrintStream(new DataOutputStream(new FileOutputStream(outFile)));
710+ CovFile.println(JcovMagicLine);
711+ for(Enumeration e = TmpCovTable.elements(); e.hasMoreElements();) {
712+ CovFile.println(e.nextElement());
713+ }
714+ CovFile.close();
715+ }
716+ catch (FileNotFoundException e) {
717+ System.out.println("ERROR: " + e);
718+ }
719+ catch (IOException e) {
720+ System.out.println("ERROR: " + e);
721+ }
722+}
723+// end JCOV
724+
725+
726+ /**
727+ * Write the linenumber table
728+ */
729+ public void writeLineNumberTable(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
730+ long ln = -1;
731+ int count = 0;
732+
733+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
734+ long n = (inst.where >> WHEREOFFSETBITS);
735+ if ((n > 0) && (ln != n)) {
736+ ln = n;
737+ count++;
738+ }
739+ }
740+
741+ ln = -1;
742+ out.writeShort(count);
743+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
744+ long n = (inst.where >> WHEREOFFSETBITS);
745+ if ((n > 0) && (ln != n)) {
746+ ln = n;
747+ out.writeShort(inst.pc);
748+ out.writeShort((int)ln);
749+ //System.out.println("pc = " + inst.pc + ", ln = " + ln);
750+ }
751+ }
752+ }
753+
754+ /**
755+ * Figure out when registers contain a legal value. This is done
756+ * using a simple data flow algorithm. This information is later used
757+ * to generate the local variable table.
758+ */
759+ void flowFields(Environment env, Label lbl, MemberDefinition locals[]) {
760+ if (lbl.locals != null) {
761+ // Been here before. Erase any conflicts.
762+ MemberDefinition f[] = lbl.locals;
763+ for (int i = 0 ; i < maxvar ; i++) {
764+ if (f[i] != locals[i]) {
765+ f[i] = null;
766+ }
767+ }
768+ return;
769+ }
770+
771+ // Remember the set of active registers at this point
772+ lbl.locals = new MemberDefinition[maxvar];
773+ System.arraycopy(locals, 0, lbl.locals, 0, maxvar);
774+
775+ MemberDefinition newlocals[] = new MemberDefinition[maxvar];
776+ System.arraycopy(locals, 0, newlocals, 0, maxvar);
777+ locals = newlocals;
778+
779+ for (Instruction inst = lbl.next ; inst != null ; inst = inst.next) {
780+ switch (inst.opc) {
781+ case opc_istore: case opc_istore_0: case opc_istore_1:
782+ case opc_istore_2: case opc_istore_3:
783+ case opc_fstore: case opc_fstore_0: case opc_fstore_1:
784+ case opc_fstore_2: case opc_fstore_3:
785+ case opc_astore: case opc_astore_0: case opc_astore_1:
786+ case opc_astore_2: case opc_astore_3:
787+ case opc_lstore: case opc_lstore_0: case opc_lstore_1:
788+ case opc_lstore_2: case opc_lstore_3:
789+ case opc_dstore: case opc_dstore_0: case opc_dstore_1:
790+ case opc_dstore_2: case opc_dstore_3:
791+ if (inst.value instanceof LocalVariable) {
792+ LocalVariable v = (LocalVariable)inst.value;
793+ locals[v.slot] = v.field;
794+ }
795+ break;
796+
797+ case opc_label:
798+ flowFields(env, (Label)inst, locals);
799+ return;
800+
801+ case opc_ifeq: case opc_ifne: case opc_ifgt:
802+ case opc_ifge: case opc_iflt: case opc_ifle:
803+ case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpgt:
804+ case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmple:
805+ case opc_if_acmpeq: case opc_if_acmpne:
806+ case opc_ifnull: case opc_ifnonnull:
807+ case opc_jsr:
808+ flowFields(env, (Label)inst.value, locals);
809+ break;
810+
811+ case opc_goto:
812+ flowFields(env, (Label)inst.value, locals);
813+ return;
814+
815+ case opc_return: case opc_ireturn: case opc_lreturn:
816+ case opc_freturn: case opc_dreturn: case opc_areturn:
817+ case opc_athrow: case opc_ret:
818+ return;
819+
820+ case opc_tableswitch:
821+ case opc_lookupswitch: {
822+ SwitchData sw = (SwitchData)inst.value;
823+ flowFields(env, sw.defaultLabel, locals);
824+ for (Enumeration e = sw.tab.elements() ; e.hasMoreElements();) {
825+ flowFields(env, (Label)e.nextElement(), locals);
826+ }
827+ return;
828+ }
829+
830+ case opc_try: {
831+ Vector catches = ((TryData)inst.value).catches;
832+ for (Enumeration e = catches.elements(); e.hasMoreElements();) {
833+ CatchData cd = (CatchData)e.nextElement();
834+ flowFields(env, cd.getLabel(), locals);
835+ }
836+ break;
837+ }
838+ }
839+ }
840+ }
841+
842+ /**
843+ * Write the local variable table. The necessary constants have already been
844+ * added to the constant table by the collect() method. The flowFields method
845+ * is used to determine which variables are alive at each pc.
846+ */
847+ public void writeLocalVariableTable(Environment env, MemberDefinition field, DataOutputStream out, ConstantPool tab) throws IOException {
848+ MemberDefinition locals[] = new MemberDefinition[maxvar];
849+ int i = 0;
850+
851+ // Initialize arguments
852+ if ((field != null) && (field.getArguments() != null)) {
853+ int reg = 0;
854+ Vector v = field.getArguments();
855+ for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
856+ MemberDefinition f = ((MemberDefinition)e.nextElement());
857+ locals[reg] = f;
858+ reg += f.getType().stackSize();
859+ }
860+ }
861+
862+ flowFields(env, first, locals);
863+ LocalVariableTable lvtab = new LocalVariableTable();
864+
865+ // Initialize arguments again
866+ for (i = 0; i < maxvar; i++)
867+ locals[i] = null;
868+ if ((field != null) && (field.getArguments() != null)) {
869+ int reg = 0;
870+ Vector v = field.getArguments();
871+ for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
872+ MemberDefinition f = ((MemberDefinition)e.nextElement());
873+ locals[reg] = f;
874+ lvtab.define(f, reg, 0, maxpc);
875+ reg += f.getType().stackSize();
876+ }
877+ }
878+
879+ int pcs[] = new int[maxvar];
880+
881+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
882+ switch (inst.opc) {
883+ case opc_istore: case opc_istore_0: case opc_istore_1:
884+ case opc_istore_2: case opc_istore_3: case opc_fstore:
885+ case opc_fstore_0: case opc_fstore_1: case opc_fstore_2:
886+ case opc_fstore_3:
887+ case opc_astore: case opc_astore_0: case opc_astore_1:
888+ case opc_astore_2: case opc_astore_3:
889+ case opc_lstore: case opc_lstore_0: case opc_lstore_1:
890+ case opc_lstore_2: case opc_lstore_3:
891+ case opc_dstore: case opc_dstore_0: case opc_dstore_1:
892+ case opc_dstore_2: case opc_dstore_3:
893+ if (inst.value instanceof LocalVariable) {
894+ LocalVariable v = (LocalVariable)inst.value;
895+ int pc = (inst.next != null) ? inst.next.pc : inst.pc;
896+ if (locals[v.slot] != null) {
897+ lvtab.define(locals[v.slot], v.slot, pcs[v.slot], pc);
898+ }
899+ pcs[v.slot] = pc;
900+ locals[v.slot] = v.field;
901+ }
902+ break;
903+
904+ case opc_label: {
905+ // flush previous labels
906+ for (i = 0 ; i < maxvar ; i++) {
907+ if (locals[i] != null) {
908+ lvtab.define(locals[i], i, pcs[i], inst.pc);
909+ }
910+ }
911+ // init new labels
912+ int pc = inst.pc;
913+ MemberDefinition[] labelLocals = ((Label)inst).locals;
914+ if (labelLocals == null) { // unreachable code??
915+ for (i = 0; i < maxvar; i++)
916+ locals[i] = null;
917+ } else {
918+ System.arraycopy(labelLocals, 0, locals, 0, maxvar);
919+ }
920+ for (i = 0 ; i < maxvar ; i++) {
921+ pcs[i] = pc;
922+ }
923+ break;
924+ }
925+ }
926+ }
927+
928+ // flush remaining labels
929+ for (i = 0 ; i < maxvar ; i++) {
930+ if (locals[i] != null) {
931+ lvtab.define(locals[i], i, pcs[i], maxpc);
932+ }
933+ }
934+
935+ // write the local variable table
936+ lvtab.write(env, out, tab);
937+ }
938+
939+ /**
940+ * Return true if empty
941+ */
942+ public boolean empty() {
943+ return first == last;
944+ }
945+
946+ /**
947+ * Print the byte codes
948+ */
949+ public void listing(PrintStream out) {
950+ out.println("-- listing --");
951+ for (Instruction inst = first ; inst != null ; inst = inst.next) {
952+ out.println(inst.toString());
953+ }
954+ }
955+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t