/* * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. * * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product * that is described in this document. In particular, and without limitation, these intellectual property * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or * more additional patents or pending patent applications in the U.S. and in other countries. * * U.S. Government Rights - Commercial software. Government users are subject to the Sun * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its * supplements. * * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the * U.S. and other countries. * * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open * Company, Ltd. */ package com.sun.cri.bytecode; import static com.sun.cri.bytecode.Bytecodes.Flags.*; import static com.sun.cri.bytecode.Bytecodes.JniOp.*; import static com.sun.cri.bytecode.Bytecodes.MemoryBarriers.*; import java.io.*; import java.lang.reflect.*; import java.util.*; import java.util.regex.*; /** * The definitions of the bytecodes that are valid input to the compiler and * related utility methods. This comprises two groups: the standard Java * bytecodes defined by * Java Virtual Machine Specification, and a set of extended * bytecodes that support low-level programming, for example, memory barriers. * * The extended bytecodes are one or three bytes in size. The one-byte bytecodes * follow the values in the standard set, with no gap. The three-byte extended * bytecodes share a common first byte and carry additional instruction-specific * information in the second and third bytes. * * * @author Ben L. Titzer * @author Doug Simon */ public class Bytecodes { public static final int NOP = 0; // 0x00 public static final int ACONST_NULL = 1; // 0x01 public static final int ICONST_M1 = 2; // 0x02 public static final int ICONST_0 = 3; // 0x03 public static final int ICONST_1 = 4; // 0x04 public static final int ICONST_2 = 5; // 0x05 public static final int ICONST_3 = 6; // 0x06 public static final int ICONST_4 = 7; // 0x07 public static final int ICONST_5 = 8; // 0x08 public static final int LCONST_0 = 9; // 0x09 public static final int LCONST_1 = 10; // 0x0A public static final int FCONST_0 = 11; // 0x0B public static final int FCONST_1 = 12; // 0x0C public static final int FCONST_2 = 13; // 0x0D public static final int DCONST_0 = 14; // 0x0E public static final int DCONST_1 = 15; // 0x0F public static final int BIPUSH = 16; // 0x10 public static final int SIPUSH = 17; // 0x11 public static final int LDC = 18; // 0x12 public static final int LDC_W = 19; // 0x13 public static final int LDC2_W = 20; // 0x14 public static final int ILOAD = 21; // 0x15 public static final int LLOAD = 22; // 0x16 public static final int FLOAD = 23; // 0x17 public static final int DLOAD = 24; // 0x18 public static final int ALOAD = 25; // 0x19 public static final int ILOAD_0 = 26; // 0x1A public static final int ILOAD_1 = 27; // 0x1B public static final int ILOAD_2 = 28; // 0x1C public static final int ILOAD_3 = 29; // 0x1D public static final int LLOAD_0 = 30; // 0x1E public static final int LLOAD_1 = 31; // 0x1F public static final int LLOAD_2 = 32; // 0x20 public static final int LLOAD_3 = 33; // 0x21 public static final int FLOAD_0 = 34; // 0x22 public static final int FLOAD_1 = 35; // 0x23 public static final int FLOAD_2 = 36; // 0x24 public static final int FLOAD_3 = 37; // 0x25 public static final int DLOAD_0 = 38; // 0x26 public static final int DLOAD_1 = 39; // 0x27 public static final int DLOAD_2 = 40; // 0x28 public static final int DLOAD_3 = 41; // 0x29 public static final int ALOAD_0 = 42; // 0x2A public static final int ALOAD_1 = 43; // 0x2B public static final int ALOAD_2 = 44; // 0x2C public static final int ALOAD_3 = 45; // 0x2D public static final int IALOAD = 46; // 0x2E public static final int LALOAD = 47; // 0x2F public static final int FALOAD = 48; // 0x30 public static final int DALOAD = 49; // 0x31 public static final int AALOAD = 50; // 0x32 public static final int BALOAD = 51; // 0x33 public static final int CALOAD = 52; // 0x34 public static final int SALOAD = 53; // 0x35 public static final int ISTORE = 54; // 0x36 public static final int LSTORE = 55; // 0x37 public static final int FSTORE = 56; // 0x38 public static final int DSTORE = 57; // 0x39 public static final int ASTORE = 58; // 0x3A public static final int ISTORE_0 = 59; // 0x3B public static final int ISTORE_1 = 60; // 0x3C public static final int ISTORE_2 = 61; // 0x3D public static final int ISTORE_3 = 62; // 0x3E public static final int LSTORE_0 = 63; // 0x3F public static final int LSTORE_1 = 64; // 0x40 public static final int LSTORE_2 = 65; // 0x41 public static final int LSTORE_3 = 66; // 0x42 public static final int FSTORE_0 = 67; // 0x43 public static final int FSTORE_1 = 68; // 0x44 public static final int FSTORE_2 = 69; // 0x45 public static final int FSTORE_3 = 70; // 0x46 public static final int DSTORE_0 = 71; // 0x47 public static final int DSTORE_1 = 72; // 0x48 public static final int DSTORE_2 = 73; // 0x49 public static final int DSTORE_3 = 74; // 0x4A public static final int ASTORE_0 = 75; // 0x4B public static final int ASTORE_1 = 76; // 0x4C public static final int ASTORE_2 = 77; // 0x4D public static final int ASTORE_3 = 78; // 0x4E public static final int IASTORE = 79; // 0x4F public static final int LASTORE = 80; // 0x50 public static final int FASTORE = 81; // 0x51 public static final int DASTORE = 82; // 0x52 public static final int AASTORE = 83; // 0x53 public static final int BASTORE = 84; // 0x54 public static final int CASTORE = 85; // 0x55 public static final int SASTORE = 86; // 0x56 public static final int POP = 87; // 0x57 public static final int POP2 = 88; // 0x58 public static final int DUP = 89; // 0x59 public static final int DUP_X1 = 90; // 0x5A public static final int DUP_X2 = 91; // 0x5B public static final int DUP2 = 92; // 0x5C public static final int DUP2_X1 = 93; // 0x5D public static final int DUP2_X2 = 94; // 0x5E public static final int SWAP = 95; // 0x5F public static final int IADD = 96; // 0x60 public static final int LADD = 97; // 0x61 public static final int FADD = 98; // 0x62 public static final int DADD = 99; // 0x63 public static final int ISUB = 100; // 0x64 public static final int LSUB = 101; // 0x65 public static final int FSUB = 102; // 0x66 public static final int DSUB = 103; // 0x67 public static final int IMUL = 104; // 0x68 public static final int LMUL = 105; // 0x69 public static final int FMUL = 106; // 0x6A public static final int DMUL = 107; // 0x6B public static final int IDIV = 108; // 0x6C public static final int LDIV = 109; // 0x6D public static final int FDIV = 110; // 0x6E public static final int DDIV = 111; // 0x6F public static final int IREM = 112; // 0x70 public static final int LREM = 113; // 0x71 public static final int FREM = 114; // 0x72 public static final int DREM = 115; // 0x73 public static final int INEG = 116; // 0x74 public static final int LNEG = 117; // 0x75 public static final int FNEG = 118; // 0x76 public static final int DNEG = 119; // 0x77 public static final int ISHL = 120; // 0x78 public static final int LSHL = 121; // 0x79 public static final int ISHR = 122; // 0x7A public static final int LSHR = 123; // 0x7B public static final int IUSHR = 124; // 0x7C public static final int LUSHR = 125; // 0x7D public static final int IAND = 126; // 0x7E public static final int LAND = 127; // 0x7F public static final int IOR = 128; // 0x80 public static final int LOR = 129; // 0x81 public static final int IXOR = 130; // 0x82 public static final int LXOR = 131; // 0x83 public static final int IINC = 132; // 0x84 public static final int I2L = 133; // 0x85 public static final int I2F = 134; // 0x86 public static final int I2D = 135; // 0x87 public static final int L2I = 136; // 0x88 public static final int L2F = 137; // 0x89 public static final int L2D = 138; // 0x8A public static final int F2I = 139; // 0x8B public static final int F2L = 140; // 0x8C public static final int F2D = 141; // 0x8D public static final int D2I = 142; // 0x8E public static final int D2L = 143; // 0x8F public static final int D2F = 144; // 0x90 public static final int I2B = 145; // 0x91 public static final int I2C = 146; // 0x92 public static final int I2S = 147; // 0x93 public static final int LCMP = 148; // 0x94 public static final int FCMPL = 149; // 0x95 public static final int FCMPG = 150; // 0x96 public static final int DCMPL = 151; // 0x97 public static final int DCMPG = 152; // 0x98 public static final int IFEQ = 153; // 0x99 public static final int IFNE = 154; // 0x9A public static final int IFLT = 155; // 0x9B public static final int IFGE = 156; // 0x9C public static final int IFGT = 157; // 0x9D public static final int IFLE = 158; // 0x9E public static final int IF_ICMPEQ = 159; // 0x9F public static final int IF_ICMPNE = 160; // 0xA0 public static final int IF_ICMPLT = 161; // 0xA1 public static final int IF_ICMPGE = 162; // 0xA2 public static final int IF_ICMPGT = 163; // 0xA3 public static final int IF_ICMPLE = 164; // 0xA4 public static final int IF_ACMPEQ = 165; // 0xA5 public static final int IF_ACMPNE = 166; // 0xA6 public static final int GOTO = 167; // 0xA7 public static final int JSR = 168; // 0xA8 public static final int RET = 169; // 0xA9 public static final int TABLESWITCH = 170; // 0xAA public static final int LOOKUPSWITCH = 171; // 0xAB public static final int IRETURN = 172; // 0xAC public static final int LRETURN = 173; // 0xAD public static final int FRETURN = 174; // 0xAE public static final int DRETURN = 175; // 0xAF public static final int ARETURN = 176; // 0xB0 public static final int RETURN = 177; // 0xB1 public static final int GETSTATIC = 178; // 0xB2 public static final int PUTSTATIC = 179; // 0xB3 public static final int GETFIELD = 180; // 0xB4 public static final int PUTFIELD = 181; // 0xB5 public static final int INVOKEVIRTUAL = 182; // 0xB6 public static final int INVOKESPECIAL = 183; // 0xB7 public static final int INVOKESTATIC = 184; // 0xB8 public static final int INVOKEINTERFACE = 185; // 0xB9 public static final int XXXUNUSEDXXX = 186; // 0xBA public static final int NEW = 187; // 0xBB public static final int NEWARRAY = 188; // 0xBC public static final int ANEWARRAY = 189; // 0xBD public static final int ARRAYLENGTH = 190; // 0xBE public static final int ATHROW = 191; // 0xBF public static final int CHECKCAST = 192; // 0xC0 public static final int INSTANCEOF = 193; // 0xC1 public static final int MONITORENTER = 194; // 0xC2 public static final int MONITOREXIT = 195; // 0xC3 public static final int WIDE = 196; // 0xC4 public static final int MULTIANEWARRAY = 197; // 0xC5 public static final int IFNULL = 198; // 0xC6 public static final int IFNONNULL = 199; // 0xC7 public static final int GOTO_W = 200; // 0xC8 public static final int JSR_W = 201; // 0xC9 public static final int BREAKPOINT = 202; // 0xCA // Start extended bytecodes /** * Native function call. * * The 'function_address' value on the top of the stack is the result of * linking a native function. Typically, a {@link #JNIOP_LINK} operation * is used to obtain this address. * *
* Format: { u1 opcode; // JNICALL
* u2 sig; // Constant pool index of a CONSTANT_Utf8_info representing the signature of the call
* }
*
* Operand Stack:
* ..., [arg1, [arg2 ... ]] function_address => [return value, ]...,
*
*
* @see #JNIOP_LINK
* @see #JNIOP_J2N
* @see #JNIOP_N2J
*/
public static final int JNICALL = 203;
/**
* @see #JNIOP_LINK
* @see #JNIOP_J2N
* @see #JNIOP_N2J
*/
public static final int JNIOP = 204;
public static final int CALL = 205;
public static final int WLOAD = 206;
public static final int WLOAD_0 = 207;
public static final int WLOAD_1 = 208;
public static final int WLOAD_2 = 209;
public static final int WLOAD_3 = 210;
public static final int WSTORE = 211;
public static final int WSTORE_0 = 212;
public static final int WSTORE_1 = 213;
public static final int WSTORE_2 = 214;
public static final int WSTORE_3 = 215;
public static final int WCONST_0 = 216;
public static final int WDIV = 217;
public static final int WDIVI = 218; // Divisor is an int
public static final int WREM = 219;
public static final int WREMI = 220; // Divisor is an int
public static final int ICMP = 221; // Signed int compare, sets condition flags (for template JIT)
public static final int WCMP = 222; // Word compare, sets condition flags (for template JIT)
public static final int PREAD = 223;
public static final int PWRITE = 224;
public static final int PGET = 225;
public static final int PSET = 226;
/**
* Atomic update of a value in memory.
*
* Compares {@code expectedValue} value with the actual value in a memory location (given by {@code pointer + offset}).
* Iff they are same, {@code newValue} is stored into the memory location and the {@code expectedValue} is returned.
* Otherwise, the actual value is returned.
* All of the above is performed in one atomic hardware transaction.
*
*
* Format: { u3 opcode; // PCMPSWP_INT, PCMPSWP_WORD, PCMPSWP_REFERENCE,
* // PCMPSWP_INT_I, PCMPSWP_WORD_I or PCMPSWP_REFERENCE_I
* }
*
* Operand Stack:
* ... pointer, offset, expectedValue, newValue => ..., result
*
* param pointer base of denoted memory location
* param offset offset from pointer to the memory location
* param expectedValue if this value is currently in the memory location, perform the swap
* param newValue the new value to store into the memory location
* return either expectedValue or the actual value
*
*/
public static final int PCMPSWP = 227;
public static final int MOV_I2F = 228;
public static final int MOV_F2I = 229;
public static final int MOV_L2D = 230;
public static final int MOV_D2L = 231;
/**
* Unsigned integer comparison.
*
*
* Format: { u1 opcode; // UCMP
* u2 op; // ABOVE_EQUAL, ABOVE_THAN, BELOW_EQUAL or BELOW_THAN
* }
*
* Operand Stack:
* ..., left, right => ..., result
*
*
* @see UnsignedComparisons
*/
public static final int UCMP = 232;
/**
* Unsigned word comparison.
*
*
* Format: { u1 opcode; // UWCMP
* u2 op; // ABOVE_EQUAL, ABOVE_THAN, BELOW_EQUAL or BELOW_THAN
* }
*
* Operand Stack:
* ..., left, right => ..., result
*
*
* @see UnsignedComparisons
*/
public static final int UWCMP = 233;
/**
* Reads the value of a register playing a runtime-defined role.
*
*
* Format: { u1 opcode; // READREG
* u2 role; // runtime-defined register role id
* }
*
* Operand Stack:
* ... => ..., value
*
*/
public static final int READREG = 234;
/**
* Writes the value of a register playing a runtime-defined role.
*
*
* Format: { u1 opcode; // WRITEREG
* u2 role; // runtime-defined register role id
* }
*
* Operand Stack:
* ..., value => ...
*
*/
public static final int WRITEREG = 235;
/**
* Unsafe cast of top value on stack.
*
*
* Format: { u1 opcode; // UNSAFE_CAST
* u2 method; // Constant pool index to method (CONSTANT_Methodref_info) whose signature
* // describes the source and target types of the cast
* }
*
* Operand Stack:
* ..., value => ..., value
*
*/
public static final int UNSAFE_CAST = 236;
public static final int WRETURN = 237;
public static final int SAFEPOINT = 238;
/**
* Allocates a requested block of memory within the current activation frame.
* The allocated memory is reclaimed when the method returns.
*
* The allocation is for the lifetime of the method execution. That is, the compiler
* reserves the space in the compiled size of the frame. As such, a failure
* to allocate the requested space will result in a {@link StackOverflowError}
* when the method's prologue is executed.
*
*
* Format: { u1 opcode; // ALLOCA
* u2 unused;
* }
*
* Operand Stack:
* ..., size => ..., address
*
*
* The value on the top of the stack is the size in bytes to allocate.
* The result is the address of the allocated block. N.B. The contents of the block are uninitialized.
*/
public static final int ALLOCA = 239;
/**
* Inserts a memory barrier.
*
*
* Format: { u1 opcode; // MEMBAR
* u2 barrier; // 1=LOAD_LOAD, 2=LOAD_STORE, 3=STORE_LOAD, 4=STORE_STORE, 5=MEMOP_STORE, 6=ALL
* }
*
* Operand Stack:
* ... => ...
*
*/
public static final int MEMBAR = 240;
/**
* Allocates and initializes a slot on the native stack frame.
* * Forces the compiler to allocate a native frame slot and initializes it with {@code value} * The result is the address of the native frame slot. * The native frame slot will be live for the rest of the method. The type of {@code value} determines * if it is a GC root. If {@code value} is an object, any subsequent value written to the slot * (via {@code address}) must be an object. If {@code value} is not an object, any subsequent value * written to the slot must not be an object. * * The compiler is not required to enforce this type safety. * *
* Format: { u1 opcode; // ALLOCSTKVAR
* u2 method; // Constant pool index to method (CONSTANT_Methodref_info) whose signature
* // describes the type of the input value
* }
*
* Operand Stack:
* ..., value => ..., address
*
*/
public static final int ALLOCSTKVAR = 241;
public static final int PAUSE = 242;
public static final int BREAKPOINT_TRAP = 248;
public static final int ADD_SP = 243;
public static final int READ_PC = 244;
public static final int FLUSHW = 245;
/**
* Produces the index of the least significant bit within {@code value} or {@code -1} if {@code value == 0}.
*
*
* Format: { u1 opcode; // LSB
* u2 ignore;
* }
*
* Operand Stack:
* ..., value => ..., index
*
*/
public static final int LSB = 246;
/**
* Produces the index of the most significant bit within {@code value} or {@code -1} if {@code value == 0}.
*
*
* Format: { u1 opcode; // MSB
* u2 ignore;
* }
*
* Operand Stack:
* ..., value => ..., index
*
*/
public static final int MSB = 247;
// End extended bytecodes
// Extended bytecodes with operand:
// Pointer compare-and-swap with word-sized offset
public static final int PCMPSWP_INT = PCMPSWP | 1 << 8;
public static final int PCMPSWP_LONG = PCMPSWP | 2 << 8;
public static final int PCMPSWP_WORD = PCMPSWP | 3 << 8;
public static final int PCMPSWP_REFERENCE = PCMPSWP | 4 << 8;
// Pointer compare-and-swap with int-sized offset
public static final int PCMPSWP_INT_I = PCMPSWP | 5 << 8;
public static final int PCMPSWP_LONG_I = PCMPSWP | 6 << 8;
public static final int PCMPSWP_WORD_I = PCMPSWP | 7 << 8;
public static final int PCMPSWP_REFERENCE_I = PCMPSWP | 8 << 8;
// Pointer read with word-sized offset
public static final int PREAD_BYTE = PREAD | 1 << 8;
public static final int PREAD_CHAR = PREAD | 2 << 8;
public static final int PREAD_SHORT = PREAD | 3 << 8;
public static final int PREAD_INT = PREAD | 4 << 8;
public static final int PREAD_FLOAT = PREAD | 5 << 8;
public static final int PREAD_LONG = PREAD | 6 << 8;
public static final int PREAD_DOUBLE = PREAD | 7 << 8;
public static final int PREAD_WORD = PREAD | 8 << 8;
public static final int PREAD_REFERENCE = PREAD | 9 << 8;
// Pointer read with int-sized offset
public static final int PREAD_BYTE_I = PREAD | 10 << 8;
public static final int PREAD_CHAR_I = PREAD | 11 << 8;
public static final int PREAD_SHORT_I = PREAD | 12 << 8;
public static final int PREAD_INT_I = PREAD | 13 << 8;
public static final int PREAD_FLOAT_I = PREAD | 14 << 8;
public static final int PREAD_LONG_I = PREAD | 15 << 8;
public static final int PREAD_DOUBLE_I = PREAD | 16 << 8;
public static final int PREAD_WORD_I = PREAD | 17 << 8;
public static final int PREAD_REFERENCE_I = PREAD | 18 << 8;
// Pointer write with word-sized offset
public static final int PWRITE_BYTE = PWRITE | 1 << 8;
public static final int PWRITE_SHORT = PWRITE | 2 << 8;
public static final int PWRITE_INT = PWRITE | 3 << 8;
public static final int PWRITE_FLOAT = PWRITE | 4 << 8;
public static final int PWRITE_LONG = PWRITE | 5 << 8;
public static final int PWRITE_DOUBLE = PWRITE | 6 << 8;
public static final int PWRITE_WORD = PWRITE | 7 << 8;
public static final int PWRITE_REFERENCE = PWRITE | 8 << 8;
// Pointer write with int-sized offset
public static final int PWRITE_BYTE_I = PWRITE | 9 << 8;
public static final int PWRITE_SHORT_I = PWRITE | 10 << 8;
public static final int PWRITE_INT_I = PWRITE | 11 << 8;
public static final int PWRITE_FLOAT_I = PWRITE | 12 << 8;
public static final int PWRITE_LONG_I = PWRITE | 13 << 8;
public static final int PWRITE_DOUBLE_I = PWRITE | 14 << 8;
public static final int PWRITE_WORD_I = PWRITE | 15 << 8;
public static final int PWRITE_REFERENCE_I = PWRITE | 16 << 8;
public static final int PGET_BYTE = PGET | 1 << 8;
public static final int PGET_CHAR = PGET | 2 << 8;
public static final int PGET_SHORT = PGET | 3 << 8;
public static final int PGET_INT = PGET | 4 << 8;
public static final int PGET_FLOAT = PGET | 5 << 8;
public static final int PGET_LONG = PGET | 6 << 8;
public static final int PGET_DOUBLE = PGET | 7 << 8;
public static final int PGET_WORD = PGET | 8 << 8;
public static final int PGET_REFERENCE = PGET | 9 << 8;
public static final int PSET_BYTE = PSET | 1 << 8;
public static final int PSET_SHORT = PSET | 2 << 8;
public static final int PSET_INT = PSET | 3 << 8;
public static final int PSET_FLOAT = PSET | 4 << 8;
public static final int PSET_LONG = PSET | 5 << 8;
public static final int PSET_DOUBLE = PSET | 6 << 8;
public static final int PSET_WORD = PSET | 7 << 8;
public static final int PSET_REFERENCE = PSET | 8 << 8;
public static final int MEMBAR_LOAD_LOAD = MEMBAR | LOAD_LOAD << 8;
public static final int MEMBAR_LOAD_STORE = MEMBAR | LOAD_STORE << 8;
public static final int MEMBAR_STORE_LOAD = MEMBAR | STORE_LOAD << 8;
public static final int MEMBAR_STORE_STORE = MEMBAR | STORE_STORE << 8;
public static final int MEMBAR_MEMOP_STORE = MEMBAR | MEMOP_STORE << 8;
public static final int MEMBAR_FENCE = MEMBAR | FENCE << 8;
/**
* Links a native function.
*
* This instruction can only be used in a stub generated for a {@code native} method.
* It causes the VM linker to find the address for the native function
* corresponding to the native method.
*
*
* Format: { u1 opcode; // JNIOP
* u2 op; // JniOp.LINK
* }
*
* Operand Stack:
* ... => address
*
*/
public static final int JNIOP_LINK = JNIOP | LINK << 8;
/**
* Effects a transition from compiled Java code to native code.
*
* This instruction must appear immediately before {@link #JNICALL} in the instruction stream.
*
*
* Format: { u1 opcode; // JNIOP
* u2 op; // JniOp.J2N
* }
*
* Operand Stack:
* ... => ...
*
*/
public static final int JNIOP_J2N = JNIOP | J2N << 8;
/**
* Effects a transition from native code to compiled Java code.
*
* This instruction must appear immediately after {@link #JNICALL} in the instruction stream.
*
*
* Format: { u1 opcode; // JNIOP
* u2 op; // JniOp.N2J
* }
*
* Operand Stack:
* ... => ...
*
*/
public static final int JNIOP_N2J = JNIOP | N2J << 8;
/**
* Constants for the operations performed as part of JNI call from compiled Java code
* to native code or vice versa.
*/
public static class JniOp {
/**
* @see Bytecodes#JNIOP_LINK
*/
public static final int LINK = 1;
/**
* @see Bytecodes#JNIOP_N2J
*/
public static final int N2J = 2;
/**
* @see Bytecodes#JNIOP_J2N
*/
public static final int J2N = 3;
}
/**
* Constants and {@link INTRINSIC} definitions for unsigned comparisons.
*/
public static class UnsignedComparisons {
public static final int ABOVE_THAN = 1;
public static final int ABOVE_EQUAL = 2;
public static final int BELOW_THAN = 3;
public static final int BELOW_EQUAL = 4;
}
/**
* Constants for memory barriers.
*
* The documentation for each constant is taken from Doug Lea's
* The JSR-133 Cookbook for Compiler Writers.
*/
public static class MemoryBarriers {
/**
* The sequence {@code Load1; LoadLoad; Load2} ensures that {@code Load1}'s data are loaded before data accessed
* by {@code Load2} and all subsequent load instructions are loaded. In general, explicit {@code LoadLoad}
* barriers are needed on processors that perform speculative loads and/or out-of-order processing in which
* waiting load instructions can bypass waiting stores. On processors that guarantee to always preserve load
* ordering, these barriers amount to no-ops.
*/
public static final int LOAD_LOAD = 0x0001;
/**
* The sequence {@code Load1; LoadStore; Store2} ensures that {@code Load1}'s data are loaded before all data
* associated with {@code Store2} and subsequent store instructions are flushed. {@code LoadStore} barriers are
* needed only on those out-of-order processors in which waiting store instructions can bypass loads.
*/
public static final int LOAD_STORE = 0x0002;
/**
* The sequence {@code Store1; StoreLoad; Load2} ensures that {@code Store1}'s data are made visible to other
* processors (i.e., flushed to main memory) before data accessed by {@code Load2} and all subsequent load
* instructions are loaded. {@code StoreLoad} barriers protect against a subsequent load incorrectly using
* {@code Store1}'s data value rather than that from a more recent store to the same location performed by a
* different processor. Because of this, on the processors discussed below, a {@code StoreLoad} is strictly
* necessary only for separating stores from subsequent loads of the same location(s) as were stored before the
* barrier. {@code StoreLoad} barriers are needed on nearly all recent multiprocessors, and are usually the most
* expensive kind. Part of the reason they are expensive is that they must disable mechanisms that ordinarily
* bypass cache to satisfy loads from write-buffers. This might be implemented by letting the buffer fully
* flush, among other possible stalls.
*/
public static final int STORE_LOAD = 0x0004;
/**
* The sequence {@code Store1; StoreStore; Store2} ensures that {@code Store1}'s data are visible to other
* processors (i.e., flushed to memory) before the data associated with {@code Store2} and all subsequent store
* instructions. In general, {@code StoreStore} barriers are needed on processors that do not otherwise
* guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.
*/
public static final int STORE_STORE = 0x0008;
public static final int MEMOP_STORE = STORE_STORE | LOAD_STORE;
public static final int FENCE = LOAD_LOAD | LOAD_STORE | STORE_STORE | STORE_LOAD;
/**
* Ensures all preceding loads complete before any subsequent loads.
*/
@INTRINSIC(MEMBAR_LOAD_LOAD)
public static void loadLoad() {
}
/**
* Ensures all preceding loads complete before any subsequent stores.
*/
@INTRINSIC(MEMBAR_LOAD_STORE)
public static void loadStore() {
}
/**
* Ensures all preceding stores complete before any subsequent loads.
*/
@INTRINSIC(MEMBAR_STORE_LOAD)
public static void storeLoad() {
}
/**
* Ensures all preceding stores complete before any subsequent stores.
*/
@INTRINSIC(MEMBAR_STORE_STORE)
public static void storeStore() {
}
/**
* Ensures all preceding stores and loads complete before any subsequent stores.
*/
@INTRINSIC(MEMBAR_MEMOP_STORE)
public static void memopStore() {
}
/**
* Ensures all preceding stores and loads complete before any subsequent stores and loads.
*/
@INTRINSIC(MEMBAR_FENCE)
public static void fence() {
}
}
public static final int ILLEGAL = 255;
public static final int END = 256;
/**
* The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
*
* for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
* //
* }
*
*/
public static final int LAST_JVM_OPCODE = JSR_W;
/**
* A collection of flags describing various bytecode attributes.
*/
static class Flags {
/**
* Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
*/
static final int STOP = 0x00000001;
/**
* Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
* In practice this means it is a conditional branch.
*/
static final int FALL_THROUGH = 0x00000002;
/**
* Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
* This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
*/
static final int BRANCH = 0x00000004;
/**
* Denotes an instruction that reads the value of a static or instance field.
*/
static final int FIELD_READ = 0x00000008;
/**
* Denotes an instruction that writes the value of a static or instance field.
*/
static final int FIELD_WRITE = 0x00000010;
/**
* Denotes an instruction that is not defined in the JVM specification.
*/
static final int EXTENSION = 0x00000020;
/**
* Denotes an instruction that can cause an implicit exception.
*/
static final int TRAP = 0x00000080;
/**
* Denotes an instruction that is commutative.
*/
static final int COMMUTATIVE = 0x00000100;
/**
* Denotes an instruction that is associative.
*/
static final int ASSOCIATIVE = 0x00000200;
/**
* Denotes an instruction that loads an operand.
*/
static final int LOAD = 0x00000400;
/**
* Denotes an instruction that stores an operand.
*/
static final int STORE = 0x00000800;
}
// Performs a sanity check that none of the flags overlap.
static {
int allFlags = 0;
try {
for (Field field : Flags.class.getDeclaredFields()) {
int flagsFilter = Modifier.FINAL | Modifier.STATIC;
if ((field.getModifiers() & flagsFilter) == flagsFilter) {
assert field.getType() == int.class : "Only " + field;
final int flag = field.getInt(null);
assert flag != 0;
assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
allFlags |= flag;
}
}
} catch (Exception e) {
throw new InternalError(e.toString());
}
}
/**
* A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
* This will include the root instruction for the three-byte extended instructions.
*/
private static final String[] names = new String[256];
/**
* Maps from a three-byte extended bytecode value to a {@link String} for the corresponding instruction mnemonic.
*/
private static final HashMap