⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kvmstackmap.java

📁 已经移植好的java虚拟机
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *		KVMStackMap.java		1.4		01/02/02		SMI * * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").	 You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * Use is subject to license terms. */package runtime;import components.*;import jcc.Util;import vm.EVMMethodInfo;import util.*;import java.io.ByteArrayOutputStream;import vm.Const;/* * The CoreImageWriter for the Embedded VM */public class KVMStackMap implements Const {     KVMWriter    writer;    KVMNameTable nameTable;    public KVMStackMap(KVMWriter writer, KVMNameTable nameTable) { 	this.writer = writer;	this.nameTable = nameTable;    }    private long    frameToLong(MethodInfo mi, StackMapFrame frame) { 	boolean[] locals = frame.getLocalsBitmap();	boolean[] stack = frame.getStackBitmap();	int maxLocals = mi.locals;	long stackMap = 0;	// this gives us 64 bits	for (int i = 0; i < locals.length; i++) { 	    if (locals[i]) { 		stackMap |= 1L << i;	    }	}	for (int i = 0; i < stack.length; i++) { 	    if (stack[i]) { 		stackMap |= 1L << (i + maxLocals);	    }	}	return stackMap;    }    private String frameToString(MethodInfo mi, StackMapFrame frame) {	long stackMap = frameToLong(mi, frame);	StringBuffer sb = new StringBuffer();	sb.append((char)frame.getStackSize());	while (stackMap != 0) { 	    sb.append((char)(stackMap & 0xFF));	    stackMap = stackMap >>> 8;	}	String result = sb.toString();	return result;    }    public void initialPass(EVMMethodInfo meth) { 	MethodInfo mi = meth.method;	StackMapFrame frames[] = mi.stackMapTable;	if (frames != null) {             // removeExtraStackMaps(meth);            if (!useShortStackMaps(meth)) {                 for (int i = 0; i < frames.length; i++) {                     nameTable.getKey(frameToString(mi, frames[i]));	                }            }        }    }    void showStatistics() {         if (removeKeep + removeBut + removeSame > 0) {             System.out.println("Total: " +                                (removeKeep +  removeBut + removeSame));            System.out.println("Keep:  " + (removeKeep));            System.out.println("Toss:  " + (removeSame));            System.out.println("But:   " + (removeBut));            System.out.println("Long stack maps: " + longStackMaps);        }    }    void printDeclaration(CCodeWriter out, EVMMethodInfo meth, String prefix)     {	String methodNativeName = meth.getNativeName();	MethodInfo mi = meth.method;	out.println(prefix + "struct { /* " 		    + mi.parent.className + ": " + writer.prettyName(mi) + "*/");	out.println(prefix + "\tunsigned short length;");	if (useShortStackMaps(meth)) { 	    out.println(prefix + "\tstruct { unsigned short offset; "			+ "unsigned char map[2]; } frame["			+ mi.stackMapTable.length + "];");	} else { 	    out.println(prefix + "\tstruct { unsigned short offset; "			+ "unsigned short info; } frame["			+ mi.stackMapTable.length + "];");	}	out.println(prefix + "} " + methodNativeName + ";");    }    void printDefinition(CCodeWriter out, EVMMethodInfo meth, String prefix)    {	MethodInfo mi = meth.method;	StackMapFrame frames[] = mi.stackMapTable;	String pprefix = prefix + "\t";	out.println(prefix + "{ /* " + mi.parent.className + ": " 		    + writer.prettyName(mi) + "*/");	boolean useShort = useShortStackMaps(meth);		out.println(pprefix + frames.length + (useShort ? " | STACK_MAP_SHORT_ENTRY_FLAG" : "") + ",");	out.println(pprefix + "{");	for (int i = 0; i < frames.length; i++) { 	    StackMapFrame frame = frames[i];	    int offset = frame.getOffset();	    out.print(pprefix + "\t\t");	    printComment(out, meth, frame);	    out.println();	    if (useShort) { 		int map = (int)frameToLong(mi, frame);		out.print(pprefix + "\t{" + offset + " + (" + 			  frame.getStackSize() + " << 12), { ");		out.printHexInt(map & 0xFF);		out.print(", ");		out.printHexInt((map >> 8) & 0xFF);		out.print(" }");	    } else { 		String string = frameToString(mi, frame);		int key = nameTable.getKey(string);		out.print(pprefix + "\t{" + offset + ", " );		out.printHexInt(key);	    }	    out.print("}");	    if (i < frames.length - 1) { 		out.println(",");	    } else { 		out.println();	    }	}	out.println(pprefix + "}");	out.println(prefix + "},");    }    java.util.Hashtable useShortStackMapsCache = new java.util.Hashtable();    static int longStackMaps;    public boolean useShortStackMaps(EVMMethodInfo meth) {         Boolean value = (Boolean)useShortStackMapsCache.get(meth);        if (value != null) {             return value.booleanValue();        } else {             boolean result = useShortStackMapsInternal(meth.method);            if (result) {                 useShortStackMapsCache.put(meth, Boolean.TRUE);            } else {                 useShortStackMapsCache.put(meth, Boolean.FALSE);                longStackMaps++;            }            return result;        }    }    boolean useShortStackMapsInternal(MethodInfo mi) {         if (mi.code.length > 1023) {             return false;        } else if (mi.stack <= 15 && mi.locals + mi.stack <= 16) {             /* This is almost always they case */            return true;        } else {             StackMapFrame frames[] = mi.stackMapTable;            for (int i = 0; i < frames.length; i++) {                 if (frames[i].getStackSize() > 15) {                     return false;                }                if (frameToLong(mi, frames[i]) > 65535) {                     return false;                }            }            return true;	}    }    String frameToComment(MethodInfo mi, StackMapFrame frame) { 	StringBuffer sb = new StringBuffer();	boolean[] locals = frame.getLocalsBitmap();	boolean[] stack = frame.getStackBitmap();	int maxLocals = mi.locals;	int maxStack = mi.stack;	sb.append("Locals: ");	for (int i = 0; i < locals.length; i++) { 	    sb.append(locals[i] ? 'X' : '-');	}	for (int i = locals.length; i < maxLocals; i++) { 	    sb.append('.');	}	sb.append("; Stack: ");	for (int i = 0; i < stack.length; i++) { 	    sb.append(stack[i] ? 'X' : '-');	}	return sb.toString();    }    private void     printComment(CCodeWriter out, EVMMethodInfo meth, StackMapFrame frame)     { 	MethodInfo mi = meth.method;	boolean[] locals = frame.getLocalsBitmap();	boolean[] stack = frame.getStackBitmap();	int maxLocals = mi.locals;	int maxStack = mi.stack;	out.print("/* Locals: ");	if (maxLocals == 0) { 	    out.print("<None>");	} else { 	    for (int i = 0; i < locals.length; i++) { 		out.write(locals[i] ? 'X' : '-');	    }	    for (int i = locals.length; i < maxLocals; i++) { 		out.write('.');	    }	}	out.print("; Stack: ");	if (stack.length == 0) { 	    out.print("<None>");	} else { 	    for (int i = 0; i < stack.length; i++) { 		out.write(stack[i] ? 'X' : '-');	    }	} 	out.print(" */");    }        /* This is some experimental code that we're not yet using.     * It allows us to delete some unneeded stack maps from the code.     */    private boolean removeVerbose = false;    private int removeKeep, removeBut, removeSame;    private void    removeExtraStackMaps(EVMMethodInfo meth) { 	MethodInfo mi = meth.method;        ClassInfo ci = mi.parent;        ConstantObject cpool[] = ci.constants;	StackMapFrame frames[] = mi.stackMapTable;        boolean[] locals = new boolean[mi.locals];        boolean[] stack = new boolean[mi.stack];        boolean[] discardList = new boolean[frames.length];        int discardCount = 0;        byte[] code = mi.code;        int stackSize = 0;        int thisIP = 0;        boolean needStackmap = false;        int currentFrameIndex = 0;        if (removeVerbose) {             System.out.println("Method: " +                                ci.className + "." + writer.prettyName(mi));        }        initializeLocals(mi, locals);        for (thisIP = 0; thisIP < code.length; ) {                         StackMapFrame currentFrame = null;            boolean[] newStack = null;            boolean[] newLocals = null;                        if (currentFrameIndex < frames.length) {                 if (frames[currentFrameIndex].getOffset() < thisIP) {                     throw new RuntimeException("Missed stack frame??");                } else if (frames[currentFrameIndex].getOffset() == thisIP) {                    currentFrame = frames[currentFrameIndex];                    newStack = currentFrame.getStackBitmap();                    boolean[] temp = currentFrame.getLocalsBitmap();                    if (temp.length == locals.length) {                         newLocals = temp;                    } else {                         newLocals = new boolean[mi.locals];                        System.arraycopy(temp, 0, newLocals, 0, temp.length);                    }                 }            }                        if (removeVerbose) {                 if (currentFrame != null || thisIP == 0) {                     System.out.print("    Old: ");                    for (int i = 0; i < locals.length; i++) {                         System.out.print(locals[i] ? 'X' : '-');                    }                    System.out.print(' ');                    for (int i = 0; i < stackSize; i++) {                         System.out.print(stack[i] ? 'X' : '-');                    }                    System.out.println();                }                if (currentFrame != null) {                     System.out.print("    New: ");                    for (int i = 0; i < newLocals.length; i++) {                         System.out.print(newLocals[i] ? 'X' : '-');                    }                    System.out.print(' ');                    for (int i = 0; i < newStack.length; i++) {                         System.out.print(newStack[i] ? 'X' : '-');                    }                }            }                        if (needStackmap) {                 if (currentFrame == null) {                     throw new RuntimeException("Expected stack map at "                                                + thisIP);                }            }                         if (currentFrame != null) {                 if (!needStackmap && (newStack.length != stackSize)) {                     throw new RuntimeException("Inconsistent stack size at " +                                                thisIP);                }                boolean same = sameStackMaps(locals, stack, stackSize,                                              newLocals, newStack);                if (!same) {                     removeKeep++;                } else if (needStackmap) {                     removeBut++;                } else {                     removeSame++;                    discardCount++;                    discardList[currentFrameIndex] = true;                }                if (removeVerbose) {                     System.out.print(same ? "=" : "#");                    System.out.println(needStackmap ? "+" : "-");                }            }            if (currentFrame != null) {                 locals = newLocals;                stackSize = newStack.length;                System.arraycopy(newStack, 0, stack, 0, stackSize);                currentFrameIndex++;            }            needStackmap = false;            if (removeVerbose) {                 System.out.print(thisIP + ": " +                                  mi.disassemble(thisIP, thisIP + 1));                /* Note, that the println is at the end */            }            int token = code[thisIP++] & 0xFF;            int index;            switch(token) {                /* Store a single non pointer from the stack to a register */            case opc_istore: case opc_fstore:                index = code[thisIP++] & 0xFF;                locals[index] = false;                stackSize--;                break;                /* Store a single pointer from the stack to a register */            case opc_astore:                index = code[thisIP++] & 0xFF;                locals[index] = true;                stackSize--;                break;                                /* Store a double or long from the stack to a register */            case opc_lstore: case opc_dstore:                index = code[thisIP++] & 0xFF;                locals[index] = false;                locals[index+1] = false;                stackSize -= 2;                break;            case opc_istore_0: case opc_istore_1:             case opc_istore_2: case opc_istore_3:                index = token - opc_istore_0;                locals[index] = false;                stackSize--;                break;            case opc_lstore_0: case opc_lstore_1:             case opc_lstore_2: case opc_lstore_3:                index = token - opc_lstore_0;                locals[index] = false;                locals[index+1] = false;                stackSize -= 2;                break;            case opc_fstore_0: case opc_fstore_1:             case opc_fstore_2: case opc_fstore_3:                index = (token - opc_fstore_0);                locals[index] = false;                stackSize--;                break;            case opc_dstore_0: case opc_dstore_1:             case opc_dstore_2: case opc_dstore_3:                index = (token - opc_dstore_0);                locals[index] = false;                locals[index+1] = false;                stackSize -= 2;                break;            case opc_astore_0: case opc_astore_1:             case opc_astore_2: case opc_astore_3:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -