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/03/15 11:27:24 UTC

svn commit: r518565 [2/3] - in /harmony/enhanced/drlvm/trunk: src/test/microbenchmark/harmony-2874/ vm/jitrino/config/em64t/ vm/jitrino/config/ia32/ vm/jitrino/src/optimizer/

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=518565&r1=518564&r2=518565
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Thu Mar 15 03:27:22 2007
@@ -34,12 +34,26 @@
 #include "optpass.h"
 #include "devirtualizer.h"
 #include "DrlVMInterface.h"
+//#include "Windows.h"
 
 namespace Jitrino {
 
+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_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"
+    "    escape.do_scalar_repl_only_final_fields[={on,OFF}] \n"
+    "    escape.scalarize_final_fields[={on,OFF}] - scalarize final field usage when\n"
+    "                                               escaped object wasn't optimized\n"
+    "    escape.exec_count_mult[=0]               - entry node execCount multiplier\n";
+
 
 DEFINE_SESSION_ACTION(EscapeAnalysisPass, escape, "Escape Analysis")
 
+
 struct ComObjStat {
     ComObjStat()    :_n0(0), _n_ge(0), _n_ae(0), _n_ne(0), _n_lo(0) {};
     uint32 _n0;
@@ -82,29 +96,48 @@
 
 
 EscAnalyzer::EscAnalyzer(MemoryManager& mm, SessionAction* argSource, IRManager& irm)
-: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc()) 
+: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc()),os_sc(Log::out()), 
+  compInterface(irm.getCompilationInterface())
 {
     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_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);
+    execCountMultiplier_string = argSource->getStringArg("exec_count_mult", NULL);
+    ec_mult = ( execCountMultiplier_string==NULL ? 0 : atof(execCountMultiplier_string) );
+    do_scalar_repl_only_final_fields = argSource->getBoolArg("do_scalar_repl_only_final_fields",false);
+    scalarize_final_fields = argSource->getBoolArg("scalarize_final_fields",false);
+
     const char* translatorName = argSource->getStringArg("translatorActionName", "translator");
     translatorAction = (TranslatorAction*)PMF::getAction(argSource->getPipeline(), translatorName);
     assert(translatorAction);
 
     init();
+
+    if (compInterface.isBCMapInfoRequired()) {
+        isBCmapRequired = true;
+        MethodDesc* meth = compInterface.getMethodToCompile();
+        bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, meth);
+    } else {
+        isBCmapRequired = false;
+        bc2HIRMapHandler = NULL;
+    }
 }
 
 EscAnalyzer::EscAnalyzer(EscAnalyzer* parent, IRManager& irm) 
-: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc())
+: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc()), os_sc(Log::out()),
+  compInterface(irm.getCompilationInterface())
 {
     maxMethodExamLevel = parent->maxMethodExamLevel;
     allProps = parent->allProps;
     debug_method = parent->debug_method;
     translatorAction  = parent->translatorAction;
     method_ea_level = parent->method_ea_level + 1;
-    
+
     init();
 }
 
@@ -115,9 +148,12 @@
     initNodeType = 0;     // type of initial scanned node
 
     scannedObjs = new (eaMemManager) ObjIds(eaMemManager);
+    scannedObjsRev = new (eaMemManager) ObjIds(eaMemManager);
     scannedInsts = new (eaMemManager) ObjIds(eaMemManager);
     scannedSucNodes = new (eaMemManager) ObjIds(eaMemManager);
     monitorInstUnits = new (eaMemManager) MonInstUnits(eaMemManager);    
+    methodEndInsts = new (eaMemManager) Insts(eaMemManager);
+    checkInsts = new (eaMemManager) Insts(eaMemManager);
 
     _cfgirun=0;
     _instrInfo=0;
@@ -129,6 +165,13 @@
     _printstat=0;
     _eainfo=0;
     _seinfo=0;
+    if (Log::isEnabled())
+        _scinfo = 1;
+    else
+        if (print_scinfo)
+            _scinfo=1;
+        else 
+            _scinfo=0;
     std::fill(prsArr, prsArr + prsNum, 0);
 
 
@@ -157,6 +200,20 @@
     }
 }
 
+void 
+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_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;
+    os << "    escape.do_scalar_repl_only_final_fields[={on,OFF}] " << std::endl;
+    os << "    escape.scalarize_final_fields[={on,OFF}] - scalarize final field usage when" << std::endl;
+    os << "                                               escaped object wasn't optimized" << std::endl;
+    os << "    escape.exec_count_mult[=0]               - entry node execCount multiplier" << std::endl;
+}
+
 void
 EscAnalyzer::doAnalysis() {
     const char* mn = mh.getName();
@@ -190,8 +247,10 @@
             Log::out() << "_printstat   " << _printstat  << std::endl;
             Log::out() << "_eainfo      " << _eainfo     << std::endl;
             Log::out() << "_seinfo      " << _seinfo     << std::endl;
-       }
+            Log::out() << "_scinfo      " << _scinfo     << std::endl;
+        }
     }
+
     if (_eainfo || _seinfo) {
         Log::out()<<"======  doAnalysis  ====== "<<mn<<"   level: ";
         Log::out()<<method_ea_level<<"   "; 
@@ -262,12 +321,12 @@
     
     setCreatedObjectStates();
 
-#ifdef _DEBUG
+//#ifdef _DEBUG
     if (_eainfo) {
         if (Log::isEnabled()) 
             printCreatedObjectsInfo(Log::out());
     }
-#endif
+//#endif
 
     saveScannedMethodInfo();    //??? to save states of contained obj, if needed
 
@@ -294,7 +353,7 @@
         markNotEscInsts();    
     }
 
-#ifdef _DEBUG
+//#ifdef _DEBUG
     if (_cngnodes) {
         Log::out() <<"printCnGNodes: "; 
         if (Log::isEnabled()) 
@@ -303,19 +362,28 @@
         if (Log::isEnabled()) 
             printCnGNodes("Marked nodes",Log::out());
     }
-#endif
+//#endif
 
     if (method_ea_level == 0) {  
         createdObjectInfo();     // prints if _printstat==1
     }
 
     if (method_ea_level == 0) {
-        scanSyncInsts();
-
+        if (do_sync_removal) {
+            scanSyncInsts();
+        }
+        if (do_scalar_repl) {
+            scanLocalObjects();
+            eaFixupVars(irManager);
+            if (do_esc_scalar_repl) {
+                scanEscapedObjects();
+                eaFixupVars(irManager);
+            }
+        }
 #ifdef _DEBUG
         if (_seinfo && Log::isEnabled()) {
             printCreatedObjectsInfo(Log::out());
-            Log::out() << "================ this agrument of sync method" 
+            Log::out() << "================ this argument of sync method" 
                     << std::endl;
             CnGNodes::iterator it;
             for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
@@ -371,6 +439,21 @@
 
 
 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;
@@ -613,12 +696,12 @@
 }  // 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.
-*/
+/**
+ *  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;
@@ -661,15 +744,15 @@
 }  // 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
-*/
+/**
+ *  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();
@@ -710,11 +793,11 @@
 }  // insertReadJitHelperCall() 
 
 
-/*
-*  Checks, that method contains monitor instructions with parameter 
-*  which is this or subobject of this.
-*    Returns: true, if such monitors exist, false overwise.
-*/
+/**
+ *  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;
@@ -830,8 +913,8 @@
                                     printMethodInfo(mtdInfo);
                             }
 #endif
-                         }
-                     }
+                        }
+                    }
                 }
                 findObject1(einst);
                 collectSuccessors(einst->getNode());
@@ -867,10 +950,10 @@
 }  // setSencEscState(CnGNode* node,Insts* syncInsts)
 
 
-/*
-*  Collect all reachable from specified node nodes in FlowGraph.
-*  scannedSucNodes - result of collection.
-*/
+/**
+ *  Collect all reachable from specified node nodes in FlowGraph.
+ *  scannedSucNodes - result of collection.
+ */
 void 
 EscAnalyzer::collectSuccessors(Node* node) {
     Node* n;
@@ -892,7 +975,7 @@
 void
 EscAnalyzer::collectGlobalNodeSuccessors(CnGNode* node) {
     CnGEdges::iterator it;
-     CnGRefs::iterator it2;
+    CnGRefs::iterator it2;
     Inst* einst;
     bool pGlobalObj = false;
 #ifdef _DEBUG
@@ -954,7 +1037,7 @@
                             }
 #endif
                         } 
-                     }
+                    }
                 }
                 if (einst->getOpcode() == Op_IndirectMemoryCall) 
                     pGlobalObj = true;
@@ -1069,7 +1152,6 @@
                 scannedObjs->clear();
             }
         }
-
     }
 
 } // removeMonitorInsts(Insts* syncInsts)
@@ -1116,15 +1198,15 @@
 } // removeNode(Node* node) 
 
 
-/*
-*  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
-*/
+/**
+ *  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();
@@ -1243,11 +1325,11 @@
 } // fixMonitorInstsVCalls(MonUnit* mu)
 
 
-/*
-*  Insers flag check before monitor instruction.
-*  If flag = 0 monitor instruction isn't executed.
-*  Operand flag may be VarOpnd* or SsaTmpOpnd* type.
-*/
+/**
+ *  Inserts flag check before monitor instruction.
+ *  If flag = 0 monitor instruction isn't executed.
+ *  Operand flag may be VarOpnd* or SsaTmpOpnd* type.
+ */
 void 
 EscAnalyzer::insertFlagCheck(Insts* syncInsts, Opnd* muflag) {
     Insts::iterator inst_it;
@@ -1340,13 +1422,13 @@
 } // printNode(Node* n,::std::ostream& os) 
 
 
