23
24 #include "gc/z/zGeneration.inline.hpp"
25 #include "gc/z/zHeap.inline.hpp"
26 #include "gc/z/zLiveMap.inline.hpp"
27 #include "gc/z/zStat.hpp"
28 #include "gc/z/zUtils.hpp"
29 #include "logging/log.hpp"
30 #include "utilities/debug.hpp"
31 #include "utilities/powerOfTwo.hpp"
32 #include "utilities/spinYield.hpp"
33
34 static const ZStatCounter ZCounterMarkSeqNumResetContention("Contention", "Mark SeqNum Reset Contention", ZStatUnitOpsPerSecond);
35 static const ZStatCounter ZCounterMarkSegmentResetContention("Contention", "Mark Segment Reset Contention", ZStatUnitOpsPerSecond);
36
37 ZLiveMap::ZLiveMap(uint32_t object_max_count)
38 : _segment_size((object_max_count == 1 ? 1u : (object_max_count / NumSegments)) * BitsPerObject),
39 _segment_shift(log2i_exact(_segment_size)),
40 _seqnum(0),
41 _live_objects(0),
42 _live_bytes(0),
43 _segment_live_bits(0),
44 _segment_claim_bits(0),
45 _bitmap(0) {}
46
47 void ZLiveMap::initialize_bitmap() {
48 if (_bitmap.size() == 0) {
49 _bitmap.initialize(size_t(_segment_size) * size_t(NumSegments), false /* clear */);
50 }
51 }
52
53 void ZLiveMap::reset(ZGenerationId id) {
54 ZGeneration* const generation = ZGeneration::generation(id);
55 const uint32_t seqnum_initializing = (uint32_t)-1;
56 bool contention = false;
57
58 SpinYield yielder(0, 0, 1000);
59
60 // Multiple threads can enter here, make sure only one of them
61 // resets the marking information while the others busy wait.
62 for (uint32_t seqnum = _seqnum.load_acquire();
63 seqnum != generation->seqnum();
64 seqnum = _seqnum.load_acquire()) {
65
66 if (seqnum != seqnum_initializing) {
67 // No one has claimed initialization of the livemap yet
68 if (_seqnum.compare_set(seqnum, seqnum_initializing)) {
69 // This thread claimed the initialization
70
71 // Reset marking information
72 _live_bytes.store_relaxed(0u);
73 _live_objects.store_relaxed(0u);
74
75 // Clear segment claimed/live bits
76 segment_live_bits().clear();
77 segment_claim_bits().clear();
78
79 // We lazily initialize the bitmap the first time the page is marked, i.e.
80 // a bit is about to be set for the first time.
81 initialize_bitmap();
82
83 assert(_seqnum.load_relaxed() == seqnum_initializing, "Invalid");
84
85 // Make sure the newly reset marking information is ordered
86 // before the update of the page seqnum, such that when the
87 // up-to-date seqnum is load acquired, the bit maps will not
88 // contain stale information.
89 _seqnum.release_store(generation->seqnum());
90 break;
91 }
92 }
93
|
23
24 #include "gc/z/zGeneration.inline.hpp"
25 #include "gc/z/zHeap.inline.hpp"
26 #include "gc/z/zLiveMap.inline.hpp"
27 #include "gc/z/zStat.hpp"
28 #include "gc/z/zUtils.hpp"
29 #include "logging/log.hpp"
30 #include "utilities/debug.hpp"
31 #include "utilities/powerOfTwo.hpp"
32 #include "utilities/spinYield.hpp"
33
34 static const ZStatCounter ZCounterMarkSeqNumResetContention("Contention", "Mark SeqNum Reset Contention", ZStatUnitOpsPerSecond);
35 static const ZStatCounter ZCounterMarkSegmentResetContention("Contention", "Mark Segment Reset Contention", ZStatUnitOpsPerSecond);
36
37 ZLiveMap::ZLiveMap(uint32_t object_max_count)
38 : _segment_size((object_max_count == 1 ? 1u : (object_max_count / NumSegments)) * BitsPerObject),
39 _segment_shift(log2i_exact(_segment_size)),
40 _seqnum(0),
41 _live_objects(0),
42 _live_bytes(0),
43 _will_expand_objects(0),
44 _segment_live_bits(0),
45 _segment_claim_bits(0),
46 _bitmap(0) {}
47
48 void ZLiveMap::initialize_bitmap() {
49 if (_bitmap.size() == 0) {
50 _bitmap.initialize(size_t(_segment_size) * size_t(NumSegments), false /* clear */);
51 }
52 }
53
54 void ZLiveMap::reset(ZGenerationId id) {
55 ZGeneration* const generation = ZGeneration::generation(id);
56 const uint32_t seqnum_initializing = (uint32_t)-1;
57 bool contention = false;
58
59 SpinYield yielder(0, 0, 1000);
60
61 // Multiple threads can enter here, make sure only one of them
62 // resets the marking information while the others busy wait.
63 for (uint32_t seqnum = _seqnum.load_acquire();
64 seqnum != generation->seqnum();
65 seqnum = _seqnum.load_acquire()) {
66
67 if (seqnum != seqnum_initializing) {
68 // No one has claimed initialization of the livemap yet
69 if (_seqnum.compare_set(seqnum, seqnum_initializing)) {
70 // This thread claimed the initialization
71
72 // Reset marking information
73 _live_bytes.store_relaxed(0u);
74 _live_objects.store_relaxed(0u);
75 _will_expand_objects.store_relaxed(0u);
76
77 // Clear segment claimed/live bits
78 segment_live_bits().clear();
79 segment_claim_bits().clear();
80
81 // We lazily initialize the bitmap the first time the page is marked, i.e.
82 // a bit is about to be set for the first time.
83 initialize_bitmap();
84
85 assert(_seqnum.load_relaxed() == seqnum_initializing, "Invalid");
86
87 // Make sure the newly reset marking information is ordered
88 // before the update of the page seqnum, such that when the
89 // up-to-date seqnum is load acquired, the bit maps will not
90 // contain stale information.
91 _seqnum.release_store(generation->seqnum());
92 break;
93 }
94 }
95
|