Skip to content

Commit ed99551

Browse files
authored
GC verify debugging (#4)
* update with changes done in the past few weeks, maily remapping from new to original addresses * fixed a bug related to G1HeapRegion's parsable area * added the printMemoryRegionMap() function for debugging and other debugging prints
1 parent 9cc65c2 commit ed99551

14 files changed

+166
-24
lines changed

src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ void G1BarrierSetC2::post_barrier(GraphKit* kit,
485485
Node* mapped;
486486
if (SanitizeGC) {
487487
mapped = __ make_leaf_call(mapNewAddrToOriginalAddr_Type(), CAST_FROM_FN_PTR(address,
488-
SanitizerGCMapper::mapNewAddrToOriginalAddr), "mapNewAddrToOriginalAddr", card_adr)->in(0);
488+
SanitizerGCMapper::mapNewAddrToOriginalAddr), "mapNewAddrToOriginalAddr", card_adr)->in(0);//->lookup(3); SANITIZE TODO
489489
} else {
490490
mapped = card_adr;
491491
}

src/hotspot/share/gc/g1/customMapper.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
ptrdiff_t SanitizerGCMapper::movedRegionOffset = 0;
44
const void* SanitizerGCMapper::movedRegionStart = nullptr;
55
const void* SanitizerGCMapper::movedRegionEnd = nullptr;
6+
const void* SanitizerGCMapper::originalRegionStart = nullptr;
7+
const void* SanitizerGCMapper::originalRegionEnd = nullptr;
68

79
// Since we can't use void* for pointer arithmetic, we need another pointer
810
// type, whose base element size is the unit for movedRegionOffset. We must use
@@ -12,23 +14,34 @@ const void* SanitizerGCMapper::movedRegionEnd = nullptr;
1214
using byte_ptr = const char*;
1315

1416
void SanitizerGCMapper::initializeMapping(const void* originalRegionStart,
15-
const void* movedRegionStart, const void* movedRegionEnd) {
17+
const void* originalRegionEnd, const void* movedRegionStart, const void* movedRegionEnd) {
1618
SanitizerGCMapper::movedRegionOffset =
1719
static_cast<byte_ptr>(originalRegionStart) -
1820
static_cast<byte_ptr>(movedRegionStart);
1921
SanitizerGCMapper::movedRegionStart = movedRegionStart;
2022
SanitizerGCMapper::movedRegionEnd = movedRegionEnd;
23+
SanitizerGCMapper::originalRegionStart = originalRegionStart;
24+
SanitizerGCMapper::originalRegionEnd = originalRegionEnd;
2125
}
2226

2327
const void* SanitizerGCMapper::mapNewAddrToOriginalAddr(const void* newAddr) {
2428
if (movedRegionOffset != 0 &&
25-
newAddr >= movedRegionStart && newAddr < movedRegionEnd) {
29+
newAddr >= movedRegionStart && newAddr <= movedRegionEnd) { // TODO
2630
return static_cast<byte_ptr>(newAddr) + movedRegionOffset;
2731
}
2832

2933
return newAddr;
3034
}
3135

36+
const void* SanitizerGCMapper::mapOriginalAddrToNewAddr(const void* originalAddr) {
37+
if (movedRegionOffset != 0 &&
38+
originalAddr >= originalRegionStart && originalAddr <= originalRegionEnd) {
39+
return static_cast<byte_ptr>(originalAddr) - movedRegionOffset;
40+
}
41+
42+
return originalAddr;
43+
}
44+
3245
void SanitizerGCMapper::testPrint(void* newAddr) {
3346
printf("---+++%p\n", newAddr);
3447
}

src/hotspot/share/gc/g1/customMapper.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,32 @@
66