-/*
-*   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
-*/
+/**
+ *   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;
@@ -1387,7 +1469,7 @@
     if (st <= GLOBAL_ESCAPE)
         return st;
     switch (inst->getOpcode()) {
-        case Op_LdRef:        // ldstr
+        case Op_LdRef:           // ldref
         case Op_NewObj:          // newobj
         case Op_NewArray:        // newarray
         case Op_NewMultiArray:   // newmultiarray
@@ -1433,7 +1515,7 @@
     if (scannedObjs->size()!=0) {
         if (checkScannedObjs(inst->getId())) {
 #ifdef _DEBUG
-            if (_seinfo) {
+            if (_seinfo || _scinfo) {
                 Log::out() << "instId " << inst->getId() 
                     << "  .  .  . " << std::endl;
             }
@@ -1442,7 +1524,7 @@
         }
     }
 #ifdef _DEBUG
-    if (_seinfo) {
+    if (_seinfo || _scinfo) {
         Log::out() << text; 
         if (Log::isEnabled()) 
             inst->print(Log::out()); 
@@ -1455,7 +1537,7 @@
             CnGNode* n = findCnGNode_op(returnOpnd->getId());
             if (n != NULL) {
 #ifdef _DEBUG
-                if (_seinfo) {
+                if (_seinfo || _scinfo) {
                     Log::out()<< text << "  ";
                     if (Log::isEnabled())          
                         printCnGNode(n,Log::out()); 
@@ -1466,8 +1548,13 @@
         }
         if (inst->getOpcode()==Op_IndirectMemoryCall) {
 #ifdef _DEBUG
-            MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
-            if (_seinfo) {
+            MethodDesc* md;
+            if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) {
+                md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc();
+            } else {
+                md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            }
+            if (_seinfo || _scinfo) {
                 Log::out() << text << "  "; 
                 if (Log::isEnabled())         
                     md->printFullName(Log::out() ); 
@@ -1482,7 +1569,7 @@
         CnGNode* n = findCnGNode_op(dst->getId());
         if (n != NULL) {
 #ifdef _DEBUG
-            if (_seinfo) {
+            if (_seinfo || _scinfo) {
                 Log::out()<< text << "  "; 
                 if (Log::isEnabled())         
                     printCnGNode(n,Log::out()); 
@@ -1492,7 +1579,7 @@
         }
     }
     switch (inst->getOpcode()) {
-        case Op_LdRef:        // ldstr
+        case Op_LdRef:           // ldref
         case Op_NewObj:          // newobj
         case Op_NewArray:        // newarray
         case Op_NewMultiArray:   // newmultiarray
@@ -1501,7 +1588,7 @@
             CnGNode* n = findCnGNode_in(inst->getId());
             if (n != NULL) {
 #ifdef _DEBUG
-                if (_seinfo) {
+                if (_seinfo || _scinfo) {
                     Log::out() << text << "  "; 
                     if (Log::isEnabled())         
                         printCnGNode(n,Log::out() ); 
@@ -1525,9 +1612,9 @@
 }  // findObject(Inst* inst,std::string text) 
 
 
-/*
-*  Finds (prints) origin objects of monitor instruction operand.
-*/
+/**
+ *  Finds (prints) origin objects of monitor instruction operand.
+ */
 void
 EscAnalyzer::findObject1(Inst* inst,std::string text) {
     Inst* inst1;
@@ -1535,48 +1622,45 @@
 
     if (scannedObjs->size()!=0) {
         if (checkScannedObjs(inst->getId())) {
-#ifdef _DEBUG
-            if (_seinfo) {
+            if (_seinfo || _scinfo) {
                 Log::out() << "instId " << inst->getId() 
                     << "  .  .  . " << std::endl;
             }
-#endif
             return;
         }
     }
-#ifdef _DEBUG
-    if (_seinfo) {
+    if (_seinfo || _scinfo) {
         Log::out() << text; 
         if (Log::isEnabled()) 
             inst->print(Log::out()); 
         Log::out() << std::endl;
     }
-#endif
     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) {
-#ifdef _DEBUG
-                if (_seinfo) {
+                if (_seinfo || _scinfo) {
                     Log::out()<< text << "  ";
                     if (Log::isEnabled())          
                         printCnGNode(n,Log::out()); 
                     Log::out()<< std::endl;
                 }
-#endif
             }
         }
         if (inst->getOpcode()==Op_IndirectMemoryCall) {
-#ifdef _DEBUG
-            MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
-            if (_seinfo) {
+            MethodDesc* md;
+            if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) {
+                md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc();
+            } else {
+                md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            }
+            if (_seinfo || _scinfo) {
                 Log::out() << text << "  "; 
                 if (Log::isEnabled())         
                     md->printFullName(Log::out() ); 
                 Log::out() << std::endl;
             }
-#endif
         }
         return;
     }
@@ -1584,18 +1668,16 @@
         Opnd *dst = inst->getDst(); 
         CnGNode* n = findCnGNode_op(dst->getId());
         if (n != NULL) {
-#ifdef _DEBUG
-            if (_seinfo) {
+            if (_seinfo || _scinfo) {
                 Log::out()<< text << "  "; 
                 if (Log::isEnabled())         
                     printCnGNode(n,Log::out()); 
                 Log::out()<< std::endl;
             }
-#endif
         }
     }
     switch (inst->getOpcode()) {
-        case Op_LdRef:        // ldstr
+        case Op_LdRef:           // ldref
         case Op_NewObj:          // newobj
         case Op_NewArray:        // newarray
         case Op_NewMultiArray:   // newmultiarray
@@ -1603,14 +1685,12 @@
         {
             CnGNode* n = findCnGNode_in(inst->getId());
             if (n != NULL) {
-#ifdef _DEBUG
-                if (_seinfo) {
+                if (_seinfo || _scinfo) {
                     Log::out() << text << "  "; 
                     if (Log::isEnabled())         
                         printCnGNode(n,Log::out() ); 
                     Log::out() << std::endl;
                 }
-#endif
             }
             break;
         }
@@ -1660,10 +1740,10 @@
 }  // markNotEscInsts() 
 
 
-/*
-*  Summarizes common number of objects with the same state.
-*  Prints statictics if required.
-*/
+/**
+ *  Summarizes common number of objects with the same state.
+ *  Prints statictics if required.
+ */
 void
 EscAnalyzer::createdObjectInfo() {
     CnGNodes::iterator it;
@@ -1721,13 +1801,16 @@
     CnGNodes::iterator it;
     MethodDesc* mdesc = &irManager.getMethodDesc();
     MemoryManager& globalMM = irManager.getCurrentJITContext()->getGlobalMemoryManager();
+//    MemoryManager& globalMM = eaMemManager;
     const char* ch1 = mdesc->getParentType()->getName();
     const char* ch2 = mdesc->getName(); 
     const char* ch3 = mdesc->getSignatureString();
     if (calledMethodInfos==NULL) {
+//std::cout<< "*1****** lock   "<<GetCurrentThreadId()<<std::endl;
         calledMethodInfosLock.lock();
         if (calledMethodInfos==NULL)
             calledMethodInfos = new (globalMM) CalledMethodInfos(globalMM);
+//std::cout<< "*1****** unlock "<<GetCurrentThreadId()<<std::endl;
         calledMethodInfosLock.unlock();
     } else {
         CalledMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3);
@@ -1736,10 +1819,11 @@
     }
     if (getMethodInfo(ch1,ch2,ch3)!=NULL) // info was saved by another jit
         return;
-
+//std::cout<< "*2****** lock   "<<GetCurrentThreadId()<<std::endl;
     calledMethodInfosLock.lock();  // Lock to save method info in common memory
 
     if (getMethodInfo(ch1,ch2,ch3)!=NULL) {   // already saved by another jit
+//std::cout<< "*2 ***** unlock "<<GetCurrentThreadId()<<std::endl;
         calledMethodInfosLock.unlock();  // Unlock 
         return;
     }
@@ -1783,7 +1867,7 @@
         }
     }
     calledMethodInfos->push_back(minfo);
-
+//std::cout<< "*2****** unlock "<<GetCurrentThreadId()<<std::endl;
     calledMethodInfosLock.unlock();  // Unlock 
 
 #ifdef _DEBUG
@@ -1905,19 +1989,20 @@
         ci.setBCMapInfoRequired(false);
     }
     
-    CompilationContext inlineCC(irManager.getMemoryManager(), &ci, ci.getCompilationContext());
-    inlineCC.setHIRManager(inlinedIRM);
-    runTranslatorSession(inlineCC);
+    {
+        CompilationContext inlineCC(irManager.getMemoryManager(), &ci, ci.getCompilationContext());
+        inlineCC.setHIRManager(inlinedIRM);
+        runTranslatorSession(inlineCC);
+    }
     
     optimizeTranslatedCode(*inlinedIRM);
-
-    if (cibcmap) {
-        ci.setBCMapInfoRequired(true);
-    }
     
     EscAnalyzer ea1(this, *inlinedIRM);
     ea1.doAnalysis();
 
+    if (cibcmap) {
+        ci.setBCMapInfoRequired(true);
+    }
 }  // scanCalleeMethod(Inst* call, MemoryManager& mm) 
 
 void EscAnalyzer::runTranslatorSession(CompilationContext& inlineCC) {
@@ -1944,8 +2029,8 @@
     irm.setSsaUpdated();
 
     // run devirt pass
-    Devirtualizer pass(irm);
-    pass.guardCallsInRegion(irm, dominatorTree);
+//    Devirtualizer pass(irm);
+//    pass.guardCallsInRegion(irm, dominatorTree);
 
 }  // optimizeTranslatedCode(IRManager& irManager) 
 
@@ -1967,10 +2052,11 @@
                 Log::out() << std::endl;
             }
 #endif
-            scanCnGNodeRefsGE(*it);
+            scanCnGNodeRefsGE(*it,false);
         }
     }
     scannedObjs->clear();
+    scannedObjsRev->clear();
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
         if ((*it)->nodeType&NT_EXITVAL) {  // returned, thrown
 #ifdef _DEBUG
@@ -1983,10 +2069,11 @@
             }
 #endif
             initNodeType = (*it)->nodeType;
-            scanCnGNodeRefsGE(*it);
+            scanCnGNodeRefsGE(*it,false);
         }
     }
     scannedObjs->clear();
+    scannedObjsRev->clear();
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
         if ((*it)->nodeType==NT_DEFARG) {
 #ifdef _DEBUG
@@ -1999,11 +2086,13 @@
             }
 #endif
             initNodeType = NT_DEFARG;
-            scanCnGNodeRefsGE(*it);
+            scanCnGNodeRefsGE(*it,false);
             scannedObjs->clear(); // temporary
