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
--- 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") \