< prev index next >

src/share/vm/gc/shared/referenceProcessor.cpp

Print this page




 170     _soft_ref_timestamp_clock = now;
 171     java_lang_ref_SoftReference::set_clock(now);
 172   }
 173   // Else leave clock stalled at its old value until time progresses
 174   // past clock value.
 175 }
 176 
 177 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) {
 178   size_t total = 0;
 179   for (uint i = 0; i < _max_num_q; ++i) {
 180     total += lists[i].length();
 181   }
 182   return total;
 183 }
 184 
 185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
 186   BoolObjectClosure*           is_alive,
 187   OopClosure*                  keep_alive,
 188   VoidClosure*                 complete_gc,
 189   AbstractRefProcTaskExecutor* task_executor,
 190   GCTimer*                     gc_timer,
 191   GCId                         gc_id) {
 192 
 193   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
 194   // Stop treating discovered references specially.
 195   disable_discovery();
 196 
 197   // If discovery was concurrent, someone could have modified
 198   // the value of the static field in the j.l.r.SoftReference
 199   // class that holds the soft reference timestamp clock using
 200   // reflection or Unsafe between when discovery was enabled and
 201   // now. Unconditionally update the static field in ReferenceProcessor
 202   // here so that we use the new value during processing of the
 203   // discovered soft refs.
 204 
 205   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 206 
 207   bool trace_time = PrintGCDetails && PrintReferenceGC;
 208 
 209   // Soft references
 210   size_t soft_count = 0;
 211   {
 212     GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id);
 213     soft_count =
 214       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
 215                                  is_alive, keep_alive, complete_gc, task_executor);
 216   }
 217 
 218   update_soft_ref_master_clock();
 219 
 220   // Weak references
 221   size_t weak_count = 0;
 222   {
 223     GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id);
 224     weak_count =
 225       process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 226                                  is_alive, keep_alive, complete_gc, task_executor);
 227   }
 228 
 229   // Final references
 230   size_t final_count = 0;
 231   {
 232     GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id);
 233     final_count =
 234       process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 235                                  is_alive, keep_alive, complete_gc, task_executor);
 236   }
 237 
 238   // Phantom references
 239   size_t phantom_count = 0;
 240   {
 241     GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id);
 242     phantom_count =
 243       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
 244                                  is_alive, keep_alive, complete_gc, task_executor);
 245 
 246   }
 247 
 248   // Cleaners
 249   size_t cleaner_count = 0;
 250   {
 251     GCTraceTime tt("Cleaners", trace_time, false, gc_timer, gc_id);
 252     cleaner_count =
 253       process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
 254                                  is_alive, keep_alive, complete_gc, task_executor);
 255   }
 256 
 257   // Weak global JNI references. It would make more sense (semantically) to
 258   // traverse these simultaneously with the regular weak references above, but
 259   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 260   // thus use JNI weak references to circumvent the phantom references and
 261   // resurrect a "post-mortem" object.
 262   size_t jni_weak_ref_count = 0;
 263   {
 264     GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id);
 265     if (task_executor != NULL) {
 266       task_executor->set_single_threaded_mode();
 267     }
 268     jni_weak_ref_count =
 269       process_phaseJNI(is_alive, keep_alive, complete_gc);
 270   }
 271 
 272   return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count, cleaner_count, jni_weak_ref_count);
 273 }
 274 
 275 #ifndef PRODUCT
 276 // Calculate the number of jni handles.
 277 uint ReferenceProcessor::count_jni_refs() {
 278   class AlwaysAliveClosure: public BoolObjectClosure {
 279   public:
 280     virtual bool do_object_b(oop obj) { return true; }
 281   };
 282 
 283   class CountHandleClosure: public OopClosure {
 284   private:


1139 
1140     if (TraceReferenceGC) {
1141       gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
1142                                 p2i(obj), obj->klass()->internal_name());
1143     }
1144   }
1145   assert(obj->is_oop(), "Discovered a bad reference");
1146   verify_referent(obj);
1147   return true;
1148 }
1149 
1150 // Preclean the discovered references by removing those
1151 // whose referents are alive, and by marking from those that
1152 // are not active. These lists can be handled here
1153 // in any order and, indeed, concurrently.
1154 void ReferenceProcessor::preclean_discovered_references(
1155   BoolObjectClosure* is_alive,
1156   OopClosure* keep_alive,
1157   VoidClosure* complete_gc,
1158   YieldClosure* yield,
1159   GCTimer* gc_timer,
1160   GCId     gc_id) {
1161 
1162   // Soft references
1163   {
1164     GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
1165               false, gc_timer, gc_id);
1166     for (uint i = 0; i < _max_num_q; i++) {
1167       if (yield->should_return()) {
1168         return;
1169       }
1170       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
1171                                   keep_alive, complete_gc, yield);
1172     }
1173   }
1174 
1175   // Weak references
1176   {
1177     GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
1178               false, gc_timer, gc_id);
1179     for (uint i = 0; i < _max_num_q; i++) {
1180       if (yield->should_return()) {
1181         return;
1182       }
1183       preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
1184                                   keep_alive, complete_gc, yield);
1185     }
1186   }
1187 
1188   // Final references
1189   {
1190     GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
1191               false, gc_timer, gc_id);
1192     for (uint i = 0; i < _max_num_q; i++) {
1193       if (yield->should_return()) {
1194         return;
1195       }
1196       preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
1197                                   keep_alive, complete_gc, yield);
1198     }
1199   }
1200 
1201   // Phantom references
1202   {
1203     GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
1204               false, gc_timer, gc_id);
1205     for (uint i = 0; i < _max_num_q; i++) {
1206       if (yield->should_return()) {
1207         return;
1208       }
1209       preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
1210                                   keep_alive, complete_gc, yield);
1211     }
1212 
1213     // Cleaner references.  Included in timing for phantom references.  We
1214     // expect Cleaner references to be temporary, and don't want to deal with
1215     // possible incompatibilities arising from making it more visible.
1216     for (uint i = 0; i < _max_num_q; i++) {
1217       if (yield->should_return()) {
1218         return;
1219       }
1220       preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive,
1221                                   keep_alive, complete_gc, yield);
1222     }
1223   }
1224 }




 170     _soft_ref_timestamp_clock = now;
 171     java_lang_ref_SoftReference::set_clock(now);
 172   }
 173   // Else leave clock stalled at its old value until time progresses
 174   // past clock value.
 175 }
 176 
 177 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) {
 178   size_t total = 0;
 179   for (uint i = 0; i < _max_num_q; ++i) {
 180     total += lists[i].length();
 181   }
 182   return total;
 183 }
 184 
 185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
 186   BoolObjectClosure*           is_alive,
 187   OopClosure*                  keep_alive,
 188   VoidClosure*                 complete_gc,
 189   AbstractRefProcTaskExecutor* task_executor,
 190   GCTimer*                     gc_timer) {

 191 
 192   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
 193   // Stop treating discovered references specially.
 194   disable_discovery();
 195 
 196   // If discovery was concurrent, someone could have modified
 197   // the value of the static field in the j.l.r.SoftReference
 198   // class that holds the soft reference timestamp clock using
 199   // reflection or Unsafe between when discovery was enabled and
 200   // now. Unconditionally update the static field in ReferenceProcessor
 201   // here so that we use the new value during processing of the
 202   // discovered soft refs.
 203 
 204   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 205 
 206   bool trace_time = PrintGCDetails && PrintReferenceGC;
 207 
 208   // Soft references
 209   size_t soft_count = 0;
 210   {
 211     GCTraceTime tt("SoftReference", trace_time, false, gc_timer);
 212     soft_count =
 213       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
 214                                  is_alive, keep_alive, complete_gc, task_executor);
 215   }
 216 
 217   update_soft_ref_master_clock();
 218 
 219   // Weak references
 220   size_t weak_count = 0;
 221   {
 222     GCTraceTime tt("WeakReference", trace_time, false, gc_timer);
 223     weak_count =
 224       process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 225                                  is_alive, keep_alive, complete_gc, task_executor);
 226   }
 227 
 228   // Final references
 229   size_t final_count = 0;
 230   {
 231     GCTraceTime tt("FinalReference", trace_time, false, gc_timer);
 232     final_count =
 233       process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 234                                  is_alive, keep_alive, complete_gc, task_executor);
 235   }
 236 
 237   // Phantom references
 238   size_t phantom_count = 0;
 239   {
 240     GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);
 241     phantom_count =
 242       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
 243                                  is_alive, keep_alive, complete_gc, task_executor);
 244 
 245   }
 246 
 247   // Cleaners
 248   size_t cleaner_count = 0;
 249   {
 250     GCTraceTime tt("Cleaners", trace_time, false, gc_timer, gc_id);
 251     cleaner_count =
 252       process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
 253                                  is_alive, keep_alive, complete_gc, task_executor);
 254   }
 255 
 256   // Weak global JNI references. It would make more sense (semantically) to
 257   // traverse these simultaneously with the regular weak references above, but
 258   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 259   // thus use JNI weak references to circumvent the phantom references and
 260   // resurrect a "post-mortem" object.
 261   size_t jni_weak_ref_count = 0;
 262   {
 263     GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
 264     if (task_executor != NULL) {
 265       task_executor->set_single_threaded_mode();
 266     }
 267     jni_weak_ref_count =
 268       process_phaseJNI(is_alive, keep_alive, complete_gc);
 269   }
 270 
 271   return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count, cleaner_count, jni_weak_ref_count);
 272 }
 273 
 274 #ifndef PRODUCT
 275 // Calculate the number of jni handles.
 276 uint ReferenceProcessor::count_jni_refs() {
 277   class AlwaysAliveClosure: public BoolObjectClosure {
 278   public:
 279     virtual bool do_object_b(oop obj) { return true; }
 280   };
 281 
 282   class CountHandleClosure: public OopClosure {
 283   private:


1138 
1139     if (TraceReferenceGC) {
1140       gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
1141                                 p2i(obj), obj->klass()->internal_name());
1142     }
1143   }
1144   assert(obj->is_oop(), "Discovered a bad reference");
1145   verify_referent(obj);
1146   return true;
1147 }
1148 
1149 // Preclean the discovered references by removing those
1150 // whose referents are alive, and by marking from those that
1151 // are not active. These lists can be handled here
1152 // in any order and, indeed, concurrently.
1153 void ReferenceProcessor::preclean_discovered_references(
1154   BoolObjectClosure* is_alive,
1155   OopClosure* keep_alive,
1156   VoidClosure* complete_gc,
1157   YieldClosure* yield,
1158   GCTimer* gc_timer) {

1159 
1160   // Soft references
1161   {
1162     GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
1163               false, gc_timer);
1164     for (uint i = 0; i < _max_num_q; i++) {
1165       if (yield->should_return()) {
1166         return;
1167       }
1168       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
1169                                   keep_alive, complete_gc, yield);
1170     }
1171   }
1172 
1173   // Weak references
1174   {
1175     GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
1176               false, gc_timer);
1177     for (uint i = 0; i < _max_num_q; i++) {
1178       if (yield->should_return()) {
1179         return;
1180       }
1181       preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
1182                                   keep_alive, complete_gc, yield);
1183     }
1184   }
1185 
1186   // Final references
1187   {
1188     GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
1189               false, gc_timer);
1190     for (uint i = 0; i < _max_num_q; i++) {
1191       if (yield->should_return()) {
1192         return;
1193       }
1194       preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
1195                                   keep_alive, complete_gc, yield);
1196     }
1197   }
1198 
1199   // Phantom references
1200   {
1201     GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
1202               false, gc_timer);
1203     for (uint i = 0; i < _max_num_q; i++) {
1204       if (yield->should_return()) {
1205         return;
1206       }
1207       preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
1208                                   keep_alive, complete_gc, yield);
1209     }
1210 
1211     // Cleaner references.  Included in timing for phantom references.  We
1212     // expect Cleaner references to be temporary, and don't want to deal with
1213     // possible incompatibilities arising from making it more visible.
1214     for (uint i = 0; i < _max_num_q; i++) {
1215       if (yield->should_return()) {
1216         return;
1217       }
1218       preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive,
1219                                   keep_alive, complete_gc, yield);
1220     }
1221   }
1222 }


< prev index next >