Пример #1
0
Function* JavaLLVMCompiler::parseFunction(JavaMethod* meth, Class* customizeFor) {
  assert(!isAbstract(meth->access));
  LLVMMethodInfo* LMI = getMethodInfo(meth);
  Function* func = LMI->getMethod(customizeFor);
  
  // We are jitting. Take the lock.
  vmkit::VmkitModule::protectIR();
  if (func->getLinkage() == GlobalValue::ExternalWeakLinkage) {
    JavaJIT jit(this, meth, func, LMI->isCustomizable ? customizeFor : NULL);
    if (isNative(meth->access)) {
      jit.nativeCompile();
      vmkit::VmkitModule::runPasses(func, JavaNativeFunctionPasses);
      vmkit::VmkitModule::runPasses(func, J3FunctionPasses);
    } else {
      jit.javaCompile();
      vmkit::VmkitModule::runPasses(func, JavaFunctionPasses);
      vmkit::VmkitModule::runPasses(func, J3FunctionPasses);
    }
    func->setLinkage(GlobalValue::ExternalLinkage);
    if (!LMI->isCustomizable && jit.isCustomizable) {
      // It's the first time we parsed the method and we just found
      // out it can be customized.
      // TODO(geoffray): return a customized version to this caller.
      meth->isCustomizable = true;
      LMI->isCustomizable = true;
    }
  }
  vmkit::VmkitModule::unprotectIR();

  return func;
}
Пример #2
0
void DataBus::AbstractClient::processGetClientMethodInfoRequestPacket(const Packet &packet)
{
    // Check if registered
    if (m_registered == false)
    {
        // Error, can't send a response if not registered
        return;
    }

    // Check destination
    if (packet.getDestination() != m_clientId)
    {
        // Error, invalid destination
        return;
    }

    // Get Method ID
    quint8 methodId;

    if (GetClientMethodInfoRequestPacket::parse(packet,
                                                &methodId) == false)
    {
        // Error, failed to parse packet
        return;
    }

    // Get Method Info
    MethodInfo methodInfo;

    if (getMethodInfo(methodId, &methodInfo) == false)
    {
        // Error, failed to get Method Info
        return;
    }

    // Create response
    Packet responsePacket;

    if (GetClientMethodInfoResponsePacket::create(m_clientId,
                                                  packet.getSource(),
                                                  packet.getPacketId(),
                                                  methodInfo,
                                                  &responsePacket) == false)
    {
        // Error, failed to create packet
        return;
    }

    // Send Response
    if (sendPacket(responsePacket) == false)
    {
        // Error, failed to create packet
        return;
    }

    // Success
    return;
}
/*
 * Dump a bytecode disassembly.
 */
void dumpBytecodes(DexFile* pDexFile, const DexMethod* pDexMethod)
{
    const DexCode* pCode = dexGetCode(pDexFile, pDexMethod);
    const u2* insns;
    int insnIdx;
    FieldMethodInfo methInfo;
    int startAddr;
    char* className = NULL;

    assert(pCode->insnsSize > 0);
    insns = pCode->insns;

    getMethodInfo(pDexFile, pDexMethod->methodIdx, &methInfo);
    startAddr = ((u1*)pCode - pDexFile->baseAddr);
    className = descriptorToDot(methInfo.classDescriptor);

    printf("%06x:                                        |[%06x] %s.%s:%s\n",
        startAddr, startAddr,
        className, methInfo.name, methInfo.signature);

    insnIdx = 0;
    while (insnIdx < (int) pCode->insnsSize) {
        int insnWidth;
        OpCode opCode;
        DecodedInstruction decInsn;
        u2 instr;

        instr = get2LE((const u1*)insns);
        if (instr == kPackedSwitchSignature) {
            insnWidth = 4 + get2LE((const u1*)(insns+1)) * 2;
        } else if (instr == kSparseSwitchSignature) {
            insnWidth = 2 + get2LE((const u1*)(insns+1)) * 4;
        } else if (instr == kArrayDataSignature) {
            int width = get2LE((const u1*)(insns+1));
            int size = get2LE((const u1*)(insns+2)) | 
                       (get2LE((const u1*)(insns+3))<<16);
            // The plus 1 is to round up for odd size and width 
            insnWidth = 4 + ((size * width) + 1) / 2;
        } else {
            opCode = instr & 0xff;
            insnWidth = dexGetInstrWidthAbs(gInstrWidth, opCode);
            if (insnWidth == 0) {
                fprintf(stderr,
                    "GLITCH: zero-width instruction at idx=0x%04x\n", insnIdx);
                break;
            }
        }

        dexDecodeInstruction(gInstrFormat, insns, &decInsn);
        dumpInstruction(pDexFile, pCode, insnIdx, insnWidth, &decInsn);

        insns += insnWidth;
        insnIdx += insnWidth;
    }

    free(className);
}
Пример #4
0
Function* JavaLLVMCompiler::getMethod(JavaMethod* meth, Class* customizeFor) {
  return getMethodInfo(meth)->getMethod(customizeFor);
}
/*
 * Dump a single instruction.
 */
void dumpInstruction(DexFile* pDexFile, const DexCode* pCode, int insnIdx,
    int insnWidth, const DecodedInstruction* pDecInsn)
{
    static const float gSpecialTab[16] = {
        -2.0f, -1.0f, -0.5f, -0.25f, -0.1f, 0.1f, 0.25f, 0.5f,
        1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 10.0f, 100.0f, 1000.0f
    };
    const u2* insns = pCode->insns;
    int i;

    printf("%06x:", ((u1*)insns - pDexFile->baseAddr) + insnIdx*2);
    for (i = 0; i < 8; i++) {
        if (i < insnWidth) {
            if (i == 7) {
                printf(" ... ");
            } else {
                /* print 16-bit value in little-endian order */
                const u1* bytePtr = (const u1*) &insns[insnIdx+i];
                printf(" %02x%02x", bytePtr[0], bytePtr[1]);
            }
        } else {
            fputs("     ", stdout);
        }
    }

    if (pDecInsn->opCode == OP_NOP) {
        u2 instr = get2LE((const u1*) &insns[insnIdx]);
        if (instr == kPackedSwitchSignature) {
            printf("|%04x: packed-switch-data (%d units)",
                insnIdx, insnWidth);
        } else if (instr == kSparseSwitchSignature) {
            printf("|%04x: sparse-switch-data (%d units)",
                insnIdx, insnWidth);
        } else if (instr == kArrayDataSignature) {
            printf("|%04x: array-data (%d units)",
                insnIdx, insnWidth);
        } else {
            printf("|%04x: nop // spacer", insnIdx);
        }
    } else {
        printf("|%04x: %s", insnIdx, getOpcodeName(pDecInsn->opCode));
    }

    switch (dexGetInstrFormat(gInstrFormat, pDecInsn->opCode)) {
    case kFmt10x:        // op
        break;
    case kFmt12x:        // op vA, vB
        printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
        break;
    case kFmt11n:        // op vA, #+B
        printf(" v%d, #int %d // #%x",
            pDecInsn->vA, (s4)pDecInsn->vB, (u1)pDecInsn->vB);
        break;
    case kFmt11x:        // op vAA
        printf(" v%d", pDecInsn->vA);
        break;
    case kFmt10t:        // op +AA
    case kFmt20t:        // op +AAAA
        {
            s4 targ = (s4) pDecInsn->vA;
            printf(" %04x // %c%04x",
                insnIdx + targ,
                (targ < 0) ? '-' : '+',
                (targ < 0) ? -targ : targ);
        }
        break;
    case kFmt22x:        // op vAA, vBBBB
        printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
        break;
    case kFmt21t:        // op vAA, +BBBB
        {
            s4 targ = (s4) pDecInsn->vB;
            printf(" v%d, %04x // %c%04x", pDecInsn->vA,
                insnIdx + targ,
                (targ < 0) ? '-' : '+',
                (targ < 0) ? -targ : targ);
        }
        break;
    case kFmt21s:        // op vAA, #+BBBB
        printf(" v%d, #int %d // #%x",
            pDecInsn->vA, (s4)pDecInsn->vB, (u2)pDecInsn->vB);
        break;
    case kFmt21h:        // op vAA, #+BBBB0000[00000000]
        // The printed format varies a bit based on the actual opcode.
        if (pDecInsn->opCode == OP_CONST_HIGH16) {
            s4 value = pDecInsn->vB << 16;
            printf(" v%d, #int %d // #%x",
                pDecInsn->vA, value, (u2)pDecInsn->vB);
        } else {
            s8 value = ((s8) pDecInsn->vB) << 48;
            printf(" v%d, #long %lld // #%x",
                pDecInsn->vA, value, (u2)pDecInsn->vB);
        }
        break;
    case kFmt21c:        // op vAA, thing@BBBB
        if (pDecInsn->opCode == OP_CONST_STRING) {
            printf(" v%d, \"%s\" // string@%04x", pDecInsn->vA,
                dexStringById(pDexFile, pDecInsn->vB), pDecInsn->vB);
        } else if (pDecInsn->opCode == OP_CHECK_CAST ||
                   pDecInsn->opCode == OP_NEW_INSTANCE ||
                   pDecInsn->opCode == OP_CONST_CLASS)
        {
            printf(" v%d, %s // class@%04x", pDecInsn->vA,
                getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
        } else /* OP_SGET* */ {
            FieldMethodInfo fieldInfo;
            if (getFieldInfo(pDexFile, pDecInsn->vB, &fieldInfo)) {
                printf(" v%d, %s.%s:%s // field@%04x", pDecInsn->vA,
                    fieldInfo.classDescriptor, fieldInfo.name,
                    fieldInfo.signature, pDecInsn->vB);
            } else {
                printf(" v%d, ??? // field@%04x", pDecInsn->vA, pDecInsn->vB);
            }
        }
        break;
    case kFmt23x:        // op vAA, vBB, vCC
        printf(" v%d, v%d, v%d", pDecInsn->vA, pDecInsn->vB, pDecInsn->vC);
        break;
    case kFmt22b:        // op vAA, vBB, #+CC
        printf(" v%d, v%d, #int %d // #%02x",
            pDecInsn->vA, pDecInsn->vB, (s4)pDecInsn->vC, (u1)pDecInsn->vC);
        break;
    case kFmt22t:        // op vA, vB, +CCCC
        {
            s4 targ = (s4) pDecInsn->vC;
            printf(" v%d, v%d, %04x // %c%04x", pDecInsn->vA, pDecInsn->vB,
                insnIdx + targ,
                (targ < 0) ? '-' : '+',
                (targ < 0) ? -targ : targ);
        }
        break;
    case kFmt22s:        // op vA, vB, #+CCCC
        printf(" v%d, v%d, #int %d // #%04x",
            pDecInsn->vA, pDecInsn->vB, (s4)pDecInsn->vC, (u2)pDecInsn->vC);
        break;
    case kFmt22c:        // op vA, vB, thing@CCCC
        if (pDecInsn->opCode >= OP_IGET && pDecInsn->opCode <= OP_IPUT_SHORT) {
            FieldMethodInfo fieldInfo;
            if (getFieldInfo(pDexFile, pDecInsn->vC, &fieldInfo)) {
                printf(" v%d, v%d, %s.%s:%s // field@%04x", pDecInsn->vA,
                    pDecInsn->vB, fieldInfo.classDescriptor, fieldInfo.name,
                    fieldInfo.signature, pDecInsn->vC);
            } else {
                printf(" v%d, v%d, ??? // field@%04x", pDecInsn->vA,
                    pDecInsn->vB, pDecInsn->vC);
            }
        } else {
            printf(" v%d, v%d, %s // class@%04x",
                pDecInsn->vA, pDecInsn->vB,
                getClassDescriptor(pDexFile, pDecInsn->vC), pDecInsn->vC);
        }
        break;
    case kFmt22cs:       // [opt] op vA, vB, field offset CCCC
        printf(" v%d, v%d, [obj+%04x]",
            pDecInsn->vA, pDecInsn->vB, pDecInsn->vC);
        break;
    case kFmt30t:
        printf(" #%08x", pDecInsn->vA);
        break;
    case kFmt31i:        // op vAA, #+BBBBBBBB
        {
            /* this is often, but not always, a float */
            union {
                float f;
                u4 i;
            } conv;
            conv.i = pDecInsn->vB;
            printf(" v%d, #float %f // #%08x",
                pDecInsn->vA, conv.f, pDecInsn->vB);
        }
        break;
    case kFmt31c:        // op vAA, thing@BBBBBBBB
        printf(" v%d, \"%s\" // string@%08x", pDecInsn->vA,
            dexStringById(pDexFile, pDecInsn->vB), pDecInsn->vB);
        break;
    case kFmt31t:       // op vAA, offset +BBBBBBBB
        printf(" v%d, %08x // +%08x",
            pDecInsn->vA, insnIdx + pDecInsn->vB, pDecInsn->vB);
        break;
    case kFmt32x:        // op vAAAA, vBBBB
        printf(" v%d, v%d", pDecInsn->vA, pDecInsn->vB);
        break;
    case kFmt35c:        // op vB, {vD, vE, vF, vG, vA}, thing@CCCC
        {
            /* NOTE: decoding of 35c doesn't quite match spec */
            fputs(" {", stdout);
            for (i = 0; i < (int) pDecInsn->vA; i++) {
                if (i == 0)
                    printf("v%d", pDecInsn->arg[i]);
                else
                    printf(", v%d", pDecInsn->arg[i]);
            }
            if (pDecInsn->opCode == OP_FILLED_NEW_ARRAY) {
                printf("}, %s // class@%04x",
                    getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
            } else {
                FieldMethodInfo methInfo;
                if (getMethodInfo(pDexFile, pDecInsn->vB, &methInfo)) {
                    printf("}, %s.%s:%s // method@%04x",
                        methInfo.classDescriptor, methInfo.name,
                        methInfo.signature, pDecInsn->vB);
                } else {
                    printf("}, ??? // method@%04x", pDecInsn->vB);
                }
            }
        }
        break;
    case kFmt35ms:       // [opt] invoke-virtual+super
    case kFmt35fs:       // [opt] invoke-interface
        {
            fputs(" {", stdout);
            for (i = 0; i < (int) pDecInsn->vA; i++) {
                if (i == 0)
                    printf("v%d", pDecInsn->arg[i]);
                else
                    printf(", v%d", pDecInsn->arg[i]);
            }
            printf("}, [%04x] // vtable #%04x", pDecInsn->vB, pDecInsn->vB);
        }
        break;
    case kFmt3rc:        // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
        {
            /*
             * This doesn't match the "dx" output when some of the args are
             * 64-bit values -- dx only shows the first register.
             */
            fputs(" {", stdout);
            for (i = 0; i < (int) pDecInsn->vA; i++) {
                if (i == 0)
                    printf("v%d", pDecInsn->vC + i);
                else
                    printf(", v%d", pDecInsn->vC + i);
            }
            if (pDecInsn->opCode == OP_FILLED_NEW_ARRAY_RANGE) {
                printf("}, %s // class@%04x",
                    getClassDescriptor(pDexFile, pDecInsn->vB), pDecInsn->vB);
            } else {
                FieldMethodInfo methInfo;
                if (getMethodInfo(pDexFile, pDecInsn->vB, &methInfo)) {
                    printf("}, %s.%s:%s // method@%04x",
                        methInfo.classDescriptor, methInfo.name,
                        methInfo.signature, pDecInsn->vB);
                } else {
                    printf("}, ??? // method@%04x", pDecInsn->vB);
                }
            }
        }
        break;
    case kFmt3rms:       // [opt] invoke-virtual+super/range
    case kFmt3rfs:       // [opt] invoke-interface/range
        {
            /*
             * This doesn't match the "dx" output when some of the args are
             * 64-bit values -- dx only shows the first register.
             */
            fputs(" {", stdout);
            for (i = 0; i < (int) pDecInsn->vA; i++) {
                if (i == 0)
                    printf("v%d", pDecInsn->vC + i);
                else
                    printf(", v%d", pDecInsn->vC + i);
            }
            printf("}, [%04x] // vtable #%04x", pDecInsn->vB, pDecInsn->vB);
        }
        break;
    case kFmt3inline:    // [opt] inline invoke
        {
#if 0
            const InlineOperation* inlineOpsTable = dvmGetInlineOpsTable();
            u4 tableLen = dvmGetInlineOpsTableLength();
#endif

            fputs(" {", stdout);
            for (i = 0; i < (int) pDecInsn->vA; i++) {
                if (i == 0)
                    printf("v%d", pDecInsn->arg[i]);
                else
                    printf(", v%d", pDecInsn->arg[i]);
            }
#if 0
            if (pDecInsn->vB < tableLen) {
                printf("}, %s.%s:%s // inline #%04x",
                    inlineOpsTable[pDecInsn->vB].classDescriptor,
                    inlineOpsTable[pDecInsn->vB].methodName,
                    inlineOpsTable[pDecInsn->vB].methodSignature,
                    pDecInsn->vB);
            } else {
#endif
                printf("}, [%04x] // inline #%04x", pDecInsn->vB, pDecInsn->vB);
#if 0
            }
#endif
        }
        break;
    case kFmt51l:        // op vAA, #+BBBBBBBBBBBBBBBB
        {
            /* this is often, but not always, a double */
            union {
                double d;
                u8 j;
            } conv;
            conv.j = pDecInsn->vB_wide;
            printf(" v%d, #double %f // #%016llx",
                pDecInsn->vA, conv.d, pDecInsn->vB_wide);
        }
        break;
    case kFmtUnknown:
        break;
    default:
        printf(" ???");
        break;
    }


    putchar('\n');

}