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};