Mercurial > hg > truffle
comparison src/share/vm/oops/instanceKlass.cpp @ 52:75b0f3cb1943
Merge
author | dcubed |
---|---|
date | Thu, 13 Mar 2008 14:17:48 -0700 |
parents | 52fed2ec0afb 31000d79ec71 |
children | ba764ed4b6f2 |
comparison
equal
deleted
inserted
replaced
46:8b6e49187640 | 52:75b0f3cb1943 |
---|---|
970 | 970 |
971 // Do all the safepointing things (allocations) before grabbing the lock. | 971 // Do all the safepointing things (allocations) before grabbing the lock. |
972 // These allocations will have to be freed if they are unused. | 972 // These allocations will have to be freed if they are unused. |
973 | 973 |
974 // Allocate a new array of methods. | 974 // Allocate a new array of methods. |
975 jmethodID* to_dealloc_jmeths = NULL; | |
976 jmethodID* new_jmeths = NULL; | 975 jmethodID* new_jmeths = NULL; |
977 if (length <= idnum) { | 976 if (length <= idnum) { |
978 // A new array will be needed (unless some other thread beats us to it) | 977 // A new array will be needed (unless some other thread beats us to it) |
979 size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count()); | 978 size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count()); |
980 new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1); | 979 new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1); |
981 memset(new_jmeths, 0, (size+1)*sizeof(jmethodID)); | 980 memset(new_jmeths, 0, (size+1)*sizeof(jmethodID)); |
982 new_jmeths[0] =(jmethodID)size; // array size held in the first element | 981 new_jmeths[0] =(jmethodID)size; // array size held in the first element |
983 } | 982 } |
984 | 983 |
985 // Allocate a new method ID. | 984 // Allocate a new method ID. |
986 jmethodID to_dealloc_id = NULL; | |
987 jmethodID new_id = NULL; | 985 jmethodID new_id = NULL; |
988 if (method_h->is_old() && !method_h->is_obsolete()) { | 986 if (method_h->is_old() && !method_h->is_obsolete()) { |
989 // The method passed in is old (but not obsolete), we need to use the current version | 987 // The method passed in is old (but not obsolete), we need to use the current version |
990 methodOop current_method = ik_h->method_with_idnum((int)idnum); | 988 methodOop current_method = ik_h->method_with_idnum((int)idnum); |
991 assert(current_method != NULL, "old and but not obsolete, so should exist"); | 989 assert(current_method != NULL, "old and but not obsolete, so should exist"); |
995 // It is the current version of the method or an obsolete method, | 993 // It is the current version of the method or an obsolete method, |
996 // use the version passed in | 994 // use the version passed in |
997 new_id = JNIHandles::make_jmethod_id(method_h); | 995 new_id = JNIHandles::make_jmethod_id(method_h); |
998 } | 996 } |
999 | 997 |
1000 { | 998 if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { |
999 // No need and unsafe to lock the JmethodIdCreation_lock at safepoint. | |
1000 id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths); | |
1001 } else { | |
1001 MutexLocker ml(JmethodIdCreation_lock); | 1002 MutexLocker ml(JmethodIdCreation_lock); |
1002 | 1003 id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths); |
1003 // We must not go to a safepoint while holding this lock. | 1004 } |
1004 debug_only(No_Safepoint_Verifier nosafepoints;) | 1005 } |
1005 | 1006 return id; |
1006 // Retry lookup after we got the lock | 1007 } |
1007 jmeths = ik_h->methods_jmethod_ids_acquire(); | 1008 |
1008 if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) { | 1009 |
1009 if (jmeths != NULL) { | 1010 jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum, |
1010 // We have grown the array: copy the existing entries, and delete the old array | 1011 jmethodID new_id, jmethodID* new_jmeths) { |
1011 for (size_t index = 0; index < length; index++) { | 1012 // Retry lookup after we got the lock or ensured we are at safepoint |
1012 new_jmeths[index+1] = jmeths[index+1]; | 1013 jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); |
1013 } | 1014 jmethodID id = NULL; |
1014 to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one | 1015 jmethodID to_dealloc_id = NULL; |
1015 } | 1016 jmethodID* to_dealloc_jmeths = NULL; |
1016 ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); | 1017 size_t length; |
1017 } else { | 1018 |
1018 id = jmeths[idnum+1]; | 1019 if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) { |
1019 to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one | 1020 if (jmeths != NULL) { |
1020 } | 1021 // We have grown the array: copy the existing entries, and delete the old array |
1021 if (id == NULL) { | 1022 for (size_t index = 0; index < length; index++) { |
1022 id = new_id; | 1023 new_jmeths[index+1] = jmeths[index+1]; |
1023 jmeths[idnum+1] = id; // install the new method ID | 1024 } |
1024 } else { | 1025 to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one |
1025 to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation | 1026 } |
1026 } | 1027 ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); |
1027 } | 1028 } else { |
1028 | 1029 id = jmeths[idnum+1]; |
1029 // Free up unneeded or no longer needed resources | 1030 to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one |
1030 FreeHeap(to_dealloc_jmeths); | 1031 } |
1031 if (to_dealloc_id != NULL) { | 1032 if (id == NULL) { |
1032 JNIHandles::destroy_jmethod_id(to_dealloc_id); | 1033 id = new_id; |
1033 } | 1034 jmeths[idnum+1] = id; // install the new method ID |
1035 } else { | |
1036 to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation | |
1037 } | |
1038 | |
1039 // Free up unneeded or no longer needed resources | |
1040 FreeHeap(to_dealloc_jmeths); | |
1041 if (to_dealloc_id != NULL) { | |
1042 JNIHandles::destroy_jmethod_id(to_dealloc_id); | |
1034 } | 1043 } |
1035 return id; | 1044 return id; |
1036 } | 1045 } |
1037 | 1046 |
1038 | 1047 |
2185 | 2194 |
2186 // RC_TRACE macro has an embedded ResourceMark | 2195 // RC_TRACE macro has an embedded ResourceMark |
2187 RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", | 2196 RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", |
2188 ikh->external_name(), _previous_versions->length(), emcp_method_count)); | 2197 ikh->external_name(), _previous_versions->length(), emcp_method_count)); |
2189 constantPoolHandle cp_h(ikh->constants()); | 2198 constantPoolHandle cp_h(ikh->constants()); |
2190 jweak cp_ref = JNIHandles::make_weak_global(cp_h); | 2199 jobject cp_ref; |
2200 if (cp_h->is_shared()) { | |
2201 // a shared ConstantPool requires a regular reference; a weak | |
2202 // reference would be collectible | |
2203 cp_ref = JNIHandles::make_global(cp_h); | |
2204 } else { | |
2205 cp_ref = JNIHandles::make_weak_global(cp_h); | |
2206 } | |
2191 PreviousVersionNode * pv_node = NULL; | 2207 PreviousVersionNode * pv_node = NULL; |
2192 objArrayOop old_methods = ikh->methods(); | 2208 objArrayOop old_methods = ikh->methods(); |
2193 | 2209 |
2194 if (emcp_method_count == 0) { | 2210 if (emcp_method_count == 0) { |
2195 pv_node = new PreviousVersionNode(cp_ref, NULL); | 2211 // non-shared ConstantPool gets a weak reference |
2212 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL); | |
2196 RC_TRACE(0x00000400, | 2213 RC_TRACE(0x00000400, |
2197 ("add: all methods are obsolete; flushing any EMCP weak refs")); | 2214 ("add: all methods are obsolete; flushing any EMCP weak refs")); |
2198 } else { | 2215 } else { |
2199 int local_count = 0; | 2216 int local_count = 0; |
2200 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP) | 2217 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP) |
2210 // no more EMCP methods so bail out now | 2227 // no more EMCP methods so bail out now |
2211 break; | 2228 break; |
2212 } | 2229 } |
2213 } | 2230 } |
2214 } | 2231 } |
2215 pv_node = new PreviousVersionNode(cp_ref, method_refs); | 2232 // non-shared ConstantPool gets a weak reference |
2233 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs); | |
2216 } | 2234 } |
2217 | 2235 |
2218 _previous_versions->append(pv_node); | 2236 _previous_versions->append(pv_node); |
2219 | 2237 |
2220 // Using weak references allows the interesting parts of previous | 2238 // Using weak references allows the interesting parts of previous |
2228 // skip the last entry since we just added it | 2246 // skip the last entry since we just added it |
2229 for (int i = _previous_versions->length() - 2; i >= 0; i--) { | 2247 for (int i = _previous_versions->length() - 2; i >= 0; i--) { |
2230 // check the previous versions array for a GC'ed weak refs | 2248 // check the previous versions array for a GC'ed weak refs |
2231 pv_node = _previous_versions->at(i); | 2249 pv_node = _previous_versions->at(i); |
2232 cp_ref = pv_node->prev_constant_pool(); | 2250 cp_ref = pv_node->prev_constant_pool(); |
2233 assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); | 2251 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
2234 if (cp_ref == NULL) { | 2252 if (cp_ref == NULL) { |
2235 delete pv_node; | 2253 delete pv_node; |
2236 _previous_versions->remove_at(i); | 2254 _previous_versions->remove_at(i); |
2237 // Since we are traversing the array backwards, we don't have to | 2255 // Since we are traversing the array backwards, we don't have to |
2238 // do anything special with the index. | 2256 // do anything special with the index. |
2301 // skip the last entry since we just added it | 2319 // skip the last entry since we just added it |
2302 for (int j = _previous_versions->length() - 2; j >= 0; j--) { | 2320 for (int j = _previous_versions->length() - 2; j >= 0; j--) { |
2303 // check the previous versions array for a GC'ed weak refs | 2321 // check the previous versions array for a GC'ed weak refs |
2304 pv_node = _previous_versions->at(j); | 2322 pv_node = _previous_versions->at(j); |
2305 cp_ref = pv_node->prev_constant_pool(); | 2323 cp_ref = pv_node->prev_constant_pool(); |
2306 assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); | 2324 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
2307 if (cp_ref == NULL) { | 2325 if (cp_ref == NULL) { |
2308 delete pv_node; | 2326 delete pv_node; |
2309 _previous_versions->remove_at(j); | 2327 _previous_versions->remove_at(j); |
2310 // Since we are traversing the array backwards, we don't have to | 2328 // Since we are traversing the array backwards, we don't have to |
2311 // do anything special with the index. | 2329 // do anything special with the index. |
2399 for (int i = _previous_versions->length() - 1; i >= 0; i--) { | 2417 for (int i = _previous_versions->length() - 1; i >= 0; i--) { |
2400 // Check the previous versions array for an info node that hasn't | 2418 // Check the previous versions array for an info node that hasn't |
2401 // been GC'ed | 2419 // been GC'ed |
2402 PreviousVersionNode * pv_node = _previous_versions->at(i); | 2420 PreviousVersionNode * pv_node = _previous_versions->at(i); |
2403 | 2421 |
2404 jweak cp_ref = pv_node->prev_constant_pool(); | 2422 jobject cp_ref = pv_node->prev_constant_pool(); |
2405 assert(cp_ref != NULL, "weak reference was unexpectedly cleared"); | 2423 assert(cp_ref != NULL, "cp reference was unexpectedly cleared"); |
2406 if (cp_ref == NULL) { | 2424 if (cp_ref == NULL) { |
2407 continue; // robustness | 2425 continue; // robustness |
2408 } | 2426 } |
2409 | 2427 |
2410 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | 2428 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); |
2460 } // if no array and idnum isn't included there is nothing to do | 2478 } // if no array and idnum isn't included there is nothing to do |
2461 } | 2479 } |
2462 | 2480 |
2463 // Construct a PreviousVersionNode entry for the array hung off | 2481 // Construct a PreviousVersionNode entry for the array hung off |
2464 // the instanceKlass. | 2482 // the instanceKlass. |
2465 PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool, | 2483 PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool, |
2466 GrowableArray<jweak>* prev_EMCP_methods) { | 2484 bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) { |
2467 | 2485 |
2468 _prev_constant_pool = prev_constant_pool; | 2486 _prev_constant_pool = prev_constant_pool; |
2487 _prev_cp_is_weak = prev_cp_is_weak; | |
2469 _prev_EMCP_methods = prev_EMCP_methods; | 2488 _prev_EMCP_methods = prev_EMCP_methods; |
2470 } | 2489 } |
2471 | 2490 |
2472 | 2491 |
2473 // Destroy a PreviousVersionNode | 2492 // Destroy a PreviousVersionNode |
2474 PreviousVersionNode::~PreviousVersionNode() { | 2493 PreviousVersionNode::~PreviousVersionNode() { |
2475 if (_prev_constant_pool != NULL) { | 2494 if (_prev_constant_pool != NULL) { |
2476 JNIHandles::destroy_weak_global(_prev_constant_pool); | 2495 if (_prev_cp_is_weak) { |
2496 JNIHandles::destroy_weak_global(_prev_constant_pool); | |
2497 } else { | |
2498 JNIHandles::destroy_global(_prev_constant_pool); | |
2499 } | |
2477 } | 2500 } |
2478 | 2501 |
2479 if (_prev_EMCP_methods != NULL) { | 2502 if (_prev_EMCP_methods != NULL) { |
2480 for (int i = _prev_EMCP_methods->length() - 1; i >= 0; i--) { | 2503 for (int i = _prev_EMCP_methods->length() - 1; i >= 0; i--) { |
2481 jweak method_ref = _prev_EMCP_methods->at(i); | 2504 jweak method_ref = _prev_EMCP_methods->at(i); |
2491 // Construct a PreviousVersionInfo entry | 2514 // Construct a PreviousVersionInfo entry |
2492 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { | 2515 PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { |
2493 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle | 2516 _prev_constant_pool_handle = constantPoolHandle(); // NULL handle |
2494 _prev_EMCP_method_handles = NULL; | 2517 _prev_EMCP_method_handles = NULL; |
2495 | 2518 |
2496 jweak cp_ref = pv_node->prev_constant_pool(); | 2519 jobject cp_ref = pv_node->prev_constant_pool(); |
2497 assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared"); | 2520 assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared"); |
2498 if (cp_ref == NULL) { | 2521 if (cp_ref == NULL) { |
2499 return; // robustness | 2522 return; // robustness |
2500 } | 2523 } |
2501 | 2524 |
2502 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); | 2525 constantPoolOop cp = (constantPoolOop)JNIHandles::resolve(cp_ref); |