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 };