/* * Rewrite an iget/iput instruction if appropriate. These all have the form: * op vA, vB, field@CCCC * * Where vA holds the value, vB holds the object reference, and CCCC is * the field reference constant pool offset. For a non-volatile field, * we want to replace the opcode with "quickOpc" and replace CCCC with * the byte offset from the start of the object. For a volatile field, * we just want to replace the opcode with "volatileOpc". * * If "volatileOpc" is OP_NOP we don't check to see if it's a volatile * field. If "quickOpc" is OP_NOP, and this is a non-volatile field, * we don't do anything. * * "method" is the referring method. */ static void rewriteInstField(Method* method, u2* insns, Opcode quickOpc, Opcode volatileOpc) { ClassObject* clazz = method->clazz; u2 fieldIdx = insns[1]; InstField* instField; instField = dvmOptResolveInstField(clazz, fieldIdx, NULL); if (instField == NULL) { ALOGI("DexOpt: unable to optimize instance field ref " "0x%04x at 0x%02x in %s.%s", fieldIdx, (int) (insns - method->insns), clazz->descriptor, method->name); return; } if (volatileOpc != OP_NOP && dvmIsVolatileField(instField)) { updateOpcode(method, insns, volatileOpc); ALOGV("DexOpt: rewrote ifield access %s.%s --> volatile", instField->clazz->descriptor, instField->name); } else if (quickOpc != OP_NOP && instField->byteOffset < 65536) { updateOpcode(method, insns, quickOpc); dvmUpdateCodeUnit(method, insns+1, (u2) instField->byteOffset); ALOGV("DexOpt: rewrote ifield access %s.%s --> %d", instField->clazz->descriptor, instField->name, instField->byteOffset); } else { ALOGV("DexOpt: no rewrite of ifield access %s.%s", instField->clazz->descriptor, instField->name); } return; }
/* * Rewrite a static field access instruction if appropriate. If * the target field is volatile, we replace the opcode with "volatileOpc". * * "method" is the referring method. */ static void rewriteStaticField0(Method* method, u2* insns, Opcode volatileOpc, u4 fieldIdx) { ClassObject* clazz = method->clazz; StaticField* staticField; assert(volatileOpc != OP_NOP); staticField = dvmOptResolveStaticField(clazz, fieldIdx, NULL); if (staticField == NULL) { ALOGI("DexOpt: unable to optimize static field ref " "0x%04x at 0x%02x in %s.%s", fieldIdx, (int) (insns - method->insns), clazz->descriptor, method->name); return; } if (dvmIsVolatileField(staticField)) { updateOpcode(method, insns, volatileOpc); ALOGV("DexOpt: rewrote sfield access %s.%s --> volatile", staticField->clazz->descriptor, staticField->name); } }
void VM::runCycle () { updateOpcode (); switch (opcode) { case 0x01: transfer (A, B); break; case 0x02: transfer (B, A); break; case 0x03: transfer (A, C); break; case 0x04: transfer (C, A); break; case 0x05: transfer (B, C); break; case 0x06: transfer (C, B); break; case 0x07: A.data++; break; case 0x08: A.data--; break; case 0x09: B.data++; break; case 0x0A: B.data--; break; case 0x0B: C.data++; break; case 0x0C: C.data--; break; case 0x0D: A.data = A.data + B.data; break; case 0x0E: B.data = A.data + B.data; break; case 0x0F: A.data = A.data + C.data; break; case 0x10: C.data = A.data + C.data; break; case 0x11: B.data = B.data + B.data; break; case 0x12: C.data = B.data + C.data; break; case 0x13: A.data = A.data - B.data; break; case 0x14: A.data = A.data - C.data; break; case 0x15: B.data = B.data - A.data; break; case 0x16: B.data = B.data - C.data; break; case 0x17: C.data = C.data - A.data; break; case 0x18: C.data = C.data - B.data; break; case 0x19: A.data = A.data * B.data; break; case 0x1A: B.data = A.data * B.data; break; case 0x1B: A.data = A.data * C.data; break; case 0x1C: C.data = A.data * C.data; break; case 0x1D: B.data = B.data * C.data; break; case 0x1E: C.data = B.data * C.data; break; case 0x1F: A.data = A.data / B.data; break; case 0x20: A.data = A.data / C.data; break; case 0x21: B.data = B.data / A.data; break; case 0x22: B.data = B.data / C.data; break; case 0x23: C.data = C.data / A.data; break; case 0x24: C.data = C.data / B.data; break; case 0x25: updateOpcode (); A.data += opcode; break; case 0x26: updateOpcode (); A.data -= opcode; break; case 0x27: updateOpcode (); A.data *= opcode; break; case 0x28: updateOpcode (); A.data /= opcode; break; case 0x29: updateOpcode (); B.data += opcode; break; case 0x2A: updateOpcode (); B.data -= opcode; break; case 0x2B: updateOpcode (); B.data *= opcode; break; case 0x2C: updateOpcode (); B.data /= opcode; break; case 0x2D: updateOpcode (); C.data += opcode; break; case 0x2E: updateOpcode (); C.data -= opcode; break; case 0x2F: updateOpcode (); C.data *= opcode; break; case 0x30: updateOpcode (); C.data /= opcode; break; case 0x31: updateOpcode (); setMemory (opcode, A); break; case 0x32: updateOpcode (); setMemory (opcode, B); break; case 0x33: updateOpcode (); setMemory (opcode, C); break; case 0x34: updateOpcode (); loadMemory (opcode, A); break; case 0x35: updateOpcode (); loadMemory (opcode, B); break; case 0x36: updateOpcode (); loadMemory (opcode, C); break; case 0x37: updateOpcode (); proc.clearAll (); proc.data = A.data - opcode; break; case 0x38: if (proc.data == 0) { } break; default: break; } }