77
class SanitizerGCMapper {
88
private:
9+
// TODO, put the public variables back here
10+
11+
public:
912
static ptrdiff_t movedRegionOffset;
1013
static const void* movedRegionStart;
1114
static const void* movedRegionEnd;
15+
static const void* originalRegionStart;
16+
static const void* originalRegionEnd;
17+
1218

13-
public:
1419
static void initializeMapping(const void* originalRegionStart,
15-
const void* movedRegionStart, const void* movedRegionEnd);
20+
const void* originalRegionEnd, const void* movedRegionStart, const void* movedRegionEnd);
1621
static const void* mapNewAddrToOriginalAddr(const void* newAddr);
22+
static const void* mapOriginalAddrToNewAddr(const void *newAddr);
23+
1724
static void testPrint(void* newAddr);
1825
template <typename T> static inline void remapAddress(T &addr) {
1926
if (SanitizeGC) {
2027
addr = (T) mapNewAddrToOriginalAddr(addr);
2128
}
2229
}
30+
template <typename T> static inline void reverseRemapAddress(T &addr) {
31+
if (SanitizeGC) {
32+
addr = (T) mapOriginalAddrToNewAddr(addr);
33+
}
34+
}
2335
};
2436

2537
#endif //CUSTOMMAPPER_H

src/hotspot/share/gc/g1/g1BiasedArray.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "memory/memRegion.hpp"
3030
#include "utilities/debug.hpp"
3131
#include "utilities/powerOfTwo.hpp"
32+
#include "customMapper.hpp"
3233

3334
// Implements the common base functionality for arrays that contain provisions
3435
// for accessing its elements using a biased index.
@@ -129,6 +130,7 @@ class G1BiasedMappedArray : public G1BiasedMappedArrayBase {
129130
// Return the element of the given array that covers the given word in the
130131
// heap. Assumes the index is valid.
131132
T get_by_address(HeapWord* value) const {
133+
SanitizerGCMapper::remapAddress(value);
132134
idx_t biased_index = ((uintptr_t)value) >> this->shift_by();
133135
this->verify_biased_index(biased_index);
134136
return biased_base()[biased_index];

src/hotspot/share/gc/g1/g1ConcurrentMarkBitMap.inline.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ inline bool G1CMBitMap::iterate(G1CMBitMapClosure* cl, MemRegion mr) {
3838
"Given MemRegion from " PTR_FORMAT " to " PTR_FORMAT " not contained in heap area",
3939
p2i(mr.start()), p2i(mr.end()));
4040

41+
// TODO SANITIZE
42+
// HeapWord* end = mr.end();
43+
// SanitizerGCMapper::remapAddress(end);
4144
BitMap::idx_t const end_offset = addr_to_offset(mr.end());
45+
46+
// HeapWord* start = mr.start();
47+
// SanitizerGCMapper::remapAddress(start);
4248
BitMap::idx_t offset = _bm.find_first_set_bit(addr_to_offset(mr.start()), end_offset);
4349

4450
while (offset < end_offset) {

src/hotspot/share/gc/g1/g1HeapRegion.cpp

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,75 @@ void G1HeapRegion::move_this_region() {
7676
}
7777

7878
HeapWord* new_end = new_bottom + GrainWords;
79-
SanitizerGCMapper::initializeMapping(_bottom, new_bottom, new_end);
79+
SanitizerGCMapper::initializeMapping(_bottom, _end, new_bottom, new_end);
8080
_bottom = new_bottom;
8181
_top = new_bottom;
8282
_end = new_end;
8383
}
8484

85+
class PrintG1HeapRegionInfoClosure : public HeapRegionClosure {
86+
public:
87+
bool do_heap_region(G1HeapRegion* hr) override {
88+
uint index = hr->hrm_index();
89+
HeapWord* bottom = hr->bottom();
90+
HeapWord* top = hr->top();
91+
HeapWord* end = hr->end();
92+
93+
printf("---------- %p ----------\n", bottom);
94+
printf("| hrm_index: %d \n", index);
95+
printf("| current top: %p \n", top);
96+
printf("| is young: %d, is eden: %d, is old: %d, is survivor: %d\n", hr->is_young(), hr->is_eden(), hr->is_old(), hr->is_survivor());
97+
printf("---------- %p ----------\n\n", end);
98+
return false;
99+
}
100+
};
101+
102+
void printMemoryRegionMap() {
103+
G1CollectedHeap *heap = G1CollectedHeap::heap();
104+
105+
const void * originalStart = SanitizerGCMapper::originalRegionStart;
106+
const void * originalEnd = SanitizerGCMapper::originalRegionEnd;
107+
const void * movedStart = SanitizerGCMapper::movedRegionStart;
108+
const void * movedEnd = SanitizerGCMapper::movedRegionEnd;
109+
110+
HeapWord * firstRegionBottom = heap->region_at(0)->bottom();
111+
112+
if (reinterpret_cast<const char *>(originalStart) < reinterpret_cast<const char *>(firstRegionBottom)) {
113+
printf("---------- %p ----------\n", originalStart);
114+
printf("| MOVED original \n");
115+
printf("| hrm_index: %d \n", heap->addr_to_region(originalStart));
116+
printf("---------- %p ----------\n\n", originalEnd);
117+
printf(" ...\n\n");
118+
}
119+
120+
if (reinterpret_cast<const char *>(movedStart) < reinterpret_cast<const char *>(firstRegionBottom)) {
121+
printf("---------- %p ----------\n", movedStart);
122+
printf("| MOVED new \n");
123+
printf("| hrm_index: %d \n", heap->addr_to_region(movedStart));
124+
printf("---------- %p ----------\n\n", movedEnd);
125+
printf(" ...\n\n");
126+
}
127+
128+
PrintG1HeapRegionInfoClosure customClosure;
129+
heap->heap_region_iterate(&customClosure);
130+
131+
if (reinterpret_cast<const char *>(originalStart) > reinterpret_cast<const char *>(firstRegionBottom)) {
132+
printf(" ...\n\n");
133+
printf("---------- %p ----------\n", originalStart);
134+
printf("| MOVED original \n");
135+
printf("| hrm_index: %d \n", heap->addr_to_region(originalStart));
136+
printf("---------- %p ----------\n\n", originalEnd);
137+
}
138+
139+
if (reinterpret_cast<const char *>(movedStart) > reinterpret_cast<const char *>(firstRegionBottom)) {
140+
printf(" ...\n\n");
141+
printf("---------- %p ----------\n", movedStart);
142+
printf("| MOVED new \n");
143+
printf("| hrm_index: %d \n", heap->addr_to_region(movedStart));
144+
printf("---------- %p ----------\n\n", movedEnd);
145+
}
146+
}
147+
85148
size_t G1HeapRegion::max_region_size() {
86149
return HeapRegionBounds::max_size();
87150
}
@@ -624,6 +687,20 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
624687
bool failed() const {
625688
if (_from != _to && !_from->is_young() && _to->rem_set()->is_complete()) {
626689
const CardValue dirty = G1CardTable::dirty_card_val();
690+
691+
if (SanitizeGC) {
692+
printf(" - !( %d || ( %d ? %d : (%d || %d) ) )\n", _to->rem_set()->contains_reference(this->_p), this->_containing_obj->is_objArray(), (_cv_field == dirty), (_cv_obj == dirty), (_cv_field == dirty));
693+
}
694+
695+
bool condition = !(_to->rem_set()->contains_reference(this->_p) ||
696+
(this->_containing_obj->is_objArray() ?
697+
_cv_field == dirty :
698+
_cv_obj == dirty || _cv_field == dirty));
699+
700+
if (SanitizeGC && condition) {
701+
printf("SANITIZE"); // breakpoint catcher
702+
}
703+
627704
return !(_to->rem_set()->contains_reference(this->_p) ||
628705
(this->_containing_obj->is_objArray() ?
629706
_cv_field == dirty :

src/hotspot/share/gc/g1/g1HeapRegion.inline.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ inline bool G1HeapRegion::is_in_parsable_area(const void* const addr) const {
115115
}
116116

117117
inline bool G1HeapRegion::is_in_parsable_area(const void* const addr, const void* const pb) {
118-
return addr >= pb;
118+
return addr >= pb || (addr >= SanitizerGCMapper::movedRegionStart && addr <= SanitizerGCMapper::movedRegionEnd);
119119
}
120120

121121
inline bool G1HeapRegion::is_marked_in_bitmap(oop obj) const {

src/hotspot/share/gc/g1/g1HeapRegionManager.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ G1HeapRegion* HeapRegionManager::allocate_free_region(HeapRegionType type, uint
118118

119119
if (SanitizeGC) {
120120
// SANITIZER, printing of bottom, top and end
121-
printf("index: %d, _bottom: %p, _top: %p, _end: %p\n", hr->hrm_index(), hr->bottom(), hr->top(), hr->end());
121+
printf("REGION WITH INDEX: %d, _bottom: %p, _end: %p\n", hr->hrm_index(), hr->bottom(), hr->end());
122122

123123
// SANITIZER, moving the first region to different address
124124
if (!wasFirstTaken) {
125125
hr->move_this_region();
126-
printf("region with index %d was moved here:\n", hr->hrm_index());
127-
printf(" index: %d, _bottom: %p, _top: %p, _end: %p\n", hr->hrm_index(), hr->bottom(), hr->top(), hr->end());
126+
printf(" %d was moved here:\n", hr->hrm_index());
127+
printf(" index: %d, _bottom: %p, _end: %p\n", hr->hrm_index(), hr->bottom(), hr->end());
128128

129129
wasFirstTaken = true;
130130
}
@@ -716,19 +716,21 @@ void HeapRegionManager::verify() {
716716
num_committed++;
717717
G1HeapRegion* hr = _regions.get_by_index(i);
718718
guarantee(hr != nullptr, "invariant: i: %u", i);
719-
guarantee(!prev_committed || hr->bottom() == prev_end,
719+
HeapWord* hr_bottom = hr->bottom();
720+
SanitizerGCMapper::remapAddress(hr_bottom);
721+
guarantee(!prev_committed || hr_bottom == prev_end,
720722
"invariant i: %u " HR_FORMAT " prev_end: " PTR_FORMAT,
721723
i, HR_FORMAT_PARAMS(hr), p2i(prev_end));
722724
guarantee(hr->hrm_index() == i,
723725
"invariant: i: %u hrm_index(): %u", i, hr->hrm_index());
724726
// Asserts will fire if i is >= _length
725-
HeapWord* addr = hr->bottom();
726-
guarantee(addr_to_region(addr) == hr, "sanity");
727+
guarantee(addr_to_region(hr_bottom) == hr, "sanity");
727728
// We cannot check whether the region is part of a particular set: at the time
728729
// this method may be called, we have only completed allocation of the regions,
729730
// but not put into a region set.
730731
prev_committed = true;
731732
prev_end = hr->end();
733+
SanitizerGCMapper::remapAddress(prev_end);
732734
}
733735
for (uint i = _allocated_heapregions_length; i < reserved_length(); i++) {
734736
guarantee(_regions.get_by_index(i) == nullptr, "invariant i: %u", i);

src/hotspot/share/gc/g1/g1HeapVerifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ class VerifyRegionClosure: public HeapRegionClosure {
246246
}
247247

248248
bool do_heap_region(G1HeapRegion* r) {
249+
// TODO SANITIZE
249250
guarantee(!r->has_index_in_opt_cset(), "Region %u still has opt collection set index %u", r->hrm_index(), r->index_in_opt_cset());
250251
guarantee(!r->is_young() || r->rem_set()->is_complete(), "Remembered set for Young region %u must be complete, is %s", r->hrm_index(), r->rem_set()->get_state_str());
251252
// Humongous and old regions regions might be of any state, so can't check here.

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,21 @@ void CardTable::clear_MemRegion(MemRegion mr) {
212212
// Be conservative: only clean cards entirely contained within the
213213
// region.
214214
CardValue* cur;
215-
if (mr.start() == _whole_heap.start()) {
216-
cur = byte_for(mr.start());
215+
216+
HeapWord* start = mr.start();
217+
SanitizerGCMapper::remapAddress(start);
218+
219+
if (start == _whole_heap.start()) {
220+
cur = byte_for(start);
217221
} else {
218-
assert(mr.start() > _whole_heap.start(), "mr is not covered.");
219-
cur = byte_after(mr.start() - 1);
222+
assert(start > _whole_heap.start(), "mr is not covered.");
223+
cur = byte_after(start - 1);
220224
}
221-
CardValue* last = byte_after(mr.last());
225+
226+
HeapWord* mr_last = mr.last();
227+
SanitizerGCMapper::remapAddress(mr_last);
228+
229+
CardValue* last = byte_after(mr_last);
222230
memset(cur, clean_card, pointer_delta(last, cur, sizeof(CardValue)));
223231
}
224232

0 commit comments

Comments
 (0)