comparison src/share/vm/oops/instanceKlass.cpp @ 47:2c106685d6d0

6497639: 4/3 Profiling Swing application caused JVM crash Summary: Make RedefineClasses() interoperate better with class sharing. Reviewed-by: sspitsyn, jmasa
author dcubed
date Wed, 12 Mar 2008 18:06:50 -0700
parents a61af66fc99e
children 31000d79ec71
comparison
equal deleted inserted replaced
2:7836be3e92d0 47:2c106685d6d0
2163 2163
2164 // RC_TRACE macro has an embedded ResourceMark 2164 // RC_TRACE macro has an embedded ResourceMark
2165 RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", 2165 RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
2166 ikh->external_name(), _previous_versions->length(), emcp_method_count)); 2166 ikh->external_name(), _previous_versions->length(), emcp_method_count));
2167 constantPoolHandle cp_h(ikh->constants()); 2167 constantPoolHandle cp_h(ikh->constants());
2168 jweak cp_ref = JNIHandles::make_weak_global(cp_h); 2168 jobject cp_ref;
2169 if (cp_h->is_shared()) {
2170 // a shared ConstantPool requires a regular reference; a weak
2171 // reference would be collectible
2172 cp_ref = JNIHandles::make_global(cp_h);
2173 } else {
2174 cp_ref = JNIHandles::make_weak_global(cp_h);
2175 }
2169 PreviousVersionNode * pv_node = NULL; 2176 PreviousVersionNode * pv_node = NULL;
2170 objArrayOop old_methods = ikh->methods(); 2177 objArrayOop old_methods = ikh->methods();
2171 2178
2172 if (emcp_method_count == 0) { 2179 if (emcp_method_count == 0) {
2173 pv_node = new PreviousVersionNode(cp_ref, NULL); 2180 // non-shared ConstantPool gets a weak reference
2181 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
2174 RC_TRACE(0x00000400, 2182 RC_TRACE(0x00000400,
2175 ("add: all methods are obsolete; flushing any EMCP weak refs")); 2183 ("add: all methods are obsolete; flushing any EMCP weak refs"));
2176 } else { 2184 } else {
2177 int local_count = 0; 2185 int local_count = 0;
2178 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP) 2186 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP)
2188 // no more EMCP methods so bail out now 2196 // no more EMCP methods so bail out now
2189 break; 2197 break;
2190 } 2198 }
2191 } 2199 }
2192 } 2200 }
2193 pv_node = new PreviousVersionNode(cp_ref, method_refs); 2201 // non-shared ConstantPool gets a weak reference
2202 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
2194 } 2203 }
2195 2204
2196 _previous_versions->append(pv_node); 2205 _previous_versions->append(pv_node);
2197 2206
2198 // Using weak references allows the interesting parts of previous 2207 // Using weak references allows the interesting parts of previous
2206 // skip the last entry since we just added it 2215 // skip the last entry since we just added it
2207 for (int i = _previous_versions->length() - 2; i >= 0; i--) { 2216 for (int i = _previous_versions->length() - 2; i >= 0; i--) {
2208 // check the previous versions array for a GC'ed weak refs 2217 // check the previous versions array for a GC'ed weak refs
2209 pv_node = _previous_versions->at(i); 2218 pv_node = _previous_versions->at(i);
2210 cp_ref = pv_node->prev_constant_pool(); 2219 cp_ref = pv_node->prev_constant_pool();
2211 assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); 2220 assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
2212 if (cp_ref == NULL) { 2221 if (cp_ref == NULL) {
2213 delete pv_node; 2222 delete pv_node;
2214 _previous_versions->remove_at(i); 2223 _previous_versions->remove_at(i);
2215 // Since we are traversing the array backwards, we don't have to 2224 // Since we are traversing the array backwards, we don't have to
2216 // do anything special with the index. 2225 // do anything special with the index.
2279 // skip the last entry since we just added it 2288 // skip the last entry since we just added it
2280 for (int j = _previous_versions->length() - 2; j >= 0; j--) { 2289 for (int j = _previous_versions->length() - 2; j >= 0; j--) {
2281 // check the previous versions array for a GC'ed weak refs 2290 // check the previous versions array for a GC'ed weak refs
2282 pv_node = _previous_versions->at(j); 2291 pv_node = _previous_versions->at(j);
2283 cp_ref = pv_node->prev_constant_pool(); 2292 cp_ref = pv_node->prev_constant_pool();
2284 assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); 2293 assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
2285 if (cp_ref == NULL) { 2294 if (cp_ref == NULL) {
2286 delete pv_node; 2295 delete pv_node;
2287 _previous_versions->remove_at(j); 2296 _previous_versions->remove_at(j);
2288 // Since we are traversing the array backwards, we don't have to 2297 // Since we are traversing the array backwards, we don't have to
2289 // do anything special with the index. 2298 // do anything special with the index.
2377 for (int i = _previous_versions->length() - 1; i >= 0; i--) { 2386 for (int i = _previous_versions->length() - 1; i >= 0; i--) {
2378 // Check the previous versions array for an info node that hasn't 2387 // Check the previous versions array for an info node that hasn't
2379 // been GC'ed 2388 // been GC'ed
2380 PreviousVersionNode * pv_node = _previous_versions->at(i); 2389 PreviousVersionNode * pv_node = _previous_versions->at(i);
2381 2390
2382 jweak cp_ref = pv_node->prev_constant_pool(); 2391 jobject cp_ref = pv_node->prev_constant_pool();
2383 assert(cp_ref != NULL, "weak reference was unexpectedly cleared"); 2392 assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
2384 if (cp_ref == NULL) { 2393 if (cp_ref == NULL) {
2385 continue; // robustness 2394 continue; // robustness
2386 } 2395 }
2387 2396
2388 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); 2397 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref);
2438 } // if no array and idnum isn't included there is nothing to do 2447 } // if no array and idnum isn't included there is nothing to do
2439 } 2448 }
2440 2449
2441 // Construct a PreviousVersionNode entry for the array hung off 2450 // Construct a PreviousVersionNode entry for the array hung off
2442 // the instanceKlass. 2451 // the instanceKlass.
2443 PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool, 2452 PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
2444 GrowableArray<jweak>* prev_EMCP_methods) { 2453 bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
2445 2454
2446 _prev_constant_pool = prev_constant_pool; 2455 _prev_constant_pool = prev_constant_pool;
2456 _prev_cp_is_weak = prev_cp_is_weak;
2447 _prev_EMCP_methods = prev_EMCP_methods; 2457 _prev_EMCP_methods = prev_EMCP_methods;
2448 } 2458 }
2449 2459
2450 2460
2451 // Destroy a PreviousVersionNode 2461 // Destroy a PreviousVersionNode
2452 PreviousVersionNode::~PreviousVersionNode() { 2462 PreviousVersionNode::~PreviousVersionNode() {
2453 if (_prev_constant_pool != NULL) { 2463 if (_prev_constant_pool != NULL) {
2454 JNIHandles::destroy_weak_global(_prev_constant_pool); 2464 if (_prev_cp_is_weak) {
2465 JNIHandles::destroy_weak_global(_prev_constant_pool);
2466 } else {
2467 JNIHandles::destroy_global(_prev_constant_pool);
2468 }
2455 } 2469 }
2456 2470
2457 if (_prev_EMCP_methods != NULL) { 2471 if (_prev_EMCP_methods != NULL) {
2458 for (int i = _prev_EMCP_methods->length() - 1; i >= 0; i--) { 2472 for (int i = _prev_EMCP_methods->length() - 1; i >= 0; i--) {
2459 jweak method_ref = _prev_EMCP_methods->at(i); 2473 jweak method_ref = _prev_EMCP_methods->at(i);
2469 // Construct a PreviousVersionInfo entry 2483 // Construct a PreviousVersionInfo entry
2470 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { 2484 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
2471 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle 2485 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle
2472 _prev_EMCP_method_handles = NULL; 2486 _prev_EMCP_method_handles = NULL;
2473 2487
2474 jweak cp_ref = pv_node->prev_constant_pool(); 2488 jobject cp_ref = pv_node->prev_constant_pool();
2475 assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared"); 2489 assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
2476 if (cp_ref == NULL) { 2490 if (cp_ref == NULL) {
2477 return; // robustness 2491 return; // robustness
2478 } 2492 }
2479 2493
2480 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); 2494 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref);