Example #1
0
U_32
EscapeAnalyzer::doAnalysis() {
    MemoryManager memManager("EscapeAnalyzer::doAnalysis");
    StlDeque<Inst*> candidateSet(memManager);
    BitSet escapingInsts(memManager,irManager.getInstFactory().getNumInsts());

    const Nodes& nodes = irManager.getFlowGraph().getNodes();
    Nodes::const_iterator niter;
    //
    // Clear all marks on instructions
    // Collect instructions that are candidate for escape optimizations
    //
    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst* inst=headInst->getNextInst();inst!=NULL;inst=inst->getNextInst()) {
            if (isEscapeOptimizationCandidate(inst))
                candidateSet.push_back(inst);
        }
    }
    //
    // Iteratively mark instructions whose results escape the method
    //
    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst* inst=headInst->getNextInst();inst!=NULL;inst=inst->getNextInst()) {
            if (isPotentiallyEscapingInst(inst) == false)
                continue;
            escapingInsts.setBit(inst->getId(),true);
            for (U_32 i=0; i<inst->getNumSrcOperands(); i++) {
                if (isEscapingSrcObject(inst,i) == false)
                    continue;
                // src escapes
                markEscapingInst(inst->getSrc(i)->getInst(),escapingInsts);
            }
        }
    }
    //
    // Print out non-escaping instructions
    //
    U_32 numTrapped = 0;
    while (candidateSet.empty() == false) {
         Inst* inst = candidateSet.front();
         candidateSet.pop_front();
         if (escapingInsts.getBit(inst->getId()))
             continue;
         numTrapped++;
     }
     return numTrapped;
}
/**
 * Executes lazy exception optimization pass.
 */
