diff -r 9a04e9b8518b -r d496ecd7b9de hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri May 20 22:27:48 2011 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Sat May 21 15:39:54 2011 -0700 @@ -335,6 +335,9 @@ this_oop->rewrite_class(CHECK_false); } + // relocate jsrs and link methods after they are all rewritten + this_oop->relocate_and_link_methods(CHECK_false); + // Initialize the vtable and interface table after // methods have been rewritten since rewrite may // fabricate new methodOops. @@ -365,17 +368,8 @@ // Rewrite the byte codes of all of the methods of a class. -// Three cases: -// During the link of a newly loaded class. -// During the preloading of classes to be written to the shared spaces. -// - Rewrite the methods and update the method entry points. -// -// During the link of a class in the shared spaces. -// - The methods were already rewritten, update the metho entry points. -// // The rewriter must be called exactly once. Rewriting must happen after // verification but before the first method of the class is executed. - void instanceKlass::rewrite_class(TRAPS) { assert(is_loaded(), "must be loaded"); instanceKlassHandle this_oop(THREAD, this->as_klassOop()); @@ -383,10 +377,19 @@ assert(this_oop()->is_shared(), "rewriting an unshared class?"); return; } - Rewriter::rewrite(this_oop, CHECK); // No exception can happen here + Rewriter::rewrite(this_oop, CHECK); this_oop->set_rewritten(); } +// 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->as_klassOop()); + Rewriter::relocate_and_link(this_oop, CHECK); +} + void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) { // Make sure klass is linked (verified) before initialization