X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=libdex%2FInstrUtils.h;h=4c4dcfe6a89281838fe2b001b18761e97606a47b;hb=1530c3e6952581aa20ac1e06562a49b9d70bc2b6;hp=d987ef42f1056414d66eff7f359555cf133533c7;hpb=d325011fc98e0f1179d467bbc284cccea72f560b;p=android-x86%2Fdalvik.git diff --git a/libdex/InstrUtils.h b/libdex/InstrUtils.h index d987ef42f..4c4dcfe6a 100644 --- a/libdex/InstrUtils.h +++ b/libdex/InstrUtils.h @@ -34,6 +34,7 @@ * - this enum * - the switch inside dexDecodeInstruction() in InstrUtils.c * - the switch inside dumpInstruction() in DexDump.c + * - the switch inside dvmCompilerMIR2LIR() in CodegenDriver.c */ typedef unsigned char InstructionFormat; enum InstructionFormat { @@ -61,14 +62,36 @@ enum InstructionFormat { kFmt31i, // op vAA, #+BBBBBBBB kFmt31t, // op vAA, +BBBBBBBB kFmt31c, // op vAA, string@BBBBBBBB - kFmt35c, // op {vD, vE, vF, vG, vA}, thing@CCCC (decoded differently) + kFmt35c, // op {vC,vD,vE,vF,vG}, thing@BBBB kFmt35ms, // [opt] invoke-virtual+super - kFmt35fs, // [opt] invoke-interface - kFmt3rc, // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB + kFmt3rc, // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB kFmt3rms, // [opt] invoke-virtual+super/range kFmt51l, // op vAA, #+BBBBBBBBBBBBBBBB - kFmt3inline, // [opt] inline invoke - kFmt3rinline, // [opt] inline invoke/range + kFmt35mi, // [opt] inline invoke + kFmt3rmi, // [opt] inline invoke/range + kFmt33x, // exop vAA, vBB, vCCCC + kFmt32s, // exop vAA, vBB, #+CCCC + kFmt41c, // exop vAAAA, thing@BBBBBBBB + kFmt52c, // exop vAAAA, vBBBB, thing@CCCCCCCC + kFmt5rc, // exop {vCCCC .. v(CCCC+AAAA-1)}, thing@BBBBBBBB +}; + +/* + * Different kinds of indexed reference, for formats that include such an + * indexed reference (e.g., 21c and 35c) + */ +typedef unsigned char InstructionIndexType; +enum InstructionIndexType { + kIndexUnknown = 0, + kIndexNone, // has no index + kIndexVaries, // "It depends." Used for throw-verification-error + kIndexTypeRef, // type reference index + kIndexStringRef, // string reference index + kIndexMethodRef, // method reference index + kIndexFieldRef, // field reference index + kIndexInlineMethod, // inline method index (for inline linked methods) + kIndexVtableOffset, // vtable offset (for static linked methods) + kIndexFieldOffset // field offset (for static linked fields) }; /* @@ -81,12 +104,13 @@ typedef struct DecodedInstruction { u4 vC; u4 arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */ OpCode opCode; + InstructionIndexType indexType; } DecodedInstruction; /* - * Instruction width, a value in the range -3 to 5. + * Instruction width, a value in the range 0 to 5. */ -typedef signed char InstructionWidth; +typedef unsigned char InstructionWidth; /* * Instruction flags, used by the verifier and JIT to determine where @@ -103,6 +127,16 @@ enum InstructionFlags { kInstrUnconditional = 1 << 6, // unconditional branch }; +/* + * Struct that includes a pointer to each of the instruction information + * tables. + */ +typedef struct InstructionInfoTables { + InstructionFormat* formats; + InstructionIndexType* indexTypes; + InstructionFlags* flags; + InstructionWidth* widths; +} InstructionInfoTables; /* * Allocate and populate a 256-element array with instruction widths. A @@ -110,31 +144,14 @@ enum InstructionFlags { */ InstructionWidth* dexCreateInstrWidthTable(void); -#if 0 // no longer used -/* - * Returns the width of the specified instruction, or 0 if not defined. - * Optimized instructions use negative values. - */ -DEX_INLINE int dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode) -{ - // assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions); - return widths[opCode]; -} -#endif - /* * Return the width of the specified instruction, or 0 if not defined. */ -DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths, +DEX_INLINE size_t dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode) { //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions); - - int val = widths[opCode]; - if (val < 0) - val = -val; - /* XXX - the no-compare trick may be a cycle slower on ARM */ - return val; + return widths[opCode]; } /* @@ -142,10 +159,9 @@ DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths, * works for special OP_NOP entries, including switch statement data tables * and array data. */ -size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, +size_t dexGetInstrOrTableWidth(const InstructionWidth* widths, const u2* insns); - /* * Allocate and populate a 256-element array with instruction flags. */ @@ -160,7 +176,6 @@ DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode) return flags[opCode]; } - /* * Allocate and populate a 256-element array with instruction formats. */ @@ -177,9 +192,37 @@ DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts, } /* + * Allocate and populate an array with index types for all instructions. + * Used in conjunction with dexDecodeInstruction. + */ +InstructionIndexType* dexCreateInstrIndexTypeTable(void); + +/* + * Return the instruction index type for the specified opcode. + */ +DEX_INLINE InstructionIndexType dexGetInstrIndexType( + const InstructionIndexType* types, OpCode opCode) +{ + //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions); + return types[opCode]; +} + +/* + * Construct all of the instruction info tables, storing references to + * them into the given struct. This returns 0 on success or non-zero on + * failure. If this fails, then no net allocation will have occurred. + */ +int dexCreateInstructionInfoTables(InstructionInfoTables* info); + +/* + * Free up the tables referred to by the given instruction info struct. + */ +void dexFreeInstructionInfoTables(InstructionInfoTables* info); + +/* * Decode the instruction pointed to by "insns". */ -void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns, +void dexDecodeInstruction(const InstructionInfoTables* info, const u2* insns, DecodedInstruction* pDec); #endif /*_LIBDEX_INSTRUTILS*/