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); |