Skip to content

Commit 3ce262a

Browse files
author
Thomas Schatzl
committed
optionally use bot
1 parent c1c1326 commit 3ce262a

File tree

5 files changed

+55
-26
lines changed

5 files changed

+55
-26
lines changed

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

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -174,36 +174,47 @@ class SCCompacter {
174174
return _spaces[index]._compaction_top;
175175
}
176176

177-
// Get space at index.
177+
// Get space at index.build_
178178
ContiguousSpace* get_space(uint index) const {
179179
return _spaces[index]._space;
180180
}
181181

182182
// Find the start of the first object at or after addr (but not after limit).
183-
HeapWord* first_object_in_block(HeapWord* addr, HeapWord* start, HeapWord* limit) {
183+
HeapWord* first_object_in_block(HeapWord* addr, HeapWord* start, HeapWord* limit, TenuredSpace* bot_provider) {
184184
if (addr >= limit) return limit;
185185
if (!_mark_bitmap.is_marked(addr)) {
186186
// Easy: find next marked address.
187187
return _mark_bitmap.get_next_marked_addr(addr, limit);
188188
} else {
189-
// Find beginning of live chunk.
190-
HeapWord* current = _mark_bitmap.get_last_unmarked_addr(start, addr);
191-
if (current == addr) {
192-
// No clear bit found before search range, start of range because that must
193-
// be the previous object.
194-
current = start;
195-
} else {
196-
// Use first marked word, this must be an object.
197-
assert(!_mark_bitmap.is_marked(current), "must not be marked");
198-
current = current + 1;
199-
}
200189
// Forward-search to first object >= addr.
201-
while (current < addr) {
202-
size_t obj_size = cast_to_oop(current)->size();
203-
current += obj_size;
190+
if (bot_provider != nullptr) {
191+
HeapWord* reaching_into = bot_provider->block_start_const(addr);
192+
if (reaching_into < addr) {
193+
reaching_into = reaching_into + cast_to_oop<HeapWord*>(reaching_into)->size();
194+
}
195+
assert(reaching_into >= addr, "must be");
196+
assert(reaching_into == limit || oopDesc::is_oop(cast_to_oop<HeapWord*>(reaching_into)), "must be");
197+
return reaching_into;
198+
} else {
199+
// Find beginning of live chunk.
200+
HeapWord* current = _mark_bitmap.get_last_unmarked_addr(start, addr);
201+
if (current == addr) {
202+
// No clear bit found before search range, start of range because that must
203+
// be the previous object.
204+
current = start;
205+
} else {
206+
// Use first marked word, this must be an object.
207+
assert(!_mark_bitmap.is_marked(current), "must not be marked");
208+
current = current + 1;
209+
}
210+
211+
while (current < addr) {
212+
size_t obj_size = cast_to_oop(current)->size();
213+
current += obj_size;
214+
}
215+
assert(current >= addr, "found object start must be >= addr");
216+
return MIN2(current, limit);
204217
}
205-
assert(current >= addr, "found object start must be >= addr");
206-
return MIN2(current, limit);
207218
}
208219
}
209220

@@ -213,6 +224,7 @@ class SCCompacter {
213224
HeapWord* const bottom = space->bottom();
214225
HeapWord* const top = space->top();
215226

227+
TenuredSpace* bot_space = UseNewCode && space == SerialHeap::heap()->old_gen()->space() ? SerialHeap::heap()->old_gen()->space() : nullptr;
216228
// Clear table (only required for assertion in forwardee()).
217229
DEBUG_ONLY(clear(bottom, top);)
218230

@@ -229,7 +241,7 @@ class SCCompacter {
229241
// Find first object that starts after this block and count
230242
// live words up to that object. This is how many words we
231243
// must fit into the current compaction space.
232-
HeapWord* first_obj_after_block = first_object_in_block(current + words_per_block(), first_obj_this_block, top);
244+
HeapWord* first_obj_after_block = first_object_in_block(current + words_per_block(), first_obj_this_block, top, bot_space);
233245
size_t live_in_block = _mark_bitmap.count_marked_words(first_obj_this_block, first_obj_after_block);
234246
while (live_in_block > pointer_delta(_spaces[_index]._space->end(),
235247
compact_top)) {
@@ -398,14 +410,16 @@ void SCCompacter::compact_space(uint idx) const {
398410
// Visit all live objects in the space.
399411
while (current < top) {
400412
assert(_mark_bitmap.is_marked(current), "must be marked");
401-
402-
// Copy the object.
403-
size_t size = cast_to_oop(current)->size();
413+
// Copy the whole chunk.
404414
HeapWord* compact_to = forwardee(current);
415+
416+
HeapWord* next_dead = _mark_bitmap.get_next_unmarked_addr(current, top);
417+
size_t size = pointer_delta(next_dead, current);
418+
405419
Copy::aligned_conjoint_words(current, compact_to, size);
406420

407421
// Advance to next live object.
408-
current = _mark_bitmap.get_next_marked_addr(current + size, top);
422+
current = _mark_bitmap.get_next_marked_addr(next_dead, top);
409423
}
410424

411425
// Reset top and unused memory
@@ -637,7 +651,7 @@ class SCKeepAliveClosure: public OopClosure {
637651

638652
bool SerialCompressor::mark_object(oop obj) {
639653
HeapWord* addr = cast_from_oop<HeapWord*>(obj);
640-
if (!_mark_bitmap.is_marked(addr)) {
654+
if (_mark_bitmap.set_mark(addr)) {
641655
if (StringDedup::is_enabled() &&
642656
java_lang_String::is_instance(obj) &&
643657
SerialStringDedup::is_candidate_from_mark(obj)) {
@@ -648,7 +662,6 @@ bool SerialCompressor::mark_object(oop obj) {
648662
// which might include important class information.
649663
ContinuationGCSupport::transform_stack_chunk(obj);
650664

651-
_mark_bitmap.mark_range(addr, obj->size());
652665
return true;
653666
} else {
654667
return false;
@@ -674,9 +687,11 @@ void SerialCompressor::follow_object(oop obj) {
674687
assert(_mark_bitmap.is_marked(obj), "p must be marked");
675688
if (obj->is_objArray()) {
676689
follow_array((objArrayOop)obj);
690+
_mark_bitmap.mark_range(cast_from_oop<HeapWord*>(obj), ((objArrayOop)obj)->size());
677691
} else {
678692
SCMarkAndPushClosure mark_and_push_closure(ClassLoaderData::_claim_stw_fullgc_mark, *this);
679-
obj->oop_iterate(&mark_and_push_closure);
693+
size_t size = obj->oop_iterate_size(&mark_and_push_closure);
694+
_mark_bitmap.mark_range(cast_from_oop<HeapWord*>(obj), size);
680695
}
681696
}
682697

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class MarkBitMap {
7878
return _bm.at(addr_to_offset(addr));
7979
}
8080

81+
inline bool set_mark(HeapWord* addr);
8182
// Return the address corresponding to the next marked bit at or after
8283
// "addr", and before "limit", if "limit" is non-null. If there is no
8384
// such bit, returns "limit" if that is non-null, or else "endWord()".

src/hotspot/share/gc/shared/markBitMap.inline.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "utilities/align.hpp"
3434
#include "utilities/bitMap.inline.hpp"
3535

36+
inline bool MarkBitMap::set_mark(HeapWord* addr) {
37+
return _bm.maybe_set_bit(addr_to_offset(addr));
38+
}
39+
3640
inline HeapWord* MarkBitMap::get_next_marked_addr(const HeapWord* const addr,
3741
HeapWord* const limit) const {
3842
assert(limit != nullptr, "limit must not be null");

src/hotspot/share/utilities/bitMap.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class BitMap {
214214
// memory_order must be memory_order_relaxed or memory_order_acquire.
215215
bool par_at(idx_t index, atomic_memory_order memory_order = memory_order_acquire) const;
216216

217+
inline bool maybe_set_bit(idx_t bit);
217218
// Set or clear the specified bit.
218219
inline void set_bit(idx_t bit);
219220
inline void clear_bit(idx_t bit);

src/hotspot/share/utilities/bitMap.inline.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
#include "utilities/population_count.hpp"
3434
#include "utilities/powerOfTwo.hpp"
3535

36+
inline bool BitMap::maybe_set_bit(idx_t bit) {
37+
verify_index(bit);
38+
bm_word_t old_value = *word_addr(bit);
39+
bm_word_t new_value = old_value | bit_mask(bit);
40+
*word_addr(bit) = new_value;
41+
return new_value != old_value;
42+
}
43+
3644
inline void BitMap::set_bit(idx_t bit) {
3745
verify_index(bit);
3846
*word_addr(bit) |= bit_mask(bit);

0 commit comments

Comments
 (0)