6497639: 4/3 Profiling Swing application caused JVM crash

Make RedefineClasses() interoperate better with class sharing.

Reviewed-by: sspitsyn, jmasa
This commit is contained in:
Daniel D. Daugherty 2008-03-12 18:06:50 -07:00
parent 493ac9ee8f
commit 0f1d30354a
4 changed files with 87 additions and 27 deletions

View file

@ -2165,12 +2165,20 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
ikh->external_name(), _previous_versions->length(), emcp_method_count));
constantPoolHandle cp_h(ikh->constants());
jweak cp_ref = JNIHandles::make_weak_global(cp_h);
jobject cp_ref;
if (cp_h->is_shared()) {
// a shared ConstantPool requires a regular reference; a weak
// reference would be collectible
cp_ref = JNIHandles::make_global(cp_h);
} else {
cp_ref = JNIHandles::make_weak_global(cp_h);
}
PreviousVersionNode * pv_node = NULL;
objArrayOop old_methods = ikh->methods();
if (emcp_method_count == 0) {
pv_node = new PreviousVersionNode(cp_ref, NULL);
// non-shared ConstantPool gets a weak reference
pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
RC_TRACE(0x00000400,
("add: all methods are obsolete; flushing any EMCP weak refs"));
} else {
@ -2190,7 +2198,8 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
}
}
}
pv_node = new PreviousVersionNode(cp_ref, method_refs);
// non-shared ConstantPool gets a weak reference
pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
}
_previous_versions->append(pv_node);
@ -2208,7 +2217,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
// check the previous versions array for a GC'ed weak refs
pv_node = _previous_versions->at(i);
cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
if (cp_ref == NULL) {
delete pv_node;
_previous_versions->remove_at(i);
@ -2281,7 +2290,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
// check the previous versions array for a GC'ed weak refs
pv_node = _previous_versions->at(j);
cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
if (cp_ref == NULL) {
delete pv_node;
_previous_versions->remove_at(j);
@ -2379,8 +2388,8 @@ bool instanceKlass::has_previous_version() const {
// been GC'ed
PreviousVersionNode * pv_node = _previous_versions->at(i);
jweak cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
jobject cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
if (cp_ref == NULL) {
continue; // robustness
}
@ -2440,10 +2449,11 @@ void instanceKlass::set_methods_annotations_of(int idnum, typeArrayOop anno, obj
// Construct a PreviousVersionNode entry for the array hung off
// the instanceKlass.
PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
GrowableArray<jweak>* prev_EMCP_methods) {
PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
_prev_constant_pool = prev_constant_pool;
_prev_cp_is_weak = prev_cp_is_weak;
_prev_EMCP_methods = prev_EMCP_methods;
}
@ -2451,7 +2461,11 @@ PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
// Destroy a PreviousVersionNode
PreviousVersionNode::~PreviousVersionNode() {
if (_prev_constant_pool != NULL) {
JNIHandles::destroy_weak_global(_prev_constant_pool);
if (_prev_cp_is_weak) {
JNIHandles::destroy_weak_global(_prev_constant_pool);
} else {
JNIHandles::destroy_global(_prev_constant_pool);
}
}
if (_prev_EMCP_methods != NULL) {
@ -2471,8 +2485,8 @@ PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
_prev_constant_pool_handle = constantPoolHandle(); // NULL handle
_prev_EMCP_method_handles = NULL;
jweak cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
jobject cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
if (cp_ref == NULL) {
return; // robustness
}