Mercurial > hg > shark > hotspot
changeset 1538:48889816f448
Try again
author | Gary Benson <gbenson@redhat.com> |
---|---|
date | Wed, 19 May 2010 13:09:40 +0100 |
parents | 6fd1ffad34e2 |
children | 3b5edc5db51a |
files | src/share/vm/shark/sharkInvariants.hpp src/share/vm/shark/sharkTopLevelBlock.cpp src/share/vm/shark/sharkTopLevelBlock.hpp |
diffstat | 3 files changed, 135 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/shark/sharkInvariants.hpp Tue May 18 15:39:15 2010 +0100 +++ b/src/share/vm/shark/sharkInvariants.hpp Wed May 19 13:09:40 2010 +0100 @@ -93,11 +93,14 @@ return builder()->code_buffer(); } - // That well-known class... + // Commonly used classes protected: ciInstanceKlass* java_lang_Object_klass() const { return env()->Object_klass(); } + ciInstanceKlass* java_lang_Throwable_klass() const { + return env()->Throwable_klass(); + } }; class SharkTargetInvariants : public SharkCompileInvariants {
--- a/src/share/vm/shark/sharkTopLevelBlock.cpp Tue May 18 15:39:15 2010 +0100 +++ b/src/share/vm/shark/sharkTopLevelBlock.cpp Wed May 19 13:09:40 2010 +0100 @@ -221,8 +221,11 @@ successor(i)->enter(this, false); } } + compute_exceptions(); for (int i = 0; i < num_exceptions(); i++) { - exception(i)->enter(this, true); + SharkTopLevelBlock *handler = exception(i); + if (handler) + handler->enter(this, true); } } } @@ -438,84 +441,123 @@ builder()->SetInsertPoint(no_exception); } -void SharkTopLevelBlock::handle_exception(Value* exception, int action) { - if (action & EAM_HANDLE) { - // Build a list of exception handlers for this block - ciExceptionHandlerStream str(target(), bci()); - GrowableArray<ciExceptionHandler*>* handlers = - new GrowableArray<ciExceptionHandler*>(str.count()); - for (; !str.is_done(); str.next()) { - ciExceptionHandler* handler = str.handler(); - if (handler->handler_bci() == -1) +void SharkTopLevelBlock::compute_exceptions() { + ciExceptionHandlerStream str(target(), start()); + + int exc_count = str.count(); + _exc_handlers = new GrowableArray<ciExceptionHandler*>(exc_count); + _exceptions = new GrowableArray<SharkTopLevelBlock*>(exc_count); + + int index = 0; + for (; !str.is_done(); str.next()) { + ciExceptionHandler *handler = str.handler(); + if (handler->handler_bci() == -1) + break; + _exc_handlers->append(handler); + + // Try and get this exception's handler from typeflow + SharkTopLevelBlock *block = NULL; + ciInstanceKlass* klass; + if (handler->is_catch_all()) { + klass = java_lang_Throwable_klass(); + } + else { + klass = handler->catch_klass(); + } + for (int i = 0; i < ciblock()->exceptions()->length(); i++) { + if (klass == ciblock()->exc_klasses()->at(i)) { + block = function()->block(ciblock()->exceptions()->at(i)->pre_order()); + assert(block->start() == handler->handler_bci(), "should do"); break; - handlers->append(handler); + } } - if (handlers->length() != 0) { - // Clear the stack and push the exception onto it. - // We do this now to protect it across the VM call - // we may be about to make. - while (xstack_depth()) - pop(); - push(SharkValue::create_jobject(exception, true)); - - int *indexes = NEW_RESOURCE_ARRAY(int, num_exceptions()); - bool has_catch_all = false; - - ciExceptionHandlerStream eh_iter(target(), bci()); - for (int i = 0; i < num_exceptions(); i++, eh_iter.next()) { - ciExceptionHandler* handler = eh_iter.handler(); - - if (handler->is_catch_all()) { - assert(i == num_exceptions() - 1, "catch-all should be last"); - has_catch_all = true; - } - else { - indexes[i] = handler->catch_klass_index(); + // If typeflow let us down then try and figure it out ourselves + if (block == NULL) { + for (int i = 0; i < function()->block_count(); i++) { + SharkTopLevelBlock *candidate = function()->block(i); + if (candidate->start() == handler->handler_bci()) { + if (block != NULL) { + NOT_PRODUCT(warning("there may be trouble ahead")); + block = NULL; + break; + } + block = candidate; } } - - int num_options = num_exceptions(); - if (has_catch_all) - num_options--; - - // Drop into the runtime if there are non-catch-all options - if (num_options > 0) { - Value *index = call_vm( - builder()->find_exception_handler(), - builder()->CreateInlineData( - indexes, - num_options * sizeof(int), - PointerType::getUnqual(SharkType::jint_type())), - LLVMValue::jint_constant(num_options), - EX_CHECK_NO_CATCH); - - // Jump to the exception handler, if found - BasicBlock *no_handler = function()->CreateBlock("no_handler"); - SwitchInst *switchinst = builder()->CreateSwitch( - index, no_handler, num_options); - - for (int i = 0; i < num_options; i++) { - SharkTopLevelBlock* handler = this->exception(i); - - switchinst->addCase( - LLVMValue::jint_constant(i), - handler->entry_block()); - - handler->add_incoming(current_state()); - } - - builder()->SetInsertPoint(no_handler); + } + _exceptions->append(block); + } +} + +void SharkTopLevelBlock::handle_exception(Value* exception, int action) { + if (action & EAM_HANDLE && num_exceptions() != 0) { + // Clear the stack and push the exception onto it. + // We do this now to protect it across the VM call + // we may be about to make. + while (xstack_depth()) + pop(); + push(SharkValue::create_jobject(exception, true)); + + int *indexes = NEW_RESOURCE_ARRAY(int, num_exceptions()); + bool has_catch_all = false; + + ciExceptionHandlerStream eh_iter(target(), bci()); + for (int i = 0; i < num_exceptions(); i++, eh_iter.next()) { + ciExceptionHandler* handler = eh_iter.handler(); + + if (handler->is_catch_all()) { + assert(i == num_exceptions() - 1, "catch-all should be last"); + has_catch_all = true; + } + else { + indexes[i] = handler->catch_klass_index(); } - - // No specific handler exists, but maybe there's a catch-all - if (has_catch_all) { - SharkTopLevelBlock* handler = this->exception(num_options); - - builder()->CreateBr(handler->entry_block()); + } + + int num_options = num_exceptions(); + if (has_catch_all) + num_options--; + + // Drop into the runtime if there are non-catch-all options + if (num_options > 0) { + Value *index = call_vm( + builder()->find_exception_handler(), + builder()->CreateInlineData( + indexes, + num_options * sizeof(int), + PointerType::getUnqual(SharkType::jint_type())), + LLVMValue::jint_constant(num_options), + EX_CHECK_NO_CATCH); + + // Jump to the exception handler, if found + BasicBlock *no_handler = function()->CreateBlock("no_handler"); + SwitchInst *switchinst = builder()->CreateSwitch( + index, no_handler, num_options); + + for (int i = 0; i < num_options; i++) { + SharkTopLevelBlock* handler = this->exception(i); + if (handler == NULL) + Unimplemented(); + + switchinst->addCase( + LLVMValue::jint_constant(i), + handler->entry_block()); + handler->add_incoming(current_state()); - return; } + + builder()->SetInsertPoint(no_handler); + } + + // No specific handler exists, but maybe there's a catch-all + if (has_catch_all) { + SharkTopLevelBlock* handler = this->exception(num_options); + assert(handler, "no catch all handler?"); + + builder()->CreateBr(handler->entry_block()); + handler->add_incoming(current_state()); + return; } } @@ -592,7 +634,8 @@ } for (int i = 0; i < num_exceptions(); i++) { - if (exception(i)->can_reach_helper(other)) + SharkTopLevelBlock *handler = exception(i); + if (handler && handler->can_reach_helper(other)) return true; }
--- a/src/share/vm/shark/sharkTopLevelBlock.hpp Tue May 18 15:39:15 2010 +0100 +++ b/src/share/vm/shark/sharkTopLevelBlock.hpp Wed May 19 13:09:40 2010 +0100 @@ -79,12 +79,6 @@ bool falls_through() const { return ciblock()->control() == ciBlock::fall_through_bci; } - int num_exceptions() const { - return ciblock()->exceptions()->length(); - } - SharkTopLevelBlock* exception(int index) const { - return function()->block(ciblock()->exceptions()->at(index)->pre_order()); - } int num_successors() const { return ciblock()->successors()->length(); } @@ -93,6 +87,22 @@ } SharkTopLevelBlock* bci_successor(int bci) const; + // Exceptions + private: + GrowableArray<ciExceptionHandler*>* _exc_handlers; + GrowableArray<SharkTopLevelBlock*>* _exceptions; + + private: + void compute_exceptions(); + + private: + int num_exceptions() const { + return _exceptions->length(); + } + SharkTopLevelBlock* exception(int index) const { + return _exceptions->at(index); + } + // Traps private: bool _has_trap;