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

📄 intel86jitcodegen.java

📁 java 到c的转换程序的原代码.对喜欢C程序而不懂JAVA程序的人很有帮助
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                break;        }        /* If haven't already gotten the class address into reg,         * put it there */        if (0 != cp) {            code.MOV (new Immediate (cp), reg);        }        return;    }    /** Take a value of a particular type out of memory and push it onto      * the evaluation stack.      * @param areg Register containing memory address of value; _not_ %eax      * @param tychar Encoded type of object at address      */    private void    pushFromMemory (Register areg,                    char tychar)    {        if (areg.equals (R_eax)) {            throw new InternalError ("can't use %eax as address reg in popIntoMemory");        }/* code.freeReg (R_eax); */        /* Load the whosit at areg onto the evaluation stack.  If the value         * is less than one int, extend to an int, with or without sign, as         * appropriate. */        switch (tychar) {            default:                throw new InternalError ("invalid pushFromMemory type " + tychar);            case Field.FT_void:                throw new InternalError ("invalid pushFromMemory void data.");            case Field.FT_boolean:                code.XOR (R_eax, R_eax);                code.MOV (new MemoryRef (areg).setRefSize (1), R_al);                code.pushES (R_eax);                break;            case Field.FT_byte:                code.XOR (R_eax, R_eax);                code.MOV (new MemoryRef (areg).setRefSize (1), R_al);                code.PrefixOPSIZE ();                code.CBW ();                code.CBW ();                code.pushES (R_eax);                break;            case Field.FT_char:                code.XOR (R_eax, R_eax);                code.PrefixOPSIZE ();                code.MOV (new MemoryRef (areg), R_eax);                code.pushES (R_eax);                break;            case Field.FT_short:                code.XOR (R_eax, R_eax);                code.PrefixOPSIZE ();                code.MOV (new MemoryRef (areg).setRefSize (2), R_eax);                code.CBW ();                code.pushES (R_eax);                break;            case Field.FT_float:            case Field.FT_int:            case Field.FT_object:            case Field.FT_array:                code.MOV (new MemoryRef (areg), R_eax);                code.pushES (R_eax);                break;            case Field.FT_double:            case Field.FT_long:                code.MOV (new MemoryRef (IMM_4, areg), R_eax);                code.pushES (R_eax); // msw                code.MOV (new MemoryRef (areg), R_eax);                code.pushES (R_eax); // lsw                break;        }        return;    }    /** Take a value of a particular type off the stack and store it into      * memory.      * @param areg Register containing memory address of value; _not_ %eax      * @param tychar Encoded type of object to be stored at address      */    private void    popIntoMemory (Register areg,                   char tychar)    {        if (areg.equals (R_eax)) {            throw new InternalError ("can't use %eax as address reg in popIntoMemory");        }        /* Load the whosit at areg onto the evaluation stack.  If the value         * is less than one int, extend to an int, with or without sign, as         * appropriate. */        code.popES (R_eax);        switch (tychar) {            default:                throw new InternalError ("invalid popIntoMemory type " + tychar);            case Field.FT_void:                throw new InternalError ("invalid popIntoMemory void data.");            case Field.FT_boolean:            case Field.FT_byte:                code.MOV (R_al, new MemoryRef (areg).setRefSize (1));                break;            case Field.FT_char:            case Field.FT_short:                code.PrefixOPSIZE ();                code.MOV (R_eax, new MemoryRef (areg));                break;            case Field.FT_float:            case Field.FT_int:            case Field.FT_object:            case Field.FT_array:                code.MOV (R_eax, new MemoryRef (areg));                break;            case Field.FT_double:            case Field.FT_long:                code.MOV (R_eax, new MemoryRef (areg)); // lsw                code.popES (R_eax);                code.MOV (R_eax, new MemoryRef (IMM_4, areg)); // msw                break;        }        return;    }        /* %ebx has been initialized to an object reference.  Return one or zero     * in %eax depending on whether the object can be cast to the provided     * class. */    private void    EmitCkInstance (Instr i,                    ClassRef cr)    {        int iv;        /* code.freeReg (R_eax); */        /* If the target type is Object, the cast always succeeds, whether         * the object is of non-array or array class. */        if (cr.name.equals ("java.lang.Object")) {            code.MOV (IMM_1, R_eax);            return;        }/* code.freeReg (); // all of them */        /* Get a pointer to the C class of the object into %o1. */        code.MOV (MR_ebx, R_esi);                if (Field.FT_array != cr.name.charAt(0)) {            /* Non array objects: if going to an interface, %esi must implement             * it; if going to a class, %esi must be a subclass of it.  We don't             * know yet whether this is a class or an interface, so have to             * make the decision at runtime. */            code.reserveCode (CodeBlock.brLOADNatCl, i, R_edi, cr);            code.MOV (new MemoryRef (IO_class_flags, R_edi), R_eax);            code.TEST (new Immediate (ClassRT.IS_INTERFACE), R_eax);            code.Jccn (Intel86.CND_nz, IMM_0);            int bo_isiface = code.nextByteOffs ();            /* Is not an interface: we're OK iff o2 is a super class of %esi. */            code.MOV (new MemoryRef (IO_class_nsupers, R_esi), R_ecx);            code.MOV (new MemoryRef (IO_class_nsupers, R_edi), R_edx);            code.SUB (R_edx, R_ecx);            code.Jccn (Intel86.CND_l, IMM_0);            int bo_fail1 = code.nextByteOffs ();            /* OK, %esi->nsupers >= o2->nsupers.  See if the superclass up             * that high is right.             * %esi->supers[%esi->nsupers-%edi->nsupers] == o2 */            code.MOV (new MemoryRef (IO_class_supers, R_esi), R_esi);            code.MOV (new MemoryRef (null, R_esi, 4, R_ecx, 4), R_ecx);            code.CMP (R_ecx, R_edi);            /* If not equal, jump to the failure point */            code.Jccn (Intel86.CND_ne, IMM_0);            int bo_fail2 = code.nextByteOffs ();            /* Are equal: cast is OK. */            code.MOV (IMM_1, R_eax);            code.JMPn (IMM_0);            int bo_exit1 = code.nextByteOffs ();            /* OK, here on out it's an interface.  Just call instanceof. */            code.PatchNearJump (bo_isiface, (code.nextByteOffs() - bo_isiface));            /* We already have %ebx as the object ref, %edi as the target             * class pointer.  Rearrange to meet the parameter requirements             * of instanceof(Object,Class,ArrayDim). */            code.PUSH (IMM_0);            code.PUSH (R_edi);            code.PUSH (R_ebx);            code.reserveCode (CodeBlock.brACALL, i, null, FA_instanceof);            code.ADD (new Immediate (3*4), R_esp);            /* Jump to exit */            code.JMPn (IMM_0);            int bo_exit2 = code.nextByteOffs ();                        /* Fail: backpatch all fails, and clear the return value */            code.PatchNearJump (bo_fail1, (code.nextByteOffs() - bo_fail1));            code.PatchNearJump (bo_fail2, (code.nextByteOffs() - bo_fail2));            code.XOR (R_eax, R_eax);            /* Exit: backpatch all exits */            code.PatchNearJump (bo_exit1, (code.nextByteOffs() - bo_exit1));            code.PatchNearJump (bo_exit2, (code.nextByteOffs() - bo_exit2));                        return;        }        if ((Field.FT_array != cr.name.charAt(1)) &&            (Field.FT_object != cr.name.charAt(1))) {            /* Array of primitive object: class has to be array of that             * primitive object.  Load the pointer to the appropriate class,             * hiding inside the acl_Foo object. */            loadClassPointer (i, cr, 1, R_edi);            /* Presume this will work, to simplify control flow */            code.MOV (IMM_1, R_eax);            /* See if classes match */            code.CMP (R_esi, R_edi);            code.Jccn (Intel86.CND_e, IMM_0);            int bo_exit = code.nextByteOffs ();            /* Nope, set to fail. */            code.XOR (R_eax, R_eax);            /* Here's where we go out. */            code.PatchNearJump (bo_exit, (code.nextByteOffs() - bo_exit));                    }        /* General array of object.  Count up the array depth,         * and call instanceof checking against the base class of the         * target class. */        int n = 0;        while (Field.FT_array == cr.name.charAt(n)) {            ++n;        }        if (Field.FT_object == cr.name.charAt(n)) {            /* Problem: loadClassPointer can't get the base class, because             * classes haven't been resolved yet.  So just call as 0, and have             * instanceof do the walk down the array chain. */            /* !!TOFIX!! We really need to be able to get ClassRefs that             * will be resolved, when we only have a string name. */            n = 0;        }        /* Already have object reference in %ebx.  Put class pointer into         * %edi, presuming this loadClassPointer function will go down to         * the base object.  Put array rank into %edi.  Call instanceof. */        code.PUSH (new Immediate (n));        loadClassPointer (i, cr, 0, R_eax);        code.PUSH (R_eax);        code.PUSH (R_ebx);        code.reserveCode (CodeBlock.brACALL, i, null, FA_instanceof);        code.ADD (new Immediate (3*4), R_esp);    }    /** Add the code for a JVM instruction to the code cache      * @param i the instruction to generate code for      * @param m the method that i appears in      */    private void    EmitCode (Method m,         // Method we're in              int idx)          // Index of instruction to work with    {        Instr i;                // Instruction we're working with        Opcode opc;             // Opcode for instruction        int lvi;                // Local variable index        MethodRef mr;           // MethodRef for operand        VariableRef vr;         // VariableRef for operand        FieldRef fr;            // FieldRef for operand        Constant cn;            // Constant for operand        Class c;                // Class for m        Field f;                // Field for m in c        int aw;                 // Number of argwords        int ab;                 // Number of arg bytes        long adr;               // Generic address value        String opdtype;         // Type of operand        int iv;                 // Intermediate int value        long lv;                // Intermediate long value        ClassRef cr;            // Class reference value        char tychar;            // Type character, from Field.FT_*        int boffs;              // Branch offset, for local backpatching        int boffs2;             // Another branch offset, for local backpatching        int boffs3;             // Another branch offset, for local backpatching        BackpatchInfo bpi;      // Backpatch info structure created        i = m.instrs [idx];//        System.out.println (i.toString());        /* Mark where code related to this instruction starts. */        if (idx >= code.instrToByteOffs.length) {            throw new InternalError ("EmitCode: idx " + idx + " but iTBO length " + code.instrToByteOffs.length +                                        " with instr len " + m.instrs.length);        }        code.instrToByteOffs [idx] = code.nextByteOffs ();        /* Tell the low-level generator where the evaluation stack         * is at right now.  For the most part, this will be either the same         * as the previous instruction, or zero at the top of a basic block,         * but in the presence of trinary operators it can be non-empty at         * the start of a basic block.  We have to assume that the evaluation         * stack is in a check-pointed state then. *///        int oesd = code.getEStackDepth ();//        int nesd = i.before.length ();//        if ((oesd != nesd) && (0 != nesd) && (Opcode.POP != i.opcode.code)) {//            System.out.println ("In " + m.cl.name + "." + m.fl.name + " from:\n" + m.instrs[idx-1] + "\nset estack from " + code.getEStackDepth () + " to " + i.before.length () + " before:\n" + i);//        }        code.setEStackTop (i.before.length());        /* If we're doing exception handling, we need to update the pc         * variable so we can tell where the exception was raised. */        if (0 < m.handlers.length) {            code.MOV (new Immediate (i.pc), excOheadAddr (ARLV_pc));        }        /* If instrumentation is enabled, increment the counter for this         * instruction. */        if (null != instrcounts) {            code.INC (new MemoryRef (new Immediate ((int) (icaddr + 4 * i.opcode.code)), null));        }        /* We can often deal with a bunch of instructions at once, so         * we switch on the opcode kind, rather than the exact opcode. */        opc = i.opcode;        switch (opc.kind) {        

⌨️ 快捷键说明

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