提交 063d9de9 编写于 作者: C coleenp

8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with...

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
上级 e3e4f6b0
...@@ -27,13 +27,8 @@ ...@@ -27,13 +27,8 @@
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "interpreter/rewriter.hpp" #include "interpreter/rewriter.hpp"
#include "memory/gcLocker.hpp" #include "memory/gcLocker.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/generateOopMap.hpp" #include "oops/generateOopMap.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodComparator.hpp"
#include "prims/methodHandles.hpp" #include "prims/methodHandles.hpp"
// Computes a CPC map (new_index -> original_index) for constant pool entries // Computes a CPC map (new_index -> original_index) for constant pool entries
...@@ -402,13 +397,6 @@ void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { ...@@ -402,13 +397,6 @@ void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) {
} }
void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) {
ResourceMark rm(THREAD);
Rewriter rw(klass, cpool, methods, CHECK);
// (That's all, folks.)
}
Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS)
: _klass(klass), : _klass(klass),
_pool(cpool), _pool(cpool),
...@@ -453,46 +441,25 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me ...@@ -453,46 +441,25 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me
restore_bytecodes(); restore_bytecodes();
return; return;
} }
}
// Relocate jsr/rets in a method. This can't be done with the rewriter // Relocate after everything, but still do this under the is_rewritten flag,
// stage because it can throw other exceptions, leaving the bytecodes // so methods with jsrs in custom class lists in aren't attempted to be
// pointing at constant pool cache entries. // rewritten in the RO section of the shared archive.
// Link and check jvmti dependencies while we're iterating over the methods. // Relocated bytecodes don't have to be restored, only the cp cache entries
// 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<Method*>* methods, TRAPS) {
int len = methods->length();
for (int i = len-1; i >= 0; i--) { for (int i = len-1; i >= 0; i--) {
methodHandle m(THREAD, methods->at(i)); methodHandle m(THREAD, _methods->at(i));
if (m->has_jsrs()) { 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. // Method might have gotten rewritten.
methods->at_put(i, m()); 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
} }
} }
...@@ -158,14 +158,6 @@ class Rewriter: public StackObj { ...@@ -158,14 +158,6 @@ class Rewriter: public StackObj {
public: public:
// Driver routine: // Driver routine:
static void rewrite(instanceKlassHandle klass, TRAPS); static void rewrite(instanceKlassHandle klass, TRAPS);
static void rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* 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<Method*>* methods, TRAPS);
}; };
#endif // SHARE_VM_INTERPRETER_REWRITER_HPP #endif // SHARE_VM_INTERPRETER_REWRITER_HPP
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "oops/symbol.hpp" #include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp" #include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodComparator.hpp"
#include "runtime/fieldDescriptor.hpp" #include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp" #include "runtime/javaCalls.hpp"
...@@ -602,7 +603,7 @@ bool InstanceKlass::link_class_impl( ...@@ -602,7 +603,7 @@ bool InstanceKlass::link_class_impl(
} }
// relocate jsrs and link methods after they are all rewritten // 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 // Initialize the vtable and interface table after
// methods have been rewritten since rewrite may // methods have been rewritten since rewrite may
...@@ -650,10 +651,31 @@ void InstanceKlass::rewrite_class(TRAPS) { ...@@ -650,10 +651,31 @@ void InstanceKlass::rewrite_class(TRAPS) {
// Now relocate and link method entry points after class is 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 // This is outside is_rewritten flag. In case of an exception, it can be
// executed more than once. // executed more than once.
void InstanceKlass::relocate_and_link_methods(TRAPS) { void InstanceKlass::link_methods(TRAPS) {
assert(is_loaded(), "must be loaded"); int len = methods()->length();
instanceKlassHandle this_oop(THREAD, this); for (int i = len-1; i >= 0; i--) {
Rewriter::relocate_and_link(this_oop, CHECK); 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
}
} }
......
...@@ -454,7 +454,7 @@ class InstanceKlass: public Klass { ...@@ -454,7 +454,7 @@ class InstanceKlass: public Klass {
bool link_class_or_fail(TRAPS); // returns false on failure bool link_class_or_fail(TRAPS); // returns false on failure
void unlink_class(); void unlink_class();
void rewrite_class(TRAPS); void rewrite_class(TRAPS);
void relocate_and_link_methods(TRAPS); void link_methods(TRAPS);
Method* class_initializer(); Method* class_initializer();
// set the class to initialized if no static initializer is present // set the class to initialized if no static initializer is present
......
...@@ -1043,7 +1043,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { ...@@ -1043,7 +1043,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
Rewriter::rewrite(scratch_class, THREAD); Rewriter::rewrite(scratch_class, THREAD);
if (!HAS_PENDING_EXCEPTION) { if (!HAS_PENDING_EXCEPTION) {
Rewriter::relocate_and_link(scratch_class, THREAD); scratch_class->link_methods(THREAD);
} }
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
......
...@@ -80,6 +80,8 @@ inline name##Handle::name##Handle(const name##Handle &h) { \ ...@@ -80,6 +80,8 @@ inline name##Handle::name##Handle(const name##Handle &h) { \
_thread = Thread::current(); \ _thread = Thread::current(); \
} \ } \
_thread->metadata_handles()->push((Metadata*)_value); \ _thread->metadata_handles()->push((Metadata*)_value); \
} else { \
_thread = NULL; \
} \ } \
} \ } \
inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \
...@@ -94,6 +96,8 @@ 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 = Thread::current(); \
} \ } \
_thread->metadata_handles()->push((Metadata*)_value); \ _thread->metadata_handles()->push((Metadata*)_value); \
} else { \
_thread = NULL; \
} \ } \
return *this; \ return *this; \
} \ } \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册