Beispiel #1
0
/*
 * 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;
}
Beispiel #2
0
/*
 * 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);
    }
}
Beispiel #3
0
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;
	}
}