comparison 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
comparison
equal deleted inserted replaced
22892:951689652d2c 22893:695017a614d5
2230 default: ShouldNotReachHere(); 2230 default: ShouldNotReachHere();
2231 } 2231 }
2232 } 2232 }
2233 2233
2234 // Look at the method's handlers. If the bci is in the handler's try block 2234 // Look at the method's handlers. If the bci is in the handler's try block
2235 // then check if the handler_pc is already on the stack. If not, push it. 2235 // then check if the handler_pc is already on the stack. If not, push it
2236 // unless the handler has already been scanned.
2236 void ClassVerifier::push_handlers(ExceptionTable* exhandlers, 2237 void ClassVerifier::push_handlers(ExceptionTable* exhandlers,
2238 GrowableArray<u4>* handler_list,
2237 GrowableArray<u4>* handler_stack, 2239 GrowableArray<u4>* handler_stack,
2238 u4 bci) { 2240 u4 bci) {
2239 int exlength = exhandlers->length(); 2241 int exlength = exhandlers->length();
2240 for(int x = 0; x < exlength; x++) { 2242 for(int x = 0; x < exlength; x++) {
2241 if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) { 2243 if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) {
2242 handler_stack->append_if_missing(exhandlers->handler_pc(x)); 2244 u4 exhandler_pc = exhandlers->handler_pc(x);
2245 if (!handler_list->contains(exhandler_pc)) {
2246 handler_stack->append_if_missing(exhandler_pc);
2247 handler_list->append(exhandler_pc);
2248 }
2243 } 2249 }
2244 } 2250 }
2245 } 2251 }
2246 2252
2247 // Return TRUE if all code paths starting with start_bc_offset end in 2253 // Return TRUE if all code paths starting with start_bc_offset end in
2255 u4 target; 2261 u4 target;
2256 // Create stack for storing bytecode start offsets for if* and *switch. 2262 // Create stack for storing bytecode start offsets for if* and *switch.
2257 GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30); 2263 GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30);
2258 // Create stack for handlers for try blocks containing this handler. 2264 // Create stack for handlers for try blocks containing this handler.
2259 GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30); 2265 GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30);
2266 // Create list of handlers that have been pushed onto the handler_stack
2267 // so that handlers embedded inside of their own TRY blocks only get
2268 // scanned once.
2269 GrowableArray<u4>* handler_list = new GrowableArray<u4>(30);
2260 // Create list of visited branch opcodes (goto* and if*). 2270 // Create list of visited branch opcodes (goto* and if*).
2261 GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30); 2271 GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30);
2262 ExceptionTable exhandlers(_method()); 2272 ExceptionTable exhandlers(_method());
2263 2273
2264 while (true) { 2274 while (true) {
2273 Bytecodes::Code opcode = bcs.raw_next(); 2283 Bytecodes::Code opcode = bcs.raw_next();
2274 u4 bci = bcs.bci(); 2284 u4 bci = bcs.bci();
2275 2285
2276 // If the bytecode is in a TRY block, push its handlers so they 2286 // If the bytecode is in a TRY block, push its handlers so they
2277 // will get parsed. 2287 // will get parsed.
2278 push_handlers(&exhandlers, handler_stack, bci); 2288 push_handlers(&exhandlers, handler_list, handler_stack, bci);
2279 2289
2280 switch (opcode) { 2290 switch (opcode) {
2281 case Bytecodes::_if_icmpeq: 2291 case Bytecodes::_if_icmpeq:
2282 case Bytecodes::_if_icmpne: 2292 case Bytecodes::_if_icmpne:
2283 case Bytecodes::_if_icmplt: 2293 case Bytecodes::_if_icmplt: