📄 codeblock.java
字号:
/** Native routine to allocate a block of memory at least numCodeBytes bytes * long, into which the code generated in this object will be copied. * @param numCodeBytes size in bytes required to store code * @returns address of native block for code * Toba hash code: _i_eyDZd */ static private native long allocNativeBlock (int numCodeBytes); // How many bytes are needed? /** Native routine to copy data from the Java array arr into the * native code block mtentry. * @param codeBytes[] byte array of machine code * @param numCodeBytes prefex of array to save * @param mtentry pre-allocated native block of code. * @returns address of native block for code * Toba hash code: _abil_J4do9 */ static private native void copyNativeCode (byte codeBytes[], // Java array of data int nCodeBytes, // Number of bytes to copy long mtentry); // Where data should be copied /** Copy the generated code into a native block of memory. * Invoking this precludes addition of instructions to the code, since * it permanently assigns a target address to the code start. * @returns the address of the native block containing the code */ protected long installCode () { /* If we haven't already allocated a block, get one big enough to * hold what we've already built up. Can't add any more * instructions after this. */ if (0 == mtentry) { /* Shrink the array down to what we need */ expandArr (numCodeBytes); mtentry = setMethodEntry (allocNativeBlock (numCodeBytes)); if (0 == mtentry) { throw new OutOfMemoryError ("allocating " + numCodeBytes + " bytes for native JIT code"); } /* If we have a synchronization wrapper, the value stored * is relative to the start of the buffer. Update that * to be absolute. */ if (null != syncwrap_bpi) { syncwrap_bpi.setLongVal (mtentry + syncwrap_bpi.setLongVal (-1)); } } if (! allNativeCode) { /* Copy the data from the array into the native block. */// System.out.println ("Copying into code at " + Long.toHexString (mtentry)); copyNativeCode (codeBytes, numCodeBytes, mtentry); } return mtentry; } protected void overwriteInstalledCode (byte [] codeBytes, int offs) { if (0 == mtentry) { throw new InternalError ("CodeBlock: overwrite of non-installed code"); } if ((mtentry + offs + codeBytes.length) > numCodeBytes) { throw new InternalError ("CodeBlock: overwrite of installed code overruns code block"); } copyNativeCode (codeBytes, codeBytes.length, mtentry + offs); return; } /** Expand (or shrink) the Java array to hold at least nmax bytes * @param nmax number of bytes now required in code block */ private void expandArr (int nmax) // Size required for array { /* Allocate a new array, copy the old one into it, and update the * fields to reflect the new array and size. */ byte newarr[] = new byte [nmax]; System.arraycopy (codeBytes, 0, newarr, 0, (codeBytes.length < nmax) ? codeBytes.length : nmax); codeBytes = newarr; maxCodeBytes = nmax; return; } protected int storeWord (int v, int offs) { if (checkWordAlign && (0 != (offs & 0x03))) { throw new InternalError ("CodeBlock: attempt to store word data at misaligned offset"); } if (! lockCodeBytes) {// System.out.println ("storing word " + Integer.toHexString (v) + " at offset " + offs); /* Store the value, increment the used size, and return the value */ if (littleEndian) { codeBytes [offs++] = (byte) (0xFF & (v >>> 0)); codeBytes [offs++] = (byte) (0xFF & (v >>> 8)); codeBytes [offs++] = (byte) (0xFF & (v >>> 16)); codeBytes [offs++] = (byte) (0xFF & (v >>> 24)); } else { codeBytes [offs++] = (byte) (0xFF & (v >>> 24)); codeBytes [offs++] = (byte) (0xFF & (v >>> 16)); codeBytes [offs++] = (byte) (0xFF & (v >>> 8)); codeBytes [offs++] = (byte) (0xFF & (v >>> 0)); } } return v; } protected byte storeByte (byte v, int offs) { if (! lockCodeBytes) { codeBytes [offs++] = v; } return v; } protected byte[] storeByteArray (byte va[], int offs) { int i; if (! lockCodeBytes) {// System.out.println ("storing " + va.length + " bytes at " + offs); for (i = 0; i < va.length; i++) { codeBytes [offs++] = va [i]; } } return va; } /** Add a new word (4-bytes) to the end of the array, expanding it if necessary * @param v new word going onto array tail * @returns value of parameter v */ protected int addWord (int v) // Instruction to add { /* If we've allocated the native block where the code will live, * we can't generate any more code: somebody may already have a * reference to it. */// System.out.println ("addword 0x" + Integer.toHexString (v)); if ((0 != mtentry) || lockCodeBytes) { /* If we've already closed off, or otherwise have locked * off storage, just return the data silently---presumbly, * we're using it in an storeByte* call. */ return v; } /* If we're at the limit of the allocated array, expand it */ if ((numCodeBytes + 4) > maxCodeBytes) { expandArr (2*maxCodeBytes + 5); } /* Store the value at the end. Expansion ensured there's room. */ numCodeBytes += 4; return storeWord (v, numCodeBytes - 4); } /** Add a new byte to the end of the array, expanding it if necessary * @param v new byte going onto array tail * @returns value of parameter v */ protected byte addByte (byte v) // Instruction to add { /* If we've allocated the native block where the code will live, * we can't generate any more code: somebody may already have a * reference to it. */ if ((0 != mtentry) || lockCodeBytes) { /* If we've already closed off, or otherwise have locked * off storage, just return the data silently---presumbly, * we're using it in an storeByte* call. */ return v; } /* If we're at the limit of the allocated array, expand it */ if ((numCodeBytes + 1) > maxCodeBytes) { expandArr (2*maxCodeBytes + 5); } /* Store the value at the end. Expansion ensured there's room. */ return storeByte (v, numCodeBytes++); } /** Add a new array of bytes to the end of the array, expanding it if necessary * @param va new bytes going onto array tail * @returns value of parameter va */ protected byte[] addByteArray (byte va[]) // Bytes to add { /* If we've allocated the native block where the code will live, * we can't generate any more code: somebody may already have a * reference to it. */ if ((0 != mtentry) || lockCodeBytes) { /* If we've already closed off, or otherwise have locked * off storage, just return the data silently---presumbly, * we're using it in an storeByte* call. */ return va; } /* If we're at the limit of the allocated array, expand it */ if ((numCodeBytes + va.length) >= maxCodeBytes) { expandArr (2*maxCodeBytes + va.length); } /* Store the value at the end. Expansion ensured there's room. */ numCodeBytes += va.length; return storeByteArray (va, numCodeBytes - va.length); } /** Retrieve value of code byte at a given index. * @param offs from where in the codeBytes array the value should be read * @returns the value stored therein */ protected int getCodeByte (int offs) // offset of byte { return codeBytes [offs]; } /** Retrieve value of code word (4-byte) at a given index. * @param offs from where in the codeBytes array the value should be read * @returns the value stored therein */ protected int getCodeWord (int offs) // offset of byte { int v; int i; int sv; if (checkWordAlign && (0 != (offs & 0x03))) { throw new InternalError ("CodeBlock: attempt to access word data at misaligned offset"); } v = 0; if (littleEndian) { sv = 0; for (i = 0; i < 4; i++) { v += ((0x7F & codeBytes [offs+i]) + (0x80 & codeBytes [offs+i])) << sv; sv += 8; } } else { sv = 24; for (i = 0; i < 4; i++) { v += ((0x7F & codeBytes [offs+i]) + (0x80 & codeBytes [offs+i])) << sv; sv -= 8; } } return v; } /** Retrieve value of a sequence of code bytes at a given index. * @param offs from where in the codeBytes array the value should be read * @returns the value stored therein */ protected byte[] getCodeByteArray (int offs, // offset of sequence start int len) // Length of sequence to retrieve { byte rv[] = new byte [len]; System.arraycopy (codeBytes, offs, rv, 0, len); return rv; } /** Print the code block in hexadecimal form, one byte per line */ public void dumpHex () { int ii; int cw; System.out.println (numCodeBytes + " bytes for " + method.instrs.length + " instructions:"); ii = 0; cw = 0; while (cw < numCodeBytes) { while ((ii < method.instrs.length) && (instrToByteOffs [ii] == cw)) { System.out.println ("# " + method.instrs [ii]); ++ii; } System.out.println (" " + Integer.toHexString (codeBytes [cw])); ++cw; } return; } /* These are a set of backpatch types which are used by most if not * all JITs. The actual code generated in each case is architecture- * dependent. */ // Call to the MethodRef parameter: MethodRef mr protected static final int brCALL = 1; // Jump to the local label: long tlbl protected static final int brJUMP = 2; // Load from the VariableRef parameter: VariableRef vr protected static final int brLOAD = 3; // Set from the FieldRef table slot: FieldRef fr protected static final int brFIELDLOAD = 4; // Call to a fixed address: long addr protected static final int brACALL = 5; // Load a pointer to the native class for a reference: (ClassRef|FieldRef) fr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -