# HG changeset patch # User Thomas Wuerthinger # Date 1330126834 -3600 # Node ID 07bcee8b70a46eaf0c7eadfe0d6723e07d16e8be # Parent 9d48ccb3929230c17b16f88883746034e7305b43 Simplify exception debug information and exception handler table creation based on Graal's simplified model of exception handler information (i.e. the dispatch is done in compiled code). diff -r 9d48ccb39292 -r 07bcee8b70a4 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTargetMethod.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTargetMethod.java Fri Feb 24 22:32:43 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTargetMethod.java Sat Feb 25 00:40:34 2012 +0100 @@ -309,24 +309,16 @@ * */ private static final long serialVersionUID = 4897339464722665281L; - public final int bci; - public final int scopeLevel; public final int handlerPos; - public final int handlerBci; - public final RiType exceptionType; - ExceptionHandler(int pcOffset, int bci, int scopeLevel, int handlerPos, int handlerBci, RiType exceptionType) { + ExceptionHandler(int pcOffset, int handlerPos) { super(pcOffset); - this.bci = bci; - this.scopeLevel = scopeLevel; this.handlerPos = handlerPos; - this.handlerBci = handlerBci; - this.exceptionType = exceptionType; } @Override public String toString() { - return String.format("%d[]", pcOffset, handlerPos, (exceptionType == null) ? "null" : exceptionType); + return String.format("%d[]", pcOffset, handlerPos); } } @@ -461,8 +453,8 @@ * @param handlerPos the position of the handler * @param throwableType the type of exceptions handled by the handler */ - public void recordExceptionHandler(int codePos, int bci, int scopeLevel, int handlerPos, int handlerBci, RiType throwableType) { - exceptionHandlers.add(new ExceptionHandler(codePos, bci, scopeLevel, handlerPos, handlerBci, throwableType)); + public void recordExceptionHandler(int codePos, int handlerPos) { + exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos)); } /** diff -r 9d48ccb39292 -r 07bcee8b70a4 graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java Fri Feb 24 22:32:43 2012 +0100 +++ b/graal/com.oracle.max.graal.lir/src/com/oracle/max/graal/lir/asm/TargetMethodAssembler.java Sat Feb 25 00:40:34 2012 +0100 @@ -87,7 +87,7 @@ if (exceptionInfoList != null) { for (ExceptionInfo ei : exceptionInfoList) { int codeOffset = ei.codeOffset; - targetMethod.recordExceptionHandler(codeOffset, -1, 0, ei.exceptionEdge.label().position(), -1, null); + targetMethod.recordExceptionHandler(codeOffset, ei.exceptionEdge.label().position()); } } diff -r 9d48ccb39292 -r 07bcee8b70a4 src/share/vm/code/exceptionHandlerTable.hpp --- a/src/share/vm/code/exceptionHandlerTable.hpp Fri Feb 24 22:32:43 2012 +0100 +++ b/src/share/vm/code/exceptionHandlerTable.hpp Sat Feb 25 00:40:34 2012 +0100 @@ -88,12 +88,12 @@ int _length; // the current length of the table int _size; // the number of allocated entries ReallocMark _nesting; // assertion check for reallocations - + + public: // add the entry & grow the table if needed void add_entry(HandlerTableEntry entry); HandlerTableEntry* subtable_for(int catch_pco) const; - public: // (compile-time) construction within compiler ExceptionHandlerTable(int initial_size = 8); diff -r 9d48ccb39292 -r 07bcee8b70a4 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Feb 24 22:32:43 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Sat Feb 25 00:40:34 2012 +0100 @@ -415,55 +415,17 @@ if (_exception_handlers != NULL) { oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT); for (int i = 0; i < _exception_handlers->length(); i++) { - jint pc_offset = CiTargetMethod_Site::pcOffset(exception_handlers[i]); - int start = i; - while ((i + 1) < _exception_handlers->length() && CiTargetMethod_Site::pcOffset(exception_handlers[i + 1]) == pc_offset) - i++; - - // empty the arrays - bcis->trunc_to(0); - scope_depths->trunc_to(0); - pcos->trunc_to(0); - - for (int j = start; j <= i; j++) { - oop exc = exception_handlers[j]; - jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc); - jint handler_bci = CiTargetMethod_ExceptionHandler::handlerBci(exc); - jint scope_level = CiTargetMethod_ExceptionHandler::scopeLevel(exc); - - assert(handler_offset != -1, "must have been generated"); + oop exc = exception_handlers[i]; + jint pc_offset = CiTargetMethod_Site::pcOffset(exc); + jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc); - int e = bcis->find(handler_bci); - if (e >= 0 && scope_depths->at(e) == scope_level) { - // two different handlers are declared to dispatch to the same - // catch bci. During parsing we created edges for each - // handler but we really only need one. The exception handler - // table will also get unhappy if we try to declare both since - // it's nonsensical. Just skip this handler. - continue; - } + // Subtable header + _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); - bcis->append(handler_bci); - if (handler_bci == -1) { - // insert a wildcard handler at scope depth 0 so that the - // exception lookup logic with find it. - scope_depths->append(0); - } else { - scope_depths->append(scope_level); - } - pcos->append(handler_offset); - - // TODO: Check if we need that assert! - // stop processing once we hit a catch any - // if (handler->is_catch_all()) { - // assert(i == handlers->length() - 1, "catch all must be last handler"); - // } - - } - _exception_handler_table.add_subtable(pc_offset, bcis, scope_depths, pcos); + // Subtable entry + _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0)); } } - } void CodeInstaller::record_scope(jint pc_offset, oop code_pos, GrowableArray* objects) { diff -r 9d48ccb39292 -r 07bcee8b70a4 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Fri Feb 24 22:32:43 2012 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Sat Feb 25 00:40:34 2012 +0100 @@ -143,8 +143,6 @@ end_class \ start_class(CiTargetMethod_ExceptionHandler) \ int_field(CiTargetMethod_ExceptionHandler, handlerPos) \ - int_field(CiTargetMethod_ExceptionHandler, handlerBci) \ - int_field(CiTargetMethod_ExceptionHandler, scopeLevel) \ end_class \ start_class(CiTargetMethod_Mark) \ oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;") \ diff -r 9d48ccb39292 -r 07bcee8b70a4 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Fri Feb 24 22:32:43 2012 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Sat Feb 25 00:40:34 2012 +0100 @@ -127,38 +127,27 @@ // Now the expressions off-stack // Same silliness as above - bool rethrow_exception = vf->scope()->rethrow_exception(); - if (rethrow_exception) { - // (tw) Make sure there are only null pointers on the stack, because the stack values do not correspond to the GC map at the bytecode at which the exception is rethrown. - // TODO: Fix this! Locals map might be wrong too. - _expressions = new StackValueCollection(vf->method()->max_stack()); - assert(Thread::current()->has_pending_exception(), "just checking"); - for (int i=0; imethod()->max_stack(); ++i) { - _expressions->add( new StackValue()); - } - } else { - StackValueCollection *exprs = vf->expressions(); - _expressions = new StackValueCollection(exprs->size()); - for(index = 0; index < exprs->size(); index++) { - StackValue* value = exprs->at(index); - switch(value->type()) { - case T_OBJECT: - assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); - // preserve object type - _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); - break; - case T_CONFLICT: - // A dead stack element. Will be initialized to null/zero. - // This can occur when the compiler emits a state in which stack - // elements are known to be dead (because of an imminent exception). - _expressions->add( new StackValue()); - break; - case T_INT: - _expressions->add( new StackValue(value->get_int())); - break; - default: - ShouldNotReachHere(); - } + StackValueCollection *exprs = vf->expressions(); + _expressions = new StackValueCollection(exprs->size()); + for(index = 0; index < exprs->size(); index++) { + StackValue* value = exprs->at(index); + switch(value->type()) { + case T_OBJECT: + assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); + // preserve object type + _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); + break; + case T_CONFLICT: + // A dead stack element. Will be initialized to null/zero. + // This can occur when the compiler emits a state in which stack + // elements are known to be dead (because of an imminent exception). + _expressions->add( new StackValue()); + break; + case T_INT: + _expressions->add( new StackValue(value->get_int())); + break; + default: + ShouldNotReachHere(); } } }