hotspot/src/share/vm/oops/instanceKlass.cpp
changeset 220 e6ef4818c49d
parent 1 489c9b5090e2
child 222 3d1795325749
equal deleted inserted replaced
173:bf2517e15f0c 220:e6ef4818c49d
  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);