# HG changeset patch # User coleenp # Date 1357176489 18000 # Node ID cc6a617fffd2c42ac29961aab3d13f09787f916e # Parent 4daebd4cc1dd29f2c74544ee48b65a1e3321b424 8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs Summary: Relocate functions with jsr's when rewriting so not repeated after reading shared archive Reviewed-by: twisti, jrose diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/interpreter/rewriter.cpp Wed Jan 02 20:28:09 2013 -0500 @@ -27,13 +27,8 @@ #include "interpreter/interpreter.hpp" #include "interpreter/rewriter.hpp" #include "memory/gcLocker.hpp" -#include "memory/metadataFactory.hpp" -#include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/generateOopMap.hpp" -#include "oops/objArrayOop.hpp" -#include "oops/oop.inline.hpp" -#include "prims/methodComparator.hpp" #include "prims/methodHandles.hpp" // Computes a CPC map (new_index -> original_index) for constant pool entries @@ -402,13 +397,6 @@ } -void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) { - ResourceMark rm(THREAD); - Rewriter rw(klass, cpool, methods, CHECK); - // (That's all, folks.) -} - - Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) : _klass(klass), _pool(cpool), @@ -453,46 +441,25 @@ restore_bytecodes(); return; } -} -// Relocate jsr/rets in a method. This can't be done with the rewriter -// stage because it can throw other exceptions, leaving the bytecodes -// pointing at constant pool cache entries. -// Link and check jvmti dependencies while we're iterating over the methods. -// JSR292 code calls with a different set of methods, so two entry points. -void Rewriter::relocate_and_link(instanceKlassHandle this_oop, TRAPS) { - relocate_and_link(this_oop, this_oop->methods(), THREAD); -} - -void Rewriter::relocate_and_link(instanceKlassHandle this_oop, - Array* methods, TRAPS) { - int len = methods->length(); + // Relocate after everything, but still do this under the is_rewritten flag, + // so methods with jsrs in custom class lists in aren't attempted to be + // rewritten in the RO section of the shared archive. + // Relocated bytecodes don't have to be restored, only the cp cache entries for (int i = len-1; i >= 0; i--) { - methodHandle m(THREAD, methods->at(i)); + methodHandle m(THREAD, _methods->at(i)); if (m->has_jsrs()) { - m = rewrite_jsrs(m, CHECK); + m = rewrite_jsrs(m, THREAD); + // Restore bytecodes to their unrewritten state if there are exceptions + // 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(); + return; + } // Method might have gotten rewritten. methods->at_put(i, m()); } - - // Set up method entry points for compiler and interpreter . - m->link_method(m, CHECK); - - // This is for JVMTI and unrelated to relocator but the last thing we do -#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(), - methods->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 } } diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/interpreter/rewriter.hpp --- a/src/share/vm/interpreter/rewriter.hpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/interpreter/rewriter.hpp Wed Jan 02 20:28:09 2013 -0500 @@ -158,14 +158,6 @@ public: // Driver routine: static void rewrite(instanceKlassHandle klass, TRAPS); - static void rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS); - - // Second pass, not gated by is_rewritten flag - static void relocate_and_link(instanceKlassHandle klass, TRAPS); - // JSR292 version to call with it's own methods. - static void relocate_and_link(instanceKlassHandle klass, - Array* methods, TRAPS); - }; #endif // SHARE_VM_INTERPRETER_REWRITER_HPP diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jan 02 20:28:09 2013 -0500 @@ -47,6 +47,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" +#include "prims/methodComparator.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -602,7 +603,7 @@ } // relocate jsrs and link methods after they are all rewritten - this_oop->relocate_and_link_methods(CHECK_false); + this_oop->link_methods(CHECK_false); // Initialize the vtable and interface table after // methods have been rewritten since rewrite may @@ -650,10 +651,31 @@ // Now relocate and link method entry points after class is rewritten. // This is outside is_rewritten flag. In case of an exception, it can be // executed more than once. -void InstanceKlass::relocate_and_link_methods(TRAPS) { - assert(is_loaded(), "must be loaded"); - instanceKlassHandle this_oop(THREAD, this); - Rewriter::relocate_and_link(this_oop, CHECK); +void InstanceKlass::link_methods(TRAPS) { + int len = methods()->length(); + for (int i = len-1; i >= 0; i--) { + methodHandle m(THREAD, methods()->at(i)); + + // Set up method entry points for compiler and interpreter . + m->link_method(m, CHECK); + + // This is for JVMTI and unrelated to relocator but the last thing we do +#ifdef ASSERT + if (StressMethodComparator) { + ResourceMark rm(THREAD); + 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(), + methods()->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 + } } diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Jan 02 20:28:09 2013 -0500 @@ -454,7 +454,7 @@ bool link_class_or_fail(TRAPS); // returns false on failure void unlink_class(); void rewrite_class(TRAPS); - void relocate_and_link_methods(TRAPS); + void link_methods(TRAPS); Method* class_initializer(); // set the class to initialized if no static initializer is present diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jan 02 20:28:09 2013 -0500 @@ -1043,7 +1043,7 @@ Rewriter::rewrite(scratch_class, THREAD); if (!HAS_PENDING_EXCEPTION) { - Rewriter::relocate_and_link(scratch_class, THREAD); + scratch_class->link_methods(THREAD); } if (HAS_PENDING_EXCEPTION) { Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); diff -r 4daebd4cc1dd -r cc6a617fffd2 src/share/vm/runtime/handles.inline.hpp --- a/src/share/vm/runtime/handles.inline.hpp Mon Dec 24 11:46:38 2012 -0800 +++ b/src/share/vm/runtime/handles.inline.hpp Wed Jan 02 20:28:09 2013 -0500 @@ -80,6 +80,8 @@ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ } \ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ @@ -94,6 +96,8 @@ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ return *this; \ } \