changeset 13390:d61a1a166f44

8028347: Rewriter::scan_method asserts with array oob in RT_Baseline Summary: Fix reversing rewriting for invokespecial Reviewed-by: jrose, hseigel
author coleenp
date Fri, 15 Nov 2013 17:20:22 -0500
parents 438fe38c63c8
children 0b9ea9a72436
files src/share/vm/interpreter/rewriter.cpp src/share/vm/interpreter/rewriter.hpp
diffstat 2 files changed, 29 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/rewriter.cpp	Fri Nov 15 21:39:27 2013 +0100
+++ b/src/share/vm/interpreter/rewriter.cpp	Fri Nov 15 17:20:22 2013 -0500
@@ -70,12 +70,14 @@
 }
 
 // Unrewrite the bytecodes if an error occurs.
-void Rewriter::restore_bytecodes(TRAPS) {
+void Rewriter::restore_bytecodes() {
   int len = _methods->length();
+  bool invokespecial_error = false;
 
   for (int i = len-1; i >= 0; i--) {
     Method* method = _methods->at(i);
-    scan_method(method, true, CHECK);
+    scan_method(method, true, &invokespecial_error);
+    assert(!invokespecial_error, "reversing should not get an invokespecial error");
   }
 }
 
@@ -160,22 +162,21 @@
 // These cannot share cpCache entries.  It's unclear if all invokespecial to
 // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry
 // is created for each one.  This was added with lambda.
-void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS) {
-  static int count = 0;
+void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
   address p = bcp + offset;
   if (!reverse) {
     int cp_index = Bytes::get_Java_u2(p);
+    if (_pool->tag_at(cp_index).is_interface_method()) {
     int cache_index = add_invokespecial_cp_cache_entry(cp_index);
     if (cache_index != (int)(jushort) cache_index) {
-      THROW_MSG(vmSymbols::java_lang_InternalError(),
-                "This classfile overflows invokespecial for interfaces "
-                "and cannot be loaded");
+      *invokespecial_error = true;
     }
     Bytes::put_native_u2(p, cache_index);
   } else {
-    int cache_index = Bytes::get_native_u2(p);
-    int cp_index = cp_cache_entry_pool_index(cache_index);
-    Bytes::put_Java_u2(p, cp_index);
+      rewrite_member_reference(bcp, offset, reverse);
+    }
+  } else {
+    rewrite_member_reference(bcp, offset, reverse);
   }
 }
 
@@ -329,7 +330,7 @@
 
 
 // Rewrites a method given the index_map information
-void Rewriter::scan_method(Method* method, bool reverse, TRAPS) {
+void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_error) {
 
   int nof_jsrs = 0;
   bool has_monitor_bytecodes = false;
@@ -391,15 +392,7 @@
         }
 
         case Bytecodes::_invokespecial  : {
-          int offset = prefix_length + 1;
-          address p = bcp + offset;
-          int cp_index = Bytes::get_Java_u2(p);
-          // InterfaceMethodref
-          if (_pool->tag_at(cp_index).is_interface_method()) {
-            rewrite_invokespecial(bcp, offset, reverse, CHECK);
-          } else {
-            rewrite_member_reference(bcp, offset, reverse);
-          }
+          rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);
           break;
         }
 
@@ -496,11 +489,20 @@
 
   // rewrite methods, in two passes
   int len = _methods->length();
+  bool invokespecial_error = false;
 
   for (int i = len-1; i >= 0; i--) {
     Method* method = _methods->at(i);
-    scan_method(method, false, CHECK);  // If you get an error here,
-                                        // there is no reversing bytecodes
+    scan_method(method, false, &invokespecial_error);
+    if (invokespecial_error) {
+      // If you get an error here, there is no reversing bytecodes
+      // This exception is stored for this class and no further attempt is
+      // made at verifying or rewriting.
+      THROW_MSG(vmSymbols::java_lang_InternalError(),
+                "This classfile overflows invokespecial for interfaces "
+                "and cannot be loaded");
+      return;
+     }
   }
 
   // May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref
@@ -513,7 +515,7 @@
   // Restore bytecodes to their unrewritten state if there are exceptions
   // rewriting bytecodes or allocating the cpCache
   if (HAS_PENDING_EXCEPTION) {
-    restore_bytecodes(CATCH);
+    restore_bytecodes();
     return;
   }
 
@@ -530,7 +532,7 @@
       // relocating bytecodes.  If some are relocated, that is ok because that
       // doesn't affect constant pool to cpCache rewriting.
       if (HAS_PENDING_EXCEPTION) {
-        restore_bytecodes(CATCH);
+        restore_bytecodes();
         return;
       }
       // Method might have gotten rewritten.
--- a/src/share/vm/interpreter/rewriter.hpp	Fri Nov 15 21:39:27 2013 +0100
+++ b/src/share/vm/interpreter/rewriter.hpp	Fri Nov 15 17:20:22 2013 -0500
@@ -189,18 +189,18 @@
 
   void compute_index_maps();
   void make_constant_pool_cache(TRAPS);
-  void scan_method(Method* m, bool reverse, TRAPS);
+  void scan_method(Method* m, bool reverse, bool* invokespecial_error);
   void rewrite_Object_init(methodHandle m, TRAPS);
   void rewrite_member_reference(address bcp, int offset, bool reverse);
   void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
   void rewrite_invokedynamic(address bcp, int offset, bool reverse);
   void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse);
-  void rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS);
+  void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error);
 
   void patch_invokedynamic_bytecodes();
 
   // Revert bytecodes in case of an exception.
-  void restore_bytecodes(TRAPS);
+  void restore_bytecodes();
 
   static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
  public: