📄 classinfo.java
字号:
/* * Created on 05.06.2005 * */package com.jopdesign.build;import java.io.PrintWriter;import java.util.*;import org.apache.bcel.Constants;import org.apache.bcel.classfile.*;/** * @author Flavius, Martin * * Class struct: * * -n: class variables * 0: instance size (class reference) * 1: GC info field (one bit per field) * 2: pointer to interface table * 3+: method table, two words per entry * : class reference (pointer back to class info) * : constant pool (cp) * : optional interface table * * Flavius type class struct: * * A Class struct image should look as follows: * (the byte code for used Methods is output and at known locations) * * a. GCInfo: USE length + PACKED 2w into 1w ? (not big anyway) * b. static fields * c. -2. addrOf(staticfields) * c. -1. addrOf(GCInfo) * c. 0. instance size (class struct ptr) * c. 1. addrOf(interfaces) * d. method table, 2w per entry * - uses f or other classes' f * e. addrOf(class struct) * f. constant pool * - length * - uses entries in b. and d. */public class ClassInfo { static final int CLS_HEAD = 3; static final int METH_STR = 2; static final int CONST_STR = 1; static class IT { int nr; String key;// String nativeName; MethodInfo meth; } // 'global' interface table static LinkedList listIT = new LinkedList(); static int nrObjMethods; static int bootAddress; static int jvmAddress; static int jvmHelpAddress; static int mainAddress; // 'global' mapping of class names to ClassInfo static HashMap mapClassNames = new HashMap(); // virtual method table class ClVT { int len; // Method name plus signature is the key String[] key;// do I need this?// int[] ptr;// do I need this?// This was a app.-wide unique id.// String[] nativeName; MethodInfo mi[]; } /** * Field table * @author Martin * */ class ClFT { int len; int instSize; // fieldname and signature String[] key; // index in the object int[] idx; int[] size; boolean[] isStatic; boolean[] isReference; public String toString() { StringBuffer sb = new StringBuffer(); for (int i=0; i<len; ++i) { sb.append(key[i]+" "); } return sb.toString(); } } static int cntValueStatic = 0; static int cntRefStatic = 0; static int addrValueStatic = 0; static int addrRefStatic = 0; public JavaClass clazz; public ClassInfo superClass; private HashMap usedMethods = new HashMap(); // Methods in a list private List list = new LinkedList(); public ClVT clvt; public ClFT clft; private int instSize; private int instGCinfo; public List cpoolUsed; public int cpoolArry[]; public String cpoolComments[]; public int staticValueVarAddress; public int staticRefVarAddress; public int classRefAddress; public int methodsAddress; public int cpoolAddress; public int iftableAddress; public ClassInfo(JavaClass clazz) { this.clazz = clazz; methodsAddress = 0; cpoolAddress = 0; instSize = 0; instGCinfo = 0; cpoolUsed = new LinkedList(); mapClassNames.put(clazz.getClassName(), this); if (clazz.getClassName().equals(JOPizer.stringClass)) { StringInfo.cli = this; } if (clazz.getClassName().equals(JOPizer.objectClass)) { nrObjMethods = clazz.getMethods().length; } } public boolean isMethodPresent(String amth) { return usedMethods.containsKey(amth); } public void addMethodOnce(String mid) { if(!isMethodPresent(mid)) { MethodInfo mi = new MethodInfo(this, mid); usedMethods.put(mid, mi); list.add(mi); //System.err.println(className+" has a new method: "+amth); } } public MethodInfo getMethodInfo(String amth) { return (MethodInfo)usedMethods.get(amth); } public MethodInfo getVTMethodInfo(String mid) { for (int i=0; i<clvt.len; ++i) { if (clvt.key[i].equals(mid)) { return clvt.mi[i]; } } return null; } public List getMethods() { return list; } public ClVT getClVT() { if (clvt==null) { clvt = new ClVT(); } return clvt; } public ClFT getClFT() { if (clft==null) { clft = new ClFT(); } return clft; } public void setInstanceSize(int size) { instSize = size; } /** * Get an IT object. * @return */ public static IT getITObject() { return new IT(); } void cntStaticFields() { int i; for (i=0; i<clft.len; ++i) { if (clft.isStatic[i]) { if (clft.isReference[i]) { cntRefStatic += clft.size[i]; } else { cntValueStatic += clft.size[i]; } } } } /** * Calculate the size of the class info table, * adjust the addresses and return the next available * address. * Calculate GC info for the instance. * @param addr * @return */ public int setAddress(int addr) { int i; instGCinfo = getGCInfo(); // the class variables (the static fields) are in a special area staticRefVarAddress = addrRefStatic; staticValueVarAddress = addrValueStatic; for (i=0; i<clft.len; ++i) { if (clft.isStatic[i]) { // resolve the address // idx is now the static address if (clft.isReference[i]) { clft.idx[i] = addrRefStatic; addrRefStatic += clft.size[i]; } else { clft.idx[i] = addrValueStatic; addrValueStatic += clft.size[i]; } } } classRefAddress = addr; // class head contains the instance size and // a pointer to the inteface table // class references point to the instance size addr += CLS_HEAD; // start of the method table, objects contain a pointer // to the start of this table (at ref-1) methodsAddress = addr; for (i=0; i<clvt.len; ++i) { MethodInfo m = clvt.mi[i]; m.vtindex = i; m.structAddress = addr; if (clazz.getClassName().equals(JOPizer.startupClass)) { if (m.methodId.equals(JOPizer.bootMethod)) { bootAddress = addr; } } if (clazz.getClassName().equals(JOPizer.mainClass)) { if (m.methodId.equals(JOPizer.mainMethod)) { mainAddress = addr; } } addr += METH_STR; } // back reference from cp-1 to class struct addr += 1; // constant pool cpoolAddress = addr;//System.out.println(clazz.getClassName()+" cplen="+clazz.getConstantPool().getLength()); // the final size of the cp plus the length field addr += cpoolUsed.size()+1; // the optional interface table iftableAddress = 0; if (clazz.getInterfaceNames().length>0) { iftableAddress = addr; addr += listIT.size(); } // add method count of class Object ! if (clazz.getClassName().equals(JOPizer.jvmClass)) { jvmAddress = methodsAddress+nrObjMethods*METH_STR; } if (clazz.getClassName().equals(JOPizer.helpClass)) { jvmHelpAddress = methodsAddress+nrObjMethods*METH_STR; } return addr; } /** * generate GC info for the instance */ private int getGCInfo() { int gcInfo = 0; for (ClassInfo clinf = this; clinf!=null; clinf = clinf.superClass) { ClFT ft = clinf.clft; for (int i=0; i<ft.len; ++i) { if (!ft.isStatic[i] & ft.isReference[i]) { gcInfo |= (1<<ft.idx[i]); } } } return gcInfo; } public void addUsedConst(int idx, int len) { Integer ii = new Integer(idx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -