Fri, 15 Nov 2013 17:20:22 -0500
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: