Skip to content

Commit 4195246

Browse files
committed
8317354: Serial: Move DirtyCardToOopClosure to gc/serial folder
Reviewed-by: tschatzl, iwalulya
1 parent 0a3a925 commit 4195246

File tree

4 files changed

+181
-181
lines changed

4 files changed

+181
-181
lines changed

src/hotspot/share/gc/serial/cardTableRS.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,187 @@
3737
#include "runtime/os.hpp"
3838
#include "utilities/macros.hpp"
3939

40+
// A dirty card to oop closure for contiguous spaces (ContiguousSpace and
41+
// sub-classes). It knows how to filter out objects that are outside of the
42+
// _boundary.
43+
// (Note that because of the imprecise nature of the write barrier, this may
44+
// iterate over oops beyond the region.)
45+
//
46+
// Assumptions:
47+
// 1. That the actual top of any area in a memory region
48+
// contained by the space is bounded by the end of the contiguous
49+
// region of the space.
50+
// 2. That the space is really made up of objects and not just
51+
// blocks.
52+
53+
class DirtyCardToOopClosure: public MemRegionClosure {
54+
protected:
55+
OopIterateClosure* _cl;
56+
Space* _sp;
57+
HeapWord* _min_done; // Need a downwards traversal to compensate
58+
// imprecise write barrier; this is the
59+
// lowest location already done (or,
60+
// alternatively, the lowest address that
61+
// shouldn't be done again. null means infinity.)
62+
NOT_PRODUCT(HeapWord* _last_bottom;)
63+
64+
// Get the actual top of the area on which the closure will
65+
// operate, given where the top is assumed to be (the end of the
66+
// memory region passed to do_MemRegion) and where the object
67+
// at the top is assumed to start. For example, an object may
68+
// start at the top but actually extend past the assumed top,
69+
// in which case the top becomes the end of the object.
70+
HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj);
71+
72+
// Walk the given memory region from bottom to (actual) top
73+
// looking for objects and applying the oop closure (_cl) to
74+
// them. The base implementation of this treats the area as
75+
// blocks, where a block may or may not be an object. Sub-
76+
// classes should override this to provide more accurate
77+
// or possibly more efficient walking.
78+
void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
79+
80+
// Walk the given memory region, from bottom to top, applying
81+
// the given oop closure to (possibly) all objects found. The
82+
// given oop closure may or may not be the same as the oop
83+
// closure with which this closure was created, as it may
84+
// be a filtering closure which makes use of the _boundary.
85+
// We offer two signatures, so the FilteringClosure static type is
86+
// apparent.
87+
void walk_mem_region_with_cl(MemRegion mr,
88+
HeapWord* bottom, HeapWord* top,
89+
OopIterateClosure* cl);
90+
public:
91+
DirtyCardToOopClosure(Space* sp, OopIterateClosure* cl) :
92+
_cl(cl), _sp(sp), _min_done(nullptr) {
93+
NOT_PRODUCT(_last_bottom = nullptr);
94+
}
95+
96+
void do_MemRegion(MemRegion mr) override;
97+
};
98+
99+
HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
100+
HeapWord* top_obj) {
101+
if (top_obj != nullptr && top_obj < (_sp->toContiguousSpace())->top()) {
102+
if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) {
103+
// An arrayOop is starting on the dirty card - since we do exact
104+
// store checks for objArrays we are done.
105+
} else {
106+
// Otherwise, it is possible that the object starting on the dirty
107+
// card spans the entire card, and that the store happened on a
108+
// later card. Figure out where the object ends.
109+
assert(_sp->block_size(top_obj) == cast_to_oop(top_obj)->size(),
110+
"Block size and object size mismatch");
111+
top = top_obj + cast_to_oop(top_obj)->size();
112+
}
113+
} else {
114+
top = (_sp->toContiguousSpace())->top();
115+
}
116+
return top;
117+
}
118+
119+
void DirtyCardToOopClosure::walk_mem_region(MemRegion mr,
120+
HeapWord* bottom,
121+
HeapWord* top) {
122+
// Note that this assumption won't hold if we have a concurrent
123+
// collector in this space, which may have freed up objects after
124+
// they were dirtied and before the stop-the-world GC that is
125+
// examining cards here.
126+
assert(bottom < top, "ought to be at least one obj on a dirty card.");
127+
128+
walk_mem_region_with_cl(mr, bottom, top, _cl);
129+
}
130+
131+
// We get called with "mr" representing the dirty region
132+
// that we want to process. Because of imprecise marking,
133+
// we may need to extend the incoming "mr" to the right,
134+
// and scan more. However, because we may already have
135+
// scanned some of that extended region, we may need to
136+
// trim its right-end back some so we do not scan what
137+
// we (or another worker thread) may already have scanned
138+
// or planning to scan.
139+
void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
140+
HeapWord* bottom = mr.start();
141+
HeapWord* last = mr.last();
142+
HeapWord* top = mr.end();
143+
HeapWord* bottom_obj;
144+
HeapWord* top_obj;
145+
146+
assert(_last_bottom == nullptr || top <= _last_bottom,
147+
"Not decreasing");
148+
NOT_PRODUCT(_last_bottom = mr.start());
149+
150+
bottom_obj = _sp->block_start(bottom);
151+
top_obj = _sp->block_start(last);
152+
153+
assert(bottom_obj <= bottom, "just checking");
154+
assert(top_obj <= top, "just checking");
155+
156+
// Given what we think is the top of the memory region and
157+
// the start of the object at the top, get the actual
158+
// value of the top.
159+
top = get_actual_top(top, top_obj);
160+
161+
// If the previous call did some part of this region, don't redo.
162+
if (_min_done != nullptr && _min_done < top) {
163+
top = _min_done;
164+
}
165+
166+
// Top may have been reset, and in fact may be below bottom,
167+
// e.g. the dirty card region is entirely in a now free object
168+
// -- something that could happen with a concurrent sweeper.
169+
bottom = MIN2(bottom, top);
170+
MemRegion extended_mr = MemRegion(bottom, top);
171+
assert(bottom <= top &&
172+
(_min_done == nullptr || top <= _min_done),
173+
"overlap!");
174+
175+
// Walk the region if it is not empty; otherwise there is nothing to do.
176+
if (!extended_mr.is_empty()) {
177+
walk_mem_region(extended_mr, bottom_obj, top);
178+
}
179+
180+
_min_done = bottom;
181+
}
182+
183+
void DirtyCardToOopClosure::walk_mem_region_with_cl(MemRegion mr,
184+
HeapWord* bottom,
185+
HeapWord* top,
186+
OopIterateClosure* cl) {
187+
bottom += cast_to_oop(bottom)->oop_iterate_size(cl, mr);
188+
if (bottom < top) {
189+
HeapWord* next_obj = bottom + cast_to_oop(bottom)->size();
190+
while (next_obj < top) {
191+
/* Bottom lies entirely below top, so we can call the */
192+
/* non-memRegion version of oop_iterate below. */
193+
cast_to_oop(bottom)->oop_iterate(cl);
194+
bottom = next_obj;
195+
next_obj = bottom + cast_to_oop(bottom)->size();
196+
}
197+
/* Last object. */
198+
cast_to_oop(bottom)->oop_iterate(cl, mr);
199+
}
200+
}
201+
202+
class ClearNoncleanCardWrapper: public MemRegionClosure {
203+
DirtyCardToOopClosure* _dirty_card_closure;
204+
CardTableRS* _ct;
205+
206+
public:
207+
208+
typedef CardTable::CardValue CardValue;
209+
private:
210+
// Clears the given card, return true if the corresponding card should be
211+
// processed.
212+
inline bool clear_card(CardValue* entry);
213+
// check alignment of pointer
214+
bool is_word_aligned(CardValue* entry);
215+
216+
public:
217+
ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct);
218+
void do_MemRegion(MemRegion mr) override;
219+
};
220+
40221
inline bool ClearNoncleanCardWrapper::clear_card(CardValue* entry) {
41222
assert(*entry == CardTableRS::dirty_card_val(), "Only look at dirty cards.");
42223
*entry = CardTableRS::clean_card_val();

src/hotspot/share/gc/serial/cardTableRS.hpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,4 @@ class CardTableRS : public CardTable {
8080
bool is_in_young(const void* p) const override;
8181
};
8282

83-
class ClearNoncleanCardWrapper: public MemRegionClosure {
84-
DirtyCardToOopClosure* _dirty_card_closure;
85-
CardTableRS* _ct;
86-
87-
public:
88-
89-
typedef CardTable::CardValue CardValue;
90-
private:
91-
// Clears the given card, return true if the corresponding card should be
92-
// processed.
93-
inline bool clear_card(CardValue* entry);
94-
// check alignment of pointer
95-
bool is_word_aligned(CardValue* entry);
96-
97-
public:
98-
ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct);
99-
void do_MemRegion(MemRegion mr) override;
100-
};
101-
10283
#endif // SHARE_GC_SERIAL_CARDTABLERS_HPP

src/hotspot/share/gc/shared/space.cpp

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -46,109 +46,6 @@
4646
#include "gc/serial/defNewGeneration.hpp"
4747
#endif
4848

49-
HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top,
50-
HeapWord* top_obj) {
51-
if (top_obj != nullptr && top_obj < (_sp->toContiguousSpace())->top()) {
52-
if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) {
53-
// An arrayOop is starting on the dirty card - since we do exact
54-
// store checks for objArrays we are done.
55-
} else {
56-
// Otherwise, it is possible that the object starting on the dirty
57-
// card spans the entire card, and that the store happened on a
58-
// later card. Figure out where the object ends.
59-
assert(_sp->block_size(top_obj) == cast_to_oop(top_obj)->size(),
60-
"Block size and object size mismatch");
61-
top = top_obj + cast_to_oop(top_obj)->size();
62-
}
63-
} else {
64-
top = (_sp->toContiguousSpace())->top();
65-
}
66-
return top;
67-
}
68-
69-
void DirtyCardToOopClosure::walk_mem_region(MemRegion mr,
70-
HeapWord* bottom,
71-
HeapWord* top) {
72-
// Note that this assumption won't hold if we have a concurrent
73-
// collector in this space, which may have freed up objects after
74-
// they were dirtied and before the stop-the-world GC that is
75-
// examining cards here.
76-
assert(bottom < top, "ought to be at least one obj on a dirty card.");
77-
78-
walk_mem_region_with_cl(mr, bottom, top, _cl);
79-
}
80-
81-
// We get called with "mr" representing the dirty region
82-
// that we want to process. Because of imprecise marking,
83-
// we may need to extend the incoming "mr" to the right,
84-
// and scan more. However, because we may already have
85-
// scanned some of that extended region, we may need to
86-
// trim its right-end back some so we do not scan what
87-
// we (or another worker thread) may already have scanned
88-
// or planning to scan.
89-
void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) {
90-
HeapWord* bottom = mr.start();
91-
HeapWord* last = mr.last();
92-
HeapWord* top = mr.end();
93-
HeapWord* bottom_obj;
94-
HeapWord* top_obj;
95-
96-
assert(_last_bottom == nullptr || top <= _last_bottom,
97-
"Not decreasing");
98-
NOT_PRODUCT(_last_bottom = mr.start());
99-
100-
bottom_obj = _sp->block_start(bottom);
101-
top_obj = _sp->block_start(last);
102-
103-
assert(bottom_obj <= bottom, "just checking");
104-
assert(top_obj <= top, "just checking");
105-
106-
// Given what we think is the top of the memory region and
107-
// the start of the object at the top, get the actual
108-
// value of the top.
109-
top = get_actual_top(top, top_obj);
110-
111-
// If the previous call did some part of this region, don't redo.
112-
if (_min_done != nullptr && _min_done < top) {
113-
top = _min_done;
114-
}
115-
116-
// Top may have been reset, and in fact may be below bottom,
117-
// e.g. the dirty card region is entirely in a now free object
118-
// -- something that could happen with a concurrent sweeper.
119-
bottom = MIN2(bottom, top);
120-
MemRegion extended_mr = MemRegion(bottom, top);
121-
assert(bottom <= top &&
122-
(_min_done == nullptr || top <= _min_done),
123-
"overlap!");
124-
125-
// Walk the region if it is not empty; otherwise there is nothing to do.
126-
if (!extended_mr.is_empty()) {
127-
walk_mem_region(extended_mr, bottom_obj, top);
128-
}
129-
130-
_min_done = bottom;
131-
}
132-
133-
void DirtyCardToOopClosure::walk_mem_region_with_cl(MemRegion mr,
134-
HeapWord* bottom,
135-
HeapWord* top,
136-
OopIterateClosure* cl) {
137-
bottom += cast_to_oop(bottom)->oop_iterate_size(cl, mr);
138-
if (bottom < top) {
139-
HeapWord* next_obj = bottom + cast_to_oop(bottom)->size();
140-
while (next_obj < top) {
141-
/* Bottom lies entirely below top, so we can call the */
142-
/* non-memRegion version of oop_iterate below. */
143-
cast_to_oop(bottom)->oop_iterate(cl);
144-
bottom = next_obj;
145-
next_obj = bottom + cast_to_oop(bottom)->size();
146-
}
147-
/* Last object. */
148-
cast_to_oop(bottom)->oop_iterate(cl, mr);
149-
}
150-
}
151-
15249
void Space::initialize(MemRegion mr,
15350
bool clear_space,
15451
bool mangle_space) {

src/hotspot/share/gc/shared/space.hpp

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -221,65 +221,6 @@ class Space: public CHeapObj<mtGC> {
221221
virtual void verify() const = 0;
222222
};
223223

224-
// A dirty card to oop closure for contiguous spaces (ContiguousSpace and
225-
// sub-classes). It knows how to filter out objects that are outside of the
226-
// _boundary.
227-
// (Note that because of the imprecise nature of the write barrier, this may
228-
// iterate over oops beyond the region.)
229-
//
230-
// Assumptions:
231-
// 1. That the actual top of any area in a memory region
232-
// contained by the space is bounded by the end of the contiguous
233-
// region of the space.
234-
// 2. That the space is really made up of objects and not just
235-
// blocks.
236-
237-
class DirtyCardToOopClosure: public MemRegionClosure {
238-
protected:
239-
OopIterateClosure* _cl;
240-
Space* _sp;
241-
HeapWord* _min_done; // Need a downwards traversal to compensate
242-
// imprecise write barrier; this is the
243-
// lowest location already done (or,
244-
// alternatively, the lowest address that
245-
// shouldn't be done again. null means infinity.)
246-
NOT_PRODUCT(HeapWord* _last_bottom;)
247-
248-
// Get the actual top of the area on which the closure will
249-
// operate, given where the top is assumed to be (the end of the
250-
// memory region passed to do_MemRegion) and where the object
251-
// at the top is assumed to start. For example, an object may
252-
// start at the top but actually extend past the assumed top,
253-
// in which case the top becomes the end of the object.
254-
HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj);
255-
256-
// Walk the given memory region from bottom to (actual) top
257-
// looking for objects and applying the oop closure (_cl) to
258-
// them. The base implementation of this treats the area as
259-
// blocks, where a block may or may not be an object. Sub-
260-
// classes should override this to provide more accurate
261-
// or possibly more efficient walking.
262-
void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top);
263-
264-
// Walk the given memory region, from bottom to top, applying
265-
// the given oop closure to (possibly) all objects found. The
266-
// given oop closure may or may not be the same as the oop
267-
// closure with which this closure was created, as it may
268-
// be a filtering closure which makes use of the _boundary.
269-
// We offer two signatures, so the FilteringClosure static type is
270-
// apparent.
271-
void walk_mem_region_with_cl(MemRegion mr,
272-
HeapWord* bottom, HeapWord* top,
273-
OopIterateClosure* cl);
274-
public:
275-
DirtyCardToOopClosure(Space* sp, OopIterateClosure* cl) :
276-
_cl(cl), _sp(sp), _min_done(nullptr) {
277-
NOT_PRODUCT(_last_bottom = nullptr);
278-
}
279-
280-
void do_MemRegion(MemRegion mr) override;
281-
};
282-
283224
// A structure to represent a point at which objects are being copied
284225
// during compaction.
285226
class CompactPoint : public StackObj {

0 commit comments

Comments
 (0)