8028347: Rewriter::scan_method asserts with array oob in RT_Baseline

Fri, 15 Nov 2013 17:20:22 -0500

author
coleenp
date
Fri, 15 Nov 2013 17:20:22 -0500
changeset 6121
d61a1a166f44
parent 6120
438fe38c63c8
child 6122
0b9ea9a72436

8028347: Rewriter::scan_method asserts with array oob in RT_Baseline
Summary: Fix reversing rewriting for invokespecial
Reviewed-by: jrose, hseigel

src/share/vm/interpreter/rewriter.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/rewriter.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/interpreter/rewriter.cpp	Fri Nov 15 21:39:27 2013 +0100
     1.2 +++ b/src/share/vm/interpreter/rewriter.cpp	Fri Nov 15 17:20:22 2013 -0500
     1.3 @@ -70,12 +70,14 @@
     1.4  }
     1.5  
     1.6  // Unrewrite the bytecodes if an error occurs.
     1.7 -void Rewriter::restore_bytecodes(TRAPS) {
     1.8 +void Rewriter::restore_bytecodes() {
     1.9    int len = _methods->length();
    1.10 +  bool invokespecial_error = false;
    1.11  
    1.12    for (int i = len-1; i >= 0; i--) {
    1.13      Method* method = _methods->at(i);
    1.14 -    scan_method(method, true, CHECK);
    1.15 +    scan_method(method, true, &invokespecial_error);
    1.16 +    assert(!invokespecial_error, "reversing should not get an invokespecial error");
    1.17    }
    1.18  }
    1.19  
    1.20 @@ -160,22 +162,21 @@
    1.21  // These cannot share cpCache entries.  It's unclear if all invokespecial to
    1.22  // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry
    1.23  // is created for each one.  This was added with lambda.
    1.24 -void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS) {
    1.25 -  static int count = 0;
    1.26 +void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
    1.27    address p = bcp + offset;
    1.28    if (!reverse) {
    1.29      int cp_index = Bytes::get_Java_u2(p);
    1.30 +    if (_pool->tag_at(cp_index).is_interface_method()) {
    1.31      int cache_index = add_invokespecial_cp_cache_entry(cp_index);
    1.32      if (cache_index != (int)(jushort) cache_index) {
    1.33 -      THROW_MSG(vmSymbols::java_lang_InternalError(),
    1.34 -                "This classfile overflows invokespecial for interfaces "
    1.35 -                "and cannot be loaded");
    1.36 +      *invokespecial_error = true;
    1.37      }
    1.38      Bytes::put_native_u2(p, cache_index);
    1.39    } else {
    1.40 -    int cache_index = Bytes::get_native_u2(p);
    1.41 -    int cp_index = cp_cache_entry_pool_index(cache_index);
    1.42 -    Bytes::put_Java_u2(p, cp_index);
    1.43 +      rewrite_member_reference(bcp, offset, reverse);
    1.44 +    }
    1.45 +  } else {
    1.46 +    rewrite_member_reference(bcp, offset, reverse);
    1.47    }
    1.48  }
    1.49  
    1.50 @@ -329,7 +330,7 @@
    1.51  
    1.52  
    1.53  // Rewrites a method given the index_map information
    1.54 -void Rewriter::scan_method(Method* method, bool reverse, TRAPS) {
    1.55 +void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_error) {
    1.56  
    1.57    int nof_jsrs = 0;
    1.58    bool has_monitor_bytecodes = false;
    1.59 @@ -391,15 +392,7 @@
    1.60          }
    1.61  
    1.62          case Bytecodes::_invokespecial  : {
    1.63 -          int offset = prefix_length + 1;
    1.64 -          address p = bcp + offset;
    1.65 -          int cp_index = Bytes::get_Java_u2(p);
    1.66 -          // InterfaceMethodref
    1.67 -          if (_pool->tag_at(cp_index).is_interface_method()) {
    1.68 -            rewrite_invokespecial(bcp, offset, reverse, CHECK);
    1.69 -          } else {
    1.70 -            rewrite_member_reference(bcp, offset, reverse);
    1.71 -          }
    1.72 +          rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);
    1.73            break;
    1.74          }
    1.75  
    1.76 @@ -496,11 +489,20 @@
    1.77  
    1.78    // rewrite methods, in two passes
    1.79    int len = _methods->length();
    1.80 +  bool invokespecial_error = false;
    1.81  
    1.82    for (int i = len-1; i >= 0; i--) {
    1.83      Method* method = _methods->at(i);
    1.84 -    scan_method(method, false, CHECK);  // If you get an error here,
    1.85 -                                        // there is no reversing bytecodes
    1.86 +    scan_method(method, false, &invokespecial_error);
    1.87 +    if (invokespecial_error) {
    1.88 +      // If you get an error here, there is no reversing bytecodes
    1.89 +      // This exception is stored for this class and no further attempt is
    1.90 +      // made at verifying or rewriting.
    1.91 +      THROW_MSG(vmSymbols::java_lang_InternalError(),
    1.92 +                "This classfile overflows invokespecial for interfaces "
    1.93 +                "and cannot be loaded");
    1.94 +      return;
    1.95 +     }
    1.96    }
    1.97  
    1.98    // May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref
    1.99 @@ -513,7 +515,7 @@
   1.100    // Restore bytecodes to their unrewritten state if there are exceptions
   1.101    // rewriting bytecodes or allocating the cpCache
   1.102    if (HAS_PENDING_EXCEPTION) {
   1.103 -    restore_bytecodes(CATCH);
   1.104 +    restore_bytecodes();
   1.105      return;
   1.106    }
   1.107  
   1.108 @@ -530,7 +532,7 @@
   1.109        // relocating bytecodes.  If some are relocated, that is ok because that
   1.110        // doesn't affect constant pool to cpCache rewriting.
   1.111        if (HAS_PENDING_EXCEPTION) {
   1.112 -        restore_bytecodes(CATCH);
   1.113 +        restore_bytecodes();
   1.114          return;
   1.115        }
   1.116        // Method might have gotten rewritten.
     2.1 --- a/src/share/vm/interpreter/rewriter.hpp	Fri Nov 15 21:39:27 2013 +0100
     2.2 +++ b/src/share/vm/interpreter/rewriter.hpp	Fri Nov 15 17:20:22 2013 -0500
     2.3 @@ -189,18 +189,18 @@
     2.4  
     2.5    void compute_index_maps();
     2.6    void make_constant_pool_cache(TRAPS);
     2.7 -  void scan_method(Method* m, bool reverse, TRAPS);
     2.8 +  void scan_method(Method* m, bool reverse, bool* invokespecial_error);
     2.9    void rewrite_Object_init(methodHandle m, TRAPS);
    2.10    void rewrite_member_reference(address bcp, int offset, bool reverse);
    2.11    void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
    2.12    void rewrite_invokedynamic(address bcp, int offset, bool reverse);
    2.13    void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse);
    2.14 -  void rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS);
    2.15 +  void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error);
    2.16  
    2.17    void patch_invokedynamic_bytecodes();
    2.18  
    2.19    // Revert bytecodes in case of an exception.
    2.20 -  void restore_bytecodes(TRAPS);
    2.21 +  void restore_bytecodes();
    2.22  
    2.23    static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
    2.24   public:

mercurial