6957080: MethodComparator needs stress testing
authorjrose
Sat, 29 May 2010 19:22:32 -0700
changeset 5697 0cf7190475ee
parent 5696 93e15b419ad4
child 5698 091095915ee6
6957080: MethodComparator needs stress testing Summary: Add a stress-test flag for running MethodComparator over many inputs. Fix bugs that crop up. Reviewed-by: kvn
hotspot/src/share/vm/includeDB_core
hotspot/src/share/vm/interpreter/bytecode.cpp
hotspot/src/share/vm/interpreter/rewriter.cpp
hotspot/src/share/vm/prims/methodComparator.cpp
hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/src/share/vm/includeDB_core	Fri May 28 16:23:51 2010 -0700
+++ b/hotspot/src/share/vm/includeDB_core	Sat May 29 19:22:32 2010 -0700
@@ -3636,6 +3636,7 @@
 rewriter.cpp                            gcLocker.hpp
 rewriter.cpp                            generateOopMap.hpp
 rewriter.cpp                            interpreter.hpp
+rewriter.cpp                            methodComparator.hpp
 rewriter.cpp                            objArrayOop.hpp
 rewriter.cpp                            oop.inline.hpp
 rewriter.cpp                            oopFactory.hpp
--- a/hotspot/src/share/vm/interpreter/bytecode.cpp	Fri May 28 16:23:51 2010 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecode.cpp	Sat May 29 19:22:32 2010 -0700
@@ -215,7 +215,14 @@
 
 int Bytecode_loadconstant::index() const {
   Bytecodes::Code stdc = Bytecodes::java_code(code());
-  return stdc == Bytecodes::_ldc ? get_index_u1(stdc) : get_index_u2(stdc);
+  if (stdc != Bytecodes::_wide) {
+    if (Bytecodes::java_code(stdc) == Bytecodes::_ldc)
+      return get_index_u1(stdc);
+    else
+      return get_index_u2(stdc, false);
+  }
+  stdc = Bytecodes::code_at(addr_at(1));
+  return get_index_u2(stdc, true);
 }
 
 //------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Fri May 28 16:23:51 2010 -0700
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Sat May 29 19:22:32 2010 -0700
@@ -307,5 +307,19 @@
 
     // Set up method entry points for compiler and interpreter.
     m->link_method(m, CHECK);
+
+#ifdef ASSERT
+    if (StressMethodComparator) {
+      static int nmc = 0;
+      for (int j = i; j >= 0 && j >= i-4; j--) {
+        if ((++nmc % 1000) == 0)  tty->print_cr("Have run MethodComparator %d times...", nmc);
+        bool z = MethodComparator::methods_EMCP(m(), (methodOop)_methods->obj_at(j));
+        if (j == i && !z) {
+          tty->print("MethodComparator FAIL: "); m->print(); m->print_codes();
+          assert(z, "method must compare equal to itself");
+        }
+      }
+    }
+#endif //ASSERT
   }
 }
--- a/hotspot/src/share/vm/prims/methodComparator.cpp	Fri May 28 16:23:51 2010 -0700
+++ b/hotspot/src/share/vm/prims/methodComparator.cpp	Sat May 29 19:22:32 2010 -0700
@@ -163,14 +163,10 @@
 
   case Bytecodes::_ldc   : // fall through
   case Bytecodes::_ldc_w : {
-    u2 cpi_old, cpi_new;
-    if (c_old == Bytecodes::_ldc) {
-      cpi_old = _s_old->bcp()[1];
-      cpi_new = _s_new->bcp()[1];
-    } else {
-      cpi_old = _s_old->get_index_u2();
-      cpi_new = _s_new->get_index_u2();
-    }
+    Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method()(), _s_old->bcp());
+    Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method()(), _s_new->bcp());
+    int cpi_old = ldc_old->index();
+    int cpi_new = ldc_new->index();
     constantTag tag_old = _old_cp->tag_at(cpi_old);
     constantTag tag_new = _new_cp->tag_at(cpi_new);
     if (tag_old.is_int() || tag_old.is_float()) {
@@ -180,7 +176,9 @@
         if (_old_cp->int_at(cpi_old) != _new_cp->int_at(cpi_new))
           return false;
       } else {
-        if (_old_cp->float_at(cpi_old) != _new_cp->float_at(cpi_new))
+        // Use jint_cast to compare the bits rather than numerical values.
+        // This makes a difference for NaN constants.
+        if (jint_cast(_old_cp->float_at(cpi_old)) != jint_cast(_new_cp->float_at(cpi_new)))
           return false;
       }
     } else if (tag_old.is_string() || tag_old.is_unresolved_string()) {
@@ -210,7 +208,9 @@
       if (_old_cp->long_at(cpi_old) != _new_cp->long_at(cpi_new))
         return false;
     } else {
-      if (_old_cp->double_at(cpi_old) != _new_cp->double_at(cpi_new))
+      // Use jlong_cast to compare the bits rather than numerical values.
+      // This makes a difference for NaN constants.
+      if (jlong_cast(_old_cp->double_at(cpi_old)) != jlong_cast(_new_cp->double_at(cpi_new)))
         return false;
     }
     break;
@@ -261,8 +261,8 @@
   case Bytecodes::_ifnonnull : // fall through
   case Bytecodes::_ifnull    : // fall through
   case Bytecodes::_jsr       : {
-    short old_ofs = (short) _s_old->get_index_u2();
-    short new_ofs = (short) _s_new->get_index_u2();
+    int old_ofs = _s_old->bytecode()->get_offset_s2(c_old);
+    int new_ofs = _s_new->bytecode()->get_offset_s2(c_new);
     if (_switchable_test) {
       int old_dest = _s_old->bci() + old_ofs;
       int new_dest = _s_new->bci() + new_ofs;
@@ -298,8 +298,8 @@
 
   case Bytecodes::_goto_w : // fall through
   case Bytecodes::_jsr_w  : {
-    int old_ofs = (int) Bytes::get_Java_u4(_s_old->bcp() + 1);
-    int new_ofs = (int) Bytes::get_Java_u4(_s_new->bcp() + 1);
+    int old_ofs = _s_old->bytecode()->get_offset_s4(c_old);
+    int new_ofs = _s_new->bytecode()->get_offset_s4(c_new);
     if (_switchable_test) {
       int old_dest = _s_old->bci() + old_ofs;
       int new_dest = _s_new->bci() + new_ofs;
--- a/hotspot/src/share/vm/runtime/globals.hpp	Fri May 28 16:23:51 2010 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Sat May 29 19:22:32 2010 -0700
@@ -1120,6 +1120,9 @@
   product(intx, TraceRedefineClasses, 0,                                    \
           "Trace level for JVMTI RedefineClasses")                          \
                                                                             \
+  develop(bool, StressMethodComparator, false,                              \
+          "run the MethodComparator on all loaded methods")                 \
+                                                                            \
   /* change to false by default sometime after Mustang */                   \
   product(bool, VerifyMergedCPBytecodes, true,                              \
           "Verify bytecodes after RedefineClasses constant pool merging")   \