void
LazyExceptionOpt::doLazyExceptionOpt() {
    MethodDesc &md = irManager.getMethodDesc();
    BitSet excOpnds(leMemManager,irManager.getOpndManager().getNumSsaOpnds());
    StlDeque<Inst*> candidateSet(leMemManager);
    optCandidates = new (leMemManager) OptCandidates(leMemManager);
    Method_Side_Effects m_sideEff = md.getSideEffect();

    const Nodes& nodes = irManager.getFlowGraph().getNodes();
    Nodes::const_iterator niter;

#ifdef _DEBUG
    mtdDesc=&md;
#endif

#ifdef _DEBUG
    if (Log::isEnabled()) {
        Log::out() << std::endl;
        for (int i=0; i<level; i++) Log::out() << " ";
        Log::out() << "doLE ";
        md.printFullName(Log::out());
        Log::out() << " SideEff " << (int)m_sideEff << std::endl;
    }
#endif

    level++;
    U_32 opndId = 0;
    isArgCheckNull = false;
    isExceptionInit = md.isInstanceInitializer() &&
                      md.getParentType()->isLikelyExceptionType();
//  core api exception init
    if (m_sideEff == MSE_Unknown && isExceptionInit
            && strncmp(md.getParentType()->getName(),"java/lang/",10) == 0) {
        m_sideEff = MSE_False;
        md.setSideEffect(m_sideEff);
#ifdef _DEBUG
        if (Log::isEnabled()) {
            Log::out() << "      core api exc ";
            md.printFullName(Log::out());
            Log::out() << " SideEff " << (int)m_sideEff << std::endl;
        }
#endif
    }

    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst* inst=headInst->getNextInst(); inst!=NULL; inst=inst->getNextInst()) {
#ifdef _DEBUG
            if (inst->getOpcode()==Op_DefArg && isExceptionInit) {
                if (Log::isEnabled()) {
                    Log::out() << "    defarg: ";
                    inst->print(Log::out());
                    Log::out()  << std::endl;
                    Log::out() << "            ";
                    Log::out() << (int)(inst->getDefArgModifier()) << " " <<
                               (inst->getDefArgModifier()==DefArgNoModifier) << " " <<
                               (inst->getDefArgModifier()==NonNullThisArg) << " " <<
                               (inst->getDefArgModifier()==SpecializedToExactType) << " " <<
                               (inst->getDefArgModifier()==DefArgBothModifiers) << std::endl;
                }
            }
#endif
            if (inst->getOpcode()==Op_Throw) {
                if (inst->getSrc(0)->getInst()->getOpcode()==Op_NewObj) {
                    excOpnds.setBit(opndId=inst->getSrc(0)->getId(),true);
                    if (!addOptCandidates(opndId,inst))
                        excOpnds.setBit(opndId,false); // different exc. edges
#ifdef _DEBUG
                    if (excOpnds.getBit(opndId)==1) {
                        if (Log::isEnabled()) {
                            Log::out() << "      add opnd: ";
                            inst->print(Log::out());
                            Log::out() << std::endl;
                            Log::out() << "      add  obj: ";
                            inst->getSrc(0)->getInst()->print(Log::out());
                            Log::out() << std::endl;
                        }
                    }
#endif
                }
            }
            if (m_sideEff == MSE_Unknown)
                if (instHasSideEffect(inst)) {
                    m_sideEff = MSE_True;
#ifdef _DEBUG
                    if (Log::isEnabled()) {
                        Log::out() << "~~~~~~inst sideEff ";
                        inst->print(Log::out());
                        Log::out() << std::endl;
                    }
#endif
                }
        }
    }
    if (md.getSideEffect() == MSE_Unknown) {
        if (m_sideEff == MSE_Unknown) {
            if (isExceptionInit && isArgCheckNull) {
#ifdef _DEBUG
                if (Log::isEnabled()) {
                    Log::out() << "~~~~~~init sideEff reset: " << m_sideEff << " 3 ";
                    md.printFullName(Log::out());
                    Log::out() << std::endl;
                }
#endif
                m_sideEff = MSE_True_Null_Param;
            } else
                m_sideEff = MSE_False;
        }
        md.setSideEffect(m_sideEff);
    }

    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        Opnd* opnd;
        for (Inst* inst=headInst->getNextInst(); inst!=NULL; inst=inst->getNextInst()) {
            U_32 nsrc = inst->getNumSrcOperands();
            for (U_32 i=0; i<nsrc; i++) {
                if (!(opnd=inst->getSrc(i))->isSsaOpnd())  // check ssa operands
                    continue;
                if (excOpnds.getBit(opndId=opnd->getId())==0)
                    continue;
                if (inst->getOpcode()==Op_DirectCall) {
                    MethodDesc* md = inst->asMethodInst()->getMethodDesc();
                    if (md->isInstanceInitializer() &&
                            md->getParentType()->isLikelyExceptionType()) {
                        if (!addOptCandidates(opndId,inst)) {
                            excOpnds.setBit(opndId,false);
#ifdef _DEBUG
                            if (Log::isEnabled()) {
                                Log::out() << "    - rem opnd " << opnd->getId() << " ";
                                inst->print(Log::out());
                                Log::out() << std::endl;
                            }
#endif
                        }
                    } else {
                        excOpnds.setBit(opndId,false);
#ifdef _DEBUG
                        if (Log::isEnabled()) {
                            Log::out() << "   -- rem opnd " << opnd->getId() << " ";
                            inst->print(Log::out());
                            Log::out() << std::endl;
                        }
#endif
                    }
                } else {
                    if (inst->getOpcode()!=Op_Throw) {
                        excOpnds.setBit(opndId,false);
#ifdef _DEBUG
                        if (Log::isEnabled()) {
                            Log::out() << "      rem opnd " << opnd->getId() << " ";
                            inst->print(Log::out());
                            Log::out() << std::endl;
                        }
#endif
                    }
                }
            }
        }
    }
    if (!excOpnds.isEmpty()) {
#ifdef _DEBUG
        if (Log::isEnabled()) {
            Log::out() << "------LE: ";
            md.printFullName(Log::out());
            Log::out() << std::endl;
        }
#endif
        fixOptCandidates(&excOpnds);
    }

    level--;
#ifdef _DEBUG
    if (Log::isEnabled()) {
        for (int i=0; i<level; i++) Log::out() << " ";
        Log::out() << "done ";
        md.printFullName(Log::out());
        Log::out() << " SideEff " << (int)m_sideEff << std::endl;
    }
#endif
};