+            scannedObjsRev->clear();
         }
     }
     scannedObjs->clear();
+    scannedObjsRev->clear();
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
         if ((*it)->nodeType==NT_ACTARG) {
             curMDNode=(*it)->cngNodeId;
@@ -2017,10 +2106,13 @@
             }
 #endif
             initNodeType = NT_ACTARG;
-            scanCnGNodeRefsAE(*it);
+            scanCnGNodeRefsAE(*it,false);
+            scannedObjs->clear();
+            scannedObjsRev->clear();
         }
     }
     scannedObjs->clear();
+    scannedObjsRev->clear();
     if (method_ea_level==0) {
         DominatorTree* dominatorTree = irManager.getDominatorTree();
         if (!(dominatorTree && dominatorTree->isValid())) {
@@ -2062,13 +2154,24 @@
     }
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
         uint32 nt = (*it)->nodeType;
-        if ((nt&NT_OBJECT || nt==NT_LDOBJ) && (getEscState(*it)==ARG_ESCAPE)) {
+//        if (((nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ)&&((*it)->nodeRefType!=NR_PRIM)) && (getEscState(*it)==ARG_ESCAPE)) {
+        if ((nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ) && (getEscState(*it)==ARG_ESCAPE)) {
             for (it1 = (*it)->nodeMDs->begin(); it1 != (*it)->nodeMDs->end(); 
                     it1++) {
                 CnGNode* n=findCnGNode_id(*it1);   // method argument node
                 assert(n!=NULL);
                 MethodDesc* mdesc = (MethodDesc*)n->refObj;
                 Inst* callInst = n->nInst;
+#ifdef _DEBUG
+                if (_setState) {
+                    Log::out()<<"--setSt chk arg_esc: node " <<(*it)->cngNodeId
+                        <<" opndId " <<(*it)->opndId<<" state "; 
+                    printState(*it); Log::out() << std::endl; 
+                    Log::out() << "       ";
+                    callInst->print(Log::out());
+                    Log::out() << std::endl;
+                }
+#endif
                 if (mdesc->isNative()) {  // not scanned native methods 
                     if (strcmp(mdesc->getParentType()->getName(),"java/lang/VMMemoryManager")==0
                         &&strcmp(mdesc->getName(),"arrayCopy")==0) {
@@ -2103,15 +2206,16 @@
                     break;
                 }
                 if (callInst->getOpcode()!=Op_DirectCall) {   // not direct call
-                    if (method_ea_level == 0) {
+                    setVirtualCall(*it);
+                    if (method_ea_level == 0 && do_sync_removal) {
                         MonUnit* mu = NULL;
                         if (monitorInstUnits!=NULL)
                             mu = findMonUnit((*it)->opndId);
                         if (mu != NULL) {
-                            setVirtualCall(*it);
+//                            setVirtualCall(*it);
                             addMonUnitVCall(mu,callInst);
 #ifdef _DEBUG
-                            if (Log::isEnabled()) {
+                            if (_seinfo&&Log::isEnabled()) {
                                 Log::out() << "=-=-=-=- callimem for this ";
                                 Log::out() << std::endl;
                                 Log::out() << "=-=- ";
@@ -2129,8 +2233,7 @@
                             continue;
                         }
                     }
-
-                    setEscState(*it,GLOBAL_ESCAPE);
+ //                   setEscState(*it,GLOBAL_ESCAPE);
 #ifdef _DEBUG
                     if (_scanMtds==1) {
                         if (Log::isEnabled()) {
@@ -2173,13 +2276,13 @@
                             <<" state ";
                         if (Log::isEnabled()) 
                             printState(*it);
-                        Log::out() <<" to gl.esc."
+//                        Log::out() <<" to gl.esc."
+                        Log::out() <<" to v.call."
                             << std::endl;
                     }
 #endif
-                    break;
+                    continue; //break;
                 }
-
                 CalledMethodInfo* mtdInfo = findMethodInfo(mdesc,callInst);
                 if (mtdInfo == NULL) {    // no info about called method
                     setEscState(*it,GLOBAL_ESCAPE);
@@ -2239,8 +2342,9 @@
                 }
             }
             if (getEscState(*it)==GLOBAL_ESCAPE) { // to set gl.escape for contained objects
-                scanCnGNodeRefsGE(*it);    //??? to set initNodeType?
+                scanCnGNodeRefsGE(*it,false);    //??? to set initNodeType?
                 scannedObjs->clear();
+                scannedObjsRev->clear();
             }
         }
     }
@@ -2342,6 +2446,7 @@
 
         }
         scannedObjs->clear();
+        scannedObjsRev->clear();
     }
 
 
@@ -2430,12 +2535,12 @@
 } // findMethodInfo(MethodDesc* mdesc) 
 
 
-/*
-*   Finds specified parameter in specified method info.
-*   Returns: 
-*       state - for existent parameter,
-*       0     - for another cases.
-*/
+/**
+ *   Finds specified parameter in specified method info.
+ *   Returns: 
+ *       state - for existent parameter,
+ *       0     - for another cases.
+ */
 uint32 
 EscAnalyzer::getMethodParamState(CalledMethodInfo* mi, uint32 np) {
     ParamInfos::iterator it;
@@ -2460,7 +2565,8 @@
     irManager.getMethodDesc().printFullName(os); 
     os << std::endl;
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
-        if ((*it)->nodeType & NT_OBJECT || (*it)->nodeType==NT_LDOBJ) {
+        uint32 nt = (*it)->nodeType;
+        if (nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ) {
             printCnGNode(*it,os);
             ((Opnd*)(*it)->refObj)->printWithType(os);
             if (getEscState(*it)==ARG_ESCAPE) {
@@ -2485,25 +2591,32 @@
 
 
 void
-EscAnalyzer::scanCnGNodeRefsGE(CnGNode* cgn) {
+EscAnalyzer::scanCnGNodeRefsGE(CnGNode* cgn, bool check_var_src, bool check_field_elem) {
 //    CnGEdges* cge = cngEdges;
     CnGEdges::iterator it;
     CnGRefs::iterator it1;
+    CnGNode* next_node;
+    ObjIds* scObjs = check_var_src ? scannedObjsRev : scannedObjs;
     uint32 nscan=0;
-    if (scannedObjs->size()!=0) {
-        if (checkScannedObjs(cgn->cngNodeId))
-            return;
-    }
+    uint32 ni_opcode = cgn->nInst->getOpcode();
+
 #ifdef _DEBUG
     if (_setState) {
         Log::out() <<"--scanGE 1: node "<<cgn->cngNodeId
             <<" opndId "<<cgn->opndId<<" state ";
         if (Log::isEnabled()) 
             printState(cgn); 
-        Log::out() <<" " 
-            << nodeTypeToString(cgn) << cgn->nodeType << std::endl;
+        Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+            <<"  check_var_src " << check_var_src 
+            <<"  check_field_elem " << check_field_elem << std::endl;
     }
 #endif
+    if (cgn->nodeType == NT_LDVAL)
+        return;
+    if (scObjs->size()!=0) {
+        if (checkScanned(scObjs,cgn->cngNodeId))
+            return;
+    }
     if (cgn->nodeType&NT_OBJS) {
         if (initNodeType!=NT_EXITVAL && initNodeType!=NT_DEFARG) { // 
             if (getEscState(cgn) > GLOBAL_ESCAPE) {
@@ -2539,51 +2652,98 @@
             // The objects created in the method are not global escaped through return
         }
         if (initNodeType==NT_DEFARG) {
-             if (getCalleeEscaped(cgn) == 0) {
+            if (getCalleeEscaped(cgn) == 0) {
 #ifdef _DEBUG
-                 if (_setState) {
-                     Log::out() <<"--scanGE 5: node "
-                         <<cgn->cngNodeId<<" opndId "<<cgn->opndId <<" state ";
-                     if (Log::isEnabled()) 
-                         printState(cgn);
-                     Log::out() <<" to callee.esc."<< std::endl;
-                     Log::out() <<"--scanGE 5: "<< nodeTypeToString(cgn) 
-                         << cgn->nodeType <<" initNode "<<initNodeType<< std::endl;
-                 }
+                if (_setState) {
+                    Log::out() <<"--scanGE 4: node "
+                        <<cgn->cngNodeId<<" opndId "<<cgn->opndId <<" state ";
+                    if (Log::isEnabled()) 
+                        printState(cgn);
+                    Log::out() <<" to callee.esc."<< std::endl;
+                    Log::out() <<"--scanGE 4: "<< nodeTypeToString(cgn) 
+                        << cgn->nodeType <<" initNode "<<initNodeType<< std::endl;
+                }
 #endif
-                 setCalleeEscaped(cgn);
-             }
+                setCalleeEscaped(cgn);
+            }
         }
     }
-    scannedObjs->push_back(cgn->cngNodeId);
+//    scannedObjs->push_back(cgn->cngNodeId);
+    scObjs->push_back(cgn->cngNodeId);
     if (cgn->outEdges != NULL) {
+        bool to_check_var_src = check_var_src;
+        bool to_check_field_elem = check_field_elem;
+        if (cgn->nodeType!=NT_INSTFLD && cgn->nodeType!=NT_ARRELEM)
+            to_check_field_elem = true;
         for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
-            scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
+            next_node = (*it1)->cngNodeTo;
+            if (next_node->nodeType == NT_LDOBJ)
+                if (next_node->nInst->getOpcode()==Op_LdVar && cgn->nodeType!=NT_VARVAL)
+                    to_check_var_src = true;
+#ifdef _DEBUG
+                    if (_setState) {
+                        Log::out() <<"--scanGE 5 next: node "
+                            <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                        printState(next_node); Log::out() << std::endl;
+                }
+#endif
+            scanCnGNodeRefsGE(next_node,to_check_var_src,to_check_field_elem);
             if ((*it1)->edgeType!=ET_POINT)
                 nscan++;
         }
     }
+    if (check_var_src) {
+        if (ni_opcode == Op_LdVar || ni_opcode == Op_StVar || ni_opcode ==Op_Phi) {
+            uint32 nsrc=cgn->nInst->getNumSrcOperands();
+            for (uint32 i=0; i<nsrc; i++) {
+                next_node = findCnGNode_op(cgn->nInst->getSrc(i)->getId());
+#ifdef _DEBUG
+                if (_setState) {
+                    Log::out() <<"--scanGE 6 next: node "
+                        <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                    printState(next_node); Log::out() << std::endl;
+                }
+#endif
+                scanCnGNodeRefsGE(next_node,check_var_src);
+            }
+        }
+    }
 #ifdef _DEBUG
     if (_setState) {
-        Log::out()<<"--scanGE 6: nscan "<<nscan<<" opndId "<<cgn->opndId<<std::endl;
+        Log::out()<<"--scanGE: nscan "<<nscan<<" opndId "<<cgn->opndId<<std::endl;
     }
 #endif
-    if (cgn->nodeType==NT_ARRELEM && nscan==0) {
-        Inst* inst_ldbase= ((Opnd*)(cgn->refObj))->getInst()->getSrc(0)->getInst();
+    if (cgn->nodeType==NT_ARRELEM) {
+        Inst* inst_ldbase = cgn->nInst;
+        if (inst_ldbase->getOpcode()==Op_AddScaledIndex)
+            inst_ldbase = ((Opnd*)(cgn->refObj))->getInst()->getSrc(0)->getInst();
         CnGNode* cgnode=findCnGNode_op(inst_ldbase->getSrc(0)->getId());
 #ifdef _DEBUG
         if (_setState) {
-            Log::out() <<"--scanGE arrElem: "; 
+            Log::out() <<"--scanGE 7 arrElem: "; 
             if (Log::isEnabled()) 
                 inst_ldbase->print(Log::out()); 
             Log::out() << std::endl;
-            Log::out() <<"--scanGE next: " << cgnode->cngNodeId << " - " 
+            Log::out() <<"--scanGE 7 next: " << cgnode->cngNodeId << " - " 
                 << cgnode->opndId << std::endl;
         }
 #endif
-        scanCnGNodeRefsGE(cgnode);
+        // if some array element is escaped, then all array elements are escaped
+        if (cgnode->outEdges != NULL) {
+            for (it1 = cgnode->outEdges->begin( ); it1 != cgnode->outEdges->end( ); it1++ ) {
+                next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+                if (_setState) {
+                    Log::out() <<"--scanGE 7 next arrElem: node "
+                        <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                    printState(next_node); Log::out() << std::endl;
+                }
+#endif
+                scanCnGNodeRefsGE(next_node,check_var_src,false);
+            }
+        }
     }  
-    if (cgn->nodeType==NT_LDOBJ && nscan==0) {
+    if (cgn->nodeType==NT_LDOBJ && check_field_elem) {
         Inst* ldinst =((Opnd*)(cgn->refObj))->getInst();
         if (ldinst->getOpcode()==Op_TauLdInd) { //tttt
             Inst* inst_fldaddr= ldinst->getSrc(0)->getInst();
@@ -2591,7 +2751,7 @@
                 CnGNode* cgnode=findCnGNode_fl(inst_fldaddr,NT_INSTFLD);
 #ifdef _DEBUG
                 if (_setState) {
-                    Log::out() << "TO FIND 1 for opnd "
+                    Log::out() << "--scanGE 8 TO FIND 1 for opnd "
                         << cgn->opndId << std::endl;
                     if (Log::isEnabled()) 
                         ldinst->print(Log::out());
@@ -2605,13 +2765,14 @@
                         << cgnode->opndId << std::endl;
                 }
 #endif
-                scanCnGNodeRefsGE(cgnode);
+                scanCnGNodeRefsGE(cgnode,check_var_src,false);
             } else {
-                if (inst_fldaddr->getOpcode()==Op_AddScaledIndex) {
+                uint32 oc = inst_fldaddr->getOpcode();
+                if (oc==Op_AddScaledIndex || oc == Op_LdArrayBaseAddr) {
                     CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
 #ifdef _DEBUG
                     if (_setState) {
-                        Log::out() << "TO FIND 2 for opnd "
+                        Log::out() << "--scanGE 8 TO FIND 2 for opnd "
                             << cgn->opndId << std::endl;
                         if (Log::isEnabled()) 
                             ldinst->print(Log::out());
@@ -2625,140 +2786,129 @@
                             << cgnode->opndId << std::endl;
                     }
 #endif
-                    scanCnGNodeRefsGE(cgnode);
+                    scanCnGNodeRefsGE(cgnode,check_var_src,false);
                 }
             }
         }
     }
-}  // scanCnGNodeRefsGE(CnGNode* cgn) 
+}  // scanCnGNodeRefsGE(CnGNode* cgn, bool check_var_src, bool check_field_elem) 
 
 
 void
-EscAnalyzer::scanCnGNodeRefsEV(CnGNode* cgn) {
+EscAnalyzer::scanCnGNodeRefsAE(CnGNode* cgn, bool check_var_src, bool check_field_elem) {
+    CnGEdges::iterator it;
     CnGRefs::iterator it1;
-    if (scannedObjs->size()!=0) {
-        if (checkScannedObjs(cgn->cngNodeId))
-            return;
-    }
+    CnGNode* next_node;
+    ObjIds* scObjs = check_var_src ? scannedObjsRev : scannedObjs;
+    uint32 nscan=0;
+    uint32 ni_opcode = cgn->nInst->getOpcode();
+
 #ifdef _DEBUG
     if (_setState) {
-        Log::out() <<"--scanEV: node "<<cgn->cngNodeId
-            <<" opndId "<<cgn->opndId <<" state ";
+        Log::out() <<"--scanAE < 1: node "<<cgn->cngNodeId
+            <<" opndId "<<cgn->opndId<<" state ";
         if (Log::isEnabled()) 
-            printState(cgn); 
-        Log::out() << " "
-            << nodeTypeToString(cgn) << cgn->nodeType << std::endl;
+            printState(cgn);
+        Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+            <<"  check_var_src " << check_var_src 
+            <<"  check_field_elem " << check_field_elem << std::endl;
     }
 #endif
-    if (cgn->nodeType==NT_OBJECT)       // object is escaped if it is returned 
-        if (getEscState(cgn) > GLOBAL_ESCAPE) {
-            setEscState(cgn,GLOBAL_ESCAPE);
+    if (cgn->nodeType == NT_LDVAL) {   // primitive type value
+#ifdef _DEBUG
+        if (_setState) {
+            Log::out() <<"--scanAE > 1: primitive type " << std::endl;
+        }
+#endif
+        return;
+    }
+    if (scObjs->size()!=0) {
+        if (checkScanned(scObjs,cgn->cngNodeId)) {
 #ifdef _DEBUG
             if (_setState) {
-                Log::out() <<"--scanEV: node "<<cgn->cngNodeId
-                    <<" opndId "<<cgn->opndId<<" state ";
-                if (Log::isEnabled()) 
-                    printState(cgn);
-                Log::out() <<" to gl.esc."<< std::endl;
+                Log::out() <<"--scanAE > 2: was scanned earlier " << std::endl;
             }
 #endif
-        }
-    scannedObjs->push_back(cgn->cngNodeId);
-    if (cgn->outEdges != NULL) {
-        for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
-            scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
-        }
-    }
-}  // scanCnGNodeRefsEV(CnGNode* cgn) 
-
-
-void
-EscAnalyzer::scanCnGNodeRefsDA(CnGNode* cgn) {
-    CnGEdges* cge = cngEdges;
-    CnGEdges::iterator it;
-    CnGRefs::iterator it1;
-    uint32 cgntype=cgn->nodeType;
-    bool first=true;
-    if (scannedObjs->size()!=0) {
-        first=false;
-        if (checkScannedObjs(cgn->cngNodeId))
             return;
+        }
     }
+    if (getEscState(cgn) < ARG_ESCAPE) {   // not scan global escaped
 #ifdef _DEBUG
-    if (_setState) {
-        Log::out() <<"--scanDA: node "<<cgn->cngNodeId
-            <<" opndId "<<cgn->opndId<<" state ";
-        if (Log::isEnabled()) 
-            printState(cgn);
-        Log::out() <<" "<<nodeTypeToString(cgn)<<cgn->nodeType<< std::endl;
-    }
+        if (_setState) {
+            Log::out() <<"--scanAE > 3: global escaped " << std::endl;
+        }
 #endif
-    if ((cgntype&NT_OBJECT && !first)||(cgntype==NT_OBJECT && first))
-        scannedObjs->push_back(cgn->cngNodeId);
-        for (it = cge->begin( ); it != cge->end( ); it++ ) {
-            if ((*it)->cngNodeFrom == cgn) {
-                for (it1 = (*it)->refList->begin( ); it1 != (*it)->refList->end( ); it1++ ) {
-                    scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
-                }
-            }
-        }           
-}  // scanCnGNodeRefsDA(CnGNode* cgn) 
-
-
-void
-EscAnalyzer::scanCnGNodeRefsAE(CnGNode* cgn) {
-    CnGEdges* cge = cngEdges;
-    CnGEdges::iterator it;
-    CnGRefs::iterator it1;
-    uint32 nscan=0;
-    if (scannedObjs->size()!=0) {
-        if (checkScannedObjs(cgn->cngNodeId))
-            return;
+        return;
     }
+    if (cgn->nodeType&NT_OBJS) {
+//        if (cgn->nodeMDs!=NULL && check_field_elem) {
+        if (cgn->nodeMDs!=NULL) {
+             cgn->nodeMDs->push_back(curMDNode);
 #ifdef _DEBUG
-    if (_setState) {
-        Log::out() <<"--scanAE: node "<<cgn->cngNodeId
-            <<" opndId "<<cgn->opndId<<" state ";
-        if (Log::isEnabled()) 
-            printState(cgn);
-        Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType<< std::endl;
-    }
+            if (_setState) {
+                Log::out() <<"--scanAE 1_1: node "<<cgn->cngNodeId
+                    <<" opndId "<<cgn->opndId <<" curMDNode "<<curMDNode<< std::endl;
+            }
 #endif
-    if (cgn->nodeType&NT_OBJS)
-        if (getEscState(cgn) >= ARG_ESCAPE) {
-            setEscState(cgn,ARG_ESCAPE);
+        }
+        if (getEscState(cgn) > ARG_ESCAPE) {
 #ifdef _DEBUG
             if (_setState) {
-                Log::out() <<"--scanAE: node "<<cgn->cngNodeId
+                Log::out() <<"--scanAE 2: node "<<cgn->cngNodeId
                     <<" opndId "<<cgn->opndId<<" state ";
                 if (Log::isEnabled()) 
                     printState(cgn);
                 Log::out() <<" to arg.esc."<< std::endl;
             }
 #endif
-            if (cgn->nodeMDs==NULL) {
-                Log::out() <<"--scanAE: node "<<cgn->cngNodeId
-                    <<" opndId "<<cgn->opndId<<" state ";
-                if (Log::isEnabled()) 
-                    printState(cgn);
-                Log::out() <<" " << nodeTypeToString(cgn) 
-                    << cgn->nodeType << std::endl;
+            setEscState(cgn,ARG_ESCAPE);
+        }
+    }
+//    scannedObjs->push_back(cgn->cngNodeId);
+    scObjs->push_back(cgn->cngNodeId);
+    if (cgn->outEdges != NULL) {
+        bool to_check_var_src = check_var_src;
+        bool to_check_field_elem = check_field_elem;
+        if (cgn->nodeType!=NT_INSTFLD && cgn->nodeType!=NT_ARRELEM)
+            to_check_field_elem = true;
+        for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
+            next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+            if (_setState) {
+                Log::out() <<"--scanAE 3 next: node "
+                    <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                printState(next_node); 
+                Log::out() << " " << nodeTypeToString(next_node) 
+                    << " ref.type " << next_node->nodeRefType << std::endl;
             }
-            cgn->nodeMDs->push_back(curMDNode);
+#endif
+            if (next_node->nodeType == NT_LDVAL)
+                continue;
+            if (next_node->nodeType == NT_LDOBJ)
+                if (next_node->nInst->getOpcode()==Op_LdVar && cgn->nodeType!=NT_VARVAL)
+                    to_check_var_src = true;
+            scanCnGNodeRefsAE(next_node,to_check_var_src,to_check_field_elem);
+            if ((*it1)->edgeType!=ET_POINT)
+                nscan++;
         }
-    scannedObjs->push_back(cgn->cngNodeId);
-    for (it = cge->begin( ); it != cge->end( ); it++ ) {
-        if ((*it)->cngNodeFrom == cgn) {
-            for (it1 = (*it)->refList->begin( ); it1 != (*it)->refList->end( ); it1++ ) {
-                if ((*it1)->edgeType==ET_FIELD)  // do not scan field edge
-                    continue;
-                scanCnGNodeRefsAE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
-                if ((*it1)->edgeType!=ET_POINT)
-                    nscan++;
+    }
+    if (check_var_src) {
+        if (ni_opcode == Op_LdVar || ni_opcode == Op_StVar || ni_opcode ==Op_Phi) {
+            uint32 nsrc=cgn->nInst->getNumSrcOperands();
+            for (uint32 i=0; i<nsrc; i++) {
+                next_node = findCnGNode_op(cgn->nInst->getSrc(i)->getId());
+#ifdef _DEBUG
+                if (_setState) {
+                    Log::out() <<"--scanAE 4 next: node "
+                        <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                    printState(next_node); Log::out() << std::endl;
+                }
+#endif
+                scanCnGNodeRefsAE(next_node,check_var_src);
             }
         }
     }
-    if (cgn->nodeType==NT_ARRELEM && nscan==0) {
+    if (cgn->nodeType==NT_ARRELEM && check_field_elem) {
         Inst* inst_addindex = ((Opnd*)(cgn->refObj))->getInst();
         Inst* inst_ldbase = inst_addindex->getSrc(0)->getInst();
         if (inst_addindex->getOpcode() == Op_LdArrayBaseAddr)
@@ -2766,90 +2916,89 @@
         CnGNode* cgnode=findCnGNode_op(inst_ldbase->getSrc(0)->getId());
 #ifdef _DEBUG
         if (_setState) {
-            Log::out() <<"--scanAE check1: ";
+            Log::out() <<"--scanAE 5 check1: ";
             if (Log::isEnabled())  
                 inst_ldbase->print(Log::out()); 
             Log::out() << std::endl;
-            Log::out() <<"--scanAE check2: ";
+            Log::out() <<"--scanAE 5 check2: ";
             if (cgnode==NULL)  
                 Log::out() <<"cngnode==null "<< std::endl;
-            Inst* inst_addindex= ((Opnd*)(cgn->refObj))->getInst();
-            Log::out() <<"--scanAE arrElem: ";
-            if (Log::isEnabled())  
-                inst_addindex->print(Log::out()); 
-            Log::out() << std::endl;
-            Log::out() <<"--scanAE arrElem: ";
-            if (Log::isEnabled())  
-                inst_ldbase->print(Log::out()); 
-            Log::out() << std::endl;
-            Log::out() <<"--scanAE next: " << cgnode->cngNodeId << " - " 
+            Log::out() <<"--scanAE 5 next: " << cgnode->cngNodeId << " - " 
                 << cgnode->opndId << std::endl;
         }
 #endif
-        scanCnGNodeRefsAE(cgnode);
+        if (cgnode->outEdges != NULL) {
+            for (it1 = cgnode->outEdges->begin( ); it1 != cgnode->outEdges->end( ); it1++ ) {
+                next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+                if (_setState) {
+                    Log::out() <<"--scanAE 5 next arrElem: node "
+                        <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+                    printState(next_node); Log::out() << std::endl;
+                }
+#endif
+                scanCnGNodeRefsAE(next_node,check_var_src,false);
+            }
+        }
     }        
-    if (cgn->nodeType==NT_LDOBJ && nscan==0) {
+    if (cgn->nodeType==NT_LDOBJ && check_field_elem) {
         Inst* ldinst =((Opnd*)(cgn->refObj))->getInst();
         if (ldinst->getOpcode()==Op_TauLdInd) {
-            CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
+            Inst* inst_fldaddr= ldinst->getSrc(0)->getInst();
+            if (inst_fldaddr->getOpcode()==Op_LdFieldAddr) {
+                CnGNode* cgnode=findCnGNode_fl(inst_fldaddr,NT_INSTFLD);
 #ifdef _DEBUG
-            if (_setState) {
-                Log::out() <<"TO FIND for opnd "
-                    << cgn->opndId << std::endl;
-                if (Log::isEnabled()) 
-                    ldinst->print(Log::out());
-                Log::out() << std::endl;
-                Log::out() << cgn->cngNodeId << "-"
-                    << cgn->opndId << " -> ";
-                Log::out() << cgnode->cngNodeId << "-"
-                    << cgnode->opndId << std::endl;
-            }
-#endif
-            scanCnGNodeRefsAE(cgnode);
-        }
-    }
-    if ((cgn->nodeType==NT_INSTFLD) && nscan==0) { //????????
-        if (getEscState(cgn) > ARG_ESCAPE) 
-            setEscState(cgn,ARG_ESCAPE);  // for instance fields of method parameters & array elements
-    }
-    scannedObjs->pop_back();
-}  // scanCnGNodeRefsAE(CnGNode* cgn) 
-
-
-bool 
-EscAnalyzer::checkScannedObjs(uint32 id) {
-    ObjIds::iterator it;
-    for (it = scannedObjs->begin( ); it != scannedObjs->end( ); it++ ) {
-        if ((*it)==id) {
-            return true;
-        }
-    }
-    return false;
-}  // checkScannedObjs(CnGNode* cgn)
-
-
-bool 
-EscAnalyzer::checkScannedInsts(uint32 id) {
-    ObjIds::iterator it;
-    for (it = scannedInsts->begin( ); it != scannedInsts->end( ); it++ ) {
-        if ((*it)==id) {
-            return true;
+                if (_setState) {
+                    Log::out() <<"--scanAE 6 TO FIND 1 for opnd "
+                        << cgn->opndId << std::endl;
+                    if (Log::isEnabled()) 
+                        ldinst->print(Log::out());
+                    Log::out() << std::endl;
+                    if (Log::isEnabled())  
+                        inst_fldaddr->print(Log::out());
+                    Log::out() << std::endl;
+                    Log::out() << cgn->cngNodeId << "-"
+                        << cgn->opndId << " -> ";
+                    Log::out() << cgnode->cngNodeId << "-"
+                        << cgnode->opndId << std::endl;
+                }
+#endif
+                scanCnGNodeRefsAE(cgnode,check_var_src,false);
+            } else {
+                uint32 oc = inst_fldaddr->getOpcode();
+                if (oc==Op_AddScaledIndex || oc == Op_LdArrayBaseAddr) {
+                    CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
+#ifdef _DEBUG
+                    if (_setState) {
+                        Log::out() << "--scanAE 6 TO FIND 2 for opnd "
+                            << cgn->opndId << std::endl;
+                        if (Log::isEnabled()) 
+                            ldinst->print(Log::out());
+                        Log::out() << std::endl;
+                        if (Log::isEnabled()) 
+                            inst_fldaddr->print(Log::out());
+                        Log::out() << std::endl;
+                        Log::out() << cgn->cngNodeId << "-"
+                            << cgn->opndId << " -> ";
+                        Log::out() << cgnode->cngNodeId << "-"
+                            << cgnode->opndId << std::endl;
+                    }
+#endif
+                    scanCnGNodeRefsAE(cgnode,check_var_src,false);
+                }
+            }
         }
     }
-    return false;
-}  // checkScannedInsts(CnGNode* cgn)
-
-
-bool 
-EscAnalyzer::checkScannedSucNodes(uint32 id) {
-    ObjIds::iterator it;
-    for (it = scannedSucNodes->begin( ); it != scannedSucNodes->end( ); it++ ) {
-        if ((*it)==id) {
-            return true;
-        }
+#ifdef _DEBUG
+    if (_setState) {
+        Log::out() <<"--scanAE > 4: exit: node "<<cgn->cngNodeId
+            <<" opndId "<<cgn->opndId<<" state "; printState(cgn);
+        Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+            <<"  check_var_src " << check_var_src 
+            <<"  check_field_elem " << check_field_elem << std::endl;
     }
-    return false;
-}  // checkScannedSucNodes(CnGNode* cgn)
+#endif
+}  // scanCnGNodeRefsAE(CnGNode* cgn, bool check_var_src, bool check_field_elem) 
 
 
 void
@@ -3062,7 +3211,8 @@
     os << " id. " <<opnd->getId();
     os << " type " << type->getName() << " " << type->tag<<" ";
     os << " isRef " << type->isReference();
-    os << " isObj " << type->isObject() << std::endl;
+    os << " isObj " << type->isObject();
+    os << " isVal " << type->isValue() << std::endl;
     if (type->isReference()) 
         ref_type_info(type,os);
     os << "        ";
@@ -3101,25 +3251,38 @@
     if ((ntype==NT_STFLD)||ntype==NT_THRVAL)
         setFullState(cgnode,GLOBAL_ESCAPE);
     else {
-        if (ntype==NT_ACTARG)
+        if (ntype==NT_ACTARG) {
             setFullState(cgnode,ARG_ESCAPE);
-        else
+            if (inst->getOpcode()==Op_IndirectMemoryCall)
+                setVirtualCall(cgnode);
+        } else
             setFullState(cgnode,NO_ESCAPE);
     }
     if (ntype==NT_EXITVAL)
         setCalleeEscaped(cgnode);
-    if (type->isArray()) {
-        if (type->asArrayType()->isReference()) {
-            cgnode->nodeRefType = NR_REFARR;
+    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_ARR;
-    } else
-        cgnode->nodeRefType = NR_REF;
-    if (ntype&(NT_OBJECT|NT_RETVAL)||ntype==NT_LDOBJ||ntype==NT_VARVAL||ntype==NT_REF||ntype==NT_ARRELEM) { 
-        cgnode->nodeMDs = new (eaMemManager) NodeMDs(eaMemManager);  // to collect methods receiving object
-    } else 
-        cgnode->nodeMDs = NULL;
+            cgnode->nodeRefType = NR_REF;
+        if (ntype&(NT_OBJECT|NT_RETVAL)||ntype==NT_LDOBJ) { 
+            cgnode->nodeMDs = new (eaMemManager) NodeMDs(eaMemManager);  // to collect methods receiving object
+        }
+    } else {
+        cgnode->nodeRefType = NR_PRIM;
+    }
     cngNodes->push_back(cgnode);
+#ifdef _DEBUG
+    if (_cngnodes) {
+        Log::out() <<"++++ addNode  "<<cgnode->cngNodeId
+            <<" opndId "<<cgnode->opndId; printCnGNode(cgnode,Log::out());
+        Log::out() << std::endl;
+    }
+#endif
     return cgnode;
 }  // addCnGNode(MemoryManager& mm, Type* type, Inst* inst, uint32 ntype) 
 
@@ -3231,7 +3394,8 @@
         insnum++;
         ntype=0;
         if (_instrInfo) {
-            Log::out() <<"++Node Id."<<node->getId()<<"  "<<node->getDfNum()<<std::endl;
+            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() << "==";
             if (Log::isEnabled())  
                 inst->print(Log::out()); 
@@ -3239,7 +3403,7 @@
         }
 
         switch (inst->getOpcode()) {
-            case Op_LdRef:        // ldstr
+            case Op_LdRef:        // ldref
             case Op_NewObj:          // newobj
             case Op_NewArray:        // newarray
             case Op_NewMultiArray:   // newmultiarray
@@ -3266,6 +3430,21 @@
                 }
                 break;
 
+            case Op_Conv:     // conv
+#ifdef _DEBUG
+                if (_instrInfo) {
+                    Log::out() <<"Node Id."<<node->getId()<<std::endl;
+                    if (Log::isEnabled()) 
+                        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
@@ -3284,11 +3463,23 @@
                     if (type->isReference()) {
                         assert(findCnGNode_op(inst->getDst()->getId())==NULL);
                         cgnode = addCnGNode_op(inst,type,NT_REF);
-                        if (findCnGNode_fl(inst,ntype)==NULL) {
-                            CnGNode* n = addCnGNode_fl(inst,ntype);
-                            cgnode->lNode=n;   // stick nodes         // and if fl node exists ? bug?
+                        CnGNode* n = findCnGNode_fl(inst,ntype);
+                        if (n==NULL) {
+                            n = addCnGNode_fl(inst,ntype);
                         }
+                        cgnode->lNode=n;   // stick nodes 
                         addInst(cfgnode, 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);
+                            }
+                            addInst(cfgnode, inst);
+                            cgnode->lNode=n;   // stick nodes 
+                        }
                     }
                 }
                 break;
@@ -3301,12 +3492,20 @@
                         debug_inst_info(inst,Log::out()); 
                 }
 #endif
-                if (inst->getDst()->getType()->isObject()) {
-                    type=inst->getDst()->getType();
+                type = inst->getDst()->getType();
+                if (type->isReference()) {   //isObject()) {
+//                    type=inst->getDst()->getType();
                     assert(findCnGNode_op(inst->getDst()->getId())==NULL);
                     cgnode = addCnGNode_op(inst,type,NT_LDOBJ);
                     addInst(cfgnode, inst);
                 }
+                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);
+                    addInst(cfgnode, inst);
+                }
                 break;
 
             case Op_LdArrayBaseAddr: // ldbase
@@ -3318,6 +3517,10 @@
                         debug_inst_info(inst,Log::out()); 
                 }
 #endif
+//                if (inst->getSrc(0)->getInst()->getOpcode()==Op_VMHelperCall) {
+//                    Log::out() << "break "; inst->print(Log::out()); Log::out() << std::endl;
+//                    break;
+//                }
                 if (inst->getDst()->getType()->isReference()) {
                     type=inst->getDst()->getType();
                     assert(findCnGNode_op(inst->getDst()->getId())==NULL);
@@ -3326,6 +3529,38 @@
                 }
                 break;
 
+            case Op_VMHelperCall:      // callvmhelper
+#ifdef _DEBUG
+                if (_instrInfo) {
+                    Log::out() <<"Node Id."<<node->getId()<<std::endl;
+                    if (Log::isEnabled()) 
+                        debug_inst_info(inst,Log::out()); 
+                }
+#endif
+                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);
+                //        addInst(cfgnode, inst);
+                    }
+                }
+                break;
+
             case Op_TauStInd:        // stind    
 #ifdef _DEBUG
                 if (_instrInfo) {
@@ -3334,7 +3569,7 @@
                         debug_inst_info(inst,Log::out()); 
                 }
 #endif
-                if (inst->getSrc(0)->getType()->isObject()) {
+                if ((type=inst->getSrc(0)->getType())->isObject() || type->isValue()) {
                     addInst(cfgnode, inst);
                 }
                 break;
@@ -3406,7 +3641,14 @@
                     }
                 }
                 method_inst=inst->getSrc(0)->getInst();
-                md=method_inst->asMethodInst()->getMethodDesc();
+                if (method_inst->getOpcode() == Op_LdVar) {
+                    Opnd* funptr = inst->getSrc(0);
+                    Type* optype = funptr->getType();
+                    MethodPtrType* opmtype = optype->asMethodPtrType();
+                    md = opmtype->getMethodDesc();
+                } else {
+                    md=method_inst->asMethodInst()->getMethodDesc();
+                }
                 msd = md->getMethodSig();
                 n=msd->getNumParams();
                 addinst=false;
@@ -3561,16 +3803,18 @@
 
             case Op_TauMonitorEnter: // monenter
             case Op_TauMonitorExit:  // monexit
-                addMonInst(inst);
+                if (do_sync_removal && method_ea_level == 0) {
+                    addMonInst(inst);
 #ifdef _DEBUG
-                if (_seinfo) {
-                    Log::out() << "iE: monX  Node Id."
+                    if (_seinfo) {
+                        Log::out() << "iE: monX  Node Id."
                             << node->getId() << "  ";
-                    if (Log::isEnabled()) 
-                        inst->print(Log::out()); 
-                    Log::out()<<std::endl;
-                }
+                        if (Log::isEnabled()) 
+                            inst->print(Log::out()); 
+                        Log::out()<<std::endl;
+                    }
 #endif
+                }
                 break;
 
             case Op_TypeMonitorEnter:// tmonenter
@@ -3650,9 +3894,11 @@
                     ntype=NT_STFLD;    // for LdStaticAddr
                 FieldAccessInst* fainst;
                 if ((fainst=inst->asFieldAccessInst())!=NULL) {
-                    if (fainst->getFieldDesc()->getFieldType()->isReference()) {
+                    bool isref = fainst->getFieldDesc()->getFieldType()->isReference();
+                    if (isref || ntype==NT_INSTFLD) {
                         cgn_src=findCnGNode_op(inst->getDst()->getId());  //  field address node
-                        assert(cgn_src!=NULL);
+                        if (isref)
+                            assert(cgn_src!=NULL);
                         cgnode=findCnGNode_fl(inst,ntype);    //  field node
                         assert(cgnode!=NULL);
                         //  adding edge from fld node to address node
@@ -3671,7 +3917,16 @@
                 break;
 
             case Op_TauLdInd:        // ldind
-                if (inst->getDst()->getType()->isObject()) {
+                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
@@ -3686,14 +3941,19 @@
                 if (inst->getDst()->getType()->isReference()) {
                     cgnode=findCnGNode_op(inst->getDst()->getId());
                     assert(cgnode!=NULL);
-                   // ref to loaded address
-                    cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
-                    assert(cgn_src!=NULL);
+                    // ref to loaded address
                     if (inst->getOpcode()==Op_LdArrayBaseAddr) {
-                        cgnode->lNode=cgn_src;  //stick array object & array base address nodes
+                        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) {
-                        addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref from array object to inner objects
+                        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
+                        }
                     }
                 }
                 break;
@@ -3706,6 +3966,19 @@
                     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); 
                 }
                 break;
 
@@ -3727,7 +4000,12 @@
 
             case Op_IndirectMemoryCall:  //callimem
                 method_inst=inst->getSrc(0)->getInst();
-                md=method_inst->asMethodInst()->getMethodDesc();
+                if (method_inst->getOpcode() == Op_LdVar) {
+                    MethodPtrType* mpt = inst->getSrc(0)->getType()->asMethodPtrType();
+                    md = mpt->getMethodDesc();
+                } else {
+                    md=method_inst->asMethodInst()->getMethodDesc();
+                }
                 msd = md->getMethodSig();
                 n=msd->getNumParams();
                 for (uint32 i = 0; i < n; i++) {
@@ -3748,7 +4026,7 @@
                     assert(cgnode!=NULL);
                     cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
                     assert(cgn_src!=NULL);
-                    addEdge(cgnode,cgn_src,ET_DEFER,inst); 
+                    addEdge(cgn_src,cgnode,ET_DEFER,inst);
                 }
                 break;
 
@@ -3760,7 +4038,7 @@
                     for (uint32 i=0; i<nsrc; i++) {
                         cgn_src=findCnGNode_op(inst->getSrc(i)->getId());
                         assert(cgn_src!=NULL);
-                        addEdge(cgnode,cgn_src,ET_DEFER,inst); 
+                        addEdge(cgn_src,cgnode,ET_DEFER,inst);
                     }
                 }
                 break;
@@ -3827,7 +4105,7 @@
     std::string t2;
 
     os << "nodeId "<<cgn->cngNodeId<<"  ";
-    if (cgn->nodeType & NT_OBJS) {   //node of object created in the method
+    if (cgn->nodeType & (NT_OBJS|NT_LDVAL)) {   //node of object created in the method
         os << "opId "<<cgn->opndId<<"  ";
     } else {
         if (cgn->nodeType & NT_ACTARG) {   //node of actual method parameter
@@ -3839,6 +4117,7 @@
         os << "  nArg "<<cgn->argNumber<<"  ";    //Arg number for defarg
     os << "  inst "<<cgn->instrId<<"  ("<<nodeTypeToString(cgn)<<cgn->nodeType<<",  ";
     switch (cgn->nodeRefType) {
+        case NR_PRIM   : t2="Prim-"; break;
         case NR_REF    : t2="Ref -"; break;
         case NR_ARR    : t2="Arr -"; break;
         case NR_REFARR : t2="RArr-"; break;
@@ -3848,7 +4127,7 @@
     if (cgn->lNode)
         os << "( " << cgn->lNode->cngNodeId << "-" << cgn->lNode->opndId << " )  ";
     os << "st. ";
-    printState(cgn); os << "  ";
+    printState(cgn,os); os << "  ";
 }  // printCnGNode(CnGNode* cgn,::std::ostream& os) 
 
 
@@ -3870,6 +4149,7 @@
         case NT_ACTARG  : t1="AArg-"; break;
         case NT_EXITVAL : t1="EVal-"; break;
         case NT_THRVAL  : t1="TVal-"; break;
+        case NT_LDVAL   : t1="LVal-"; break;
         default         : t1="    -";
     }
     return t1;
@@ -3901,7 +4181,7 @@
         printCnGNode(*it,os);
         os << std::endl;
         os << "                                ";
-        if ((*it)->nodeType & (NT_OBJS|NT_EXITVAL)) {  //node of created or exit object
+        if ((*it)->nodeType & (NT_OBJS|NT_EXITVAL|NT_LDVAL)) {  //node of created or exit object
             ((Opnd*)(*it)->refObj)->printWithType(os);
         } 
         if ((*it)->nodeType == NT_RETVAL) {
@@ -3909,7 +4189,12 @@
             Inst* inst = ((Opnd*)(*it)->refObj)->getInst();
             inst->print(os);
             if (inst->getOpcode()==Op_IndirectMemoryCall) {
-                MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+                MethodDesc* md;
+                if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) {
+                    md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc();
+                } else {
+                    md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+                }
                 os << std::endl; os << "                                ";
                 md->printFullName(os);
             }
@@ -3946,17 +4231,23 @@
     os << std::endl;
     os << text; cgn->nInst->print(os); os << std::endl; 
     scannedObjs->push_back(cgn->cngNodeId);
-    if (cgn->outEdges != NULL)
+    if (cgn->outEdges != NULL) {
         for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
             os << text << edgeTypeToString(*it1) << std::endl;
             if ((node=findCnGNode_id((*it1)->cngNodeTo->cngNodeId))!=NULL)
                 printCnGNodeRefs(node,text+"  ",os);
         } 
+    }
     scannedObjs->pop_back();
     if (cgn->nodeType==NT_RETVAL) {
         inst = cgn->nInst;
         if (inst->getOpcode()==Op_IndirectMemoryCall) {
-            MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            MethodDesc* md;
+            if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) {
+                md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc();
+            } else {
+                md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            }
             os << text << "  ";         
             md->printFullName(os); os << std::endl;
         }
@@ -3990,7 +4281,12 @@
             }
         }
         if (inst->getOpcode()==Op_IndirectMemoryCall) {
-            MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            MethodDesc* md;
+            if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) {
+                md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc();
+            } else {
+                md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+            }
             os << text << "  "; md->printFullName(os); os << std::endl;
         }
         return;
@@ -4041,7 +4337,7 @@
 EscAnalyzer::findCnGNode_op(uint32 nId) {
     CnGNodes::iterator it;
     for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
-        if ((*it)->opndId==nId && ((*it)->nodeType & NT_OBJS))
+        if ((*it)->opndId==nId && ((*it)->nodeType & (NT_OBJS|NT_LDVAL)))
             return (*it);
     }
     return(NULL);
@@ -4127,9 +4423,9 @@
 }  // findCnGNode_fl(Opnd* opnd, uint32 ntype) 
 
 
-/*
-*   Creates edge if it doesn't exist yet.
-*/
+/**
+ *   Creates edge if it doesn't exist yet.
+ */
 void
 EscAnalyzer::addEdge(CnGNode* cgnfrom, CnGNode* cgnto, 
                                     uint32 etype, Inst* inst) {
@@ -4145,10 +4441,6 @@
         assert(cgn1!=NULL);
     }
 
-    if (cgnto->lNode) {
-        cgn2=findCnGNode_id(cgnto->lNode->cngNodeId);
-        assert(cgn2!=NULL);
-    }
 #ifdef _DEBUG
     if (_cngedges) {
         Log::out() 
@@ -4185,7 +4477,7 @@
                     }
                 }
             } else {
-                for ( itr = (*it)->refList->begin( ); itr != (*it)->refList->end( ); itr++ ) 
+/*                for ( itr = (*it)->refList->begin( ); itr != (*it)->refList->end( ); itr++ ) 
                     if ((*itr)->cngNodeTo == cgn2) { // needed edge exists
                        done = true;
 #ifdef _DEBUG
@@ -4193,7 +4485,7 @@
                            Log::out() << "++++ addEdge: needed edge exists" <<  std::endl;
                        }
 #endif
-                    }
+                    }--nvg */
             }
             if (!done) {
                 ref = new (eaMemManager) CnGRef;
@@ -4228,6 +4520,2162 @@
 #endif
 
 }  // addEdge(CnGNode* cgnfrom, CnGNode* cgnto, uint32 etype, Inst* inst) 
+
+
+/*
+    Scalar replacement optimization
+*/
+
+void
+EscAnalyzer::scanLocalObjects() {
+    CnGNodes::iterator it;
+    uint32 lo_count=0;             // number of local objects
+    ObjIds* lnoids = NULL;         // list of new opnds to optimize
+    ObjIds* lloids = NULL;         // list of load opnds to optimize
+    ObjIds::iterator lo_it;
+    bool prTitle = true;
+    CnGNode* stnode = NULL;
+
+    for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+        if ((*it)->nodeType == NT_OBJECT && getEscState(*it)==NO_ESCAPE 
+            && getCalleeEscaped(*it) == 0 && !((*it)->nInst->getOpcode()==Op_LdRef)) {
+            if (prTitle) {
+                if (_scinfo) {
+                    os_sc << "================ Local Object States   < "; 
+                    irManager.getMethodDesc().printFullName(os_sc); 
+                    os_sc << std::endl;
+                }
+                prTitle = false;
+            }
+            lo_count++;  // number of local objects
+            stnode = checkCnG(*it,true);
+            if (stnode != NULL) {
+                if (stnode->nodeType == NT_OBJECT) {
+                    if (lnoids == NULL) {
+                        lnoids = new (eaMemManager) ObjIds(eaMemManager);
+                    }
+                    lnoids->push_back(stnode->opndId);
+                } else {
+                    if (lloids == NULL) {
+                        lloids = new (eaMemManager) ObjIds(eaMemManager);
+                    }
+                    lloids->push_back(stnode->opndId);
+                }
+            }
+            if (_scinfo) {
+                os_sc << "- - - checkCnG returns "; 
+                if (stnode == NULL) {
+                    os_sc << " null "; 
+                    os_sc << std::endl;
+                } else {
+		            printCnGNode(stnode,os_sc); os_sc << std::endl;
+                }
+            }
+        }
+    }
+    if (prTitle)
+        return;
+    if (_scinfo) {
+        os_sc << "CFGOpnds: " << irManager.getOpndManager().getNumSsaOpnds() << "  CnGNodes: "
+            << cngNodes->size() << "  Local Objects: " << lo_count << std::endl;
+    }
+    if (lnoids != NULL || lloids != NULL) {
+        if (_scinfo) {
+            if (lnoids != NULL) {
+                if (lnoids->size()>0) {
+                    os_sc << "lnoids size: " << lnoids->size() << " - ";
+                    for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+            if (lloids != NULL) {
+                if (lloids->size()>0) {
+                    os_sc << "lloids size: " << lloids->size() << " - ";
+                    for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+        }
+        methodEndInsts->clear();
+        checkInsts->clear();
+        checkOpndUsage(lnoids,lloids,true);
+        bool doopt = false;
+        if (lnoids != NULL) {
+            if (lnoids->size()>0) {
+                doopt = true;
+                if (_scinfo) {
+                    os_sc << "lnoids size: " << lnoids->size() << " - ";
+                    for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            } else {
+                if (_scinfo) {
+                    os_sc << "lnoids size: 0" << std::endl;
+                }
+            }
+        }
+        if (lloids != NULL) {
+            if (lloids->size()>0) {
+                doopt = true;
+                if (_scinfo) {
+                    os_sc << "lloids size: " << lloids->size() << " - ";
+                    for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            } else {
+                if (_scinfo) {
+                    os_sc << "lloids size: 0" << std::endl;
+                }
+            }
+        }
+        if (doopt && do_scalar_repl) {
+            if (lnoids != NULL) {
+                doLOScalarReplacement(lnoids);
+            }
+            if (lloids != NULL) {
+                doLOScalarReplacement(lloids);
+            }
+        }    }
+    if (_scinfo) {
+        os_sc << "================                       > " ;
+        irManager.getMethodDesc().printFullName(os_sc); 
+        os_sc << std::endl;
+    }
+}  // scanLocalObjects() 
+
+
+void
+EscAnalyzer::scanEscapedObjects() {
+    CnGNodes::iterator it;
+    uint32 vco_count=0;            // number of local objects
+    uint32 ob_ref_type=0;          // object ref type
+    ObjIds* lnoids = NULL;         // list of new opnds to optimize
+    ObjIds* lloids = NULL;         // list of load opnds to optimize
+    ObjIds::iterator lo_it;
+    bool prTitle = true;
+    CnGNode* stnode = NULL;
+
+    for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+//        if ((*it)->nodeType == NT_OBJECT && getEscState(*it)!=NO_ESCAPE
+        if ((*it)->nodeType == NT_OBJECT 
+            && getCalleeEscaped(*it) == 0 && !((*it)->nInst->getOpcode()==Op_LdRef)) {
+            if ((*it)->nInst->getNode() == NULL && getEscState(*it)==NO_ESCAPE) {
+				continue;   // already scalarized
+            }
+            ob_ref_type = (*it)->nodeRefType;   // object ref type
+            if (ob_ref_type != NR_REF) {
+                continue;   // vc arrays not scalarized
+            }
+            vco_count++;  // number of vc objects
+            if (prTitle) {
+                if (_scinfo) {
+                    os_sc << "================ Escaped Object States   < "; 
+                    irManager.getMethodDesc().printFullName(os_sc); 
+                    os_sc << std::endl;
+                }
+                prTitle = false;
+            }
+
+            stnode = checkCnG(*it,false);
+            if (stnode != NULL) {
+                if (stnode->nodeType == NT_OBJECT) {
+                    if (lnoids == NULL) {
+                        lnoids = new (eaMemManager) ObjIds(eaMemManager);
+                    }
+                    lnoids->push_back(stnode->opndId);
+                } else {
+                    if (lloids == NULL) {
+                        lloids = new (eaMemManager) ObjIds(eaMemManager);
+                    }
+                    lloids->push_back(stnode->opndId);
+                }
+            }
+            if (_scinfo) {
+                os_sc << "- - - checkCnG returns "; 
+                if (stnode == NULL) {
+                    os_sc << " null "; 
+                    os_sc << std::endl;
+                } else {
+		            printCnGNode(stnode,os_sc); os_sc << std::endl;
+                }
+            }
+
+        }
+    }
+
+    if (prTitle)
+        return;
+
+    if (_scinfo) {
+        os_sc << "CFGOpnds: " << irManager.getOpndManager().getNumSsaOpnds() << "  CnGNodes: "
+            << cngNodes->size() << "  VC Objects: " << vco_count << "  lnoids size "
+            << (lnoids!=NULL?lnoids->size():0) << "  lloids size " 
+            << (lloids!=NULL?lloids->size():0)<< std::endl;
+    }
+    if (lnoids != NULL || lloids != NULL) {
+        if (_scinfo) {
+            if (lnoids != NULL) {
+                if (lnoids->size()>0) {
+                    os_sc << "lnoids size: " << lnoids->size() << " - ";
+                    for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+             if (lloids != NULL) {
+                if (lloids->size()>0) {
+                    os_sc << "lloids size: " << lloids->size() << " - ";
+                    for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+        }
+        methodEndInsts->clear();
+        checkInsts->clear();
+        checkOpndUsage(lnoids,lloids,false);
+        bool doopt = false;
+        if (lnoids != NULL) {
+            if (lnoids->size()>0) {
+                doopt = true;
+                if (_scinfo) {
+                    os_sc << "lnoids size: " << lnoids->size() << " - ";
+                    for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+        }
+        if (lloids != NULL) {
+            if (lloids->size()>0) {
+                doopt = true;
+                if (_scinfo) {
+                    os_sc << "lloids size: " << lloids->size() << " - ";
+                    for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+                        os_sc << " " << (*lo_it);
+                    }
+                    os_sc << std::endl;
+                }
+            }
+        }
+        if (doopt && do_scalar_repl) {
+            if (lnoids != NULL) {
+                doEOScalarReplacement(lnoids);
+            }
+            if (lloids != NULL) {
+                doEOScalarReplacement(lloids);
+            }
+        }
+    }
+
+    if (_scinfo) {
+        os_sc << "================                       > " ;
+        irManager.getMethodDesc().printFullName(os_sc); 
+        os_sc << std::endl;
+    }
+}  // scanEscapedObjects() 
+
+
+void 
+EscAnalyzer::doLOScalarReplacement(ObjIds* loids) {
+    ObjIds::iterator lo_it;
+    CnGNode* onode;
+    Opnd* oopnd;
+    Type* otype;
+    Inst* inst;
+    Inst* st_inst;
+    Insts::iterator it3;
+    OpndManager& _opndManager = irManager.getOpndManager();
+    InstFactory& _instFactory = irManager.getInstFactory();
+    ScObjFlds* scObjFlds = new (eaMemManager) ScObjFlds(eaMemManager);
+    ScObjFld* sco = NULL;
+    ScObjFlds::iterator ito;
+
+    if (loids == NULL)
+        return;
+    if (loids->size() == 0)       
+        return;
+    for (lo_it=loids->begin(); lo_it!=loids->end(); lo_it++) {
+        onode = findCnGNode_op(*lo_it);
+        if (onode == NULL) {
+            if (_scinfo) {
+                os_sc << " - - no cng node for opId " << *lo_it << std::endl;
+            }
+            continue;
+        }
+        if (onode->nodeRefType == NR_PRIM) {
+            continue;
+        }
+        oopnd = (Opnd*)(onode->refObj);
+        otype = oopnd->getType();
+        if (_scinfo) {
+            os_sc << " - - method: ";
+            irManager.getMethodDesc().printFullName(os_sc); 
+            os_sc << std::endl;
+            if (onode->nodeRefType == NR_REF)
+                os_sc << " - - scalarized local instance ";
+            else
+                os_sc << " - - scalarized local array ";
+            os_sc << "  "; printCnGNode(onode,os_sc);
+            ((Opnd*)onode->refObj)->printWithType(os_sc);
+            os_sc << std::endl;
+        }
+
+        // to collect stind & ldind instructions
+        scObjFlds->clear();
+        collectStLdInsts(onode, scObjFlds);
+
+        if (_scinfo) {
+            os_sc << " found objects " << scObjFlds->size() << std::endl;
+        }
+
+        if (onode->nodeType == NT_LDOBJ) {
+            if (_scinfo) {
+                os_sc << "*-*-*- not optimized " << std::endl;
+            }
+            continue;
+        }
+
+        if (scObjFlds->size() > 0) {
+            for (ito = scObjFlds->begin( ); ito != scObjFlds->end( ); ito++ ){
+                sco = (*ito);
+                if (sco->ls_insts->size()==0) {
+                    continue;
+                }
+                bool do_fld_sc = false;
+                for (it3 = sco->ls_insts->begin(); it3 != sco->ls_insts->end( ); it3++ ) {
+                    if ((*it3)->getOpcode() == Op_TauLdInd) {
+                        do_fld_sc = true;
+                        break;
+                    }
+                }
+                if (do_fld_sc) {
+                    Type* fl_type = NULL;
+                    Inst* ii = sco->ls_insts->front();
+                    if (ii->getOpcode()==Op_TauStInd) {
+                        fl_type = ii->getSrc(1)->getType()->asPtrType()->getPointedToType();
+                    } else {
+                        fl_type = ii->getSrc(0)->getType()->asPtrType()->getPointedToType();
+                    }
+                    VarOpnd* fl_var_opnd = _opndManager.createVarOpnd(fl_type, false);
+                    SsaTmpOpnd* fl_init_opnd = _opndManager.createSsaTmpOpnd(fl_type);
+                    Inst* ld_init_val_inst = NULL;
+                    Inst* st_init_val_inst = NULL;
+                    sco->fldVarOpnd = fl_var_opnd;
+
+                    if (_scinfo) {
+                        os_sc<<" PoitedType "; fl_type->print(os_sc); os_sc <<std::endl;
+                    }
+                    if (fl_type->isReference()) {
+                        ld_init_val_inst = _instFactory.makeLdNull(fl_init_opnd);
+                    } else {
+                        ld_init_val_inst = _instFactory.makeLdConst(fl_init_opnd, 0);
+                    }
+                    st_init_val_inst = _instFactory.makeStVar(fl_var_opnd, fl_init_opnd);
+
+                    scalarizeOFldUsage(sco);
+                    if (_scinfo) {
+                        os_sc << "++++ old newobj added fld_var: before"  << std::endl;
+                        FlowGraph::print(os_sc,onode->nInst->getNode());
+                        os_sc << "++++ old newobj: before end"  << std::endl;
+                    }
+                    ld_init_val_inst->insertBefore(onode->nInst);
+                    _instFactory.makeStVar(fl_var_opnd,fl_init_opnd)->insertBefore(onode->nInst);
+                    if (_scinfo) {
+                        os_sc << "++++ old newobj added fld_var: after"  << std::endl;
+                        FlowGraph::print(os_sc,onode->nInst->getNode());
+                        os_sc << "++++ old newobj: after end"  << std::endl;
+                    }        
+                } else { // there was no ldind instructions
+                    for (it3 = sco->ls_insts->begin(); it3 != sco->ls_insts->end( ); it3++ ) {
+                        st_inst = *it3;
+                        removeInst(st_inst);

[... 1779 lines stripped ...]