Mercurial > hg > graal-jvmci-8
diff src/share/vm/classfile/verifier.cpp @ 22893:695017a614d5
8075118: JVM stuck in infinite loop during verification
Summary: keep a list of handlers to prevent the same handler from being scanned repeatedly.
Reviewed-by: dlong, dholmes
author | hseigel |
---|---|
date | Thu, 19 Mar 2015 08:55:50 -0400 |
parents | ecdf1e03db40 |
children | 6b65121b3258 |
line wrap: on
line diff
--- a/src/share/vm/classfile/verifier.cpp Fri Mar 20 09:20:57 2015 -0700 +++ b/src/share/vm/classfile/verifier.cpp Thu Mar 19 08:55:50 2015 -0400 @@ -2232,14 +2232,20 @@ } // Look at the method's handlers. If the bci is in the handler's try block -// then check if the handler_pc is already on the stack. If not, push it. +// then check if the handler_pc is already on the stack. If not, push it +// unless the handler has already been scanned. void ClassVerifier::push_handlers(ExceptionTable* exhandlers, + GrowableArray<u4>* handler_list, GrowableArray<u4>* handler_stack, u4 bci) { int exlength = exhandlers->length(); for(int x = 0; x < exlength; x++) { if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) { - handler_stack->append_if_missing(exhandlers->handler_pc(x)); + u4 exhandler_pc = exhandlers->handler_pc(x); + if (!handler_list->contains(exhandler_pc)) { + handler_stack->append_if_missing(exhandler_pc); + handler_list->append(exhandler_pc); + } } } } @@ -2257,6 +2263,10 @@ GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30); // Create stack for handlers for try blocks containing this handler. GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30); + // Create list of handlers that have been pushed onto the handler_stack + // so that handlers embedded inside of their own TRY blocks only get + // scanned once. + GrowableArray<u4>* handler_list = new GrowableArray<u4>(30); // Create list of visited branch opcodes (goto* and if*). GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30); ExceptionTable exhandlers(_method()); @@ -2275,7 +2285,7 @@ // If the bytecode is in a TRY block, push its handlers so they // will get parsed. - push_handlers(&exhandlers, handler_stack, bci); + push_handlers(&exhandlers, handler_list, handler_stack, bci); switch (opcode) { case Bytecodes::_if_icmpeq: