?? intel86jitcodegen.java
字號:
/** use just-in-time compilation to generate code for methods * @version $Id: Intel86JITCodeGen.java,v 1.17 1999/04/06 03:30:37 pab Exp $ *//* This is part of the Just-In-Time compiler for the Toba system. NB: * Although we work with an instance of this class, the code is not * necessarily clean for multiple active instances; cf the static * variables. */package toba.jit;/* A note about REQUIRE: At various locations in this module are comments * which start with !! REQUIRE. The body of those comments is a C equality * test, which verifies that some constant we're using in the jit, normally * dealing with the offset of a particular field in a runtime structure, is * still correct (nobody mucked with structure layout). The requirements * are parsed by genRequire, which emits a body of C code that should * be inserted into runtime_CodeGen.c. *//* We need the basic Toba runtime data structures, and the classfile * structures. */import toba.runtime.*;import toba.classfile.*;classJITCodeGenextends CodeGen { /** Initialize the CodeGen class so its generator points to us. * This must be done before anybody touches code generation, because * the system class loader is going to look at CodeGen.generator, * and if it's null will die a quick and painful death. */ public static void Initialize () { JITCodeGen jcg; /* Verify our requirements */ CodeGen.verifyRequirements (); /* Set the global code generator to use one of us. Do _NOT_ throw * away one we've already assigned; we may have done some initialization * in the C code (specifically, codegen_init). */ jcg = (JITCodeGen) CodeGen.getGenerator (); if (null == jcg) { CodeGen.setGenerator (jcg = new JITCodeGen ()); } } /* Chances are, we'll have done this explicitly (since CodeGen.generator * can be examined without being an active use of JITCodeGen), but * just in case.... */ static { Initialize (); } /** Trivial constructor */ public JITCodeGen () { super(); } /** Return the native data address of a java array. * Toba hash code: _O_TCJx0 */ public native static long getArrayDataAddress (Object ap); /** Return a pointer to a C-format string containing this data. * Toba hash code: _S_Z43yi */ public native static long getStringAddress (String s); /* Primitive instrumentation support: counts the number of instructions * executed dynamically in code jit'd with this code generator, and * emits that information at the end of the program. */ private int instrcounts []; // Array of counts private long icaddr; // Native pointer to array data public void InitInstrumentation () { int i; instrcounts = new int [256]; i = instrcounts.length; while (0 <= --i) { instrcounts [i] = 0; } icaddr = getArrayDataAddress (instrcounts); } public void SummarizeInstrumentation () { int i; if (0 == icaddr) { return; } System.out.println ("\n# Dynamic JVM instruction counts:"); for (i = 0; i < instrcounts.length; i++) { if (0 != instrcounts [i]) { Opcode opc = Opcode.lookupOpcode (i); System.out.println (opc.name + ": " + instrcounts [i]); } } } /** With glibc2 (libc6 under Linux), setjmp becomes a two-argument * call to sigsetjmp; second argument should be zero. This flag is set * in codegen_init to indicate whether we need to set up the second * argument. */ protected boolean useBinarySetjmp = false; /** With SCOUT_THREADS, the overhead of pre-emption handling with calling * yield on each back edge is too high; use a comparison between two * longs to determine whether the time has reached a point where it * is appropriate to call the yield function. */ protected boolean useScoutThreadPreemption = false; private static final Register R_eax = Register.R_eax; private static final Register R_ecx = Register.R_ecx; private static final Register R_edx = Register.R_edx; private static final Register R_ebx = Register.R_ebx; private static final MemoryRef MR_ebx = new MemoryRef (R_ebx); private static final Register R_esp = Register.R_esp; private static final MemoryRef MR_esp = new MemoryRef (R_esp); private static final Register R_ebp = Register.R_ebp; private static final Register R_esi = Register.R_esi; private static final Register R_edi = Register.R_edi; private static final Register R_al = Register.R_al; private static final Register R_bl = Register.R_bl; private static final Register R_cl = Register.R_cl; private static final Register R_dl = Register.R_dl; private static final Register R_ah = Register.R_ah; private static final Register R_bh = Register.R_bh; private static final Register R_ch = Register.R_ch; private static final Register R_dh = Register.R_dh; private static final Register R_ST0 = Register.R_ST0; private static final Register R_ST1 = Register.R_ST1; private static final Register R_ST2 = Register.R_ST2; private static final Register R_ST3 = Register.R_ST3; private static final Register R_ST4 = Register.R_ST4; private static final Register R_ST5 = Register.R_ST5; private static final Register R_ST6 = Register.R_ST6; private static final Register R_ST7 = Register.R_ST7; /** Allocate a block of sz bytes in uncollectable memory. * @param sz number of bytes we need * @returns address of allocated block * Toba Hash: _i_qYFS3 */ private static native long allocUncolMemory (int sz); /* Function ID values to name functions. Must match the defs in * runtime/jit_JITCodeGen.c. Where's an include facility when you * need one? */ static final int FID_new = 1; static final int FID_anewarray = 2; static final int FID_initclass = 3; static final int FID_vmnewarray = 4; static final int FID_throwAIOBE = 5; static final int FID_geteltoffs = 6; static final int FID_intdiv = 7; static final int FID_intrem = 8; static final int FID_longdiv = 9; static final int FID_longrem = 10; static final int FID_longmul = 11; static final int FID_remdr = 12; static final int FID_dtoi = 13; static final int FID_dtol = 14; static final int FID_longshift = 15; static final int FID_long2f = 16; static final int FID_long2d = 17; static final int FID_longcmp = 18; static final int FID_puts = 19; static final int FID_throwNPE = 20; static final int FID_mythread = 21; static final int FID_sthread_got_exc = 22; static final int FID_setjmp = 23; static final int FID_longjmp = 24; static final int FID_findhandler = 25; static final int FID_athrow = 26; static final int FID_monitorenter = 27; static final int FID_monitorexit = 28; static final int FID_throwCCE = 29; static final int FID_instanceof = 30; static final int FID_findinterface = 31; static final int FID_throwNASE = 32; static final int FID_enterclass = 33; static final int FID_exitclass = 34; static final int FID_backjumpfn = 35; static final int FID_timeNow = 36; static final int FID_timeSliceEnd = 37; static final int FID_throwJITIntErr = 38; static final int FID_CodeBlock_resolveCode = 39; /** Return some arbitrary function's address * @param fid an index naming the function we want * @returns address as long * Toba hash code: _i_m3SYh */ private static native long getFuncAddr (int fid); static final long FA_new = getFuncAddr (FID_new); static final long FA_anewarray = getFuncAddr (FID_anewarray); static final long FA_initclass = getFuncAddr (FID_initclass); static final long FA_vmnewarray = getFuncAddr (FID_vmnewarray); static final long FA_throwAIOBE = getFuncAddr (FID_throwAIOBE); static final long FA_geteltoffs = getFuncAddr (FID_geteltoffs); static final long FA_intdiv = getFuncAddr (FID_intdiv); static final long FA_intrem = getFuncAddr (FID_intrem); static final long FA_longdiv = getFuncAddr (FID_longdiv); static final long FA_longrem = getFuncAddr (FID_longrem); static final long FA_longmul = getFuncAddr (FID_longmul); static final long FA_remdr = getFuncAddr (FID_remdr); static final long FA_dtoi = getFuncAddr (FID_dtoi); static final long FA_dtol = getFuncAddr (FID_dtol); static final long FA_longshift = getFuncAddr (FID_longshift); static final long FA_long2f = getFuncAddr (FID_long2f); static final long FA_long2d = getFuncAddr (FID_long2d); static final long FA_longcmp = getFuncAddr (FID_longcmp); static final long FA_puts = getFuncAddr (FID_puts); static final long FA_throwNPE = getFuncAddr (FID_throwNPE); static final long FA_mythread = getFuncAddr (FID_mythread); static final long FA_sthread_got_exc = getFuncAddr (FID_sthread_got_exc); static final long FA_setjmp = getFuncAddr (FID_setjmp); static final long FA_longjmp = getFuncAddr (FID_longjmp); static final long FA_findhandler = getFuncAddr (FID_findhandler); static final long FA_athrow = getFuncAddr (FID_athrow); static final long FA_monitorenter = getFuncAddr (FID_monitorenter); static final long FA_monitorexit = getFuncAddr (FID_monitorexit); static final long FA_throwCCE = getFuncAddr (FID_throwCCE); static final long FA_instanceof = getFuncAddr (FID_instanceof); static final long FA_findinterface = getFuncAddr (FID_findinterface); static final long FA_throwNASE = getFuncAddr (FID_throwNASE); static final long FA_enterclass = getFuncAddr (FID_enterclass); static final long FA_exitclass = getFuncAddr (FID_exitclass); static final long FA_backjumpfn = getFuncAddr (FID_backjumpfn); static final long FA_timeNow = getFuncAddr (FID_timeNow); static final long FA_timeSliceEnd = getFuncAddr (FID_timeSliceEnd); static final long FA_throwJITIntErr = getFuncAddr (FID_throwJITIntErr); static final long FA_CodeBlock_resolveCode = getFuncAddr (FID_CodeBlock_resolveCode); private static final int OID_mythread_jmpbuf = 1; private static final int OID_mythread_exception = 2; private static final int OID_class_flags = 3; private static final int OID_class_nsupers = 4; private static final int OID_class_supers = 5; private static final int OID_mtgeneric_f = 6; private static final int OID_mcode_isresolved = 7; private static final int OID_mcode_mtentry = 8; private static final int OID_barray_length = 9; private static final int OID_barray_data = 10; private static final Immediate immZero8b = new Immediate (0, 1, true); private static final Immediate IMM_0 = new Immediate (0); private static final Immediate IMM_1 = new Immediate (1); private static final Immediate IMM_2 = new Immediate (2); private static final Immediate IMM_3 = new Immediate (3); private static final Immediate IMM_4 = new Immediate (4); private static final Immediate IMM_8 = new Immediate (8); private static final Immediate IMM_16 = new Immediate (16); private static final Immediate IO_class_flags = new Immediate (getFieldOffset (OID_class_flags)); private static final Immediate IO_class_nsupers = new Immediate (getFieldOffset (OID_class_nsupers)); private static final Immediate IO_class_supers = new Immediate (getFieldOffset (OID_class_supers)); private static final Immediate IO_mythread_jmpbuf = new Immediate (getFieldOffset (OID_mythread_jmpbuf)); private static final Immediate IO_mythread_exception = new Immediate (getFieldOffset (OID_mythread_exception)); private static final Immediate IO_mtgeneric_f = new Immediate (getFieldOffset (OID_mtgeneric_f)); private static final Immediate IO_mcode_isresolved = new Immediate (getFieldOffset (OID_mcode_isresolved)); private static final Immediate IO_mcode_mtentry = new Immediate (getFieldOffset (OID_mcode_mtentry)); private static final Immediate IO_barray_length = new Immediate (getFieldOffset (OID_barray_length)); private static final Immediate IO_barray_data = new Immediate (getFieldOffset (OID_barray_data)); private static final MemoryRef FMA_timeSliceEnd = new MemoryRef (new Immediate ((int) FA_timeSliceEnd), null); private static final MemoryRef FMA_timeNow = new MemoryRef (new Immediate ((int) FA_timeNow), null); /** Return the offset within a structure of a given field * @param oid an index naming the structure offset we want * @returns offset as int * Toba hash code: _i_N1XnB */ private static native int getFieldOffset (int oid); /** Return a pointer to the cl_Foo structure for the primitive type * Foo. * @param tid Opcode.T_Foo code for type foo * @param getArray Return pointer to acl_Foo.C instead of cl_Foo * @returns address as long * Toba hash code: _ii_QHITB */ private static native long getNPprimclass (int tid, int getArray); private Intel86 code; // Where the code is built up private int frame_size; // Size of activation record /* To handle exceptions, we need the following local variables: * + char * methname; // Name of this method * + Object instref; // instance reference (in synchronized methods) * + struct mythread * tdata; * + volatile int pc; // or monitorheld, for syncwrappers * + void * oldbuf; * + jmp_buf newbuf; */ private static final int ARLV_NumVars = 6; private static final int ARLV_methname = 5; // char * methodname private static final int ARLV_insref = 4; // Object instance_ref, for sync method private static final int ARLV_tdata = 3; // struct mythread * private static final int ARLV_pc = 2; // volatile int (overlaid with monitorheld) private static final int ARLV_monitorheld = 2; // volatile int (overlaid with pc)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -