Ejemplo n.º 1
0
void OSR::replace(SsaOpnd* opnd, SsaOpnd* iv, SsaOpnd* rc) {
    Inst* inst = opnd->getInst();
    SsaOpnd* dstInst = reduce(inst->getDst()->getType(), inst->getOpcode(),
                              inst->getOperation(), iv, rc);
    Inst* copyInst = irManager.getInstFactory().makeCopy(opnd, dstInst);
    copyInst->insertBefore(inst);
    inst->unlink();
    writeLeadingOperand(opnd, getLeadingOperand(iv));

}
Ejemplo n.º 2
0
//_________________________________________________________________________________________________
void InternalTrace::runImpl()
{
    MemoryManager mm("InternalTrace");

    irManager->registerInternalHelperInfo("itrace_method_entry", IRManager::InternalHelperInfo((void*)&methodEntry, &CallingConvention_STDCALL));
    irManager->registerInternalHelperInfo("itrace_method_exit", IRManager::InternalHelperInfo((void*)&methodExit, &CallingConvention_STDCALL));
    irManager->registerInternalHelperInfo("itrace_field_write", IRManager::InternalHelperInfo((void*)&fieldWrite, &CallingConvention_STDCALL));

    char methodFullName[0x1000]="";
    MethodDesc & md=irManager->getMethodDesc();
    strcat(methodFullName, md.getParentType()->getName());
    strcat(methodFullName, ".");
    strcat(methodFullName, md.getName());
    strcat(methodFullName, " ");
    strcat(methodFullName, md.getSignatureString());

    Opnd * methodNameOpnd=irManager->newInternalStringConstantImmOpnd(methodFullName);
    irManager->setInfo("itraceMethodExitString", methodNameOpnd->getRuntimeInfo()->getValue(0));

    Node* prolog=irManager->getFlowGraph()->getEntryNode();

    Inst * inst=(Inst*)prolog->getFirstInst();
    if (inst->hasKind(Inst::Kind_EntryPointPseudoInst)){
        EntryPointPseudoInst * entryPointPseudoInst = (EntryPointPseudoInst *)inst;
        entryPointPseudoInst->getCallingConventionClient().finalizeInfos(Inst::OpndRole_Def, CallingConvention::ArgKind_InArg);
        const StlVector<CallingConvention::OpndInfo> & infos=((const EntryPointPseudoInst *)entryPointPseudoInst)->getCallingConventionClient().getInfos(Inst::OpndRole_Def);
        Opnd * argInfoOpnd=irManager->newBinaryConstantImmOpnd((U_32)infos.size()*sizeof(CallingConvention::OpndInfo), &infos.front());
        Opnd * args[3]={ methodNameOpnd, 
            irManager->newImmOpnd(irManager->getTypeManager().getInt32Type(), infos.size()), 
            argInfoOpnd,
        };
        Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_entry", 3, args, NULL);
        internalTraceInst->insertBefore(inst);
    }else{
        Opnd * args[3]={ methodNameOpnd, 
            irManager->newImmOpnd(irManager->getTypeManager().getInt32Type(), 0), 
            irManager->newImmOpnd(irManager->getTypeManager().getUnmanagedPtrType(irManager->getTypeManager().getIntPtrType()), 0),
        };
        Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_entry", 3, args, NULL);
        prolog->prependInst(internalTraceInst);
    }

    const Edges& inEdges = irManager->getFlowGraph()->getExitNode()->getInEdges();
    for (Edges::const_iterator ite = inEdges.begin(), ende = inEdges.end(); ite!=ende; ++ite) {
        Edge* edge = *ite;
        if (irManager->isEpilog(edge->getSourceNode())) {
            Node* epilog = edge->getSourceNode();
            Inst * retInst=(Inst*)epilog->getLastInst();
            assert(retInst->hasKind(Inst::Kind_RetInst));
            Opnd * args[1]={ methodNameOpnd };
            Inst * internalTraceInst=irManager->newInternalRuntimeHelperCallInst("itrace_method_exit", 1, args, NULL);
            internalTraceInst->insertBefore(retInst);
        }
    }

#ifdef IA32_EXTENDED_TRACE
    const Nodes& nodes = irManager->getFlowGraph()->getNodes();
    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
        Node* node = *it;
        if (node->isBlockNode()){
            for (Inst * inst=(Inst*)node->getFirstInst(); inst!=NULL; inst=inst->getNextInst()){
                if (inst->getMnemonic()==Mnemonic_MOV){
                    Opnd * dest=inst->getOpnd(0);
                    if (dest->isPlacedIn(OpndKind_Memory) && dest->getMemOpndKind()==MemOpndKind_Heap){
                        Opnd * opnd=irManager->newOpnd(Type::UnmanagedPtr);
                        Inst* newIns = irManager->newInst(Mnemonic_LEA, opnd, dest);
                        newIns->insertBefore(inst);
                        Opnd * args[1]={ opnd };
                        newIns = irManager->newInternalRuntimeHelperCallInst("itrace_field_write", 1, args, NULL);
                        newIns->insertBefore(inst);
                    }
                }
            }
        }
    }
#endif
}
/**
 * Checks that exception edges are equal for newobj instruction node and
 * throw instruction node.
 * @param bs - bit set of operands that may be optimized
 */
void
LazyExceptionOpt::fixOptCandidates(BitSet* bs) {
    OptCandidates::iterator it;
    Inst* oinst;
    MethodCallInst* iinst;
    Inst* tinst;
    Inst* tlinst;
    U_32 opcount;
    Opnd **opnds = NULL;

    if (optCandidates == NULL) {
        return;
    }
    for (it = optCandidates->begin( ); it != optCandidates->end( ); it++ ) {
        if (bs->getBit((*it)->opndId)) {
            oinst = (*it)->objInst;
            assert(oinst != NULL);
#ifdef _DEBUG
            if (Log::isEnabled()) {
                Log::out() << "  to remove ";
                oinst->print(Log::out());
                Log::out() << std::endl;
            }
#endif
            if ((*it)->initInst == NULL) {
#ifdef _DEBUG
                if (Log::isEnabled()) {
                    Log::out() << "  init inst is null ";
                    Log::out() << std::endl;
                }
#endif
                continue;
            }
            iinst = (*it)->initInst->asMethodCallInst();
            // inline info from constructor should be propagated to lazy
            // exception if any
#ifdef _DEBUG
            if (Log::isEnabled()) {
                Log::out() << "  to remove ";
                iinst->print(Log::out());
                Log::out() << std::endl;
            }
#endif
            assert((*it)->throwInsts != NULL);
            assert(iinst->getNumSrcOperands() >= 3);
            if (!removeInsts(oinst,iinst))
                continue;   // to null bitset?
            TypeManager& tm = irManager.getTypeManager();
            Opnd* mpt = irManager.getOpndManager().createSsaTmpOpnd(
                            tm.getMethodPtrType(iinst->getMethodDesc()));
            opcount = iinst->getNumSrcOperands()-2;  //numSrc-3+1
            if (opcount >0) {
                opnds = new (leMemManager) Opnd*[opcount];   //local mem should be used
                opnds[0] = mpt;
                for (U_32 i = 0; i < opcount-1; i++)
                    opnds[i+1] = iinst->getSrc(i+3);
            }
            Inst* mptinst = irManager.getInstFactory().makeLdFunAddr(mpt,iinst->getMethodDesc());
#ifdef _DEBUG
            if (Log::isEnabled()) {
                Log::out() << "  1st      ";
                mptinst->print(Log::out());
                Log::out() << std::endl;
            }
#endif
            ThrowInsts::iterator it1;
            for (it1 = (*it)->throwInsts->begin(); it1 !=(*it)->throwInsts->end(); it1++) {
                tinst = *it1;
                assert(tinst != NULL);
                tlinst=irManager.getInstFactory().makeVMHelperCall(
                           OpndManager::getNullOpnd(), VM_RT_THROW_LAZY, opcount, opnds);
#ifdef _DEBUG
                if (Log::isEnabled()) {
                    Log::out() << "  2nd      ";
                    tlinst->print(Log::out());
                    Log::out() << std::endl;
                }
                if (Log::isEnabled()) {
                    Log::out() << "  to change ";
                    tinst->print(Log::out());
                    Log::out() << std::endl;
                }
#endif
                mptinst->insertBefore(tinst);
                tlinst->insertBefore(tinst);
                tinst->unlink();

                uint16 bcOffset = iinst->getBCOffset();
                mptinst->setBCOffset(bcOffset);
                tlinst->setBCOffset(bcOffset);
            }
        }
    }
}