void PrintDotFile::printDotHeader(MethodDesc& mh) { *os << "digraph dotgraph {" << ::std::endl << "node [shape=record,fontname=\"Courier\",fontsize=9];" << ::std::endl << "label=\"" << mh.getParentType()->getName() << "::" << mh.getName() << "\";" << ::std::endl; }
/** * Checks a callee method side effect. * @param inst - method call instruction * @return <code>true</code> if method has side effect; * <code>false<code> if method has no side effect. */ bool LazyExceptionOpt::methodCallHasSideEffect(Inst* inst) { U_32 opcode = inst->getOpcode(); MethodDesc* cmd = NULL; Method_Side_Effects mse = MSE_Unknown; if (opcode==Op_DirectCall || opcode==Op_TauVirtualCall) { cmd = inst->asMethodCallInst()->getMethodDesc(); } else { if (opcode==Op_IndirectCall || opcode==Op_IndirectMemoryCall) { Type* type = inst->asCallInst()->getFunPtr()->getType(); if (type->isUnresolvedType()) { return true; } cmd = type->asMethodPtrType()->getMethodDesc(); } else { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: no check "; inst->print(Log::out()); Log::out() << std::endl; } #endif return true; } } #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: "; cmd->printFullName(Log::out()); Log::out() << std::endl; } #endif mse = cmd->getSideEffect(); #ifdef _DEBUG if (mse != MSE_Unknown) { if (Log::isEnabled()) { Log::out() << " checkMC: prev.set sideEff " << mse << " "; inst->print(Log::out()); Log::out() << std::endl; } } #endif if (mse == MSE_True) { return true; } if (mse == MSE_False) { return false; } // core api exception init if (cmd->isInstanceInitializer() && cmd->getParentType()->isLikelyExceptionType() && strncmp(cmd->getParentType()->getName(),"java/lang/",10) == 0) { cmd->setSideEffect(MSE_False); #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: core api exc "; inst->print(Log::out()); Log::out() << std::endl; } #endif return false; } if ( opcode!=Op_DirectCall && !cmd->isFinal() ) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: not DirCall not final "; inst->print(Log::out()); Log::out() << std::endl; } #endif return true; } if (!isExceptionInit && !(cmd->isInstanceInitializer()&&cmd->getParentType()->isLikelyExceptionType())) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: no init "; Log::out() << isExceptionInit << " "; Log::out() << cmd->isInstanceInitializer() << " "; Log::out() << cmd->getParentType()->isLikelyExceptionType() << " "; inst->print(Log::out()); Log::out() << std::endl; } #endif return true; } /* if (cmd->getParentType()->needsInitialization()) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: need cinit "; inst->print(Log::out()); Log::out() << std::endl; } #endif return true; // cannot compile <init> before <clinit> (to fix vm) } */ if (mse == MSE_Unknown) { // try to compile method //TODO: avoid compilation here. Use translator to perform analysis needed bool allowRecursion = !compInterface.getTypeManager().isLazyResolutionMode(); if (!allowRecursion) { return MSE_True; } if (!compInterface.compileMethod(cmd)) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: method was not compiled " << std::endl; } #endif return true; } else { mse = cmd->getSideEffect(); #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: method was compiled, sideEff " << mse << std::endl; } #endif if (mse == MSE_True) return true; if (mse == MSE_False) { return false; } } } if (mse == MSE_True_Null_Param) { U_32 nsrc=inst->getNumSrcOperands(); bool mayBeNull; if (nsrc>3) { #ifdef _DEBUG if (Log::isEnabled()) { Log::out() << " checkMC: exc.init "; inst->print(Log::out()); Log::out() << std::endl; } #endif mayBeNull=false; for (U_32 i=3; i<nsrc; i++) { if (inst->getSrc(i)->getType()->isReference()) { if (mayBeNullArg(inst,i)) mayBeNull=true; } } if (!mayBeNull) return false; #ifdef _DEBUG for (U_32 i=0; i<nsrc; i++) { if (Log::isEnabled()) { Log::out() << " "<<i<<" isRef: "<< inst->getSrc(i)->getType()->isReference()<<" "; inst->getSrc(i)->getInst()->print(Log::out()); Log::out() << std::endl; } } #endif return true; } #ifdef _DEBUG else { if (Log::isEnabled()) { Log::out() << " ?????? MSE_NULL_PARAM & nsrc "<< nsrc << std::endl; } } #endif } return true; }
/** * 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 };