1011 assert(_discovery_is_mt, "!_discovery_is_mt should have been handled by caller"); |
1011 assert(_discovery_is_mt, "!_discovery_is_mt should have been handled by caller"); |
1012 // First we must make sure this object is only enqueued once. CAS in a non null |
1012 // First we must make sure this object is only enqueued once. CAS in a non null |
1013 // discovered_addr. |
1013 // discovered_addr. |
1014 oop current_head = refs_list.head(); |
1014 oop current_head = refs_list.head(); |
1015 |
1015 |
1016 // Note: In the case of G1, this pre-barrier is strictly |
1016 // Note: In the case of G1, this specific pre-barrier is strictly |
1017 // not necessary because the only case we are interested in |
1017 // not necessary because the only case we are interested in |
1018 // here is when *discovered_addr is NULL, so this will expand to |
1018 // here is when *discovered_addr is NULL (see the CAS further below), |
1019 // nothing. As a result, I am just manually eliding this out for G1. |
1019 // so this will expand to nothing. As a result, we have manually |
|
1020 // elided this out for G1, but left in the test for some future |
|
1021 // collector that might have need for a pre-barrier here. |
1020 if (_discovered_list_needs_barrier && !UseG1GC) { |
1022 if (_discovered_list_needs_barrier && !UseG1GC) { |
1021 _bs->write_ref_field_pre((void*)discovered_addr, current_head); guarantee(false, "Needs to be fixed: YSR"); |
1023 if (UseCompressedOops) { |
|
1024 _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head); |
|
1025 } else { |
|
1026 _bs->write_ref_field_pre((oop*)discovered_addr, current_head); |
|
1027 } |
|
1028 guarantee(false, "Need to check non-G1 collector"); |
1022 } |
1029 } |
1023 oop retest = oopDesc::atomic_compare_exchange_oop(current_head, discovered_addr, |
1030 oop retest = oopDesc::atomic_compare_exchange_oop(current_head, discovered_addr, |
1024 NULL); |
1031 NULL); |
1025 if (retest == NULL) { |
1032 if (retest == NULL) { |
1026 // This thread just won the right to enqueue the object. |
1033 // This thread just won the right to enqueue the object. |
1027 // We have separate lists for enqueueing so no synchronization |
1034 // We have separate lists for enqueueing so no synchronization |
1028 // is necessary. |
1035 // is necessary. |
1029 refs_list.set_head(obj); |
1036 refs_list.set_head(obj); |
1030 refs_list.inc_length(1); |
1037 refs_list.inc_length(1); |
1031 if (_discovered_list_needs_barrier) { |
1038 if (_discovered_list_needs_barrier) { |
1032 _bs->write_ref_field((void*)discovered_addr, current_head); guarantee(false, "Needs to be fixed: YSR"); |
1039 _bs->write_ref_field((void*)discovered_addr, current_head); |
1033 } |
1040 } |
1034 |
|
1035 } else { |
1041 } else { |
1036 // If retest was non NULL, another thread beat us to it: |
1042 // If retest was non NULL, another thread beat us to it: |
1037 // The reference has already been discovered... |
1043 // The reference has already been discovered... |
1038 if (TraceReferenceGC) { |
1044 if (TraceReferenceGC) { |
1039 gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)", |
1045 gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)", |
1175 oop current_head = list->head(); |
1181 oop current_head = list->head(); |
1176 // As in the case further above, since we are over-writing a NULL |
1182 // As in the case further above, since we are over-writing a NULL |
1177 // pre-value, we can safely elide the pre-barrier here for the case of G1. |
1183 // pre-value, we can safely elide the pre-barrier here for the case of G1. |
1178 assert(discovered == NULL, "control point invariant"); |
1184 assert(discovered == NULL, "control point invariant"); |
1179 if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1 |
1185 if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1 |
1180 _bs->write_ref_field_pre((oop*)discovered_addr, current_head); |
1186 if (UseCompressedOops) { |
|
1187 _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head); |
|
1188 } else { |
|
1189 _bs->write_ref_field_pre((oop*)discovered_addr, current_head); |
|
1190 } |
|
1191 guarantee(false, "Need to check non-G1 collector"); |
1181 } |
1192 } |
1182 oop_store_raw(discovered_addr, current_head); |
1193 oop_store_raw(discovered_addr, current_head); |
1183 if (_discovered_list_needs_barrier) { |
1194 if (_discovered_list_needs_barrier) { |
1184 _bs->write_ref_field((oop*)discovered_addr, current_head); |
1195 _bs->write_ref_field((void*)discovered_addr, current_head); |
1185 } |
1196 } |
1186 list->set_head(obj); |
1197 list->set_head(obj); |
1187 list->inc_length(1); |
1198 list->inc_length(1); |
1188 } |
1199 } |
1189 |
1200 |