Add support for jumbo volatile field access opcodes

This commit is contained in:
Ben Gruver
2011-11-20 11:39:21 -08:00
committed by =
parent 4dda65fdb3
commit 0d785ac315
8 changed files with 230 additions and 10 deletions

View File

@ -1098,6 +1098,20 @@ public class MethodAnalyzer {
case INVOKE_OBJECT_INIT_JUMBO:
analyzeInvokeObjectInitJumbo(analyzedInstruction);
return true;
case IGET_VOLATILE_JUMBO:
case IGET_WIDE_VOLATILE_JUMBO:
case IGET_OBJECT_VOLATILE_JUMBO:
case IPUT_VOLATILE_JUMBO:
case IPUT_WIDE_VOLATILE_JUMBO:
case IPUT_OBJECT_VOLATILE_JUMBO:
case SGET_VOLATILE_JUMBO:
case SGET_WIDE_VOLATILE_JUMBO:
case SGET_OBJECT_VOLATILE_JUMBO:
case SPUT_VOLATILE_JUMBO:
case SPUT_WIDE_VOLATILE_JUMBO:
case SPUT_OBJECT_VOLATILE_JUMBO:
analyzePutGetVolatile(analyzedInstruction);
return true;
default:
assert false;
return true;
@ -1593,6 +1607,18 @@ public class MethodAnalyzer {
case SGET_OBJECT_VOLATILE:
case SPUT_OBJECT_VOLATILE:
case INVOKE_OBJECT_INIT_JUMBO:
case IGET_VOLATILE_JUMBO:
case IGET_WIDE_VOLATILE_JUMBO:
case IGET_OBJECT_VOLATILE_JUMBO:
case IPUT_VOLATILE_JUMBO:
case IPUT_WIDE_VOLATILE_JUMBO:
case IPUT_OBJECT_VOLATILE_JUMBO:
case SGET_VOLATILE_JUMBO:
case SGET_WIDE_VOLATILE_JUMBO:
case SGET_OBJECT_VOLATILE_JUMBO:
case SPUT_VOLATILE_JUMBO:
case SPUT_WIDE_VOLATILE_JUMBO:
case SPUT_OBJECT_VOLATILE_JUMBO:
//TODO: throw validation exception?
default:
assert false;
@ -3627,14 +3653,23 @@ public class MethodAnalyzer {
if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) {
SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(),
fieldIdItem);
if (analyzedInstruction.instruction.opcode.format == Format.Format21c) {
deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
} else {
assert(analyzedInstruction.instruction.opcode.format == Format.Format41c);
deodexedInstruction = new Instruction41c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
}
} else {
TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
(byte)instruction.getRegisterB(), fieldIdItem);
if (analyzedInstruction.instruction.opcode.format == Format.Format22c) {
deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
(byte)instruction.getRegisterB(), fieldIdItem);
} else {
assert(analyzedInstruction.instruction.opcode.format == Format.Format52c);
deodexedInstruction = new Instruction52c(opcode, (byte)instruction.getRegisterA(),
(byte)instruction.getRegisterB(), fieldIdItem);
}
}
analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

View File

