You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/05/08 11:44:53 UTC
svn commit: r536140 [2/3] - in /harmony/enhanced/drlvm/trunk/vm/jitrino:
config/em64t/opt.emconf config/ia32/opt.emconf
src/optimizer/escanalyzer.cpp src/optimizer/escanalyzer.h
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp?view=diff&rev=536140&r1=536139&r2=536140
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Tue May 8 02:44:50 2007
@@ -40,7 +40,11 @@
const char* help =
" escape flags:\n"
" escape.max_level[=0] - max level callee method analysis\n"
- " escape.do_sync_removal[={on,OFF}] - do synchonization removal optimization\n"
+ " escape.do_sync_removal[={on,OFF}] - do synchronization removal optimization\n"
+ " escape.do_sync_removal_vc[={ON,off}] - do synchronization removal optimization\n"
+ " for virtual call escaped operands\n"
+ " escape.do_sync_removal_sm[={ON,off}] - do synchronization removal optimization\n"
+ " for synchronized methods\n"
" escape.do_scalar_repl[={ON,off}] - do scalar replacement optimization for\n"
" local and escaped objects\n"
" escape.do_esc_scalar_repl[={ON,off}] - scalar replacement for escaped objects\n"
@@ -62,8 +66,8 @@
uint32 _n_lo;
};
static ComObjStat comObjStat;
-EscAnalyzer::CalledMethodInfos* EscAnalyzer::calledMethodInfos=NULL;
-Mutex EscAnalyzer::calledMethodInfosLock;
+EscAnalyzer::CalleeMethodInfos* EscAnalyzer::calleeMethodInfos=NULL;
+Mutex EscAnalyzer::calleeMethodInfosLock;
void
@@ -76,33 +80,22 @@
Log::out() << "E s c a p e A n a l y s i s " << std::endl;
}
- //if (Log::isEnabled()) {
- // const char* i1=Log::getDotFileDirName();
- // if (strlen(i1)!=0) {
- // ControlFlowGraph& flowGraph = irm.getFlowGraph();
- // FlowGraph::printDotFile(flowGraph, irm.getMethodDesc(), "ea1");
- // }
- //}
ea.doAnalysis();
- //if (Log::isEnabled()) {
- // const char* i1=Log::getDotFileDirName();
- // if (strlen(i1)!=0) {
- // ControlFlowGraph& flowGraph = irm.getFlowGraph();
- // FlowGraph::printDotFile(flowGraph, irm.getMethodDesc(), "ea2");
- // }
- //}
+
} // run(IRManager& irm)
EscAnalyzer::EscAnalyzer(MemoryManager& mm, SessionAction* argSource, IRManager& irm)
-: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc()),os_sc(Log::out()),
- compInterface(irm.getCompilationInterface())
+: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc()),
+ compInterface(irm.getCompilationInterface()),os_sc(Log::out())
{
maxMethodExamLevel = (uint32)argSource->getIntArg("max_level",maxMethodExamLevel_default);
allProps = (uint32)argSource->getIntArg("d_prop",0);
debug_method = argSource->getStringArg("d_method", NULL);
method_ea_level = 0; // determines level of method scan
- do_sync_removal = argSource->getBoolArg("do_sync_removal",false);
+ do_sync_removal = argSource->getBoolArg("do_sync_removal",true);
+ do_sync_removal_vc = argSource->getBoolArg("do_sync_removal_vc",true);
+ do_sync_removal_sm = argSource->getBoolArg("do_sync_removal_sm",true);
do_scalar_repl = argSource->getBoolArg("do_scalar_repl",true);
do_esc_scalar_repl = argSource->getBoolArg("do_esc_scalar_repl",true);
print_scinfo = argSource->getBoolArg("sc_info",false);
@@ -129,8 +122,8 @@
}
EscAnalyzer::EscAnalyzer(EscAnalyzer* parent, IRManager& irm)
-: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc()), os_sc(Log::out()),
- compInterface(irm.getCompilationInterface())
+: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc()),
+ compInterface(irm.getCompilationInterface()), os_sc(Log::out())
{
maxMethodExamLevel = parent->maxMethodExamLevel;
allProps = parent->allProps;
@@ -151,7 +144,8 @@
scannedObjsRev = new (eaMemManager) ObjIds(eaMemManager);
scannedInsts = new (eaMemManager) ObjIds(eaMemManager);
scannedSucNodes = new (eaMemManager) ObjIds(eaMemManager);
- monitorInstUnits = new (eaMemManager) MonInstUnits(eaMemManager);
+ monitorInstUnits = new (eaMemManager) MonInstUnits(eaMemManager);
+ exam2Insts = new (eaMemManager) Insts(eaMemManager);
methodEndInsts = new (eaMemManager) Insts(eaMemManager);
checkInsts = new (eaMemManager) Insts(eaMemManager);
@@ -204,7 +198,11 @@
EscAnalyzer::showFlags(std::ostream& os) {
os << " escape flags:"<<std::endl;
os << " escape.max_level[=0] - max level callee method analysis" << std::endl;
- os << " escape.do_sync_removal[={on,OFF}] - do synchonization removal optimization" << std::endl;
+ os << " escape.do_sync_removal[={On,off}] - do synchronization removal optimization" << std::endl;
+ os << " escape.do_sync_removal_vc[={ON,off}] - do synchronization removal optimization" << std::endl;
+ os << " for virtual call escaped operands" << std::endl;
+ os << " escape.do_sync_removal_sm[={ON,off}] - do synchronization removal optimization" << std::endl;
+ os << " for synchronized methods" << std::endl;
os << " escape.do_scalar_repl[={ON,off}] - do scalar replacement optimization for" << std::endl;
os << " local and escaped objects" << std::endl;
os << " escape.do_esc_scalar_repl[={ON,off}] - scalar replacement for escaped objects" << std::endl;
@@ -259,11 +257,9 @@
if (mh.isStatic())
Log::out()<<"stat ";
Log::out()<<nodeNum<<" "<<num2<<" "<<num3<< " ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out()<< std::endl;
}
- cfgNode* pr_n = new (eaMemManager)cfgNode[nodeNum]; // passed nodes
int maxInd = 0;
int cur = -1;
Node* node;
@@ -272,49 +268,40 @@
for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
node = *niter;
cur = maxInd++;
- (pr_n[cur]).nodeId = node->getId();
- (pr_n[cur]).fgNode = node;
- (pr_n[cur]).instructions = NULL;
// exam instructions
#ifdef _DEBUG
if (_cfgirun) {
Log::out() <<std::endl;
- Log::out() <<"pr_n["<<cur<<"] nId "<<(pr_n[cur]).nodeId;
- Log::out() <<" Node "<<(pr_n[cur]).fgNode->getId();
- Log::out() <<std::endl;
+ Log::out() <<"Scan "<< cur <<" Node ";
+ FlowGraph::printLabel(Log::out(),node);
+ Log::out() <<" Id. "<<node->getId() <<std::endl;
}
#endif
- instrExam(&pr_n[cur]);
+ instrExam(node);
};
#ifdef _DEBUG
if (_cngnodes) {
Log::out() <<"printCnGNodes: ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out() << std::endl;
- if (Log::isEnabled())
- printCnGNodes("First run result: nodes",Log::out());
+ printCnGNodes("First run result: nodes",Log::out());
}
#endif
cngEdges=new (eaMemManager) CnGEdges(eaMemManager); // Common part of connection graph (edges)
- for (int i=0; i<maxInd; i++) {
- instrExam2(&pr_n[i]);
- }
+ instrExam2();
#ifdef _DEBUG
if (_cngedges) {
Log::out() <<"printCnGEdges: ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out() << std::endl;
- if (Log::isEnabled())
- printCnGEdges("resulting OUT CnGEdges",Log::out());
+ printCnGEdges("resulting OUT CnGEdges",Log::out());
}
#endif
@@ -323,8 +310,7 @@
//#ifdef _DEBUG
if (_eainfo) {
- if (Log::isEnabled())
- printCreatedObjectsInfo(Log::out());
+ printCreatedObjectsInfo(Log::out());
}
//#endif
@@ -333,14 +319,11 @@
#ifdef _DEBUG
if (_cngedges) {
Log::out() << "++++++++++++++ printRefInfo() ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out() << std::endl;
- if (Log::isEnabled())
- printRefInfo(Log::out());
+ printRefInfo(Log::out());
Log::out() << "++++++++++++++ end ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out() << std::endl;
}
#endif
@@ -353,16 +336,12 @@
markNotEscInsts();
}
-//#ifdef _DEBUG
if (_cngnodes) {
Log::out() <<"printCnGNodes: ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out() << std::endl;
- if (Log::isEnabled())
- printCnGNodes("Marked nodes",Log::out());
+ printCnGNodes("Marked nodes",Log::out());
}
-//#endif
if (method_ea_level == 0) {
createdObjectInfo(); // prints if _printstat==1
@@ -383,28 +362,6 @@
#ifdef _DEBUG
if (_seinfo && Log::isEnabled()) {
printCreatedObjectsInfo(Log::out());
- Log::out() << "================ this argument of sync method"
- << std::endl;
- CnGNodes::iterator it;
- for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
- CnGNode* n = (*it);
- if (n->nodeType==NT_ACTARG && n->argNumber==0 &&
- ((MethodDesc*)(n->refObj))->isSynchronized()) {
- ((MethodDesc*)(n->refObj))->printFullName(Log::out());
- Log::out()<<std::endl;
- printCnGNodeRefs(n, " ", Log::out());
- }
- }
-
- scannedObjs->clear();
- Log::out() << "================ Return Values 2" << std::endl;
- for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
- if ((*it)->nodeType==NT_EXITVAL) {
- printCnGNodeRefs(*it, "", Log::out());
- }
- }
- scannedObjs->clear();
-
}
#endif
}
@@ -416,8 +373,7 @@
Log::out()<<"sync ";
if (mh.isStatic())
Log::out()<<"stat ";
- if (Log::isEnabled())
- mh.printFullName(Log::out());
+ mh.printFullName(Log::out());
Log::out()<< std::endl;
}
@@ -438,1502 +394,1956 @@
} // doAnalysis()
-void
-EscAnalyzer::eaFixupVars(IRManager& irm) {
- OptPass::computeDominators(irm);
- DominatorTree* dominatorTree = irm.getDominatorTree();
- ControlFlowGraph& flowGraph = irm.getFlowGraph();
-
- DomFrontier frontier(irm.getNestedMemoryManager(),*dominatorTree,&flowGraph);
- SSABuilder ssaBuilder(irm.getOpndManager(),irm.getInstFactory(),frontier,&flowGraph, irm.getOptimizerFlags());
- bool phiInserted = ssaBuilder.fixupVars(&irm.getFlowGraph(), irm.getMethodDesc());
- irm.setInSsa(true);
- if (phiInserted)
- irm.setSsaUpdated();
-}
-
-
-void
-EscAnalyzer::scanSyncInsts() {
- MonInstUnits::iterator it;
- Insts::iterator it1;
- Insts* syncInsts;
- CnGNode* node;
- uint32 checkedState = 0;
- uint32 nState = 0;
- bool to_fix_ssa = false;
+void
+EscAnalyzer::instrExam(Node* node) {
+ Inst *headInst = (Inst*)node->getFirstInst();
+ int insnum=0;
+ Type* type;
+ CnGNode* cgnode;
+ uint32 ntype=0;
+ MethodDesc* md;
+ uint32 n;
+ bool addinst;
+ Inst* method_inst;
- if (monitorInstUnits == NULL)
- return;
+ for (Inst* inst=headInst->getNextInst();inst!=NULL;inst=inst->getNextInst()) {
+ insnum++;
+ ntype=0;
+ if (_instrInfo) {
+ Log::out() <<"instrExam:" << std::endl;
+ Log::out() <<"++Node Id."<<node->getId()<<" "<<node->getDfNum()<<std::endl;
+ Log::out() <<"instrExam++Node Id."<<node->getId()<<" "<<node->getDfNum()<<std::endl;
+ Log::out() << "==";
+ inst->print(Log::out());
+ Log::out() << std::endl;
+ }
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "Synchronized units: " << std::endl;
- }
-#endif
- for (it = monitorInstUnits->begin( ); it != monitorInstUnits->end( ); it++ ) {
- node = findCnGNode_op((*it)->opndId);
- checkedState = 0;
- nState = getEscState(node);
- if (node->nodeType == NT_OBJECT || nState == GLOBAL_ESCAPE)
- checkedState = nState;
- if (nState != GLOBAL_ESCAPE && (node->nodeType != NT_OBJECT)) {
- checkedState = checkState(node->nInst,nState);
- scannedObjs->clear();
- if (checkedState != nState && checkedState != 0) {
-#ifdef _DEBUG
- if (_setState) {
- Log::out() <<"--scanSyncInsts 1: node "
- <<node->cngNodeId<<" opndId "<<node->opndId
- <<" state ";
- if (Log::isEnabled())
- printState(node);
- Log::out()<<" to esc.state "<< checkedState << std::endl;
+ switch (inst->getOpcode()) {
+ case Op_NewObj: // newobj
+ case Op_NewArray: // newarray
+ case Op_NewMultiArray: // newmultiarray
+ ntype=NT_OBJECT; // for 3 cases above
+ case Op_LdRef: // ldref
+ case Op_LdConstant: // ldc
+ if (ntype==0)
+ ntype=NT_LDOBJ; // loads refs
+ case Op_DefArg: // defarg
+ if (ntype==0) {
+ ntype=NT_DEFARG; // for Op_DefArg
+ defArgNumber++;
}
-#endif
- setEscState(node,checkedState);
- }
- }
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() <<"--sync: state ";
- Log::out() << checkedState << " ";
- if (checkedState != nState)
- Log::out() << "initState " << nState << " ";
- Log::out() << node->cngNodeId << " - " << node->opndId << " ";
- if (Log::isEnabled())
- printCnGNode(node,Log::out());
- Log::out() << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- if ((node->nodeType&NT_OBJECT)==0 && (getEscState(node) != GLOBAL_ESCAPE)) {
- findObject(node->nInst);
- scannedObjs->clear();
- }
- syncInsts = (*it)->monInsts;
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,ntype);
+ }
+ break;
+
+ case Op_Conv: // conv
#ifdef _DEBUG
- if (_seinfo) {
- for (it1 = syncInsts->begin( ); it1 != syncInsts->end( ); it1++ ) {
- Log::out() << " -";
- if (Log::isEnabled())
- (*it1)->print(Log::out());
- Log::out() << " // node "
- << (*it1)->getNode()->getId() << std::endl;
- }
- }
-#endif
- if (getEscState(node) == GLOBAL_ESCAPE)
- setSencEscState(node,syncInsts);
- if (getVirtualCall(node)!=0) {
- if (checkedState > GLOBAL_ESCAPE) {
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
+#endif
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_OBJECT);
+ }
+ break;
+
+ case Op_LdFieldAddr: // ldflda
+ ntype=NT_INSTFLD;
+ case Op_LdStaticAddr: // ldsflda
+ if (ntype==0)
+ ntype=NT_STFLD; // for LdStaticAddr
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- vc loc.esc." << std::endl;
- findObject(node->nInst);
- scannedObjs->clear();
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
}
#endif
- if (node->nodeType==NT_OBJECT) {
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- vc to optimize object" << std::endl;
+ FieldAccessInst* fainst;
+ if ((fainst=inst->asFieldAccessInst())!=NULL) {
+ type=fainst->getFieldDesc()->getFieldType(); //field type
+ if (type->isReference()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_REF);
+ CnGNode* n = findCnGNode_fl(inst,ntype);
+ if (n==NULL) {
+ n = addCnGNode_fl(inst,ntype);
+ }
+ cgnode->lNode=n; // stick nodes
+ exam2Insts->push_back(inst);
+ } else {
+ if (ntype==NT_INSTFLD) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_REF);
+ CnGNode* n = findCnGNode_fl(inst,ntype);
+ if (n==NULL) {
+ n = addCnGNode_fl(inst,ntype);
+ }
+ exam2Insts->push_back(inst);
+ cgnode->lNode=n; // stick nodes
+ }
}
-#endif
- fixMonitorInstsVCalls(*it);
}
- if (node->nodeType==NT_RETVAL) {
+ break;
+
+ case Op_TauLdInd: // ldind
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- vc to optimize retval" << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- fixMonitorInstsVCalls(*it);
+ type = inst->getDst()->getType();
+ if (type->isReference()) { //isObject()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_LDOBJ);
+ exam2Insts->push_back(inst);
}
- if (!to_fix_ssa)
- to_fix_ssa = true;
- } else {
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- vc gl.esc." << std::endl;
- findObject(node->nInst);
- scannedObjs->clear();
+ if (inst->getSrc(0)->getInst()->getOpcode()==Op_LdStaticAddr)
+ break;
+ if (type->isValue()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_LDVAL);
+ exam2Insts->push_back(inst);
}
-#endif
- }
- } else {
- if (node->nodeType==NT_OBJECT && getEscState(node) != GLOBAL_ESCAPE) {
+ break;
+
+ case Op_LdArrayBaseAddr: // ldbase
+ case Op_AddScaledIndex: // addindex
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ to optimize (remove) object" << std::endl;
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
}
#endif
- removeMonitorInsts(syncInsts);
- }
+ if (inst->getDst()->getType()->isReference()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_ARRELEM);
+ exam2Insts->push_back(inst);
+ }
+ break;
- if (node->nodeType==NT_DEFARG && getEscState(node) != GLOBAL_ESCAPE
- && node->nInst->getDefArgModifier()==NonNullThisArg && mh.isSynchronized()) {
+ case Op_VMHelperCall: // callvmhelper
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ to optimize (fix) defarg.ths" << std::endl;
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
}
#endif
-#ifndef PLATFORM_POSIX
- fixSyncMethodMonitorInsts(syncInsts);
-#endif
- }
-// if (opndInst->getOpcode()==Op_DefArg && opndInst->getDefArgModifier()==NonNullThisArg) {
+ if (!inst->getDst()->isNull()) {
+ if (inst->getDst()->getType()->isObject()) {
+ CompilationInterface::RuntimeHelperId callId =
+ inst->asVMHelperCallInst()->getVMHelperId();
+ switch(callId) {
+ case CompilationInterface::Helper_GetTLSBase:
+ ntype = NT_ARRELEM;
+ break;
+ case CompilationInterface::Helper_NewObj_UsingVtable:
+ case CompilationInterface::Helper_NewVector_UsingVtable:
+ ntype = NT_OBJECT;
+ break;
+ default:
+ ntype = 0;
+ assert(0);
+ }
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,ntype);
+ }
+ }
+#ifdef _DEBUG
+ if (_seinfo) {
+ CompilationInterface::RuntimeHelperId callId =
+ inst->asVMHelperCallInst()->getVMHelperId();
+ if (method_ea_level == 0 && callId != CompilationInterface::Helper_Throw_Lazy) {
- }
- }
-#ifndef PLATFORM_POSIX
- checkCallSyncMethod();
+ Log::out() <<"iE: callvmhelper ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ }
+ }
#endif
- // to fix var operand inserted by fixMonitorInstsVCalls method
- if (to_fix_ssa) {
- OptPass::fixupSsa(irManager);
- }
- return;
-} // scanSyncInsts()
-
-
-void
-EscAnalyzer::fixSyncMethodMonitorInsts(Insts* syncInsts) {
- SsaTmpOpnd* stThis = (SsaTmpOpnd*)insertReadJitHelperCall();
- insertFlagCheck(syncInsts,stThis);
-} // fixSyncMethodMonitorInsts(Insts* syncInsts)
+ break;
+ case Op_JitHelperCall: // calljithelper
+ if (method_ea_level == 0) {
+ Log::out() <<"iE: calljithelper ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ switch(inst->asJitHelperCallInst()->getJitHelperId()) {
+ case InitializeArray:
+ case FillArrayWithConst:
+ case SaveThisState:
+ case ReadThisState:
+ case LockedCompareAndExchange:
+ case AddValueProfileValue:
+ break;
+ default:
+ assert(0);
+ }
+ }
+ break;
-void
-EscAnalyzer::checkCallSyncMethod() {
- CnGNodes::iterator it;
- CnGRefs::iterator it2;
- CnGNode* node;
- CnGNode* aanode;
- MethodDesc* md;
- CalledMethodInfo* mtdInfo;
- uint32 callee_state;
+ case Op_TauStInd: // stind
+#ifdef _DEBUG
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
+#endif
+ if ((type=inst->getSrc(0)->getType())->isObject() || type->isValue()) {
+ exam2Insts->push_back(inst);
+ }
+ break;
- for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
- node = (*it);
- if (node->nodeType == NT_ACTARG && node->argNumber == 0) {
- md = (MethodDesc*)(node->refObj);
- if (md->isSynchronized() && node->nInst->getOpcode()==Op_DirectCall) {
- const char* ch1 = md->getParentType()->getName();
- const char* ch2 = md->getName();
- const char* ch3 = md->getSignatureString();
- mtdInfo = getMethodInfo(ch1,ch2,ch3);
- if (mtdInfo==NULL) {
- callee_state = 0;
+ case Op_DirectCall: // call
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- Methodinfo is NULL";
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
+#endif
+ if (!inst->getDst()->isNull()) {
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_RETVAL);
+ }
+ }
+ md=inst->asMethodInst()->getMethodDesc();
+ n=md->getNumParams();
+ addinst=false;
+ for (uint32 i = 0; i < n; i++) {
+ Type* tt = md->getParamType(i);
+ if (!tt->isReference()) {
+ continue;
+ }
+ addinst=true;
+ assert(findCnGNode_mp(inst->getId(),i)==NULL);
+ cgnode = addCnGNode_mp(inst,md,NT_ACTARG, i);
+ }
+ if (addinst) {
+ exam2Insts->push_back(inst);
+ }
+#ifdef _DEBUG
+ if (_seinfo) {
+ if (method_ea_level == 0) {
+ Log::out() <<"iE: call ";
+ if (md->isSynchronized())
+ Log::out() << "sync ";
+ if (md->isStatic())
+ Log::out() << "stat ";
+ if (md->isNative())
+ Log::out() << "native ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ Log::out() << " ";
+ md->printFullName(Log::out());
Log::out() << std::endl;
}
+ }
+#endif
+ break;
+
+ case Op_IndirectMemoryCall: //callimem
+#ifdef _DEBUG
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
+ if (!inst->getDst()->isNull()) {
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_RETVAL);
+ }
+ }
+ method_inst=inst->getSrc(0)->getInst();
+ if (method_inst->getOpcode() == Op_LdVar) {
+ Opnd* funptr = inst->getSrc(0);
+ Type* optype = funptr->getType();
+ MethodPtrType* opmtype = optype->asMethodPtrType();
+ md = opmtype->getMethodDesc();
} else {
- callee_state = getMethodParamState(mtdInfo,0);
+ md=method_inst->asMethodInst()->getMethodDesc();
}
-#ifdef _DEBUG
+ n=md->getNumParams();
+ addinst=false;
+ for (uint32 i = 0; i < n; i++) {
+ Type* tt = md->getParamType(i);
+ if (!tt->isReference()) {
+ continue;
+ }
+ addinst=true;
+ assert(findCnGNode_mp(inst->getId(),i)==NULL);
+ cgnode = addCnGNode_mp(inst,md,NT_ACTARG,i);
+ }
+ if (addinst) {
+ exam2Insts->push_back(inst);
+ }
+#ifdef _DEBUG
if (_seinfo) {
- Log::out() << "---- checkCallSyncMethod:" << std::endl;
- if (Log::isEnabled())
- node->nInst->print(Log::out());
- Log::out() << std::endl;
- if (Log::isEnabled())
- printCnGNode(node,Log::out());
- Log::out() << std::endl;
- if (node->outEdges != NULL) {
- for (it2 = node->outEdges->begin(); it2 != node->outEdges->end(); it2++ ) {
- Log::out() << " ccsm: ";
- if (Log::isEnabled())
- printState(callee_state);
- Log::out() << " ";
- if (Log::isEnabled())
- printCnGNode((*it2)->cngNodeTo,Log::out());
- Log::out() << std::endl;
- }
- }
- Log::out() << "++++ checkCallSyncMethod: ";
- Log::out() << " instance: " << md->isInstance() <<
- " initializer: " << md->isInstanceInitializer() << " end" << std::endl;
+ if (method_ea_level == 0) {
+ Log::out() <<"iE: callimem ";
+ if (md->isSynchronized())
+ Log::out() << "sync ";
+ if (md->isStatic())
+ Log::out() << "stat ";
+ if (md->isNative())
+ Log::out() << "native ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ Log::out() << " ";
+ md->printFullName(Log::out());
+ Log::out() << std::endl;
+ }
}
#endif
- if (callee_state == 0)
- callee_state = GLOBAL_ESCAPE;
- if (!isGlobalState(callee_state)) {
- if (node->outEdges != NULL) {
- for (it2 = node->outEdges->begin(); it2 != node->outEdges->end(); it2++ ) {
- aanode = (*it2)->cngNodeTo;
- if (!isGlobalState(aanode->state)&&
- (aanode->nodeType==NT_OBJECT||aanode->nodeType==NT_RETVAL)) {
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out()
- << "=-=- sm this.agr.saving" << std::endl;
- }
-#endif
- insertSaveJitHelperCall(node);
+ break;
+
+ case Op_IntrinsicCall: // callintr
#ifdef _DEBUG
- if (_seinfo) {
- Log::out()
- << " checkCSM: this was saved"
- << std::endl;
- }
- } else {
- if (_seinfo) {
- Log::out()
- << " checkCSM: this wasn't saved"
- << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- }
- }
+
+ if (!inst->getDst()->isNull()) {
+ assert(0);
+ }
+ n=inst->getNumSrcOperands();
+ addinst=false;
+ for (uint32 i = 0; i < n; i++) {
+ Type* tt = inst->getSrc(i)->getType();
+ if (!tt->isReference()) {
+ continue;
}
+ addinst=true;
+ break;
+ }
+ if (addinst) {
+ exam2Insts->push_back(inst);
}
- }
- }
- }
-} // checkCallSyncMethod()
-
-/**
- * Inserts ldc0, if it was not inserted previously,
- * jit helper call to save this arg of direct call method.
- * Parameter:
- * CnGNode corresponding to this arg of direct call sync method.
- */
-void
-EscAnalyzer::insertSaveJitHelperCall(CnGNode* node) {
- SsaTmpOpnd* stVal;
- Inst* inst_before = node->nInst;
- Node* oldBlock = inst_before->getNode();
- ControlFlowGraph& fg = irManager.getFlowGraph();
+#ifdef _DEBUG
+ if (_seinfo) {
+ if (method_ea_level == 0) {
+ Log::out() <<"iE: callintr ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ }
+ }
+#endif
+ break;
+ case Op_Catch: // catch
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ insertSJHC: before" << std::endl;
- if (Log::isEnabled()) {
- printNode(fg.getEntryNode(),Log::out());
- printNode(oldBlock,Log::out());
- }
- Log::out() << "++++ insertSJHC: before end" << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- stVal = insertLdConst(0);
- // insert jit helper call
- Opnd* args[1] = {stVal};
- InstFactory& instfactory = irManager.getInstFactory();
- Inst* jhcinst = instfactory.makeJitHelperCall(
- OpndManager::getNullOpnd(), SaveThisState, 1, args);
- // add jit helper
- jhcinst->insertBefore(inst_before);
- Node* newBlock = fg.splitNodeAtInstruction(jhcinst, true, false, instfactory.makeLabel());
- // add dispatch edge to oldBlock
- fg.addEdge(oldBlock,newBlock->getExceptionEdgeTarget());
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_CATCHVAL);
+ }
+ break;
+
+ case Op_StVar: // stvar
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ insertSJHC: after" << std::endl;
- if (Log::isEnabled()) {
- printNode(fg.getEntryNode(),Log::out());
- printNode(oldBlock,Log::out());
- printNode(newBlock,Log::out());
- }
- Log::out() << "++++ insertSJHC: after end" << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
-} // insertSaveJitHelperCall(CnGNode* node)
-
-
-/**
- * Inserts ldc0, if it was not inserted previously,
- * jit helper call to read this arg of the method.
- * Parameter:
- * CnGNode corresponding to this arg of direct call sync method.
- * Returns:
- * Opnd* stored_value
- * 0 - this argument is thread local, 1 - this argument is thread global
- */
-Opnd*
-EscAnalyzer::insertReadJitHelperCall() {
- ControlFlowGraph& fg = irManager.getFlowGraph();
- Node* oldBlock = fg.getEntryNode();
- Inst* inst_after = (Inst*)oldBlock->getFirstInst();
- TypeManager& _typeManager = irManager.getTypeManager();
- Type* typeInt32 = _typeManager.getInt32Type();
- OpndManager& _opndManager = irManager.getOpndManager();
- SsaTmpOpnd* stThis = _opndManager.createSsaTmpOpnd(typeInt32);
+ type = inst->getDst()->getType();
+ if (type->isObject()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_VARVAL);
+ exam2Insts->push_back(inst);
+ }
+ break;
+ case Op_Phi: // phi
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ insertRJHC: before" << std::endl;
- if (Log::isEnabled())
- printNode(oldBlock,Log::out());
- Log::out() << "++++ insertRJHC: before end" << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- insertLdConst(0);
- // insert jit helper call
- Opnd** args = NULL;
- InstFactory& instfactory = irManager.getInstFactory();
- Inst* jhcinst = instfactory.makeJitHelperCall(
- stThis, ReadThisState, 0, args);
- jhcinst->insertAfter(inst_after);
- fg.splitNodeAtInstruction(jhcinst,true, false,instfactory.makeLabel());
- fg.addEdge(oldBlock,fg.getUnwindNode());
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "++++ insertRJHC: after" << std::endl;
- if (Log::isEnabled()) {
- printNode(oldBlock,Log::out());
- }
- Log::out() << "++++ insertRJHC: after end" << std::endl;
- }
-#endif
- return stThis;
-} // insertReadJitHelperCall()
-
-
-/**
- * Checks, that method contains monitor instructions with parameter
- * which is this or subobject of this.
- * Returns: true, if such monitors exist, false overwise.
- */
-bool
-EscAnalyzer::checkMonitorsOnThis() {
- MonInstUnits::iterator it;
- Insts::iterator it1;
- CnGNode* node;
-
- if (monitorInstUnits==NULL)
- return false;
- for (it = monitorInstUnits->begin( ); it != monitorInstUnits->end( ); it++ ) { //540
- node = findCnGNode_op((*it)->opndId);
+ type = inst->getDst()->getType();
+ if (type->isReference()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_VARVAL);
+ exam2Insts->push_back(inst);
+ }
+ break;
- Inst* opndInst = node->nInst;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " checkMOT: ";
- if (Log::isEnabled())
- opndInst->print(Log::out());
- Log::out() << std::endl;
- }
-#endif
- if (opndInst->getOpcode()==Op_DefArg && opndInst->getDefArgModifier()==NonNullThisArg) {
+ case Op_LdVar: // ldvar
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " checkMOT: ";
- Log::out() << (int)(opndInst->getDefArgModifier()) << " " <<
- (opndInst->getDefArgModifier()==DefArgNoModifier) << " " <<
- (opndInst->getDefArgModifier()==NonNullThisArg) << " " <<
- (opndInst->getDefArgModifier()==DefArgBothModifiers) << " state: ";
- if (Log::isEnabled())
- printState(node,Log::out());
- Log::out() << std::endl;
- if (getEscState(node) != GLOBAL_ESCAPE) {
- Log::out() << " defarg.ths isn't global "<< std::endl;
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
}
- }
#endif
- return true;
- }
- }
- return false;
-} // checkMonitorsOnThis()
-
+ type = inst->getDst()->getType();
+ if (type->isReference()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_LDOBJ);
+ exam2Insts->push_back(inst);
+ }
+ break;
-void
-EscAnalyzer::setSencEscState(CnGNode* node,Insts* syncInsts) {
- CnGEdges::iterator it;
- Insts::iterator it1;
- CnGRefs::iterator it2;
- Inst* einst;
- bool pLocalObj = true;
- bool pLocalCurObj = false;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- to node " << node->cngNodeId
- << std::endl;
- }
-#endif
- scannedSucNodes->clear(); // prepared for successor collection
- for (it = cngEdges->begin( ); it != cngEdges->end( ); it++ ) {
- for (it2 = (*it)->refList->begin( ); it2 != (*it)->refList->end( ); it2++ ) {
- if ((*it2)->cngNodeTo == node) {
- pLocalCurObj = false;
- einst = (*it2)->edgeInst;
+ case Op_Return: // return
+ ntype=NT_EXITVAL;
+ case Op_Throw: // throw
+ if (ntype==0)
+ ntype=NT_THRVAL;
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- ";
- Log::out() << einst->getNode()->getId()
- << " ";
- if (Log::isEnabled())
- einst->print(Log::out());
- Log::out() << std::endl;
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
}
#endif
- if (einst->getOpcode() == Op_DirectCall) {
- MethodDesc* md=einst->asMethodInst()->getMethodDesc();
- const char* ch1 = md->getParentType()->getName();
- const char* ch2 = md->getName();
- const char* ch3 = md->getSignatureString();
- CalledMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3);
- if (mtdInfo==NULL) {
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- Methodinfo is NULL";
- Log::out() << std::endl;
- }
-#endif
- } else {
- uint32 st = getMethodParamState(mtdInfo,(*it)->cngNodeFrom->argNumber);
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- Method param "
- << (*it)->cngNodeFrom->argNumber << " state is ";
- if (Log::isEnabled())
- printState(st);
- Log::out() << std::endl;
- }
-#endif
- if ((st&ESC_MASK)>GLOBAL_ESCAPE) {
- pLocalCurObj = true;
+ if (inst->getNumSrcOperands()>0) {
+ if (inst->getSrc(0)->getType()->isObject()) {
+ assert(findCnGNode_in(inst->getId())==NULL);
+ cgnode = addCnGNode_ex(inst,ntype);
+ exam2Insts->push_back(inst);
+ }
+ }
+ break;
+
+ case Op_TauStaticCast: // staticcast
+ case Op_TauCast: // cast
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- Method param "
- << (*it)->cngNodeFrom->argNumber << " state is ";
- if (Log::isEnabled())
- printState(st);
- Log::out() << std::endl;
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- } else {
+ type = inst->getDst()->getType();
+ if (type->isObject()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_REF);
+ exam2Insts->push_back(inst);
+ }
+ break;
+
+ case Op_SaveRet: // saveret
#ifdef _DEBUG
- if (_seinfo) {
- if (Log::isEnabled())
- printMethodInfo(mtdInfo);
- }
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ debug_inst_info(inst,Log::out());
+ }
#endif
- }
- }
+ type = inst->getDst()->getType();
+ if (type->isIntPtr()) {
+ cgnode = findCnGNode_op(inst->getDst()->getId());
+ if (cgnode == NULL)
+ cgnode = addCnGNode_op(inst,type,NT_INTPTR);
}
- findObject1(einst);
- collectSuccessors(einst->getNode());
- }
- }
- for (it1 = syncInsts->begin(); it1 != syncInsts->end( ); it1++ ) {
- if (scannedSucNodes->size()!=0) {
- if (checkScannedSucNodes((*it1)->getNode()->getId())!=0) {
+ break;
+
+ case Op_TauMonitorEnter: // monenter
+ case Op_TauMonitorExit: // monexit
+ if (do_sync_removal && method_ea_level == 0) {
+ addMonInst(inst);
#ifdef _DEBUG
if (_seinfo) {
- if (pLocalCurObj)
- Log::out() << " ";
- Log::out() << "=- contains "
- << (*it1)->getNode()->getId()
- << std::endl;
+ Log::out() << "iE: monX Node Id."
+ << node->getId() << " ";
+ inst->print(Log::out());
+ Log::out()<<std::endl;
}
#endif
- if (!pLocalCurObj)
- pLocalObj = false;
}
- }
- }
- scannedSucNodes->clear();
- }
- if (pLocalObj) {
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- may be optimized"
- << std::endl;
+ break;
+
+ case Op_TypeMonitorEnter:// tmonenter
+ case Op_TypeMonitorExit: // tmonexit
+ break;
+
+ case Op_TauVirtualCall: // callvirt
+ case Op_IndirectCall: // calli
+
+ case Op_TauStRef:
+ case Op_TauStField:
+ case Op_TauStElem:
+ case Op_TauStStatic:
+ case Op_Copy:
+
+ case Op_Box:
+
+ if (_instrInfo) {
+ Log::out() <<"--Node Id."<<node->getId()<<std::endl;
+ Log::out() << " ==";
+ inst->print(Log::out());
+ Log::out() << std::endl;
+ }
+ break;
+
+ default:
+
+ if (_instrInfo) {
+ Log::out() <<"~~Node Id."<<node->getId()<<std::endl;
+ Log::out() << " ==";
+ inst->print(Log::out());
+ Log::out() << std::endl;
+ }
}
-#endif
}
-} // setSencEscState(CnGNode* node,Insts* syncInsts)
+ return;
+} // instrExam(Node* node)
-/**
- * Collect all reachable from specified node nodes in FlowGraph.
- * scannedSucNodes - result of collection.
- */
void
-EscAnalyzer::collectSuccessors(Node* node) {
- Node* n;
- Edges::const_iterator eit;
- const Edges& out_edges = node->getOutEdges();
- if (scannedSucNodes->size()!=0) {
- if (checkScannedSucNodes(node->getId())!=0) {
- return;
- }
- }
- scannedSucNodes->push_back(node->getId());
- for (eit = out_edges.begin(); eit != out_edges.end(); ++eit) {
- n = (*eit)->getTargetNode();
- collectSuccessors(n);
- }
-} // collectSuccessors(Node* node)
+EscAnalyzer::instrExam2() {
+ Insts *instrs = exam2Insts;
+ int insnum=0;
+ Insts::iterator it;
+ Inst* inst;
+ Type* type;
+ CnGNode* cgnode;
+ CnGNode* cgn_src;
+ uint32 ntype=0;
+ MethodDesc* md;
+ uint32 n;
+ Inst* method_inst;
+ bool not_exam = false;
+ for (it = instrs->begin( ); it != instrs->end( ); it++ ) {
+ inst=*it;
+ insnum++;
+ ntype=0;
-void
-EscAnalyzer::collectGlobalNodeSuccessors(CnGNode* node) {
- CnGEdges::iterator it;
- CnGRefs::iterator it2;
- Inst* einst;
- bool pGlobalObj = false;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=- to node " << node->cngNodeId
- << std::endl;
- }
-#endif
- scannedSucNodes->clear(); // prepared for successor collection
- for (it = cngEdges->begin( ); it != cngEdges->end( ); it++ ) {
- for (it2 = (*it)->refList->begin( ); it2 != (*it)->refList->end( ); it2++ ) {
- if ((*it2)->cngNodeTo == node) {
- pGlobalObj = false;
- einst = (*it2)->edgeInst;
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-ggns ";
- Log::out() << einst->getNode()->getId()
- << " ";
- if (Log::isEnabled())
- einst->print(Log::out());
- Log::out() << std::endl;
- }
+ if (_instrInfo2) {
+ Log::out() <<"instrExam2: Node Id."<<inst->getNode()->getId()<< " ";
+ FlowGraph::printLabel(Log::out(),inst->getNode()); Log::out() << std::endl;
+ inst->print(Log::out()); Log::out() << std::endl;
+ }
#endif
- if (einst->getOpcode() == Op_DirectCall) {
- MethodDesc* md=einst->asMethodInst()->getMethodDesc();
- const char* ch1 = md->getParentType()->getName();
- const char* ch2 = md->getName();
- const char* ch3 = md->getSignatureString();
- CalledMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3);
- if (mtdInfo==NULL) {
- pGlobalObj = true;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "ggns=- Methodinfo is NULL";
- Log::out() << std::endl;
+
+ switch (inst->getOpcode()) {
+ case Op_LdFieldAddr: // ldflda
+ ntype=NT_INSTFLD;
+ case Op_LdStaticAddr: // ldsflda
+ if (ntype==0)
+ ntype=NT_STFLD; // for LdStaticAddr
+ FieldAccessInst* fainst;
+ if ((fainst=inst->asFieldAccessInst())!=NULL) {
+ bool isref = fainst->getFieldDesc()->getFieldType()->isReference();
+ if (isref || ntype==NT_INSTFLD) {
+ cgn_src=findCnGNode_op(inst->getDst()->getId()); // field address node
+ if (isref)
+ assert(cgn_src!=NULL);
+ cgnode=findCnGNode_fl(inst,ntype); // field node
+ assert(cgnode!=NULL);
+ if (ntype == NT_INSTFLD) {
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId()); // instance node
+ // adding fld edge for ldflda
+ addEdge(cgn_src,cgnode,ET_FIELD,inst);
+ // special for java/lang/String::value
+ FieldDesc* fd=inst->asFieldAccessInst()->getFieldDesc();
+ if (fd->getParentType()->isSystemString()&&strcmp(fd->getName(),"value")==0) {
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ }
}
-#endif
- } else {
- uint32 st = getMethodParamState(mtdInfo,(*it)->cngNodeFrom->argNumber);
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "ggns=-=- Method param "
- << (*it)->cngNodeFrom->argNumber << " state is ";
- if (Log::isEnabled())
- printState(st);
- Log::out() << std::endl;
+ }
+ }
+ break;
+
+ case Op_TauLdInd: // ldind
+ type=inst->getDst()->getType();
+ if (type->isObject()) {
+ cgnode=findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ // ref to loaded object
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_POINT,inst);
+ }
+ if (type->isValue()) {
+ cgnode=findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ // ref to loaded object
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_POINT,inst);
+ }
+ break;
+
+ case Op_LdArrayBaseAddr: // ldbase
+ case Op_AddScaledIndex: // addindex
+ if (inst->getDst()->getType()->isReference()) {
+ cgnode=findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ // ref to loaded address
+ if (inst->getOpcode()==Op_LdArrayBaseAddr) {
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref to base element
+ }
+ if (inst->getOpcode()==Op_AddScaledIndex) {
+ if (inst->getSrc(0)->getInst()->getOpcode()==Op_LdArrayBaseAddr) {
+ cgn_src=findCnGNode_op(
+ inst->getSrc(0)->getInst()->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref from array object to inner objects
}
-#endif
- if ((st&ESC_MASK)<=GLOBAL_ESCAPE) {
- pGlobalObj = true;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "ggns=- Method param "
- << (*it)->cngNodeFrom->argNumber << " state is ";
- if (Log::isEnabled())
- printState(st);
- Log::out() << std::endl;
- }
-#endif
- }
}
}
- if (einst->getOpcode() == Op_IndirectMemoryCall)
- pGlobalObj = true;
- if (einst->getOpcode() == Op_TauStInd) {
- Inst* i1 = einst->getSrc(0)->getInst();
- if (i1->getOpcode()==Op_LdStaticAddr)
- pGlobalObj = true;
- uint32 st = getContainingObjState(i1);
- if ((st&ESC_MASK)<=GLOBAL_ESCAPE) {
- pGlobalObj = true;
+ break;
+
+ case Op_TauStInd: // stind
+ if (inst->getSrc(0)->getType()->isObject()) {
+ // ref to loaded address
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ cgnode=findCnGNode_op(inst->getSrc(1)->getId());
+ assert(cgnode!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ break;
+ }
+ if ((type=inst->getSrc(0)->getType())->isValue()) {
+ uint32 src_opcode = inst->getSrc(1)->getInst()->getOpcode();
+ if (src_opcode==Op_LdStaticAddr)
+ break;
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ if (cgn_src==NULL) {
+ cgn_src = addCnGNode_op(inst->getSrc(0)->getInst(),type,NT_LDVAL);
}
+ cgnode=findCnGNode_op(inst->getSrc(1)->getId());
+ assert(cgnode!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
}
- findObject1(einst);
- if (pGlobalObj)
- collectSuccessors(einst->getNode());
- }
- }
- }
-} // collectGlobalNodeSuccessors(CnGNode* node)
+ break;
+ case Op_DirectCall: // call
+ md=inst->asMethodInst()->getMethodDesc();
+ n=md->getNumParams();
+ for (uint32 i = 0; i < n; i++) {
+ Type* tt = md->getParamType(i);
+ if (!tt->isReference())
+ continue;
+ cgnode=findCnGNode_mp(inst->getId(),i);
+ assert(cgnode!=NULL);
+ cgn_src=findCnGNode_op(inst->getSrc(2+i)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ }
+ break;
-uint32
-EscAnalyzer::getContainingObjState(Inst* linst) {
- Opnd* cop = NULL;
- if (linst->getOpcode()==Op_LdStaticAddr)
- return GLOBAL_ESCAPE;
- if (linst->getOpcode()==Op_LdFieldAddr || linst->getOpcode()==Op_LdArrayBaseAddr)
- cop = linst->getSrc(0);
- if (linst->getOpcode()==Op_AddScaledIndex)
- cop = linst->getSrc(0)->getInst()->getSrc(0);
- else
- return GLOBAL_ESCAPE;
- CnGNode* n = findCnGNode_op(cop->getId());
- return n->state;
-} // getContainingObjState(Inst* linst)
+ case Op_IndirectMemoryCall: //callimem
+ method_inst=inst->getSrc(0)->getInst();
+ if (method_inst->getOpcode() == Op_LdVar) {
+ MethodPtrType* mpt = inst->getSrc(0)->getType()->asMethodPtrType();
+ md = mpt->getMethodDesc();
+ } else {
+ md=method_inst->asMethodInst()->getMethodDesc();
+ }
+ n=md->getNumParams();
+ for (uint32 i = 0; i < n; i++) {
+ Type* tt = md->getParamType(i);
+ if (!tt->isReference())
+ continue;
+ cgnode = findCnGNode_mp(inst->getId(),i);
+ assert(cgnode!=NULL);
+ cgn_src=findCnGNode_op(inst->getSrc(3+i)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ }
+ break;
+ case Op_IntrinsicCall: // callintr
+ n=inst->getNumSrcOperands();
+ switch(inst->asIntrinsicCallInst()->getIntrinsicId()) {
+ case ArrayCopyDirect:
+ case ArrayCopyReverse:
+ cgnode = findCnGNode_op(inst->getSrc(4)->getId());
+ assert(cgnode!=NULL);
+ cgn_src = findCnGNode_op(inst->getSrc(2)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ Log::out() << "need to add edge from "<< cgnode->cngNodeId << " - " << cgnode->opndId << " to "
+ << cgn_src->cngNodeId << " - " << cgn_src->opndId << std::endl;
+ break;
+ default:
+ assert(0);
+ }
+ break;
-void
-EscAnalyzer::removeMonitorInsts(Insts* syncInsts) {
- ControlFlowGraph& fg = irManager.getFlowGraph();
- Insts::iterator it1;
- Edge* excedge = NULL;
- Node* targetnode = NULL;
- Inst* reminst;
-#ifdef _DEBUG
- bool canthrow = false;
-#endif
+ case Op_StVar: // stvar
+ if (inst->getDst()->getType()->isObject()) {
+ cgnode = findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_DEFER,inst);
+ }
+ break;
- for (it1 = syncInsts->begin( ); it1 != syncInsts->end( ); it1++ ) {
- reminst = *it1;
- if (reminst->getOperation().canThrow()==true) {
- excedge = (Edge*)reminst->getNode()->getExceptionEdge();
- if (excedge != NULL)
- targetnode = excedge->getTargetNode();
- else
- targetnode = NULL;
- } else {
- excedge = NULL;
- targetnode = NULL;
- }
-#ifdef _DEBUG
- if (_seinfo) {
- canthrow = reminst->getOperation().canThrow();
- Log::out() << " ";
- if (Log::isEnabled())
- reminst->print(Log::out());
- Log::out() << std::endl;
- Log::out() << " canThrow "<< canthrow;
- Log::out() << std::endl;
- if (excedge==NULL) {
- Log::out() << " exception edge is NULL " << std::endl;
- } else {
- Log::out() << " target node is "
- << targetnode->getId() << std::endl;
- }
- if (canthrow && (excedge==NULL)) {
- const Edges& out_edges = reminst->getNode()->getOutEdges();
- Edges::const_iterator eit;
- Node* n;
- for (eit = out_edges.begin(); eit != out_edges.end(); ++eit) {
- n = (*eit)->getTargetNode();
- Log::out() << " edge to node "
- << n->getId() << " kind " << (*eit)->getKind() << std::endl;
+ case Op_Phi: // phi
+ if (inst->getDst()->getType()->isObject()) {
+ uint32 nsrc=inst->getNumSrcOperands();
+ cgnode = findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ for (uint32 i=0; i<nsrc; i++) {
+ cgn_src=findCnGNode_op(inst->getSrc(i)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_DEFER,inst);
+ }
}
- }
- }
-#endif
+ break;
- reminst->unlink();
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " unlinked: ";
- if (Log::isEnabled())
- reminst->print(Log::out());
- Log::out() << std::endl;
- }
-#endif
- if (targetnode != NULL) {
- if (targetnode->getInEdges().size() > 1) {
- fg.removeEdge(excedge);
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " removed edge: "
- << excedge->getSourceNode()->getId() << " -> "
- << excedge->getTargetNode()->getId() << " kind " << excedge->getKind();
- Log::out() << std::endl;
+ case Op_LdVar: // ldvar
+ type = inst->getDst()->getType();
+ if (type->isReference()) {
+ cgnode = findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_DEFER,inst); // load ldobj
}
-#endif
- } else {
- scannedObjs->clear();
- removeNode(targetnode);
- scannedObjs->clear();
- }
- }
- }
+ break;
-} // removeMonitorInsts(Insts* syncInsts)
+ case Op_Return: // return
+ ntype=NT_EXITVAL;
+ case Op_Throw: // throw
+ if (ntype==0)
+ ntype=NT_THRVAL;
+ if (inst->getNumSrcOperands()>0) {
+ cgnode = findCnGNode_in(inst->getId());
+ assert(cgnode!=NULL);
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ }
+ break;
+ case Op_TauStaticCast: // staticcast
+ case Op_TauCast: // cast
+ type = inst->getDst()->getType();
+ cgnode = findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ if (cgnode->lNode == NULL) {
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ cgnode->lNode = cgn_src;
+ }
+ break;
-void
-EscAnalyzer::removeNode(Node* node) {
- const Edges& out_edges = node->getOutEdges();
- Edges::const_iterator eit;
- Node* n;
+ case Op_TauMonitorEnter: // monenter
+ case Op_TauMonitorExit: // monexit
+ case Op_TypeMonitorEnter:// tmonenter
+ case Op_TypeMonitorExit: // tmonexit
+ break;
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " to remove node "
- << node->getId() << std::endl;
- }
-#endif
- if (scannedObjs->size()!=0) {
- if (checkScannedObjs(node->getId())) {
- return;
+ default:
+ if (_instrInfo2) {
+ not_exam = true;
+ }
}
- }
- scannedObjs->push_back(node->getId());
- Nodes nodes2delete(irManager.getMemoryManager());
- for (eit = out_edges.begin(); eit != out_edges.end(); ++eit) {
- n = (*eit)->getTargetNode();
- if (n->getInEdges().size() == 1) {
- nodes2delete.push_back(n);
+ if (_instrInfo2) {
+ if (not_exam) {
+ Log::out() <<"!!! Not examined. ";
+ inst->print(Log::out()); Log::out() << std::endl;
+ not_exam = false;
+ }
}
}
- Nodes::iterator iter = nodes2delete.begin(), end = nodes2delete.end();
- for (; iter != end; ++iter) {
- n = (*iter);
- removeNode(n);
- }
- irManager.getFlowGraph().removeNode(node);
- scannedObjs->pop_back();
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << " removed node "
- << node->getId() << std::endl;
- }
-#endif
-} // removeNode(Node* node)
+ return;
+} // instrExam2()
-/**
- * Creates i32_0 or i32_1 SsaTmpOpnd (in accordance with value: 0 or 1)
- * if it was'n created before.
- * Inserts ldc0 or ldc1 instruction after first instruction in entry Node,
- * if SsaTmpOpnd was created.
- * Returns:
- * i32_0, if value = 0
- * i32_1, if value = 1
- */
-SsaTmpOpnd*
-EscAnalyzer::insertLdConst(uint32 value) {
- TypeManager& _typeManager = irManager.getTypeManager();
- Type* typeInt32 = _typeManager.getInt32Type();
- OpndManager& _opndManager = irManager.getOpndManager();
- InstFactory& _instFactory = irManager.getInstFactory();
- Inst* ildc = NULL;
- if (value == 0)
- if (i32_0 == NULL) {
- i32_0 = _opndManager.createSsaTmpOpnd(typeInt32);
- ildc = _instFactory.makeLdConst(i32_0, 0);
- }
- if (value == 1)
- if (i32_1 == NULL) {
- i32_1 = _opndManager.createSsaTmpOpnd(typeInt32);
- ildc = _instFactory.makeLdConst(i32_1, 1);
+EscAnalyzer::CnGNode*
+EscAnalyzer::addCnGNode(Inst* inst, Type* type, uint32 ntype) {
+ CnGNode* cgnode = new (eaMemManager) CnGNode; // new CG node
+
+ cgnode->cngNodeId = ++lastCnGNodeId;
+ cgnode->instrId = inst->getId();
+ cgnode->nodeType = ntype;
+ cgnode->lNode = NULL;
+ cgnode->nInst = inst;
+ cgnode->outEdges = NULL;
+ if (cgnode->nodeType==NT_DEFARG)
+ cgnode->argNumber = defArgNumber; // number of formal parameter
+ else
+ cgnode->argNumber = 0;
+ if ((ntype==NT_STFLD)||ntype==NT_THRVAL)
+ setFullState(cgnode,GLOBAL_ESCAPE);
+ else {
+ if (ntype==NT_ACTARG) {
+ setFullState(cgnode,ARG_ESCAPE);
+ if (inst->getOpcode()==Op_IndirectMemoryCall)
+ setVirtualCall(cgnode);
+ } else
+ setFullState(cgnode,NO_ESCAPE);
+ }
+ if (ntype==NT_EXITVAL)
+ setCalleeEscaped(cgnode);
+ cgnode->nodeMDs = NULL;
+ if (type->isReference()) {
+ if (type->isArray()) {
+ if (type->asArrayType()->getElementType()->isReference()) {
+ cgnode->nodeRefType = NR_REFARR;
+ } else
+ cgnode->nodeRefType = NR_ARR;
+ } else
+ cgnode->nodeRefType = NR_REF;
+ if (ntype&(NT_OBJECT|NT_RETVAL)||ntype==NT_LDOBJ) {
+ cgnode->nodeMDs = new (eaMemManager) NodeMDs(eaMemManager); // to collect methods receiving object
}
- if (ildc != NULL) {
- ildc->insertAfter(irManager.getFlowGraph().getEntryNode()->getFirstInst());
+ } else {
+ cgnode->nodeRefType = NR_PRIM;
}
- if (value == 0)
- return i32_0;
- return i32_1;
-} // insertLdConst(uint32 value)
+ cngNodes->push_back(cgnode);
+ return cgnode;
+} // addCnGNode(Inst* inst, Type* type, uint32 ntype)
-void
-EscAnalyzer::fixMonitorInstsVCalls(MonUnit* mu) {
- Inst* opi = findCnGNode_op(mu->opndId)->nInst;
- OpndManager& _opndManager = irManager.getOpndManager();
- InstFactory& _instFactory = irManager.getInstFactory();
- TypeManager& _typeManager = irManager.getTypeManager();
- Type* typeInt32 = _typeManager.getInt32Type();
- VarOpnd* muflag = _opndManager.createVarOpnd(typeInt32, false);
- Inst* stvar0; // = _instFactory.makeStVar(muflag, i32_0);
- Inst* stvar1;
- Insts::iterator inst_it;
- Insts* vcInsts = mu->icallInsts;;
- Insts* syncInsts = mu->monInsts;
+EscAnalyzer::CnGNode*
+EscAnalyzer::addCnGNode_op(Inst* inst, Type* type, uint32 ntype) {
+ CnGNode* cgnode = addCnGNode(inst, type, ntype); // new CG node
+ Opnd* opnd = inst->getDst();
+
+ cgnode->opndId = opnd->getId();
+ cgnode->refObj = opnd;
#ifdef _DEBUG
- ControlFlowGraph& fg = irManager.getFlowGraph();
- Node* entry_node = fg.getEntryNode();
- Node* muo_node = opi->getNode();
- Node* node;
+ if (_cngnodes) {
+ Log::out() <<"++++ addNode "; printCnGNode(cgnode,Log::out());
+ Log::out() << std::endl;
+ }
#endif
+ return cgnode;
+} // addCnGNode_op(Inst* inst, Type* type, uint32 ntype)
- // values 0 and 1 to set flag variable
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::addCnGNode_mp(Inst* inst, MethodDesc* md, uint32 ntype, uint32 narg) {
+ Type* type = md->getParamType(narg);
+ CnGNode* cgnode = addCnGNode(inst, type, ntype); // new CG node
+
+ cgnode->opndId = 0;
+ cgnode->argNumber = narg;
+ cgnode->refObj = md;
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w0 Before " << std::endl;
- if (Log::isEnabled())
- printNode(entry_node,Log::out());
+ if (_cngnodes) {
+ Log::out() <<"++++ addNode "; printCnGNode(cgnode,Log::out());
+ Log::out() << std::endl;
}
#endif
- insertLdConst(1);
- insertLdConst(0);
+ return cgnode;
+} // addCnGNode_mp(Inst* inst, MethodDesc* md, uint32 ntype, uint32 narg)
+
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::addCnGNode_ex(Inst* inst, uint32 ntype) {
+ Type* type = inst->getSrc(0)->getType();
+ CnGNode* cgnode = addCnGNode(inst, type, ntype); // new CG node
+
+ cgnode->opndId = 0;
+ cgnode->refObj = inst->getSrc(0); // returned or thrown operand
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w0 After " << std::endl;
- if (Log::isEnabled())
- printNode(entry_node,Log::out());
+ if (_cngnodes) {
+ Log::out() <<"++++ addNode "; printCnGNode(cgnode,Log::out());
+ Log::out() << std::endl;
}
#endif
+ return cgnode;
+} // addCnGNode_ex(Inst* inst, uint32 ntype)
- // insert flag=0 after monitor instruction opnd creation instruction
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::addCnGNode_fl(Inst* inst, uint32 ntype) {
+ Type* type = inst->getDst()->getType();
+ CnGNode* cgnode = addCnGNode(inst, type, ntype); // new CG node
+
+ cgnode->opndId = 0;
+ cgnode->refObj = inst; // returned or thrown operand
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w1 Before " << std::endl;
- if (Log::isEnabled())
- printNode(muo_node,Log::out());
+ if (_cngnodes) {
+ Log::out() <<"++++ addNode "; printCnGNode(cgnode,Log::out());
+ Log::out() << std::endl;
}
#endif
- stvar0 = _instFactory.makeStVar(muflag, i32_0);
- stvar0->insertAfter(opi);
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w1 After " << std::endl;
- if (Log::isEnabled())
- printNode(muo_node,Log::out());
+ return cgnode;
+} // addCnGNode_fl(Inst* inst, uint32 ntype)
+
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::findCnGNode_op(uint32 nId) {
+ CnGNodes::iterator it;
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->opndId==nId && ((*it)->nodeType & (NT_OBJS|NT_LDVAL)))
+ return (*it);
}
-#endif
+ return(NULL);
+} // findCnGNode_op(uint32 nId)
- // insert flag=1 before virtual call instructions
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=-=-=- Start w2" << std::endl;
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::findCnGNode_id(uint32 nId) {
+ CnGNodes::iterator it;
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->cngNodeId==nId)
+ return (*it);
}
-#endif
- for (inst_it = vcInsts->begin( ); inst_it != vcInsts->end( ); inst_it++ ) {
+ return(NULL);
+} // findCnGNode_id(uint32 nId)
+
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::findCnGNode_in(uint32 nId) {
+ CnGNodes::iterator it;
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->instrId==nId)
+ return (*it);
+ }
+ return(NULL);
+} // findCnGNode_in(uint32 nId)
+
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::findCnGNode_mp(uint32 iId, uint32 aId) {
+ CnGNodes::iterator it;
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->instrId==iId && (*it)->argNumber==aId &&
+ (*it)->nodeType == NT_ACTARG)
+ return (*it);
+ }
+ return(NULL);
+} // findCnGNode_mp(uint32 iId, uint32 aId)
+
+
+EscAnalyzer::CnGNode*
+EscAnalyzer::findCnGNode_fl(Inst* inst, uint32 ntype) {
+ CnGNodes::iterator it;
+ FieldDesc* fd1;
+ FieldDesc* fd2;
+ uint32 idr = 0;
+ if (ntype==NT_INSTFLD)
+ idr=inst->getSrc(0)->getId();
+ assert(inst->asFieldAccessInst()!=NULL);
+ fd1 = inst->asFieldAccessInst()->getFieldDesc();
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->nodeType==ntype) {
+ assert(((Inst*)((*it)->refObj))->asFieldAccessInst()!=NULL);
+ fd2 = ((Inst*)((*it)->refObj))->asFieldAccessInst()->getFieldDesc();
+ if ( fd1->getParentType()==fd2->getParentType() &&
+ strcmp(fd1->getName(),fd2->getName())==0) {
+ if (ntype==NT_INSTFLD) {
+ uint32 idf=((Inst*)((*it)->refObj))->getSrc(0)->getId();
+ if (idr!=idf) {
#ifdef _DEBUG
- node = (*inst_it)->getNode();
- if (_seinfo) {
- Log::out() << "=-=- w2 Before " << std::endl;
- if (Log::isEnabled())
- printNode(node,Log::out());
- }
+ if (_cngedges) {
+ Log::out()
+ << "++++ findCnGNode_fl: required " << idr
+ << " - found " << idf << " not found" << std::endl;
+ }
#endif
- stvar1 = _instFactory.makeStVar(muflag, i32_1);
- stvar1->insertBefore(*inst_it);
+ continue;
+ }
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w2 After " << std::endl;
- if (Log::isEnabled())
- printNode(node,Log::out());
- }
+ if (_cngedges) {
+ Log::out()
+ << "++++ findCnGNode_fl: required " << idr
+ << " - found " << idf << std::endl;
+ }
#endif
+ }
+ return (*it);
+ }
+ }
}
-#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=-=-=- Finish w2" << std::endl;
- }
-#endif
-
- insertFlagCheck(syncInsts,muflag);
-
-} // fixMonitorInstsVCalls(MonUnit* mu)
+ return(NULL);
+} // findCnGNode_fl(Opnd* opnd, uint32 ntype)
/**
- * Inserts flag check before monitor instruction.
- * If flag = 0 monitor instruction isn't executed.
- * Operand flag may be VarOpnd* or SsaTmpOpnd* type.
+ * Creates edge if it doesn't exist yet.
*/
-void
-EscAnalyzer::insertFlagCheck(Insts* syncInsts, Opnd* muflag) {
- Insts::iterator inst_it;
- OpndManager& _opndManager = irManager.getOpndManager();
- InstFactory& _instFactory = irManager.getInstFactory();
- ControlFlowGraph& fg = irManager.getFlowGraph();
- TypeManager& _typeManager = irManager.getTypeManager();
- Type* typeInt32 = _typeManager.getInt32Type();
+void
+EscAnalyzer::addEdge(CnGNode* cgnfrom, CnGNode* cgnto,
+ uint32 etype, Inst* inst) {
+ CnGEdges::iterator it;
+ CnGRefs* el = NULL;
+ CnGRef* ref;
+ CnGNode* cgn1=cgnfrom;
+ CnGNode* cgn2=cgnto;
+
+ if (cgnfrom->lNode) {
+ cgn1 = findCnGNode_id(cgnfrom->lNode->cngNodeId); // to find CnG node using CnG node Id
+ assert(cgn1!=NULL);
+ }
+ if (cgnfrom->nodeType == NT_REF && cgnfrom->lNode == NULL) {
+ assert(cgnfrom->nInst->getOpcode()==Op_TauCast || cgnfrom->nInst->getOpcode()==Op_TauStaticCast);
+ cgn1 = findCnGNode_op(cgnfrom->nInst->getSrc(0)->getId());
+ assert(cgn1!=NULL);
+ cgnfrom->lNode = cgn1;
+ }
- // check flag before monitor instructions
- assert(muflag->isVarOpnd()||muflag->isSsaTmpOpnd());
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=-=-=- Start w3" << std::endl;
+ if (_cngedges) {
+ Log::out()
+ << "++++ addEdge: " << cgnfrom->cngNodeId << "-" << cgnfrom->opndId
+ << " ( "<<cgn1->cngNodeId << "-" << cgn1->opndId << " ) to "
+ << cgnto->cngNodeId << "-" << cgnto->opndId << " ( "
+ << cgn2->cngNodeId << "-" << cgn2->opndId << " )" << std::endl;
}
#endif
- for (inst_it = syncInsts->begin( ); inst_it != syncInsts->end( ); inst_it++ ) {
- Inst* curMonInst = (*inst_it);
- Node* oldnode = curMonInst->getNode();
+ if (cgn1==cgn2) {
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w3 Before " << std::endl;
- if (Log::isEnabled())
- printNode(oldnode,Log::out());
+ if (_cngedges) {
+ Log::out() << "+++++++ equal "
+ << cgnfrom->cngNodeId<< "-" << cgnfrom->opndId
+ << " ( "<<cgn1->cngNodeId << "-" << cgn1->opndId << " ) to "
+ << cgnto->cngNodeId << "-" << cgnto->opndId << " ( "
+ << cgn2->cngNodeId << "-" << cgn2->opndId << " )" << std::endl;
}
#endif
- Node* afterMonInstBlock = NULL;
- Node* tiInstBlock = NULL;
- if ((*inst_it)->getNextInst()!=NULL) {
- // monitor inst isn'n last
- tiInstBlock = fg.splitNodeAtInstruction(curMonInst, true, false, _instFactory.makeLabel());
- afterMonInstBlock = tiInstBlock;
- } else {
- // monitor inst is last
- afterMonInstBlock = (Node*)(oldnode->getUnconditionalEdge()->getTargetNode());
- }
- SsaTmpOpnd* i32_flag;
- if (muflag->isVarOpnd()) {
- i32_flag = _opndManager.createSsaTmpOpnd(typeInt32);
- _instFactory.makeLdVar(i32_flag,(VarOpnd*)muflag)->insertBefore(curMonInst);
- } else
- i32_flag = (SsaTmpOpnd*)muflag;
- Inst* branch_inst = _instFactory.makeBranch(Cmp_EQ, Type::Int32,
- i32_flag, i32_0, (LabelInst*)(afterMonInstBlock->getFirstInst()));
- // insert flag check
- branch_inst->insertBefore(curMonInst);
+ return;
+ }
+ for ( it = cngEdges->begin( ); it != cngEdges->end( ); it++ ) {
+ if ((*it)->cngNodeFrom == cgn1) {
+ CnGRefs::iterator itr;
+ for ( itr = (*it)->refList->begin( ); itr != (*it)->refList->end( ); itr++ ) {
+ if ((*itr)->cngNodeTo == cgn2 && (*itr)->edgeType == etype && cgn1->nodeType != NT_INSTFLD) {
+ if (etype==ET_FIELD || cgn1->nodeType==NT_ACTARG) {
#ifdef _DEBUG
- Node* monInstBlock =
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: ET_FIELD || cgn1==NT_ACTARG && *->cngNodeTo == cgn2" << std::endl;
+ }
#endif
- fg.splitNodeAtInstruction(branch_inst,true, false, _instFactory.makeLabel());
- fg.addEdge(oldnode,afterMonInstBlock);
+ return;
+ }
+ if (inst->getOpcode() == Op_IntrinsicCall) { //callintr
+ uint32 iid = inst->asIntrinsicCallInst()->getIntrinsicId();
+ switch(iid) {
+ case ArrayCopyDirect:
+ case ArrayCopyReverse:
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=- w3 After " << std::endl;
- if (Log::isEnabled()) {
- printNode(oldnode,Log::out());
- printNode(monInstBlock,Log::out());
- if (tiInstBlock != NULL) {
- printNode(tiInstBlock,Log::out());
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: callintr" << std::endl;
+ }
+#endif
+ return;
+ default:
+ assert(0);
+ }
+ }
+ if (inst->getOpcode() == Op_LdFieldAddr) {
+ FieldDesc* fd=inst->asFieldAccessInst()->getFieldDesc();
+ if (fd->getParentType()->isSystemString()&&strcmp(fd->getName(),"value")==0) {
+#ifdef _DEBUG
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: ldflda String.value" << std::endl;
+ }
+#endif
+ return;
+ }
+ }
+#ifdef _DEBUG
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: edge already exists and new is added" << std::endl;
+ }
+#endif
}
}
- }
+ ref = new (eaMemManager) CnGRef;
+ ref->cngNodeTo=cgn2;
+ ref->edgeType=etype;
+ ref->edgeInst=inst;
+ (*it)->refList->push_back(ref);
+#ifdef _DEBUG
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: added CnGRef" << std::endl;
+ }
#endif
+ return;
+ }
}
+ ref = new (eaMemManager) CnGRef;
+ ref->cngNodeTo=cgn2;
+ ref->edgeType=etype;
+ ref->edgeInst=inst;
+ CnGEdge* cgedge=new (eaMemManager) CnGEdge;
+ el=new CnGRefs(eaMemManager);
+ cgedge->cngNodeFrom=cgn1;
+ el->push_back(ref);
+ cgedge->refList=el;
+ cngEdges->push_back(cgedge);
+ cgn1->outEdges=el;
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "=-=-=-=- Finish w3" << std::endl;
+ if (_cngedges) {
+ Log::out() << "++++ addEdge: added edge" << std::endl;
}
#endif
-} // insertFlagCheck(Insts* syncInsts, VarOpnd* muflag)
+} // addEdge(CnGNode* cgnfrom, CnGNode* cgnto, uint32 etype, Inst* inst)
-void
-EscAnalyzer::printNode(Node* n,::std::ostream& os) {
- const Edges& ie = n->getInEdges();
- const Edges& oe = n->getOutEdges();
- Edges::const_iterator i;
- os << "=- Node Id." << n->getId() << std::endl;
- FlowGraph::printInsts(os,n,2);
- os << "=- pred: ";
- for(i = ie.begin(); i != ie.end(); ++i) {
- os << (*i)->getSourceNode()->getId() << " ";
- }
- os << std::endl;
- os << "=- succ: ";
- for(i = oe.begin(); i != oe.end(); ++i) {
- os << (*i)->getTargetNode()->getId() << " ";
- }
- os << std::endl;
-} // printNode(Node* n,::std::ostream& os)
+void
+EscAnalyzer::setCreatedObjectStates() {
+ CnGNodes::iterator it;
+ NodeMDs::iterator it1;
-/**
- * Checks state for NT_LDOBJ nodes.
- * Returns
- * GLOBAL_ESCAPE - for global escaped NT_OBJECT, NT_RETVAL, NT_DEFARG
- * node state - for not global escaped NT_OBJECT
- * 0 - for not global escaped ?NT_RETVAL, NT_DEFARG
- */
-uint32
-EscAnalyzer::checkState(Inst* inst,uint32 st) {
- uint32 st1;
- Inst* inst1;
- Opnd* opnd1;
- uint32 nsrc=inst->getNumSrcOperands();
-
- if (st <= GLOBAL_ESCAPE)
- return st;
- if (scannedObjs->size()!=0) {
- if (checkScannedObjs(inst->getId())) {
- return st;
- }
- }
- if (inst->getOpcode()==Op_DirectCall || inst->getOpcode()==Op_IndirectMemoryCall) {
- Opnd *returnOpnd = inst->getDst();
- if (returnOpnd != NULL) {
- CnGNode* n = findCnGNode_op(returnOpnd->getId());
- if (n != NULL) {
- st1 = getEscState(n);
- if (st > st1)
- st=st1;
- }
- }
- return st;
- }
- if (st <= GLOBAL_ESCAPE)
- return st;
- if (inst->getOpcode()==Op_TauLdInd || inst->getOpcode()==Op_LdVar) { // ldind, ldvar
- Opnd *dst = inst->getDst();
- CnGNode* n = findCnGNode_op(dst->getId());
- if (n != NULL) {
- st1 = getEscState(n);
- if (st > st1)
- st=st1;
- }
- }
- if (st <= GLOBAL_ESCAPE)
- return st;
- switch (inst->getOpcode()) {
- case Op_LdRef: // ldref
- case Op_NewObj: // newobj
- case Op_NewArray: // newarray
- case Op_NewMultiArray: // newmultiarray
- case Op_DefArg: // defarg
- {
- CnGNode* n = findCnGNode_in(inst->getId());
- if (n != NULL) {
- st1 = getEscState(n);
- if (st > st1)
- st=st1;
- }
- break;
- }
- default:
- break;
- }
- if (st <= GLOBAL_ESCAPE)
- return st;
[... 5649 lines stripped ...]