18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/heapRegion.hpp"
27 #include "gc_implementation/g1/heapRegionRemSet.hpp"
28 #include "gc_implementation/g1/sparsePRT.hpp"
29 #include "memory/allocation.inline.hpp"
30 #include "memory/cardTableModRefBS.hpp"
31 #include "memory/space.inline.hpp"
32 #include "runtime/mutexLocker.hpp"
33
34 #define SPARSE_PRT_VERBOSE 0
35
36 void SparsePRTEntry::init(RegionIdx_t region_ind) {
37 _region_ind = region_ind;
38 _next_index = NullEntry;
39
40 for (int i = 0; i < cards_num(); i++) {
41 _cards[i] = NullEntry;
42 }
43 }
44
45 bool SparsePRTEntry::contains_card(CardIdx_t card_index) const {
46 for (int i = 0; i < cards_num(); i++) {
47 if (_cards[i] == card_index) return true;
48 }
49 return false;
50 }
51
52 int SparsePRTEntry::num_valid_cards() const {
53 int sum = 0;
54 for (int i = 0; i < cards_num(); i++) {
55 sum += (_cards[i] != NullEntry);
56 }
57 return sum;
58 }
59
60 SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
61 for (int i = 0; i < cards_num(); i++) {
62 CardIdx_t c = _cards[i];
63 if (c == card_index) return found;
64 if (c == NullEntry) { _cards[i] = card_index; return added; }
65 }
66 // Otherwise, we're full.
67 return overflow;
68 }
69
70 void SparsePRTEntry::copy_cards(CardIdx_t* cards) const {
71 memcpy(cards, _cards, cards_num() * sizeof(CardIdx_t));
72 }
73
74 void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
75 copy_cards(&e->_cards[0]);
76 }
77
78 // ----------------------------------------------------------------------
79
80 RSHashTable::RSHashTable(size_t capacity) :
81 _capacity(capacity), _capacity_mask(capacity-1),
82 _occupied_entries(0), _occupied_cards(0),
83 _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity, mtGC)),
84 _buckets(NEW_C_HEAP_ARRAY(int, capacity, mtGC)),
85 _free_list(NullEntry), _free_region(0)
86 {
87 clear();
88 }
89
90 RSHashTable::~RSHashTable() {
91 if (_entries != NULL) {
92 FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
93 _entries = NULL;
94 }
95 if (_buckets != NULL) {
203 _free_region++;
204 return res;
205 } else {
206 return NullEntry;
207 }
208 }
209
210 void RSHashTable::free_entry(int fi) {
211 entry(fi)->set_next_index(_free_list);
212 _free_list = fi;
213 }
214
215 void RSHashTable::add_entry(SparsePRTEntry* e) {
216 assert(e->num_valid_cards() > 0, "Precondition.");
217 SparsePRTEntry* e2 = entry_for_region_ind_create(e->r_ind());
218 e->copy_cards(e2);
219 _occupied_cards += e2->num_valid_cards();
220 assert(e2->num_valid_cards() > 0, "Postcondition.");
221 }
222
223 CardIdx_t RSHashTableIter::find_first_card_in_list() {
224 CardIdx_t res;
225 while (_bl_ind != RSHashTable::NullEntry) {
226 res = _rsht->entry(_bl_ind)->card(0);
227 if (res != SparsePRTEntry::NullEntry) {
228 return res;
229 } else {
230 _bl_ind = _rsht->entry(_bl_ind)->next_index();
231 }
232 }
233 // Otherwise, none found:
234 return SparsePRTEntry::NullEntry;
235 }
236
237 size_t RSHashTableIter::compute_card_ind(CardIdx_t ci) {
238 return (_rsht->entry(_bl_ind)->r_ind() * HeapRegion::CardsPerRegion) + ci;
239 }
240
241 bool RSHashTableIter::has_next(size_t& card_index) {
242 _card_ind++;
243 CardIdx_t ci;
244 if (_card_ind < SparsePRTEntry::cards_num() &&
245 ((ci = _rsht->entry(_bl_ind)->card(_card_ind)) !=
246 SparsePRTEntry::NullEntry)) {
247 card_index = compute_card_ind(ci);
248 return true;
249 }
250 // Otherwise, must find the next valid entry.
251 _card_ind = 0;
252
253 if (_bl_ind != RSHashTable::NullEntry) {
254 _bl_ind = _rsht->entry(_bl_ind)->next_index();
255 ci = find_first_card_in_list();
256 if (ci != SparsePRTEntry::NullEntry) {
257 card_index = compute_card_ind(ci);
258 return true;
259 }
260 }
261 // If we didn't return above, must go to the next non-null table index.
262 _tbl_ind++;
263 while ((size_t)_tbl_ind < _rsht->capacity()) {
264 _bl_ind = _rsht->_buckets[_tbl_ind];
265 ci = find_first_card_in_list();
266 if (ci != SparsePRTEntry::NullEntry) {
267 card_index = compute_card_ind(ci);
268 return true;
269 }
270 // Otherwise, try next entry.
271 _tbl_ind++;
272 }
273 // Otherwise, there were no entry.
274 return false;
275 }
276
277 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
278 SparsePRTEntry* e = get_entry(region_index);
279 return (e != NULL && e->contains_card(card_index));
280 }
281
282 size_t RSHashTable::mem_size() const {
283 return sizeof(RSHashTable) +
284 capacity() * (SparsePRTEntry::size() + sizeof(int));
285 }
286
|
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/heapRegion.hpp"
27 #include "gc_implementation/g1/heapRegionRemSet.hpp"
28 #include "gc_implementation/g1/sparsePRT.hpp"
29 #include "memory/allocation.inline.hpp"
30 #include "memory/cardTableModRefBS.hpp"
31 #include "memory/space.inline.hpp"
32 #include "runtime/mutexLocker.hpp"
33
34 #define SPARSE_PRT_VERBOSE 0
35
36 void SparsePRTEntry::init(RegionIdx_t region_ind) {
37 _region_ind = region_ind;
38 _next_index = RSHashTable::NullEntry;
39 _next_null = 0;
40
41 }
42
43 bool SparsePRTEntry::contains_card(CardIdx_t card_index) const {
44 for (int i = 0; i < _next_null; i++) {
45 if (_cards[i] == card_index) return true;
46 }
47 return false;
48 }
49
50
51 SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
52 for (int i = 0; i < _next_null; i++) {
53 CardIdx_t c = card(i);
54 if (c == card_index) {
55 return found;
56 }
57 }
58 if (_next_null < cards_num() -1) {
59 _cards[_next_null] = card_index;
60 _next_null++;
61 return added;
62 }
63 // Otherwise, we're full.
64 return overflow;
65 }
66
67 void SparsePRTEntry::copy_cards(CardIdx_t* cards) const {
68 memcpy(cards, _cards, _next_null * sizeof(CardIdx_t));
69 }
70
71 void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
72 copy_cards(e->_cards);
73 assert(_next_null >= 0, "invariant");
74 assert(_next_null <= cards_num(), "invariant");
75 e->_next_null = _next_null;
76 }
77
78 // ----------------------------------------------------------------------
79
80 RSHashTable::RSHashTable(size_t capacity) :
81 _capacity(capacity), _capacity_mask(capacity-1),
82 _occupied_entries(0), _occupied_cards(0),
83 _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity, mtGC)),
84 _buckets(NEW_C_HEAP_ARRAY(int, capacity, mtGC)),
85 _free_list(NullEntry), _free_region(0)
86 {
87 clear();
88 }
89
90 RSHashTable::~RSHashTable() {
91 if (_entries != NULL) {
92 FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
93 _entries = NULL;
94 }
95 if (_buckets != NULL) {
203 _free_region++;
204 return res;
205 } else {
206 return NullEntry;
207 }
208 }
209
210 void RSHashTable::free_entry(int fi) {
211 entry(fi)->set_next_index(_free_list);
212 _free_list = fi;
213 }
214
215 void RSHashTable::add_entry(SparsePRTEntry* e) {
216 assert(e->num_valid_cards() > 0, "Precondition.");
217 SparsePRTEntry* e2 = entry_for_region_ind_create(e->r_ind());
218 e->copy_cards(e2);
219 _occupied_cards += e2->num_valid_cards();
220 assert(e2->num_valid_cards() > 0, "Postcondition.");
221 }
222
223 bool RSHashTableIter::find_first_card_in_list(CardIdx_t & res) {
224 while (_bl_ind != RSHashTable::NullEntry) {
225 SparsePRTEntry * sparse_entry = _rsht->entry(_bl_ind);
226 if (sparse_entry->num_valid_cards() > 0) {
227 res = sparse_entry->card(0);
228 return true;
229 } else {
230 _bl_ind = sparse_entry->next_index();
231 }
232 }
233 // Otherwise, none found:
234 return false;
235 }
236
237 size_t RSHashTableIter::compute_card_ind(CardIdx_t ci) {
238 return (_rsht->entry(_bl_ind)->r_ind() * HeapRegion::CardsPerRegion) + ci;
239 }
240
241 bool RSHashTableIter::has_next(size_t& card_index) {
242 _card_ind++;
243 CardIdx_t ci;
244 if (_bl_ind >= 0) {
245 SparsePRTEntry * e = _rsht->entry(_bl_ind);
246 if (_card_ind < e->num_valid_cards()) {
247 ci = e->card(_card_ind);
248 card_index = compute_card_ind(ci);
249 return true;
250 }
251 }
252
253 // Otherwise, must find the next valid entry.
254 _card_ind = 0;
255
256 if (_bl_ind != RSHashTable::NullEntry) {
257 _bl_ind = _rsht->entry(_bl_ind)->next_index();
258 bool found = find_first_card_in_list(ci);
259 if (found) {
260 card_index = compute_card_ind(ci);
261 return true;
262 }
263 }
264 // If we didn't return above, must go to the next non-null table index.
265 _tbl_ind++;
266 while ((size_t)_tbl_ind < _rsht->capacity()) {
267 _bl_ind = _rsht->_buckets[_tbl_ind];
268 bool found = find_first_card_in_list(ci);
269 if (found) {
270 card_index = compute_card_ind(ci);
271 return true;
272 }
273 // Otherwise, try next entry.
274 _tbl_ind++;
275 }
276 // Otherwise, there were no entry.
277 return false;
278 }
279
280 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
281 SparsePRTEntry* e = get_entry(region_index);
282 return (e != NULL && e->contains_card(card_index));
283 }
284
285 size_t RSHashTable::mem_size() const {
286 return sizeof(RSHashTable) +
287 capacity() * (SparsePRTEntry::size() + sizeof(int));
288 }
289
|