@ -178,6 +178,107 @@ public class OdexedFieldInstructionMapper {
}
};
private static Opcode[][][][] jumboOpcodeMap = new Opcode[][][][] {
//get opcodes
new Opcode[][][] {
//iget volatile
new Opcode[][] {
//odexed
new Opcode[] {
/*Z*/ Opcode.IGET_VOLATILE_JUMBO,
/*B*/ Opcode.IGET_VOLATILE_JUMBO,
/*S*/ Opcode.IGET_VOLATILE_JUMBO,
/*C*/ Opcode.IGET_VOLATILE_JUMBO,
/*I,F*/ Opcode.IGET_VOLATILE_JUMBO,
/*J,D*/ Opcode.IGET_WIDE_VOLATILE_JUMBO,
/*L,[*/ Opcode.IGET_OBJECT_VOLATILE_JUMBO
},
//deodexed
new Opcode[] {
/*Z*/ Opcode.IGET_BOOLEAN_JUMBO,
/*B*/ Opcode.IGET_BYTE_JUMBO,
/*S*/ Opcode.IGET_SHORT_JUMBO,
/*C*/ Opcode.IGET_CHAR_JUMBO,
/*I,F*/ Opcode.IGET_JUMBO,
/*J,D*/ Opcode.IGET_WIDE_JUMBO,
/*L,[*/ Opcode.IGET_OBJECT_JUMBO
}
},
//sget volatile
new Opcode[][] {
//odexed
new Opcode[] {
/*Z*/ Opcode.SGET_VOLATILE_JUMBO,
/*B*/ Opcode.SGET_VOLATILE_JUMBO,
/*S*/ Opcode.SGET_VOLATILE_JUMBO,
/*C*/ Opcode.SGET_VOLATILE_JUMBO,
/*I,F*/ Opcode.SGET_VOLATILE_JUMBO,
/*J,D*/ Opcode.SGET_WIDE_VOLATILE_JUMBO,
/*L,[*/ Opcode.SGET_OBJECT_VOLATILE_JUMBO
},
//deodexed
new Opcode[] {
/*Z*/ Opcode.SGET_BOOLEAN_JUMBO,
/*B*/ Opcode.SGET_BYTE_JUMBO,
/*S*/ Opcode.SGET_SHORT_JUMBO,
/*C*/ Opcode.SGET_CHAR_JUMBO,
/*I,F*/ Opcode.SGET_JUMBO,
/*J,D*/ Opcode.SGET_WIDE_JUMBO,
/*L,[*/ Opcode.SGET_OBJECT_JUMBO
}
}
},
//put opcodes
new Opcode[][][] {
//iput volatile
new Opcode[][] {
//odexed
new Opcode[] {
/*Z*/ Opcode.IPUT_VOLATILE_JUMBO,
/*B*/ Opcode.IPUT_VOLATILE_JUMBO,
/*S*/ Opcode.IPUT_VOLATILE_JUMBO,
/*C*/ Opcode.IPUT_VOLATILE_JUMBO,
/*I,F*/ Opcode.IPUT_VOLATILE_JUMBO,
/*J,D*/ Opcode.IPUT_WIDE_VOLATILE_JUMBO,
/*L,[*/ Opcode.IPUT_OBJECT_VOLATILE_JUMBO
},
//deodexed
new Opcode[] {
/*Z*/ Opcode.IPUT_BOOLEAN_JUMBO,
/*B*/ Opcode.IPUT_BYTE_JUMBO,
/*S*/ Opcode.IPUT_SHORT_JUMBO,
/*C*/ Opcode.IPUT_CHAR_JUMBO,
/*I,F*/ Opcode.IPUT_JUMBO,
/*J,D*/ Opcode.IPUT_WIDE_JUMBO,
/*L,[*/ Opcode.IPUT_OBJECT_JUMBO
}
},
//sput volatile
new Opcode[][] {
//odexed
new Opcode[] {
/*Z*/ Opcode.SPUT_VOLATILE_JUMBO,
/*B*/ Opcode.SPUT_VOLATILE_JUMBO,
/*S*/ Opcode.SPUT_VOLATILE_JUMBO,
/*C*/ Opcode.SPUT_VOLATILE_JUMBO,
/*I,F*/ Opcode.SPUT_VOLATILE_JUMBO,
/*J,D*/ Opcode.SPUT_WIDE_VOLATILE_JUMBO,
/*L,[*/ Opcode.SPUT_OBJECT_VOLATILE_JUMBO
},
//deodexed
new Opcode[] {
/*Z*/ Opcode.SPUT_BOOLEAN_JUMBO,
/*B*/ Opcode.SPUT_BYTE_JUMBO,
/*S*/ Opcode.SPUT_SHORT_JUMBO,
/*C*/ Opcode.SPUT_CHAR_JUMBO,
/*I,F*/ Opcode.SPUT_JUMBO,
/*J,D*/ Opcode.SPUT_WIDE_JUMBO,
/*L,[*/ Opcode.SPUT_OBJECT_JUMBO
}
}
}
};
private static int getTypeIndex(char type) {
switch (type) {
case 'Z':
@ -214,12 +315,20 @@ public class OdexedFieldInstructionMapper {
}
static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(String fieldType, Opcode odexedOpcode) {
boolean jumbo = odexedOpcode.isJumboOpcode();
int opcodeType = odexedOpcode.setsRegister()?0:1;
int opcodeSubType = getOpcodeSubtype(odexedOpcode);
int typeIndex = getTypeIndex(fieldType.charAt(0));
Opcode correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex];
Opcode deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex];
Opcode correctOdexedOpcode, deodexedOpcode;
if (jumbo) {
correctOdexedOpcode = jumboOpcodeMap[opcodeType][opcodeSubType-1][0][typeIndex];
deodexedOpcode = jumboOpcodeMap[opcodeType][opcodeSubType-1][1][typeIndex];
} else {
correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex];
deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex];
}
if (correctOdexedOpcode != odexedOpcode) {
throw new ValidationException(String.format("Incorrect field type \"%s\" for %s", fieldType,

View File

@ -325,6 +325,18 @@ public enum Opcode
INVOKE_INTERFACE_JUMBO((short)0xff26, "invoke-interface/jumbo", ReferenceType.method, Format.Format5rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
INVOKE_OBJECT_INIT_JUMBO((short)0xfff2, "invoke-object-init/jumbo", ReferenceType.method, Format.Format5rc, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.JUMBO_OPCODE),
IGET_VOLATILE_JUMBO((short)0xfff3, "iget-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
IGET_WIDE_VOLATILE_JUMBO((short)0xfff4, "iget-wide-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
IGET_OBJECT_VOLATILE_JUMBO((short)0xfff5, "iget-object-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
IPUT_VOLATILE_JUMBO((short)0xfff6, "iput-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
IPUT_WIDE_VOLATILE_JUMBO((short)0xfff7, "iput-wide-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
IPUT_OBJECT_VOLATILE_JUMBO((short)0xfff8, "iput-object-volatile/jumbo", ReferenceType.field, Format.Format52c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
SGET_VOLATILE_JUMBO((short)0xfff9, "sget-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
SGET_WIDE_VOLATILE_JUMBO((short)0xfffa, "sget-wide-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER | Opcode.JUMBO_OPCODE),
SGET_OBJECT_VOLATILE_JUMBO((short)0xfffb, "sget-object-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.JUMBO_OPCODE),
SPUT_VOLATILE_JUMBO((short)0xfffc, "sput-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
SPUT_WIDE_VOLATILE_JUMBO((short)0xfffd, "sput-wide-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE),
SPUT_OBJECT_VOLATILE_JUMBO((short)0xfffe, "sput-object-volatile/jumbo", ReferenceType.field, Format.Format41c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.JUMBO_OPCODE);
private static Opcode[] opcodesByValue;
private static Opcode[] expandedOpcodesByValue;
@ -436,7 +448,11 @@ public enum Opcode
SGET_CHAR_JUMBO, SGET_SHORT_JUMBO, SPUT_JUMBO, SPUT_WIDE_JUMBO, SPUT_OBJECT_JUMBO,
SPUT_BOOLEAN_JUMBO, SPUT_BYTE_JUMBO, SPUT_CHAR_JUMBO, SPUT_SHORT_JUMBO, INVOKE_VIRTUAL_JUMBO,
INVOKE_SUPER_JUMBO, INVOKE_DIRECT_JUMBO, INVOKE_STATIC_JUMBO, INVOKE_INTERFACE_JUMBO,
INVOKE_OBJECT_INIT_RANGE, INVOKE_OBJECT_INIT_JUMBO);
INVOKE_OBJECT_INIT_RANGE, INVOKE_OBJECT_INIT_JUMBO, IGET_VOLATILE_JUMBO, IGET_WIDE_VOLATILE_JUMBO,
IGET_OBJECT_VOLATILE_JUMBO, IPUT_VOLATILE_JUMBO, IPUT_WIDE_VOLATILE_JUMBO,
IPUT_OBJECT_VOLATILE_JUMBO, SGET_VOLATILE_JUMBO, SGET_WIDE_VOLATILE_JUMBO,
SGET_OBJECT_VOLATILE_JUMBO, SPUT_VOLATILE_JUMBO, SPUT_WIDE_VOLATILE_JUMBO,
SPUT_OBJECT_VOLATILE_JUMBO);
addOpcodes(INVOKE_DIRECT_EMPTY);
}
}