hotspot/src/share/vm/oops/instanceRefKlass.cpp
changeset 10526 3e92f211533f
parent 9935 51267b5e1a3d
child 10537 23539f11e110
equal deleted inserted replaced
10525:5e44fe6a4262 10526:3e92f211533f
    54     }
    54     }
    55   )
    55   )
    56   if (!oopDesc::is_null(heap_oop)) {
    56   if (!oopDesc::is_null(heap_oop)) {
    57     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
    57     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
    58     if (!referent->is_gc_marked() &&
    58     if (!referent->is_gc_marked() &&
    59         MarkSweep::ref_processor()->
    59         MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
    60           discover_reference(obj, ref->reference_type())) {
    60       // reference was discovered, referent will be traversed later
    61       // reference already enqueued, referent will be traversed later
       
    62       ref->instanceKlass::oop_follow_contents(obj);
    61       ref->instanceKlass::oop_follow_contents(obj);
    63       debug_only(
    62       debug_only(
    64         if(TraceReferenceGC && PrintGCDetails) {
    63         if(TraceReferenceGC && PrintGCDetails) {
    65           gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
    64           gclog_or_tty->print_cr("       Non NULL enqueued " INTPTR_FORMAT, obj);
    66         }
    65         }
    74         }
    73         }
    75       )
    74       )
    76       MarkSweep::mark_and_push(referent_addr);
    75       MarkSweep::mark_and_push(referent_addr);
    77     }
    76     }
    78   }
    77   }
    79   // treat next as normal oop.  next is a link in the pending list.
       
    80   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
    78   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
       
    79   if (ReferenceProcessor::pending_list_uses_discovered_field()) {
       
    80     // Treat discovered as normal oop, if ref is not "active",
       
    81     // i.e. if next is non-NULL.
       
    82     T  next_oop = oopDesc::load_heap_oop(next_addr);
       
    83     if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
       
    84       T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
       
    85       debug_only(
       
    86         if(TraceReferenceGC && PrintGCDetails) {
       
    87           gclog_or_tty->print_cr("   Process discovered as normal "
       
    88                                  INTPTR_FORMAT, discovered_addr);
       
    89         }
       
    90       )
       
    91       MarkSweep::mark_and_push(discovered_addr);
       
    92     }
       
    93   } else {
       
    94 #ifdef ASSERT
       
    95     // In the case of older JDKs which do not use the discovered
       
    96     // field for the pending list, an inactive ref (next != NULL)
       
    97     // must always have a NULL discovered field.
       
    98     oop next = oopDesc::load_decode_heap_oop(next_addr);
       
    99     oop discovered = java_lang_ref_Reference::discovered(obj);
       
   100     assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
       
   101            err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
       
   102                    obj));
       
   103 #endif
       
   104   }
       
   105   // treat next as normal oop.  next is a link in the reference queue.
    81   debug_only(
   106   debug_only(
    82     if(TraceReferenceGC && PrintGCDetails) {
   107     if(TraceReferenceGC && PrintGCDetails) {
    83       gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
   108       gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
    84     }
   109     }
    85   )
   110   )
   128         }
   153         }
   129       )
   154       )
   130       PSParallelCompact::mark_and_push(cm, referent_addr);
   155       PSParallelCompact::mark_and_push(cm, referent_addr);
   131     }
   156     }
   132   }
   157   }
   133   // treat next as normal oop.  next is a link in the pending list.
       
   134   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
   158   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
   135   debug_only(
   159   if (ReferenceProcessor::pending_list_uses_discovered_field()) {
   136     if(TraceReferenceGC && PrintGCDetails) {
   160     // Treat discovered as normal oop, if ref is not "active",
   137       gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
   161     // i.e. if next is non-NULL.
   138     }
   162     T  next_oop = oopDesc::load_heap_oop(next_addr);
   139   )
   163     if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
       
   164       T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
       
   165       debug_only(
       
   166         if(TraceReferenceGC && PrintGCDetails) {
       
   167           gclog_or_tty->print_cr("   Process discovered as normal "
       
   168                                  INTPTR_FORMAT, discovered_addr);
       
   169         }
       
   170       )
       
   171       PSParallelCompact::mark_and_push(cm, discovered_addr);
       
   172     }
       
   173   } else {
       
   174 #ifdef ASSERT
       
   175     // In the case of older JDKs which do not use the discovered
       
   176     // field for the pending list, an inactive ref (next != NULL)
       
   177     // must always have a NULL discovered field.
       
   178     T next = oopDesc::load_heap_oop(next_addr);
       
   179     oop discovered = java_lang_ref_Reference::discovered(obj);
       
   180     assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
       
   181            err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
       
   182                    obj));
       
   183 #endif
       
   184   }
   140   PSParallelCompact::mark_and_push(cm, next_addr);
   185   PSParallelCompact::mark_and_push(cm, next_addr);
   141   ref->instanceKlass::oop_follow_contents(cm, obj);
   186   ref->instanceKlass::oop_follow_contents(cm, obj);
   142 }
   187 }
   143 
   188 
   144 void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
   189 void instanceRefKlass::oop_follow_contents(ParCompactionManager* cm,
   195   }
   240   }
   196   return size;
   241   return size;
   197 }
   242 }
   198 
   243 
   199 #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
   244 #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
       
   245   T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);             \
   200   if (closure->apply_to_weak_ref_discovered_field()) {                          \
   246   if (closure->apply_to_weak_ref_discovered_field()) {                          \
   201     T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);           \
       
   202     closure->do_oop##nv_suffix(disc_addr);                                      \
   247     closure->do_oop##nv_suffix(disc_addr);                                      \
   203   }                                                                             \
   248   }                                                                             \
   204                                                                                 \
   249                                                                                 \
   205   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
   250   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
   206   T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
   251   T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
   207   if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) {                 \
   252   ReferenceProcessor* rp = closure->_ref_processor;                             \
   208     ReferenceProcessor* rp = closure->_ref_processor;                           \
   253   if (!oopDesc::is_null(heap_oop)) {                                            \
   209     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
   254     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
   210     if (!referent->is_gc_marked() && (rp != NULL) &&                            \
   255     if (!referent->is_gc_marked() && (rp != NULL) &&                            \
   211         rp->discover_reference(obj, reference_type())) {                        \
   256         rp->discover_reference(obj, reference_type())) {                        \
   212       return size;                                                              \
   257       return size;                                                              \
   213     } else {                                                                    \
   258     } else if (contains(referent_addr)) {                                       \
   214       /* treat referent as normal oop */                                        \
   259       /* treat referent as normal oop */                                        \
   215       SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
   260       SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
   216       closure->do_oop##nv_suffix(referent_addr);                                \
   261       closure->do_oop##nv_suffix(referent_addr);                                \
   217     }                                                                           \
   262     }                                                                           \
   218   }                                                                             \
   263   }                                                                             \
       
   264   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
       
   265   if (ReferenceProcessor::pending_list_uses_discovered_field()) {               \
       
   266     T next_oop  = oopDesc::load_heap_oop(next_addr);                            \
       
   267     /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\
       
   268     if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {                   \
       
   269         /* i.e. ref is not "active" */                                          \
       
   270       debug_only(                                                               \
       
   271         if(TraceReferenceGC && PrintGCDetails) {                                \
       
   272           gclog_or_tty->print_cr("   Process discovered as normal "             \
       
   273                                  INTPTR_FORMAT, disc_addr);                     \
       
   274         }                                                                       \
       
   275       )                                                                         \
       
   276       SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
       
   277       closure->do_oop##nv_suffix(disc_addr);                                    \
       
   278     }                                                                           \
       
   279   } else {                                                                      \
       
   280     /* In the case of older JDKs which do not use the discovered field for  */  \
       
   281     /* the pending list, an inactive ref (next != NULL) must always have a  */  \
       
   282     /* NULL discovered field. */                                                \
       
   283     debug_only(                                                                 \
       
   284       T next_oop = oopDesc::load_heap_oop(next_addr);                           \
       
   285       T disc_oop = oopDesc::load_heap_oop(disc_addr);                           \
       
   286       assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),          \
       
   287            err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \
       
   288                    "discovered field", obj));                                   \
       
   289     )                                                                           \
       
   290   }                                                                             \
   219   /* treat next as normal oop */                                                \
   291   /* treat next as normal oop */                                                \
   220   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
       
   221   if (contains(next_addr)) {                                                    \
   292   if (contains(next_addr)) {                                                    \
   222     SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
   293     SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
   223     closure->do_oop##nv_suffix(next_addr);                                      \
   294     closure->do_oop##nv_suffix(next_addr);                                      \
   224   }                                                                             \
   295   }                                                                             \
   225   return size;                                                                  \
   296   return size;                                                                  \
   304     } else {
   375     } else {
   305       // treat referent as normal oop
   376       // treat referent as normal oop
   306       pm->claim_or_forward_depth(referent_addr);
   377       pm->claim_or_forward_depth(referent_addr);
   307     }
   378     }
   308   }
   379   }
   309   // treat next as normal oop
   380   // Treat discovered as normal oop, if ref is not "active",
       
   381   // i.e. if next is non-NULL.
   310   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
   382   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
       
   383   if (ReferenceProcessor::pending_list_uses_discovered_field()) {
       
   384     T  next_oop = oopDesc::load_heap_oop(next_addr);
       
   385     if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
       
   386       T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
       
   387       debug_only(
       
   388         if(TraceReferenceGC && PrintGCDetails) {
       
   389           gclog_or_tty->print_cr("   Process discovered as normal "
       
   390                                  INTPTR_FORMAT, discovered_addr);
       
   391         }
       
   392       )
       
   393       if (PSScavenge::should_scavenge(discovered_addr)) {
       
   394         pm->claim_or_forward_depth(discovered_addr);
       
   395       }
       
   396     }
       
   397   } else {
       
   398 #ifdef ASSERT
       
   399     // In the case of older JDKs which do not use the discovered
       
   400     // field for the pending list, an inactive ref (next != NULL)
       
   401     // must always have a NULL discovered field.
       
   402     oop next = oopDesc::load_decode_heap_oop(next_addr);
       
   403     oop discovered = java_lang_ref_Reference::discovered(obj);
       
   404     assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
       
   405            err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
       
   406                    obj));
       
   407 #endif
       
   408   }
       
   409 
       
   410   // Treat next as normal oop;  next is a link in the reference queue.
   311   if (PSScavenge::should_scavenge(next_addr)) {
   411   if (PSScavenge::should_scavenge(next_addr)) {
   312     pm->claim_or_forward_depth(next_addr);
   412     pm->claim_or_forward_depth(next_addr);
   313   }
   413   }
   314   ref->instanceKlass::oop_push_contents(pm, obj);
   414   ref->instanceKlass::oop_push_contents(pm, obj);
   315 }
   415 }