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/02 07:44:06 UTC

svn commit: r513632 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3228/ src/test/regression/H3228/H3228.java src/test/regression/H3228/run.test.xml vm/jitrino/src/optimizer/syncopt.cpp

Author: varlax
Date: Thu Mar  1 22:44:05 2007
New Revision: 513632

URL: http://svn.apache.org/viewvc?view=rev&rev=513632
Log:
Applied HARMONY-3228 [drlvm][jit][opt] Dacapo.xalan hangs up with default server+inliner options
Tested on SLES10ia32, SLES9@x64

Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3228/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3228/H3228.java
    harmony/enhanced/drlvm/trunk/src/test/regression/H3228/run.test.xml
Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/syncopt.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3228/H3228.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3228/H3228.java?view=auto&rev=513632
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3228/H3228.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3228/H3228.java Thu Mar  1 22:44:05 2007
@@ -0,0 +1,30 @@
+package org.apache.harmony.drlvm.tests.regression.h3228;
+
+import junit.framework.TestCase;
+
+
+/*  The test checks that the JIT correctly optimizes nested monenter/monexit
+ *  pairs when they are enclosed into another monenter/monexit with the same
+ *  synchronization object.
+ *  The synchronized method sync_run() contains a synchronized statement which
+ *  can be safely removed. The issue described in Harmony-3228 caused
+ *  a crash during the JIT compilation stage.
+ */
+public class H3228 extends TestCase {
+
+    public void test() {
+        boolean b = false;
+        for (int i = 0; i < 1000000000; i++) {
+            b = sync_run();
+        }
+        System.out.println("Test passed");
+    }
+
+    public synchronized boolean sync_run() {
+        boolean a = false;
+        synchronized (this) {
+            a = !a;
+        }
+        return a;
+    }
+}

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3228/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3228/run.test.xml?view=auto&rev=513632
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3228/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3228/run.test.xml Thu Mar  1 22:44:05 2007
@@ -0,0 +1,8 @@
+<project name="RUN HARMONY-3228 Regression Test">
+  <target name="run-test">
+    <run-junit-test 
+        test="org.apache.harmony.drlvm.tests.regression.h3228.H3228"
+        vmarg="-Xem:server">
+    </run-junit-test>
+  </target>
+</project>

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/syncopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/syncopt.cpp?view=diff&rev=513632&r1=513631&r2=513632
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/syncopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/syncopt.cpp Thu Mar  1 22:44:05 2007
@@ -2111,18 +2111,31 @@
 
 
 
-DEFINE_SESSION_ACTION(SO2, so2, "SyncOpt2")
+DEFINE_SESSION_ACTION(SO2, so2, "Nested synchronizations removal")
 
- 
+class SyncOpt2 {
+public:
+    SyncOpt2(IRManager& irm)
+        : irManager(irm) {};
+    void runPass();
+    void eliminateClosestMonExits(Node* enterNode, Opnd* monObject, int& nExits, BitSet& monexits);
+private:
+    IRManager& irManager;
+};
 
 void SO2::_run(IRManager& irm) {
-    OptPass::computeDominators(irm);
-    ControlFlowGraph& fg = irm.getFlowGraph();
+    SyncOpt2 opt(irm);
+    opt.runPass();
+}
+
+void SyncOpt2::runPass() {
     MemoryManager tmpMM(1024, "SO2MM");
+    ControlFlowGraph& flowGraph = irManager.getFlowGraph();
+    OptPass::computeDominators(irManager);
+    DominatorTree* domTree = flowGraph.getDominatorTree();
     StlVector<Inst*> monenters(tmpMM);   
-    DominatorTree* dom = fg.getDominatorTree();
- 
-    const Nodes& nodes = fg.getNodesPostOrder();
+    const Nodes& nodes = flowGraph.getNodesPostOrder();
+
     for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
         Node* node = *it;
         for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
@@ -2133,23 +2146,16 @@
                     if (child->getNode()==NULL) {
                         continue;
                     }
-                    if (child->getSrc(0) == inst->getSrc(0) && dom->dominates(inst->getNode(), child->getNode())) {
-                        //clean child
-                        int nExits=0;
+                    Opnd* monObject = child->getSrc(0);
+                    if ((monObject == inst->getSrc(0)) && domTree->dominates(inst->getNode(), child->getNode())) {
+                        // Find a proper child to clean
+                        int nExits = 0;
                         Node* enterNode = child->getNode();
-                        Node* exitNode = NULL;
-                        for (Nodes::const_iterator it2 = nodes.begin();exitNode!=enterNode; ++it2) {
-                            exitNode = *it2;
-                            Inst* exit = (Inst*)exitNode->getLastInst();
-                            if (exit->getOpcode() == Op_TauMonitorExit && exit->getSrc(0) == child->getSrc(0) && dom->dominates(enterNode, exitNode)) {
-//                                printf("+++++++++++++++++++++++++++++++FOUND\n");
-                                Edge* exc = exitNode->getExceptionEdge();
-                                fg.removeEdge(exc);
-                                exit->unlink();
-                                nExits++;
-                            }
-                        }
-                        assert(nExits>0);
+                        BitSet monexits(tmpMM,flowGraph.getMaxNodeId());
+
+                        eliminateClosestMonExits(enterNode, monObject, nExits, monexits);
+
+                        assert(nExits > 0);
                         child->unlink();
                     }
                 }
@@ -2158,5 +2164,28 @@
     }
 }
 
+void SyncOpt2::eliminateClosestMonExits(Node* enterNode, Opnd* monObject, int& nExits, BitSet& monexits) {
+    ControlFlowGraph& flowGraph = irManager.getFlowGraph();
+    const Edges& outEdges = enterNode->getOutEdges();
+    Edges::const_iterator eit;
+    Node* exitNode; 
+    for (eit = outEdges.begin(); eit != outEdges.end(); ++eit) {
+        exitNode = (*eit)->getTargetNode();
+        assert(exitNode != flowGraph.getExitNode());
+        if (monexits.getBit(exitNode->getId())) {
+            continue;
+        }
+        Inst* exit = (Inst*)exitNode->getLastInst();
+        if ((exit->getOpcode() == Op_TauMonitorExit) && (exit->getSrc(0) == monObject)) {
+            Edge* excEdge = exitNode->getExceptionEdge();
+            flowGraph.removeEdge(excEdge);
+            exit->unlink();
+            nExits++;
+            monexits.setBit(exitNode->getId());
+        } else {
+            eliminateClosestMonExits(exitNode, monObject, nExits, monexits);
+        }
+    }
+}
 
 } //namespace Jitrino