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

📄 intel86jitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    private static final int ARLV_oldbuf = 1; // void *    private static final int ARLV_newbuf = 0; // jmp_buf    /* Probably the first few are one word, but maybe not.  jmp_buf is a     * pretty good sized structure.  The first array of ints is     * initialized to the sizes of these objects; the second to their     * offsets within an activation record. */    private static int excOheadSize [];    private static int excOheadOffs [];    private static int excOheadTotal;    /** Return the number of bytes required to hold each of the local      * overhead variables.  The order of storage must match the index      * ordering of ARLV_foo above.      * @returns array of ints with variable sizes.      * Toba hash code: __Ds3WL      */    private static native int[]    getOverheadSize ();    /* Overhead initialization */    static {        int offs;        int i;                /* Get the size of the local variables, then compute their offsets,         * with necessary alignments. */        excOheadSize = getOverheadSize ();        excOheadOffs = new int [excOheadSize.length];        offs = 0;        for (i = 0; i < excOheadSize.length; i++) {            if (4 < excOheadSize [i]) {                // 8-byte align large elements                offs = (7 + offs) & ~0x07;            } else {                // 4-byte align normal elements                offs = (3 + offs) & ~0x03;            }            excOheadOffs [i] = offs;            offs += excOheadSize [i];        }        // 8-byte align whatever follows        excOheadTotal = (7 + offs) & ~0x07;        /* Go through and update the offsets so we can get to values         * at %ebp[- (overheadOffs + excOheadOffs[ARLV])]. */        for (i = 0; i < excOheadOffs.length; i++) {            excOheadOffs [i] = (excOheadTotal - excOheadOffs [i]);//            System.out.println ("OH " + i + " is at " + excOheadOffs [i] + " of " + excOheadTotal);        }    }    /* This is the offset from %ebp to where the overhead data starts.     * Covers: %esi, %edi, %ebx */    private int overheadOffs = 3 * 4;    /* This is the overhead size for this code's AR: either 0 or     * excOheadTotal */    private int overheadSize;    /** Convert from local variable number to a MemoryRef operand representing      * a load from the AR.      * @param lvi The local variable offset; starts from zero      * @returns reference to stack location of local variable */    private MemoryRef    LVOffs (int lvi)    {        return new MemoryRef (new Immediate (- (overheadOffs + overheadSize + 4 * (1 + lvi))), R_ebp);    }    private MemoryRef    excOheadAddr (int arlv)    {//        System.out.println (arlv + " is " + (overheadOffs + excOheadOffs [arlv]) + " below %ebp");        return new MemoryRef (new Immediate (- (overheadOffs + excOheadOffs [arlv])), R_ebp);    }    /** Allocate activation record, preserve callee-saved registers, and      * copy parameters onto Java stack.      * @param m method for which we're generating code      * @param ndata number of words to reserve for local data; -1 for normal method      */    private void    Prologue (Method m,         // What we're generating code for              int ndata)        // Number of data words for special AR    {        int i;                  // General purpose index        int maxcaw;             // Maximum callee argument words        int aw;                 // Callee argument words//        System.out.println ("Method argstack in: " + m.astack + " rstack " + m.rstack);        /* Start by saving the old base pointer, and setting the new         * one. */        code.PUSH (R_ebp);        code.MOV (R_esp, R_ebp);                /* Build up the frame size as we add things to the stack */        frame_size = 0;        /* Save the basic offset for the overhead information */        overheadOffs = frame_size;                /* What kind of AR are we generating? */        if (0 <= ndata) {            /* If we were told a non-zero amount of local data to store, just do             * that.  We're probably generating the AR for a synchronization             * wrapper.  NB: The caller is responsible for setting overheadSize,             * _before_ this function is called. */            frame_size += overheadSize;            frame_size += 4 * ndata;        } else {            /* We're computing what's needed for the method under consideration.             * Now, if there's an exception handler, we need to add local storage             * for some support data. */            overheadSize = 0;            if ((null != m.handlers) && (0 < m.handlers.length)) {                overheadSize = excOheadTotal;            }            frame_size += overheadSize;            /* Now add space for local Java variables */            frame_size += 4 * m.max_locals;            /* Here's where the Java evaluation stack starts.  Inform             * the low-level code generator, so it can maintain the ES             * pointer when it pushes and pops. */            code.setEStackBase (frame_size);            /* Add space for the Java evaluation stack */            frame_size += 4 * m.max_stack;        }        /* Sanity checks: frame size must be word-aligned */        if (0 != (frame_size % 4)) {            throw new InternalError ("frame size not multiple of 4");        }                /* Set the stack pointer to be below what we've reserved. */        code.SUB (new Immediate (frame_size), R_esp);        /* Presume we're going to modify all the callee-saved registers, so         * save them now. */        code.PUSH (R_esi);        code.PUSH (R_edi);        code.PUSH (R_ebx);        /* Stuff the name of this function in the standard location.         * NB: We can only do this if there are exception handlers, because         * otherwise we didn't allocate space for local variables on         * the AR. */        if ((null != m.handlers) && (0 < m.handlers.length)) {            code.MOV (new Immediate ((int)getStringAddress (m.cl.name + "." + m.fl.name)), excOheadAddr (ARLV_methname));//        code.PUSH (excOheadAddr (ARLV_methname));//        code.reserveCode (CodeBlock.brACALL, m.instrs[0], null, FA_puts);//        code.ADD (new Immediate (2), R_esp);        }        /* If we're creating a standard frame for executing Java code, then         * store the arguments into the local variable arena.  If not,         * whoever's creating us should take responsibility for preserving         * arguments. */        if (0 > ndata) {            int an;             // Number of arguments moved            int naw;            // Number of argument words moved            char c;             // Char denoting argument type            /* The problem here is that the JVM local variables are in the             * wrong order relative to how the parameters are passed on             * the Intel stack.  We need to reverse them; but we can't             * reverse the words in 64-bit entities.  So we walk through             * doing copies from the caller args into the JVM locals             * based on the type of the parameters.  Fortunately, all             * parameters of 1 or 2 bytes are passed as full 4-byte words. */            /* Keep track of the number of words transferred so far. */            naw = 0;            /* If this is an instance method, the first whosit is the             * object reference. */            if (0 == (m.fl.access & ClassData.ACC_STATIC)) {                code.MOV (new MemoryRef (IMM_8, R_ebp), R_eax);                code.MOV (R_eax, LVOffs(0));                ++naw;            }            naw = 0;            while (naw < m.astack.length()) {                if ('x' == m.astack.charAt (naw)) {                    /* Copy over a double word, stored LSW MSW, and                     * preserve its order. */                    code.MOV (new MemoryRef (new Immediate (8+4*naw), R_ebp), R_esi); // LSW                    code.MOV (new MemoryRef (new Immediate (12+4*naw), R_ebp), R_edi); // MSW                    code.MOV (R_esi, LVOffs (naw+1)); // LSW                    code.MOV (R_edi, LVOffs (naw)); // MSW                    naw += 2;                } else {                    /* Copy over a single word */                    code.MOV (new MemoryRef (new Immediate (8+4*naw), R_ebp), R_eax);                    code.MOV (R_eax, LVOffs (naw));                    naw++;                }            }        }        /* Call the yield function if there is one */        if (null != m.instrs) {            emitBackJumpCall (m.instrs[0]);        }        return;    }    /* Given an array structure at %ebx, and an index at %eax, make     * sure the index is legitimate, and compute the address of the     * desired element.  The element address is returned in %ebx. */    private void    emitEltOffsetCode (int esz,                       Instr ins)    {        int sf;        /* Make sure the array reference isn't null. */                code.OR (R_ebx, R_ebx);        code.Jccn (Intel86.CND_nz, IMM_0);        int boffs = code.nextByteOffs ();        /* Call throwNullPointerException (0) */        code.PUSH (IMM_0);        code.reserveCode (CodeBlock.brACALL, ins, null, FA_throwNPE);        /* No need to pop args; we never return here. */        code.UNIMP (0);        // sure about that?        /* Here's where we end up if we were nz */        code.PatchNearJump (boffs, code.nextByteOffs() - boffs);                /* Make sure the index is in range. */        code.OR (R_eax, R_eax);        code.Jccn (Intel86.CND_l, IMM_0);        boffs = code.nextByteOffs ();        /* ecx = ebx->length */        code.MOV (new MemoryRef (IO_barray_length, R_ebx), R_ecx);        /* eax < ecx? */        code.CMP (R_ecx, R_eax);        code.Jccn (Intel86.CND_l, IMM_0);        code.PatchNearJump (boffs, code.nextByteOffs() - boffs);        boffs = code.nextByteOffs ();        code.PUSH (R_eax);        code.PUSH (R_ebx);        code.reserveCode (CodeBlock.brACALL, ins, null, FA_throwAIOBE);        code.UNIMP (0);        // sure about that?        /* Here's where we end up if we were in range */        code.PatchNearJump (boffs, code.nextByteOffs() - boffs);        code.LEA (new MemoryRef (IO_barray_data, R_ebx, esz, R_eax, 4), R_ebx);        return;    }    /** Generate code to initialize a class if necessary, leaving the class      * reference in %ebx.      * @param i the instruction that induced the initialization requirement      * @param or the reference to the object (FieldRef or ClassRef) that may need to be initialized      */    private void    emitClassInit (Instr i,                   Object or)    {        int boffs;                /* Load the address of the native struct class object that is the         * basis of the object referred to by fr. */        code.reserveCode (CodeBlock.brLOADNatCl, i, R_ebx, or);        /* The first word of the class object is the flag indicating         * whether it needs to be initialized.  If that's zero, the class         * has been initialized, and we skip over the call to the         * initializer.*/        code.CMP (IMM_0, MR_ebx);        code.Jccn (Intel86.CND_z, IMM_0);        boffs = code.nextByteOffs ();        code.PUSH (R_ebx);        code.reserveCode (CodeBlock.brACALL, i, null, FA_initclass);        code.ADD (IMM_4, R_esp);        code.PatchNearJump (boffs, code.nextByteOffs() - boffs);    }    /** Push na arguments off the evaluation stack onto the code stack for      * calling a C function.   ES args are popped last to first, so first      * arg is at top of C stack.  MUST NOT TRASH %eax.      * @param nwords number of words used as parameters      * @returns int number of bytes pushed onto stack */    private int    setCallArgs (int nwords)    {        int an;        for (an = 0; an < nwords; an++) {            code.PUSH (new MemoryRef (new Immediate (code.peekEStackOffs (an)), R_ebp));        }        code.tossES (nwords);        return 4*nwords;    }    /** Get arguments off evaluation stack and put them where they're      * needed for the function call.      * @param sig Signature of caller's parameters      * @returns int number of bytes pushed onto stack */    private int    setCallArgs (String sig)    {        int naw;                // Number of words in arguments        int an;                 // Argument word counter        an = 0;        naw = sig.length () - 1;        while (0 <= naw) {            if ((0 < naw) && ('x' == sig.charAt (naw-1))) {                /* Copy over a double word, stored LSW MSW, and                 * preserve its order. */                code.PUSH (new MemoryRef (new Immediate (code.peekEStackOffs (an+1)), R_ebp)); // msw                code.PUSH (new MemoryRef (new Immediate (code.peekEStackOffs (an)), R_ebp)); // lsw                naw -= 2;

⌨️ 快捷键说明

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