📄 gcrtmethodinfo.java
字号:
} }// while (!ics.isEmpty()) END InstructionHandle ih = start.getInstruction(); //Check that all instruction have been simulated do{ InstructionContext ic = cfg.contextOf(ih); if(ic.getTag() == 0){ System.err.println("Instruction "+ic.toString()+" not simulated."); System.exit(-1); } }while((ih = ih.getNext()) != null); // int inFramesSize = inFrames.size(); // System.out.println("numInstructions:"+instCnt+" // inFramesSize:"+inFramesSize); // This array holds the operand type bits in the low bits ogci = new int[instCnt]; // This array holds the local type bits in the low bits mgci = new int[instCnt]; pcinfo = new String[instCnt]; int oldPC = 0; int PC = 0; int icnt = 0; // for debug info StringBuffer ogciStr = new StringBuffer(); ih = start.getInstruction(); do { oldPC = PC; PC = ih.getPosition(); // Pad up the operands with the same ref bits when the PC gets // ahead // it will either save time if a linked list is used or not be // used for anything // at run time as the PC will not point to the padded positions. for (int i = oldPC + 1; i < PC; i++) { // System.out.println("Padding up: // ogci["+i+"]=ogci["+oldPC+"]"); ogci[i] = ogci[oldPC]; mgci[i] = mgci[oldPC]; } ogciStr.append("ih:" + ih.toString()); pcinfo[PC] = ih.toString(); InstructionContext ic = cfg.contextOf(ih); // System.out.println(ih.toString()+" tag:"+ic.getTag()); // It is here the incoming frame is used to achieve the desired // PC->operand mapping Frame f1 = (Frame) inFrames.get(ic); LocalVariables lvs = f1.getLocals(); // mapping the all the locals for this value of the PC for (int i = 0; i < lvs.maxLocals(); i++) { if (lvs.get(i) instanceof ReferenceType) { int ref = (1 << i); mgci[PC] |= ref; } if (lvs.get(i) instanceof UninitializedObjectType) { // this.addMessage("Warning: ReturnInstruction '"+ic+"' // may leave method with an uninitialized object in the // local variables array '"+lvs+"'."); } } OperandStack os = f1.getStack(); // System.out.println("-->ih["+PC+"]: line"+ih.toString()+" // icnt:"+icnt); // System.out.println(" pre"); // System.out.println(" os slots:"+os.slotsUsed()); ogciStr.append(",os slots:" + os.slotsUsed()); // Each slot is 32 bits int j = 0; // Used to offset for LONG and DOUBLE // mapping the operands for this value of the PC for (int i = 0; i < os.slotsUsed(); i++, j++) { // System.out.println(" // op["+i+"]:"+(os.peek(j)).getSignature()); ogciStr.append(",operand(" + i + "):" + (os.peek(j)).getSignature()); if (os.peek(j) instanceof UninitializedObjectType) { // System.out.println("Warning: ReturnInstruction // '"+ic+"' may leave method with an uninitialized // object on the operand stack '"+os+"'."); } if (os.peek(j) instanceof ReferenceType) { int ref = (1 << i); ogci[PC] |= ref; } // peek() is per type if (os.peek(j).getSignature().equals("J") || os.peek(j).getSignature().equals("D")) { j--; } } // System.out.println(" ogci["+PC+"]:"+bitStr(ogci[PC])); // This frame is post (after) the instruction and thus not what // we need Frame f2 = ic.getOutFrame(new ArrayList()); LocalVariables lvs2 = f2.getLocals(); int ogci2 = 0; for (int i = 0; i < lvs2.maxLocals(); i++) { if (lvs2.get(i) instanceof UninitializedObjectType) { // System.out.println("Warning: ReturnInstruction // '"+ic+"' may leave method with an uninitialized // object in the local variables array '"+lvs+"'."); } } OperandStack os2 = f2.getStack(); // System.out.println(" post"); // System.out.println(" os slots:"+os2.slotsUsed()); // Each slot is 32 bits j = 0; // Used to offset for LONG and DOUBLE for (int i = 0; i < os2.slotsUsed(); i++, j++) { // System.out.println(" // op["+i+"]:"+(os2.peek(j)).getSignature()); // ogciStr.append(",operand("+i+"):"+(os2.peek(j)).getSignature()); if (os2.peek(j) instanceof UninitializedObjectType) { // System.out.println("Warning: ReturnInstruction // '"+ic+"' may leave method with an uninitialized // object on the operand stack '"+os+"'."); } if (os2.peek(j) instanceof ReferenceType) { int ref = (1 << i); ogci2 |= ref; } // peek() is per type if (os2.peek(j).getSignature().equals("J") || os2.peek(j).getSignature().equals("D")) { j--; } } // System.out.println(" ogci["+PC+"]:"+bitStr(ogci2)); icnt++; // System.out.println(""); } while ((ih = ih.getNext()) != null); // pad up the end for (int i = (PC + 1); i < instCnt; i++) { // System.out.println("Post padding up: // ogci["+i+"]=ogci["+PC+"]"); ogci[i] = ogci[PC]; mgci[i] = mgci[PC]; } // Good for debugging // System.out.println(" *** // "+mi.cli.clazz.getClassName()+"."+mi.methodId+" --> mreallocals // ="+mreallocals+" margs ="+margs+" mstack ="+mstack); for (int i = 0; i < instCnt; i++) { // System.out.println(pcinfo[i]+" ogci["+i+"]"+bitStr(ogci[i])); // System.out.println(pcinfo[i]+" mgci["+i+"]"+bitStr(mgci[i])); } // System.out.println("--"); // calculate length for raw method int varcnt = mstack + mreallocals + margs; int pos = instCnt * varcnt; length = pos / WORDLEN; // whole words if ((pos % WORDLEN) > 0) { length++; // partly used word } length++; // gcpack } // if has code } /** * Compares the operands of two frames. It will detect the rare event that * the Gosling property is violated from two jsr instructions reaching the * same code but with different operand or local signatures. Operands are * checked for fun even though they must obey the Gosling property. TODO: * Implement code that can split local variables if a violation occurs. * * @param prevf * the previous frame if it has been visited before * @param newf * the next frame * @return true if the frames equal or if prevf == null */ boolean frmComp(Frame prevf, Frame newf, InstructionContext ic){ boolean res = true; LocalVariables lvprev = prevf.getLocals(); LocalVariables lvnew = newf.getLocals(); OperandStack opprev = prevf.getStack(); OperandStack opnew = newf.getStack(); if(opprev.slotsUsed()!=opnew.slotsUsed()){ res = false; System.out.println("OperandStack size does not equal new OperandStack."+ prevf.toString()+newf.toString()+ic.toString()); } int j=0; for(int i=0;i<opprev.slotsUsed();i++, j++){ if(opprev.peek(j).getType()!=opnew.peek(j).getType()){ System.err.println("Operands differ "+opprev.peek(j).toString()+" "+ opnew.peek(j).toString()); res = false; } // peek() is per type if (opprev.peek(j).getSignature().equals("J") || opprev.peek(j).getSignature().equals("D")) { j--; } } if(lvprev.maxLocals()!=lvnew.maxLocals()){ res = false; System.out.println("MaxLocals LocalVariables does not equal new LocalVariables."+ prevf.toString()+newf.toString()+ic.toString()); } for(int i=0;i<lvprev.maxLocals();i++){ if(lvprev.get(i).getType()!=lvnew.get(i).getType()){ res = false; System.err.println("Local types differ "+lvprev.get(i).toString()+" "+ lvnew.get(i).toString()); } } // TODO: Why does this not work for RTThread? if(!opprev.equals(opnew)||!lvprev.equals(lvnew)){// res = false; int stopit = 0;// System.out.println("Previous OperandStack or Localvars does not equal new OperandStack."+// prevf.toString()+newf.toString()+ic.toString()); } return res; } /* boolean frmComp(Frame prevf, Frame newf, InstructionContext ic) { boolean res = true; if (prevf != null) { // check the operand stacks OperandStack osp = prevf.getStack(); OperandStack osn = newf.getStack(); if (osp.slotsUsed() != osn.slotsUsed()) { System.out .println("Frame OperandStack slotsUsed does not equal"); res = false; } int j = 0; // Used to offset for LONG and DOUBLE for (int i = 0; i < osp.slotsUsed(); i++, j++) { if (osp.peek(j).getSignature() != osn.peek(j).getSignature() && !(osp.peek(j).equals(BasicType.UNKNOWN) || osn.peek( j).equals(BasicType.UNKNOWN))) { System.out.println("Error: Signatures does not match"); res = false; } if ((osp.peek(j) instanceof UninitializedObjectType) != (osn .peek(j) instanceof UninitializedObjectType) && !(osp.peek(j).equals(BasicType.UNKNOWN) || osn.peek( j).equals(BasicType.UNKNOWN))) { System.out .println("Error: Operand stacks not equal for UninitializedObjectType"); res = false; } if ((osp.peek(j) instanceof ReferenceType) != (osn.peek(j) instanceof ReferenceType) && !(osp.peek(j).equals(BasicType.UNKNOWN) || osn.peek( j).equals(BasicType.UNKNOWN))) { System.out .println("Error: Operand stacks not equal for ReferenceType"); res = false; } // peek() is per type if (osp.peek(j).getSignature().equals("J") || osn.peek(j).getSignature().equals("D")) { j--; } } // check the locals LocalVariables lvsp = prevf.getLocals(); LocalVariables lvsn = newf.getLocals(); if (lvsp.maxLocals() != lvsn.maxLocals()) { System.out .println("Frame LocalVariables maxLocals does not equal"); res = false; } // mapping the all the locals for this value of the PC for (int i = 0; i < lvsp.maxLocals(); i++) { if (!lvsp.get(i).getSignature().equals( lvsn.get(i).getSignature()) && !(lvsp.get(i).equals(BasicType.UNKNOWN) || lvsn.get( i).equals(BasicType.UNKNOWN))) { System.out.println("Error: Local signatures for index " + i + " from prev frame does not match next frame"); System.out.println(lvsp.get(i).getSignature()); System.out.println(lvsn.get(i).getSignature()); res = false; } if (lvsp.get(i) instanceof ReferenceType != lvsn.get(i) instanceof ReferenceType && !(lvsp.get(i).equals(BasicType.UNKNOWN) || lvsn.get( i).equals(BasicType.UNKNOWN))) { System.out .println("Error: Local ref from prev frame does not match next frame"); res = false; } if (lvsp.get(i) instanceof UninitializedObjectType != lvsn .get(i) instanceof UninitializedObjectType && !(lvsp.get(i).equals(BasicType.UNKNOWN) || lvsn.get( i).equals(BasicType.UNKNOWN))) { System.out .println("Error: Local unit ref from prev frame does not match next frame"); res = false; } } } // prev != null if (res == false) { // print debug System.out.println(" *** " + mi.cli.clazz.getClassName() + "." + mi.methodId + " --> mreallocals =" + mreallocals + " margs =" + margs + " mstack =" + mstack); System.out.println("ic:" + ic.toString()); System.out.println("ih:" + ic.getInstruction().toString()); System.out.println("pc:" + ic.getInstruction().getPosition()); System.out.println("prev Frame:"); System.out.println(prevf); System.out.println("new Frame:"); System.out.println(newf); } return true; // return res; }*/ /** * It dumps the local variable and stack operands GC info structures. Can be * called with out==null to get the word length. If the method is <code> * clinit</code> then the stackmap is not written out. */ public int dumpMethodGcis(PrintWriter out) { // System.out.println("dumpMethodGcis(PrintWriter out):"+out+", // mi.methodId:"+mi.methodId); int GCIHEADERLENGTH = 1; // key, gcpack // gcpack 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 cntMgciWords = 0; int localmark = 0; int stackmark = 0; int ogcimark = 0; int mgcimark = 0; // if(mi.code != null){ // not abstract if (!method.isAbstract()) { if (instCnt != mgci.length || instCnt != ogci.length) { System.err .println("exit: instCnt!=mgci.length || instCnt!=ogci.length"); System.exit(-1); } if (out != null) { out.println("\n\t//stackwalker info for " + mi.cli.clazz.getClassName() + "." + mi.methodId); } StringBuffer sb = new StringBuffer(); int mask = 0x01; int WORDLEN = 32; // raw packing int[] bitMap = new int[2 * instCnt]; StringBuffer[] bitInfo = new StringBuffer[2 * instCnt]; for (int i = 0; i < instCnt; i++) { bitInfo[i] = new StringBuffer(); bitInfo[i].append("[bit,pos,index,offset,mgci or ogci]:"); } int pos = 0; int index = 0; // raw patterns later used to determine unique patterns and the // index int pattern[] = new int[instCnt]; // pack bitMap for (int i = 0; i < instCnt; i++) { // used for Ref. reduction in paper if (mgci[i] > 0) { mgcimark = 1; } if (ogci[i] > 0) { ogcimark = 1; } // pack locals in high bits // pattern[i] is also done here for (int j = 0; j < (mreallocals + margs); j++) { int bit = (mgci[i] >>> j) & mask; pattern[i] |= bit << (j + mstack); // (pattern[i]<<1)| index = pos / WORDLEN; int offset = pos % WORDLEN; bit = bit << offset; bitMap[index] |= bit; bitInfo[index].append("[" + bit + "," + pos + "," + index + "," + offset + "," + "mgci[" + i + "][" + j + "]] "); pos++; } // pack stack in low bits for (int j = 0; j < mstack; j++) { int bit = (ogci[i] >>> j) & mask; pattern[i] |= bit << j; index = pos / WORDLEN; int offset = pos % WORDLEN; bit = bit << offset; bitMap[index] |= bit; bitInfo[index].append("[" + bit + "," + pos + "," + index + "," + offset + "," + "ogci[" + i + "][" + j + "]] "); pos++; } }// for // packing bitMap2 according to the reduced indexed method. // identify the unique patterns int unique = 0; int uniquepattern[] = new int[instCnt]; boolean match; for (int i = 0; i < instCnt; i++) { match = false; for (int j = 0; j < unique; j++) { if (pattern[i] == uniquepattern[j]) { match = true; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -