diff --git a/src/share/vm/interpreter/rewriter.cpp b/src/share/vm/interpreter/rewriter.cpp index b699d4494a48d011e64d25dbea01e35780796a0d..d906eb0e0ce72dc43352c53182df627561e4d36f 100644 --- a/src/share/vm/interpreter/rewriter.cpp +++ b/src/share/vm/interpreter/rewriter.cpp @@ -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, TRAPS) { } -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 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Arraymethods(), 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 --git a/src/share/vm/interpreter/rewriter.hpp b/src/share/vm/interpreter/rewriter.hpp index 78d09a92e23c1201dbecf08c25a7fae34e06cfe1..56067983c84128103ab770bd3aeb0ece294ea5c5 100644 --- a/src/share/vm/interpreter/rewriter.hpp +++ b/src/share/vm/interpreter/rewriter.hpp @@ -158,14 +158,6 @@ class Rewriter: public StackObj { 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 --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index ce30929f522de2c9a8f9e35dfce2255993b16ede..de2325d54cfc68246281712536b8bed9837e706c 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -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 @@ bool InstanceKlass::link_class_impl( } // 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 @@ void InstanceKlass::rewrite_class(TRAPS) { // 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 --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp index 426486dd9654cc66868810e6f961ef7dc3f7fcfb..32938dcfbe3995c6f8ae143669076e9a3f525708 100644 --- a/src/share/vm/oops/instanceKlass.hpp +++ b/src/share/vm/oops/instanceKlass.hpp @@ -454,7 +454,7 @@ class InstanceKlass: public Klass { 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 --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp index 6fb7243a872734fd4c32544157aa8410d482c27b..a9d3d5f1e392cc6be3ec0f6b395df1c551ed1774 100644 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1043,7 +1043,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { 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 --git a/src/share/vm/runtime/handles.inline.hpp b/src/share/vm/runtime/handles.inline.hpp index 6565b97933856efe17db4d884df0ea64bec177f4..9530b127aeaff9e0c6bd652b634498365bb68dfd 100644 --- a/src/share/vm/runtime/handles.inline.hpp +++ b/src/share/vm/runtime/handles.inline.hpp @@ -80,6 +80,8 @@ inline name##Handle::name##Handle(const name##Handle &h) { \ _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 @@ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ return *this; \ } \