You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/08/10 13:54:37 UTC

svn commit: r564567 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H4265/ src/test/regression/excludes/ vm/jitrino/src/codegenerator/ia32/ vm/jitrino/src/jet/ vm/vmcore/src/exception/

Author: mfursov
Date: Fri Aug 10 04:54:36 2007
New Revision: 564567

URL: http://svn.apache.org/viewvc?view=rev&rev=564567
Log:
Fix for HARMONY-4265
[drlvm][jit] Save quantity of try and catch blocks equal

This patch fixes only 32-bit modes. 64-bit modes need additional fix to take into accont stack frames alignment.




Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H4265/
    harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RuntimeInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java?view=auto&rev=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java Fri Aug 10 04:54:36 2007
@@ -0,0 +1,140 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package org.apache.harmony.drlvm.tests.regression.h4265;
+import junit.framework.*;
+
+public class Test extends TestCase {
+
+//1
+    void _testRec1() {
+        _testRec1();
+    }
+
+    public void testRec1() {
+        try {
+            _testRec1();
+        } catch (StackOverflowError e) {
+            return;
+        }
+        fail("No SOE was thrown!");
+    }
+
+
+
+//2
+    Object lock2 = new Object();
+    void _testSyncRec1() {
+        synchronized(lock2) {
+            _testSyncRec1();
+        }
+    }
+
+    public void testSyncRec1() {
+        try {
+            _testSyncRec1();
+        } catch (StackOverflowError e) {
+            return;
+        }
+        fail("No SOE was thrown!");
+    }
+
+
+//3
+    Object lock3 = new Object();
+    void _testSyncRec2() {
+        try {
+            synchronized(lock3) {
+                _testSyncRec2();            
+            }
+        } catch (Error r) {
+            //ignore
+        }
+    }
+
+    public void testSyncRec2() throws Exception {
+        Thread t1 = new Thread(new Runnable() {
+            public void run() {
+                _testSyncRec2();                
+            }            
+        });
+        t1.start();
+        t1.join();
+
+        Thread t2 = new Thread(new Runnable() {
+            public void run() {
+                _testSyncRec2();                
+            }            
+        });
+        t2.start();
+        t2.join();
+        //pass if no hang            
+    }
+
+
+//4
+    int i1=0;
+    void _testRec2() {
+        try { 
+            i1++;
+            _testRec2();            
+        } finally {
+            i1--;
+        }
+    }
+
+    public void testRec2() {
+        i1=0;
+        try {
+            _testRec2();
+        } catch (StackOverflowError e) {
+            assertEquals(0, i1);
+            return;
+        }
+        fail("No SOE was thrown!");
+            
+    }
+
+//5
+    public void testRec3() {
+        i1=0;
+        try {
+            _testRec2();
+        } catch (Throwable e) {
+            assertEquals(0, i1);
+            return;
+        }
+        fail("No Throwable was thrown!");
+            
+    }
+
+//6
+    public void testRec4() {
+        i1=0;
+        try {
+            _testRec2();
+        } catch (Error e) {
+            assertEquals(0, i1);
+            return;
+        }
+        fail("No Error was thrown!");
+            
+    }
+    
+
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H4265/Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml?view=auto&rev=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml Fri Aug 10 04:54:36 2007
@@ -0,0 +1,13 @@
+<project name="RUN HARMONY-4265 Regression Test">
+    <target name="run-test">
+        <run-junit-test 
+            test="org.apache.harmony.drlvm.tests.regression.h4265.Test"
+            vmarg="-Xem:jet">
+        </run-junit-test>
+        <run-junit-test 
+            test="org.apache.harmony.drlvm.tests.regression.h4265.Test"
+            vmarg="-Xem:opt">
+        </run-junit-test>
+    </target>
+</project>
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H4265/run.test.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 Fri Aug 10 04:54:36 2007
@@ -20,4 +20,5 @@
 H4512
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3341
- 
+# Exclude this test because SOE handling is not ready for x86_64 in JIT/VM yet
+H4265

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 Fri Aug 10 04:54:36 2007
@@ -19,5 +19,5 @@
 H4512
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3341
-
-
+# Exclude this test because SOE handling is not ready for x86_64 in JIT/VM yet
+H4265

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp Fri Aug 10 04:54:36 2007
@@ -525,6 +525,19 @@
         }
         bb->setCodeSize( (uint32)(ip-blockStartIp) );
     }
+
+    //register SOE checks offset to be used in unwind as 0-depth area        
+    StackInfo* stackInfo = (StackInfo*)irManager->getInfo(STACK_INFO_KEY);
+    assert(stackInfo);//stack layout must be done before emitter
+    for (Inst* inst = (Inst*)irManager->getEntryPointInst()->getNext(); inst!=NULL; inst = inst->getNextInst()) {
+        if (inst->getMnemonic() != Mnemonic_TEST) {
+            break;
+        }
+        stackInfo->setSOECheckAreaOffset(inst->getCodeOffset());
+    }                
+
+
+
     unsigned codeSize = (unsigned)(ip-codeStreamStart);
     assert( codeSize < maxMethodSize );
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RuntimeInterface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RuntimeInterface.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RuntimeInterface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RuntimeInterface.cpp Fri Aug 10 04:54:36 2007
@@ -54,6 +54,9 @@
 #else
     stackInfo.read(methodDesc, *context->p_eip, isFirst);
     assert(isFirst || (uint32)context->p_eip+4 == context->esp);
+    if (stackInfo.getStackDepth() == 0) { //stack overflow exception
+        return NULL;
+    }
     return (void *)(context->esp + stackInfo.getStackDepth() + stackInfo.getOffsetOfThis());
 #endif
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.cpp Fri Aug 10 04:54:36 2007
@@ -166,6 +166,7 @@
     localOffset = ((StackInfo *)data)->localOffset;
     offsetOfThis = ((StackInfo *)data)->offsetOfThis;
     itraceMethodExitString = ((StackInfo *)data)->itraceMethodExitString;
