publicclass CodeItem implements RawDexObject { publicshort registersSize; publicshort insSize; publicshort outsSize; publicshort triesSize; publicint debugInfoOff; // NB: this is a special case publicint insnsSize; public List<Instruction> insns; public TryItem[] tries; public EncodedCatchHandlerList handlers;
private MutatableCode mutatableCode;
publicstaticclass MethodMetaInfo { public String methodName; publicboolean isStatic; public String shorty;
}
public MethodMetaInfo meta = new MethodMetaInfo();
@Override publicvoid read(DexRandomAccessFile file) throws IOException {
file.alignForwards(4);
file.getOffsetTracker().getNewOffsettable(file, this);
registersSize = file.readUShort();
insSize = file.readUShort();
outsSize = file.readUShort();
triesSize = file.readUShort();
debugInfoOff = file.readUInt();
insnsSize = file.readUInt();
populateInstructionList(file); if (triesSize > 0) { if ((insnsSize % 2) != 0) { // Consume padding.
file.readUShort();
}
tries = new TryItem[triesSize]; for (int i = 0; i < triesSize; i++) {
(tries[i] = new TryItem()).read(file);
}
(handlers = new EncodedCatchHandlerList()).read(file);
}
}
privatevoid populateInstructionList(DexRandomAccessFile file) throws IOException {
insns = new LinkedList<Instruction>(); long insnsOffset = file.getFilePointer(); if (insnsOffset != 0) { long finger = insnsOffset; long insnsEnd = insnsOffset + (2 * insnsSize);
while (finger < insnsEnd) {
file.seek(finger);
Instruction newInsn = new Instruction();
newInsn.read(file);
insns.add(newInsn);
finger += (2 * newInsn.getSize());
}
file.seek(finger);
}
}
@Override publicvoid write(DexRandomAccessFile file) throws IOException {
file.alignForwards(4);
file.getOffsetTracker().updatePositionOfNextOffsettable(file);
file.writeUShort(registersSize);
file.writeUShort(insSize);
file.writeUShort(outsSize);
file.writeUShort(triesSize); // We do not support retaining debug info currently.
file.writeUInt(0/*debug_info_off*/);
file.writeUInt(insnsSize); for (Instruction insn : insns) {
insn.write(file);
} if (triesSize > 0) { if ((insnsSize % 2) != 0) { // produce padding
file.writeUShort((short) 0);
} for (TryItem tryItem : tries) {
tryItem.write(file);
}
handlers.write(file);
}
}
@Override publicvoid incrementIndex(IndexUpdateKind kind, int insertedIdx) { if (kind == IndexUpdateKind.TYPE_ID && triesSize > 0) { // EncodedCatchHandlerList (well, the EncodedTypeAddrPairs it owns) // are only interested in TYPE_IDs.
handlers.incrementIndex(kind, insertedIdx);
}
if (kind == IndexUpdateKind.PROTO_ID) { // The only kind we can't encounter in an instruction. return;
}
List<Instruction> insnsToIncrement = insns;
// If we have an associated MutatableCode, then it may have created some new insns // that we won't know about yet, during the mutation phase. // // Ask for the latest view of the insns. if (mutatableCode != null) {
insnsToIncrement = mutatableCode.requestLatestInstructions();
}
for (Instruction insn : insnsToIncrement) {
Opcode opcode = insn.info.opcode; switch (kind) { case STRING_ID: if (opcode == Opcode.CONST_STRING || opcode == Opcode.CONST_STRING_JUMBO) { // STRING@BBBB if (insn.vregB >= insertedIdx) {
insn.vregB++;
}
} break; case TYPE_ID: if (opcode == Opcode.CONST_CLASS
|| opcode == Opcode.CHECK_CAST
|| opcode == Opcode.NEW_INSTANCE
|| opcode == Opcode.FILLED_NEW_ARRAY
|| opcode == Opcode.FILLED_NEW_ARRAY_RANGE) { // TYPE@BBBB if (insn.vregB >= insertedIdx) {
insn.vregB++;
}
} elseif (opcode == Opcode.INSTANCE_OF || opcode == Opcode.NEW_ARRAY) { // TYPE@CCCC if (insn.vregC >= insertedIdx) {
insn.vregC++;
}
} break; case FIELD_ID: if (Opcode.isBetween(opcode, Opcode.SGET, Opcode.SPUT_SHORT)) { // FIELD@BBBB if (insn.vregB >= insertedIdx) {
insn.vregB++;
}
} elseif (Opcode.isBetween(opcode, Opcode.IGET, Opcode.IPUT_SHORT)) { // FIELD@CCCC if (insn.vregC >= insertedIdx) {
insn.vregC++;
}
} break; case METHOD_ID: if (Opcode.isBetween(opcode, Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_INTERFACE)
|| Opcode.isBetween(opcode,
Opcode.INVOKE_VIRTUAL_RANGE, Opcode.INVOKE_INTERFACE_RANGE)) { // METHOD@BBBB if (insn.vregB >= insertedIdx) {
insn.vregB++;
}
} break; default:
Log.errorAndQuit("Unexpected IndexUpdateKind requested "
+ "in Instruction.incrementIndex()");
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.