@@ -2439,216 +2439,6 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
24392439 }
24402440}
24412441
2442- // Look at the method's handlers. If the bci is in the handler's try block
2443- // then check if the handler_pc is already on the stack. If not, push it
2444- // unless the handler has already been scanned.
2445- void ClassVerifier::push_handlers (ExceptionTable* exhandlers,
2446- GrowableArray<u4>* handler_list,
2447- GrowableArray<u4>* handler_stack,
2448- u4 bci) {
2449- int exlength = exhandlers->length ();
2450- for (int x = 0 ; x < exlength; x++) {
2451- if (bci >= exhandlers->start_pc (x) && bci < exhandlers->end_pc (x)) {
2452- u4 exhandler_pc = exhandlers->handler_pc (x);
2453- if (!handler_list->contains (exhandler_pc)) {
2454- handler_stack->append_if_missing (exhandler_pc);
2455- handler_list->append (exhandler_pc);
2456- }
2457- }
2458- }
2459- }
2460-
2461- // Return TRUE if all code paths starting with start_bc_offset end in
2462- // bytecode athrow or loop.
2463- bool ClassVerifier::ends_in_athrow (u4 start_bc_offset) {
2464- ResourceMark rm;
2465- // Create bytecode stream.
2466- RawBytecodeStream bcs (method ());
2467- u4 code_length = method ()->code_size ();
2468- bcs.set_start (start_bc_offset);
2469- u4 target;
2470- // Create stack for storing bytecode start offsets for if* and *switch.
2471- GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30 );
2472- // Create stack for handlers for try blocks containing this handler.
2473- GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30 );
2474- // Create list of handlers that have been pushed onto the handler_stack
2475- // so that handlers embedded inside of their own TRY blocks only get
2476- // scanned once.
2477- GrowableArray<u4>* handler_list = new GrowableArray<u4>(30 );
2478- // Create list of visited branch opcodes (goto* and if*).
2479- GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30 );
2480- ExceptionTable exhandlers (_method ());
2481-
2482- while (true ) {
2483- if (bcs.is_last_bytecode ()) {
2484- // if no more starting offsets to parse or if at the end of the
2485- // method then return false.
2486- if ((bci_stack->is_empty ()) || ((u4)bcs.end_bci () == code_length))
2487- return false ;
2488- // Pop a bytecode starting offset and scan from there.
2489- bcs.set_start (bci_stack->pop ());
2490- }
2491- Bytecodes::Code opcode = bcs.raw_next ();
2492- u4 bci = bcs.bci ();
2493-
2494- // If the bytecode is in a TRY block, push its handlers so they
2495- // will get parsed.
2496- push_handlers (&exhandlers, handler_list, handler_stack, bci);
2497-
2498- switch (opcode) {
2499- case Bytecodes::_if_icmpeq:
2500- case Bytecodes::_if_icmpne:
2501- case Bytecodes::_if_icmplt:
2502- case Bytecodes::_if_icmpge:
2503- case Bytecodes::_if_icmpgt:
2504- case Bytecodes::_if_icmple:
2505- case Bytecodes::_ifeq:
2506- case Bytecodes::_ifne:
2507- case Bytecodes::_iflt:
2508- case Bytecodes::_ifge:
2509- case Bytecodes::_ifgt:
2510- case Bytecodes::_ifle:
2511- case Bytecodes::_if_acmpeq:
2512- case Bytecodes::_if_acmpne:
2513- case Bytecodes::_ifnull:
2514- case Bytecodes::_ifnonnull:
2515- target = bcs.dest ();
2516- if (visited_branches->contains (bci)) {
2517- if (bci_stack->is_empty ()) {
2518- if (handler_stack->is_empty ()) {
2519- return true ;
2520- } else {
2521- // Parse the catch handlers for try blocks containing athrow.
2522- bcs.set_start (handler_stack->pop ());
2523- }
2524- } else {
2525- // Pop a bytecode starting offset and scan from there.
2526- bcs.set_start (bci_stack->pop ());
2527- }
2528- } else {
2529- if (target > bci) { // forward branch
2530- if (target >= code_length) return false ;
2531- // Push the branch target onto the stack.
2532- bci_stack->push (target);
2533- // then, scan bytecodes starting with next.
2534- bcs.set_start (bcs.next_bci ());
2535- } else { // backward branch
2536- // Push bytecode offset following backward branch onto the stack.
2537- bci_stack->push (bcs.next_bci ());
2538- // Check bytecodes starting with branch target.
2539- bcs.set_start (target);
2540- }
2541- // Record target so we don't branch here again.
2542- visited_branches->append (bci);
2543- }
2544- break ;
2545-
2546- case Bytecodes::_goto:
2547- case Bytecodes::_goto_w: {
2548- int offset = (opcode == Bytecodes::_goto ? bcs.get_offset_s2 () : bcs.get_offset_s4 ());
2549- int min_offset = -1 * max_method_code_size;
2550- // Check offset for overflow
2551- if (offset < min_offset || offset > max_method_code_size) return false ;
2552-
2553- target = bci + offset;
2554- if (visited_branches->contains (bci)) {
2555- if (bci_stack->is_empty ()) {
2556- if (handler_stack->is_empty ()) {
2557- return true ;
2558- } else {
2559- // Parse the catch handlers for try blocks containing athrow.
2560- bcs.set_start (handler_stack->pop ());
2561- }
2562- } else {
2563- // Been here before, pop new starting offset from stack.
2564- bcs.set_start (bci_stack->pop ());
2565- }
2566- } else {
2567- if (target >= code_length) return false ;
2568- // Continue scanning from the target onward.
2569- bcs.set_start (target);
2570- // Record target so we don't branch here again.
2571- visited_branches->append (bci);
2572- }
2573- break ;
2574- }
2575-
2576- // Check that all switch alternatives end in 'athrow' bytecodes. Since it
2577- // is difficult to determine where each switch alternative ends, parse
2578- // each switch alternative until either hit a 'return', 'athrow', or reach
2579- // the end of the method's bytecodes. This is gross but should be okay
2580- // because:
2581- // 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
2582- // constructor invocations should be rare.
2583- // 2. if each switch alternative ends in an athrow then the parsing should be
2584- // short. If there is no athrow then it is bogus code, anyway.
2585- case Bytecodes::_lookupswitch:
2586- case Bytecodes::_tableswitch:
2587- {
2588- address aligned_bcp = align_up (bcs.bcp () + 1 , jintSize);
2589- u4 default_offset = Bytes::get_Java_u4 (aligned_bcp) + bci;
2590- int keys, delta;
2591- if (opcode == Bytecodes::_tableswitch) {
2592- jint low = (jint)Bytes::get_Java_u4 (aligned_bcp + jintSize);
2593- jint high = (jint)Bytes::get_Java_u4 (aligned_bcp + 2 *jintSize);
2594- // This is invalid, but let the regular bytecode verifier
2595- // report this because the user will get a better error message.
2596- if (low > high) return true ;
2597- keys = high - low + 1 ;
2598- delta = 1 ;
2599- } else {
2600- keys = (int )Bytes::get_Java_u4 (aligned_bcp + jintSize);
2601- delta = 2 ;
2602- }
2603- // Invalid, let the regular bytecode verifier deal with it.
2604- if (keys < 0 ) return true ;
2605-
2606- // Push the offset of the next bytecode onto the stack.
2607- bci_stack->push (bcs.next_bci ());
2608-
2609- // Push the switch alternatives onto the stack.
2610- for (int i = 0 ; i < keys; i++) {
2611- int min_offset = -1 * max_method_code_size;
2612- int offset = (jint)Bytes::get_Java_u4 (aligned_bcp+(3 +i*delta)*jintSize);
2613- if (offset < min_offset || offset > max_method_code_size) return false ;
2614- u4 target = bci + offset;
2615- if (target > code_length) return false ;
2616- bci_stack->push (target);
2617- }
2618-
2619- // Start bytecode parsing for the switch at the default alternative.
2620- if (default_offset > code_length) return false ;
2621- bcs.set_start (default_offset);
2622- break ;
2623- }
2624-
2625- case Bytecodes::_return:
2626- return false ;
2627-
2628- case Bytecodes::_athrow:
2629- {
2630- if (bci_stack->is_empty ()) {
2631- if (handler_stack->is_empty ()) {
2632- return true ;
2633- } else {
2634- // Parse the catch handlers for try blocks containing athrow.
2635- bcs.set_start (handler_stack->pop ());
2636- }
2637- } else {
2638- // Pop a bytecode offset and starting scanning from there.
2639- bcs.set_start (bci_stack->pop ());
2640- }
2641- }
2642- break ;
2643-
2644- default :
2645- ;
2646- } // end switch
2647- } // end while loop
2648-
2649- return false ;
2650- }
2651-
26522442void ClassVerifier::verify_invoke_init (
26532443 RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
26542444 StackMapFrame* current_frame, u4 code_length, bool in_try_block,
@@ -2673,25 +2463,6 @@ void ClassVerifier::verify_invoke_init(
26732463 // sure that all catch clause paths end in a throw. Otherwise, this can
26742464 // result in returning an incomplete object.
26752465 if (in_try_block) {
2676- ExceptionTable exhandlers (_method ());
2677- int exlength = exhandlers.length ();
2678- for (int i = 0 ; i < exlength; i++) {
2679- u2 start_pc = exhandlers.start_pc (i);
2680- u2 end_pc = exhandlers.end_pc (i);
2681-
2682- if (bci >= start_pc && bci < end_pc) {
2683- if (!ends_in_athrow (exhandlers.handler_pc (i))) {
2684- verify_error (ErrorContext::bad_code (bci),
2685- " Bad <init> method call from after the start of a try block" );
2686- return ;
2687- } else if (log_is_enabled (Debug, verification)) {
2688- ResourceMark rm (THREAD);
2689- log_debug (verification)(" Survived call to ends_in_athrow(): %s" ,
2690- current_class ()->name ()->as_C_string ());
2691- }
2692- }
2693- }
2694-
26952466 // Check the exception handler target stackmaps with the locals from the
26962467 // incoming stackmap (before initialize_object() changes them to outgoing
26972468 // state).
0 commit comments