+    soeCheckAreaOffset = ((StackInfo *)data)->soeCheckAreaOffset;
     
     if (!isFirst){
         DepthEntry * entry = getHashEntry(data, eip, hashTableSize);
@@ -178,20 +179,22 @@
         calleeSaveRegsMask = entry->info.calleeSaveRegs;
         stackDepth = entry->info.stackDepth;
     }else{
-        DepthEntry * entry = NULL;
-        uint32 i = CALL_MIN_SIZE;
-        for (; i<= CALL_MAX_SIZE; i++) {
-            entry = getHashEntry(data, eip + i, hashTableSize);
-            if(entry)
-                break;
-        }
-        if (entry && (entry->info.callSize == i)) {
-            stackDepth = entry->info.stackDepth;
+        POINTER_SIZE_INT eipOffset = eip - (POINTER_SIZE_INT)pMethodDesc->getCodeBlockAddress(0);
+        assert(fit32(eipOffset) && eipOffset >= 0);
+        if (eipOffset <= soeCheckAreaOffset) {
+            stackDepth = 0; //0 depth -> stack overflow error
         } else {
-            if (((POINTER_SIZE_INT)pMethodDesc->getCodeBlockAddress(0)) == eip) {
-                stackDepth = 0;
+            DepthEntry * entry = NULL;
+            uint32 i = CALL_MIN_SIZE;
+            for (; i<= CALL_MAX_SIZE; i++) {
+                entry = getHashEntry(data, eip + i, hashTableSize);
+                if(entry)
+                    break;
+            }
+            if (entry && (entry->info.callSize == i)) {
+                stackDepth = entry->info.stackDepth; //call site's depth
             } else {
-                stackDepth = frameSize;
+                stackDepth = frameSize; //hardware NPE's depth
             }
         }
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.h?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackInfo.h Fri Aug 10 04:54:36 2007
@@ -94,7 +94,9 @@
         localOffset(0), 
         calleeSaveRegsMask(0),
         stackDepth(-1),
-        offsetOfThis(0){ stackDepthInfo = new(mm) DepthMap(mm);}
+        offsetOfThis(0), 
+        soeCheckAreaOffset(0)
+        { stackDepthInfo = new(mm) DepthMap(mm);}
 
     StackInfo() 
         : byteSize(0), hashTableSize(0), frameSize(0),
@@ -106,7 +108,7 @@
         localOffset(0), 
         stackDepthInfo(NULL),
         calleeSaveRegsMask(0),
-        stackDepth(-1),offsetOfThis(0) {}
+        stackDepth(-1),offsetOfThis(0),soeCheckAreaOffset(0) {}
 
     /** writes StackInfo data into memory
      */
@@ -167,6 +169,10 @@
 
     uint32 getOffsetOfThis() const {return offsetOfThis;}
 
+    uint32 getSOECheckAreaOffset() const {return soeCheckAreaOffset;}
+
+    void setSOECheckAreaOffset(uint32 v) {soeCheckAreaOffset = v;}
+
     /** returns byte size of StackInfo data
     */
     POINTER_SIZE_INT getByteSize() const;
@@ -203,6 +209,7 @@
     uint32 calleeSaveRegsMask;
     int32  stackDepth;
     uint32 offsetOfThis;
+    uint32 soeCheckAreaOffset;
 
     friend class StackLayouter;
 };

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32StackLayout.cpp Fri Aug 10 04:54:36 2007
@@ -166,21 +166,68 @@
 {
 };
 
-static void insertSOEHandler(IRManager& irm, uint32 maxStackSize) {
-    if (maxStackSize == 0) {
-        return;
+
+static bool isSOEHandler(ObjectType* type) {
+    static const char* soeHandlers[] = {"java/lang/Object", "java/lang/Throwable", "java/lang/Error", "java/lang/StackOverflowError", NULL};
+    const char* typeName = type->getName();
+    for (size_t i=0;soeHandlers[i]!=NULL; i++) {
+        if (!strcmp(typeName, soeHandlers[i])) {
+            return true;
+        }
+    }
+    return false;
+}
+
+//checks if SOE can be caught in this method
+static bool hasSOEHandlers(IRManager& irm) {
+    //A contract with VM: check extra page for synchronized methods or methods with SOE handlers.
+    if (irm.getMethodDesc().isSynchronized()) {
+        return true;
+    }
+
+    const Nodes& nodes= irm.getFlowGraph()->getNodes();
+    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
+       Node* node = *it;
+        if (node->isCatchBlock()) {
+            const Edges& edges = node->getInEdges();
+            for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) {
+                Edge* e = *ite;
+                CatchEdge* catchEdge = (CatchEdge*)e;
+                ObjectType* catchType = catchEdge->getType()->asObjectType();
+                assert(catchType!=NULL);
+                if (isSOEHandler(catchType)) {
+                    return true;
+                }
+            }
+        }
     }
+    return false;
+}
+
+#define MAX_STACK_FOR_SOE_HANDLERS 0x2000
+
+static void insertSOECheck(IRManager& irm, uint32 maxStackUsedByMethod) {
 #ifdef _EM64T_
-    RegName eaxReg = RegName_RAX;
-    RegName espReg = RegName_RSP;
-#else
-    RegName eaxReg = RegName_EAX;
-    RegName espReg = RegName_ESP;
+    //SOE checking is not finished on EM64T
+    //TODO: work on stack alignment & SOE checkers
+    if (true) return; 
 #endif
-    Opnd* guardedMemOpnd = irm.newMemOpnd(irm.getTypeFromTag(Type::IntPtr), MemOpndKind_Heap, irm.getRegOpnd(espReg), -(int)maxStackSize);
-    Inst* guardInst = irm.newInst(Mnemonic_MOV, irm.getRegOpnd(eaxReg), guardedMemOpnd);
-    Inst* entryInst = irm.getEntryPointInst();
-    guardInst->insertAfter(entryInst);
+    uint32 stackToCheck = maxStackUsedByMethod + (hasSOEHandlers(irm) ? MAX_STACK_FOR_SOE_HANDLERS : 0);
+    if (stackToCheck == 0) {
+        return;
+    }
+    static const uint32 PAGE_SIZE=0x1000;
+    
+    uint32 nPagesToCheck = stackToCheck / PAGE_SIZE;
+    Inst* prevInst = irm.getEntryPointInst();
+    for(uint32 i=0;i<=nPagesToCheck; i++) {
+        uint32 offset = i < nPagesToCheck ? PAGE_SIZE * (i+1) : stackToCheck;
+        Opnd* guardedMemOpnd = irm.newMemOpnd(irm.getTypeFromTag(Type::IntPtr), MemOpndKind_Heap, irm.getRegOpnd(STACK_REG), -(int)offset);
+        Inst* guardInst = irm.newInst(Mnemonic_TEST, guardedMemOpnd, irm.getRegOpnd(STACK_REG));
+        guardInst->insertAfter(prevInst);
+        guardInst->setBCOffset(0);
+        prevInst = guardInst;
+    }
 }
 
 void StackLayouter::runImpl()
@@ -198,7 +245,7 @@
     createProlog();
     createEpilog();
     uint32 maxStackDepth = irm.calculateStackDepth();
-    insertSOEHandler(irm, maxStackDepth);
+    insertSOECheck(irm, maxStackDepth);
     irm.layoutAliasOpnds();
 
     //fill StackInfo object

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp Fri Aug 10 04:54:36 2007
@@ -84,6 +84,7 @@
         gen_brk();
     }
 
+
     if (m_infoBlock.get_bc_size() == 1 && m_bc[0] == OPCODE_RETURN && !g_jvmtiMode) {
         // empty method, nothing to do; the same is in gen_return();
         return;
@@ -92,7 +93,7 @@
     // A special stack preparation is performed in order to deal with 
     // a stack overflow error (SOE) at runtime:
     // First, the callee-save registers are not changed until we are 
-    // absolutely sure we have enouhg stack. In this case, if SOE happens,
+    // absolutely sure we have enough stack. In this case, if SOE happens,
     // we'll simply do nothing in unwind_stack().
     
     //
@@ -117,22 +118,29 @@
     // frame setup procedures
     rlock(m_ci);
     
-    // Here is pretty rare case, though still need to be proceeded:
-    // When we allocate a stack frame of size more than one page then the 
-    // memory page(s) may not be accessible and even not allocated.
-    // A direct access to such [non existing] page raises 'access 
-    // violation'. To avoid the problem we need simply probe (make read 
-    // access) to the pages sequentially. In response on read-access to 
-    // inaccessible page, the OS grows up the stack, so pages become 
-    // accessible.
-    const unsigned PAGE_SIZE = 0x1000;
-    unsigned pages = 
-                  (frameSize + m_max_native_stack_depth + 
-                   PAGE_SIZE -1)/PAGE_SIZE;
-    //
-    for (unsigned i=1; i<pages; i++) {
-        AR ar = valloc(i32);
-        ld4(ar, sp, frameSize-i*PAGE_SIZE);
+    {
+        // Here is pretty rare case, though still need to be proceeded:
+        // When we allocate a stack frame of size more than one page then the 
+        // memory page(s) may not be accessible and even not allocated.
+        // A direct access to such [non existing] page raises 'access 
+        // violation'. To avoid the problem we need simply probe (make read 
+        // access) to the pages sequentially. In response on read-access to 
+        // inaccessible page, the OS grows up the stack, so pages become 
+        // accessible.
+        const unsigned PAGE_SIZE = 0x1000;
+        unsigned pages = 
+            (frameSize + m_max_native_stack_depth + 
+            PAGE_SIZE -1)/PAGE_SIZE;
+        
+        if (method_is_synchronized(m_method) || hasSOEHandlers)  {
+            //A contract with VM: check extra page for synchronized methods or methods with SOE handlers.
+            pages++;
+        }
+        //
+        for (unsigned i=1; i<pages; i++) {
+            AR ar = valloc(i32);
+            ld4(ar, sp, frameSize-i*PAGE_SIZE);
+        }
     }
     // When requested, store the whole context (==including scratch registers)
     // - normally for JVMTI PopFrame support.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp Fri Aug 10 04:54:36 2007
@@ -83,6 +83,20 @@
  */
 static unsigned methodsSeen = 0;
 
+
+static bool isSOEHandler(Class_Handle cls) {
+    if (cls==NULL) return true; //-> finally block
+    static const char* soeHandlers[] = {"java/lang/Throwable", "java/lang/Error", "java/lang/StackOverflowError", NULL};
+    const char* typeName = class_get_name(cls);
+    for (size_t i=0;soeHandlers[i]!=NULL; i++) {
+        if (!strcmp(typeName, soeHandlers[i])) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
 JIT_Result Compiler::compile(Compile_Handle ch, Method_Handle method,
                              const OpenMethodExecutionParams& params)
 {
@@ -414,6 +428,9 @@
     // ... now, generate exception handlers ...
     for (unsigned i=0; i<m_handlers.size(); i++) {
         comp_gen_code_bb(m_handlers[i].handler);
+        if (isSOEHandler(m_handlers[i].klass)) {
+            hasSOEHandlers=true;
+        }
     }
     
     // ... and finally, generate prolog.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h Fri Aug 10 04:54:36 2007
@@ -65,6 +65,7 @@
     {
         m_hjit = jh;
         m_bEmulation = false;
+        hasSOEHandlers = false;
     }
     /**
      * @brief Main compilation routine.
@@ -412,6 +413,9 @@
      */
     char *  m_vmCode;
     
+    /// 'TRUE' if this method has catch handlers suitable for StackOverflowError
+    bool    hasSOEHandlers;
+
     /**
      * @brief Parses method's signature at the given constant pool entry.
      *

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp?view=diff&rev=564567&r1=564566&r2=564567
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp Fri Aug 10 04:54:36 2007
@@ -139,7 +139,7 @@
 // Lazy Exception Utilities
 
 // Note: Function runs from unwindable area before exception throwing
-// function can be safe point & should be called with disable reqursion = 1
+// function can be safe point & should be called with disable recursion = 1
 static ManagedObject *create_lazy_exception(
     Class_Handle exn_class,
     Method_Handle exn_constr,
@@ -311,9 +311,13 @@
 #endif // VM_STATS
 
                     if (restore_guard_page) {
-                        if (!check_stack_size_enough_for_exception_catch(si_get_sp(si))) {
+                        bool res = check_stack_size_enough_for_exception_catch(si_get_sp(si));
+                        //must always be enough. otherwise program behavior is unspecified: finally blocks, monitor exits are not executed
+                        assert(res); 
+                        if (!res) {
                             break;
                         }
+
                     }
 
                     // Setup handler context
@@ -374,8 +378,14 @@
                 }
             }
 
+            
             // No appropriate handler found, undo synchronization
-            vm_monitor_exit_synchronized_method(si);
+
+            // Contract with JIT: check SOE for synchronized methods before monenter
+            // So if SOE happens in synchronized method -> no need to call monexit
+            if (!restore_guard_page) {
+                vm_monitor_exit_synchronized_method(si);
+            }
 
             BEGIN_RAISE_AREA;
             jvalue ret_val = {(jlong)0};