Mercurial > hg > truffle
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); |