📄 gcrtmethodinfo.java
字号:
} } if (!match) { uniquepattern[unique] = pattern[i]; // System.out.println("uniquepattern["+unique+"]="+bitStr(uniquepattern[unique])); unique++; } } // bits needed for unique patterns int patbits = unique * (mreallocals + margs + mstack); // used in a paper if (false) { // index2 reduction if (mgcimark == 0) { patbits -= unique * (mreallocals + margs); } if (ogcimark == 0) { patbits -= unique * (mstack); } } // count index bits int num = 1; int indexbits = 0; for (int i = 1; i < 32; i++) { if (num < unique) { num = (num << 1) | 1; } else { indexbits = i; break; } } // count bits used on indexing int pcbits = indexbits * instCnt; int totalbits = pcbits + patbits; // total words for bitmap int wdc = totalbits / 32; if (totalbits % 32 > 0) { wdc++; } // now make the indexed bitmaps int bitMap2[] = new int[wdc]; StringBuffer[] bitInfo2 = new StringBuffer[wdc]; for (int i = 0; i < wdc; i++) { bitInfo2[i] = new StringBuffer(); } int bitpos = 0; // bit map the indexes for (int i = 0; i < instCnt; i++) { match = false; for (int j = 0; j < unique; j++) { if (pattern[i] == uniquepattern[j]) { int control = 0; bitInfo2[bitpos / 32].append(" p" + i + "=up" + j + ":[" + bitpos + ":"); for (int k = 0; k < indexbits; k++) { int index2 = bitpos / 32; int offset2 = bitpos % 32; int bit = (j >>> k) & 0x01; control |= (bit << k); bitMap2[index2] |= (bit << offset2); bitInfo2[index2].append(bit); if (k == indexbits - 1) { bitInfo2[index2].append("]"); } bitpos++; } // System.out.println("pattern["+i+"]==uniquepattern["+j+"]"); // System.out.println("control:"+control); match = true; break; } } // for unique if (!match) { System.err.println("Problem with uniquematch for PC:" + i); System.exit(-1); } } // bit map the unique patterns for (int i = 0; i < unique; i++) { bitInfo2[bitpos / 32].append(" up" + i + ":[" + bitpos + ":"); for (int j = 0; j < (mreallocals + margs + mstack); j++) { int index2 = bitpos / 32; int offset2 = bitpos % 32; int bit = (uniquepattern[i] >>> j) & 0x01; bitMap2[index2] |= (bit << offset2); bitInfo2[index2].append(bit); if (j == (mreallocals + margs + mstack) - 1) { bitInfo2[index2].append("]"); } bitpos++; } } // pack gcpack int gcpack = unique; // unique patterns gcpack = (gcpack << INSTRLEN) | instCnt; gcpack = (gcpack << MAXSTACKLEN) | mstack; gcpack = (gcpack << MAXLOCALSLEN) | (mreallocals + margs); if ((mreallocals + margs) > 0) { localmark = 1; } // gcpack = (gcpack<<LOCALMARKLEN)|(localmark); // dump bit maps // even if no refs gcpack = (gcpack << LOCALMARKLEN) | (mgcimark); // only dump map // when a ref is // among the // operands "Ref. // only" in paper if (mstack > 0) { stackmark = 1; } // gcpack = (gcpack<<STACKMARKLEN)|(stackmark); // see above gcpack = (gcpack << STACKMARKLEN) | (ogcimark); // System.out.println("dumpMethodGcis Class // method:"+mi.cli.clazz.getClassName()+"."+mi.methodId); // System.out.println("patbits:"+patbits); // System.out.println("pcbits:"+pcbits); // System.out.println("unique:"+unique); // System.out.println("instCnt:"+instCnt); // System.out.println("indexbits:"+indexbits); // System.out.println("locals:"+(mreallocals+margs)); // System.out.println("localmark:"+localmark); // System.out.println("stack:"+mstack); // System.out.println("stackmark:"+stackmark); // System.out.println("index="+index+" // bitMap.length:"+bitMap.length+" instCnt:"+instCnt+" pos:"+pos); pcwords = 1; // set this to 0 or 1 depending if gcpack is written // out //Don't write stackmap for <clinit> methods if(method.getName().equals("<clinit>")){ gcpack = 0; localmark = 0; stackmark = 0; mgcimark = 0; ogcimark = 0; } // just check that the bitMap can be reconstructed from bitMap2 else if (!compareBitMap(bitMap, bitMap2, gcpack, mgci, ogci)) { System.err.println("Error in the bitmaps."); System.exit(-1); } // can also use localmark and stackmark here if bit maps are needed // regardless // of the presense of references if (instCnt > 0 && (mgcimark == 1 || ogcimark == 1)) { pcwords += (patbits + pcbits) / 32; if (((patbits + pcbits) % 32) > 0) { pcwords++; } // change flag below and also on in setMarkWords() in GCStkWalk if (true) { // write out indexed version for (int i = 0; i < wdc; i++) { if (out != null) { out.println("\t" + bitMap2[i] + ",//\tbitMap2[" + i + "]: " + bitInfo2[i].toString() + ", " + bitStr(bitMap2[i])); } cntMgciWords++; } //debug for (int i = 0; i < instCnt; i++) { if (out != null) { out.println("\t// mgci["+i+"]:"+bitStr(mgci[i])+" ogci["+i+"]:"+bitStr(ogci[i])); } } } else // write out raw version { for (int i = 0; i <= index; i++) { if (out != null) { // out.println("\t\t//\tbitMap["+i+"]:"+bitStr(bitMap[i])+" // "+bitInfo[i].toString()); out.println("\t\t" + bitMap[i] + ",//\tbitMap[" + i + "]:" + bitStr(bitMap[i])); } cntMgciWords++; } } } cntMgciWords += GCIHEADERLENGTH; if (out != null) { out.println("\t" + gcpack + ",//\tgcpack[0:stackmark=" + stackmark + ",1:localmark=" + localmark + ",2-6:maxlocals=" + (mreallocals + margs) + ",7-11:maxstack=" + mstack + ",12-21:instr=" + instCnt + ",22-31:unicnt=" + unique + "] indexbits(to index unique):" + indexbits + " gcpack:" + bitStr(gcpack)); } // System.out.println("cntMgciWords:"+cntMgciWords); // System.out.println("pcwords:"+pcwords); if (out != null) { totalpcwords += pcwords; totalcntMgciWords += cntMgciWords; } // System.out.println("totalpcwords:"+totalpcwords); // System.out.println("totalcntMgciWords:"+totalcntMgciWords); // System.out.println("--"); } // if not abstract // System.err.println("dumpMethodGcis // method:"+cli.clazz.getClassName()+"."+methodId); // System.err.println("out MethodInfo.cntMgci:"+MethodInfo.cntMgci+" // MethodInfo.cntMgciWords:"+MethodInfo.cntMgciWords); // System.err.println("index="+index+" bitMap.length:"+bitMap.length+" // instCnt:"+instCnt+" mreallocals:"+mreallocals+" margs:"+margs +" // mstack:"+mstack+" pos:"+pos); // System.err.println("method.isAbstract():"+method.isAbstract()); // System.err.println("..."); // System.out.println("cntMgciWords:"+cntMgciWords); return cntMgciWords; } /** * Called with a pc (program counter) value which will be removed from the * mgci and ogci structures. The <oode>instCnt</code> is also decremented by * one. * @param pc * @return true if pc<instCnt */ public void removePC(int pc){ int oldogci[] = ogci; int oldmgci[] = mgci; ogci = new int[instCnt-1]; mgci = new int[instCnt-1]; if(pc==0){ System.arraycopy(oldogci,1,ogci,0,instCnt-1); System.arraycopy(oldmgci,1,mgci,0,instCnt-1); } else if(pc==instCnt-1){ System.arraycopy(oldogci,0,ogci,0,instCnt-1); System.arraycopy(oldmgci,0,mgci,0,instCnt-1); } else{ System.arraycopy(oldogci,0,ogci,0,pc); System.arraycopy(oldogci,pc+1,ogci,pc,instCnt-1-pc); System.arraycopy(oldmgci,0,mgci,0,pc); System.arraycopy(oldmgci,pc+1,mgci,pc,instCnt-1-pc); } //reduce instcnt accordingly instCnt--; } // Sanity checking the bitmaps by unpacking both and comparing boolean compareBitMap(int bitMap[], int bitMap2[], int gcpack, int mcgi[], int ocgi[]) { boolean compareresult = true; int UNICNTLEN = 10; // worst case if every PC has a unique pattern int INSTRLEN = 10; // 1024 instructions int MAXSTACKLEN = 5; // max 31 operands int MAXLOCALSLEN = 5; // max 31 args+locals int LOCALMARKLEN = 1; // 1 if local references int STACKMARKLEN = 1; // 1 if stack references int unicnt = (gcpack >>> (INSTRLEN + MAXSTACKLEN + MAXLOCALSLEN + LOCALMARKLEN + STACKMARKLEN)) & 0x03ff; int instr = (gcpack >>> (MAXSTACKLEN + MAXLOCALSLEN + LOCALMARKLEN + STACKMARKLEN)) & 0x03ff; int maxstack = (gcpack >>> (MAXLOCALSLEN + LOCALMARKLEN + STACKMARKLEN)) & 0x1f; int maxlocals = (gcpack >>> (LOCALMARKLEN + STACKMARKLEN)) & 0x1f; int localmark = (gcpack >>> (STACKMARKLEN)) & 0x01; ; int stackmark = gcpack & 0x01; // System.out.println("unicnt:"+unicnt); // System.out.println("instr:"+instr); // System.out.println("maxstack:"+maxstack); // System.out.println("maxlocals:"+maxlocals); // System.out.println("localmark:"+localmark); // System.out.println("stackmark:"+stackmark); int num = 1; int indexbits = 0; for (int i = 1; i < 32; i++) { if (num < unicnt) { num = (num << 1) | 1; } else { indexbits = i; break; } } // reconstruct patterns from bitMap2 int patternindex2[] = new int[instr]; int unipattern[] = new int[unicnt]; int pos = 0; for (int i = 0; i < instr; i++) { patternindex2[i] = getBitsFromArray(bitMap2, pos, indexbits); pos += indexbits; } for (int i = 0; i < unicnt; i++) { unipattern[i] = getBitsFromArray(bitMap2, pos, (maxstack + maxlocals)); pos += (maxstack + maxlocals); } // bitmap1 patterns int patterns1[] = new int[instr]; pos = 0; for (int i = 0; i < instr; i++) { patterns1[i] = getBitsFromArray(bitMap, pos, (maxstack + maxlocals)); pos += (maxstack + maxlocals); if (patterns1[i] != unipattern[patternindex2[i]]) { // System.out.println("mgci["+i+"]:"+bitStr(mcgi[i])); // System.out.println("ocgi["+i+"]:"+bitStr(ocgi[i])); // System.out.println("patterns1["+i+"]:"+bitStr(patterns1[i])); // System.out.println("patternindex2["+i+"]:"+patternindex2[i]); // System.out.println("unipattern[patternindex2[["+i+"]]:"+bitStr(unipattern[patternindex2[i]])); compareresult = false; break; } } return compareresult; } // can return max 32 bits. int getBitsFromArray(int array[], int pos, int len) { if (len > 32) { System.out.println("len>32"); System.exit(-1); } if ((pos + len) > array.length * 32) { System.out.println("pos:" + pos + " len:" + len + " too big for array[].length:" + array.length); System.exit(-1); } int res = 0; for (int i = pos; i < pos + len; i++) { int index = i / 32; int offset = i % 32; int word = array[index]; res |= (word >> offset) & 0x01; } return res; } /** * Returns the length in words that the GC info wil consume. Called from * SetMethodInfo's visitJavaClass method. */ public int gcLength() { return dumpMethodGcis(null); } /** * Make a word into a 0/1 bit string. Note that the bit are written with the * low bits first. */ String bitStr(int word) { // make ogci[PC] to bit string for debugging StringBuffer sb = new StringBuffer(); int mask = 0x01; // for(int i = 31;i>=0;i--){ for (int i = 0; i < 32; i++) { int res = (word >>> i) & mask; if ((i + 1) % 8 == 0 && i < 31) { sb.append("_"); } sb.append(res); } return sb.toString(); }}/** * Extends org.apache.bcel.verifier.structurals.Frame just to get access to the * _this field, which the the operandWalker method in MethodInfo uses. */class FrameFrame extends Frame { public FrameFrame(int maxLocals, int maxStack) { super(maxLocals, maxStack); } public FrameFrame(LocalVariables locals, OperandStack stack) { super(locals, stack); } void setThis(UninitializedObjectType uot) { _this = uot; } UninitializedObjectType getThis() { return _this; }}/** * BCEL throws an exception for the util.Dbg class because it overloads a field. * The choice (as described in the BCEL method comment for around line 2551 in * org.apache.bcel.verifier.structurals.InstConstraintVisitor) is to comment out * this check and recompile BCEL jar. Insted of recompiling BCEL the choice is * to override the methods, which is ok? as we are not using BCEL for bytecode * verification purposes (using Sun Javac). */class AnInstConstraintVisitor extends InstConstraintVisitor { public void visitAALOAD(AALOAD o) { } public void visitAASTORE(AASTORE o) { } public void visitACONST_NULL(ACONST_NULL o) { } public void visitALOAD(ALOAD o) { } public void visitANEWARRAY(ANEWARRAY o) { } public void visitARETURN(ARETURN o) { } public void visitARRAYLENGTH(ARRAYLENGTH o) { } public void visitASTORE(ASTORE o) { } public void visitATHROW(ATHROW o) { } public void visitBALOAD(BALOAD o) { } public void visitBASTORE(BASTORE o) { } public void visitBIPUSH(BIPUSH o) { } public void visitBREAKPOINT(BREAKPOINT o) { } public void visitCALOAD(CALOAD o) { }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -