270 }
271 // Otherwise, try next entry.
272 _tbl_ind++;
273 }
274 // Otherwise, there were no entry.
275 return false;
276 }
277
278 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
279 SparsePRTEntry* e = get_entry(region_index);
280 return (e != NULL && e->contains_card(card_index));
281 }
282
283 size_t RSHashTable::mem_size() const {
284 return sizeof(RSHashTable) +
285 _num_entries * (SparsePRTEntry::size() + sizeof(int));
286 }
287
288 // ----------------------------------------------------------------------
289
290 SparsePRT* volatile SparsePRT::_head_expanded_list = NULL;
291
292 void SparsePRT::add_to_expanded_list(SparsePRT* sprt) {
293 // We could expand multiple times in a pause -- only put on list once.
294 if (sprt->expanded()) return;
295 sprt->set_expanded(true);
296 SparsePRT* hd = _head_expanded_list;
297 while (true) {
298 sprt->_next_expanded = hd;
299 SparsePRT* res = Atomic::cmpxchg(sprt, &_head_expanded_list, hd);
300 if (res == hd) return;
301 else hd = res;
302 }
303 }
304
305
306 SparsePRT* SparsePRT::get_from_expanded_list() {
307 SparsePRT* hd = _head_expanded_list;
308 while (hd != NULL) {
309 SparsePRT* next = hd->next_expanded();
310 SparsePRT* res = Atomic::cmpxchg(next, &_head_expanded_list, hd);
311 if (res == hd) {
312 hd->set_next_expanded(NULL);
313 return hd;
314 } else {
315 hd = res;
316 }
317 }
318 return NULL;
319 }
320
321 void SparsePRT::reset_for_cleanup_tasks() {
322 _head_expanded_list = NULL;
323 }
324
325 void SparsePRT::do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task) {
326 if (should_be_on_expanded_list()) {
327 sprt_cleanup_task->add(this);
328 }
329 }
330
331 void SparsePRT::finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task) {
332 assert(ParGCRareEvent_lock->owned_by_self(), "pre-condition");
333 SparsePRT* head = sprt_cleanup_task->head();
334 SparsePRT* tail = sprt_cleanup_task->tail();
335 if (head != NULL) {
336 assert(tail != NULL, "if head is not NULL, so should tail");
337
338 tail->set_next_expanded(_head_expanded_list);
339 _head_expanded_list = head;
340 } else {
341 assert(tail == NULL, "if head is NULL, so should tail");
342 }
343 }
344
345 bool SparsePRT::should_be_on_expanded_list() {
346 if (_expanded) {
347 assert(_cur != _next, "if _expanded is true, cur should be != _next");
348 } else {
349 assert(_cur == _next, "if _expanded is false, cur should be == _next");
350 }
351 return expanded();
352 }
353
354 void SparsePRT::cleanup_all() {
355 // First clean up all expanded tables so they agree on next and cur.
356 SparsePRT* sprt = get_from_expanded_list();
357 while (sprt != NULL) {
358 sprt->cleanup();
359 sprt = get_from_expanded_list();
360 }
361 }
362
363
364 SparsePRT::SparsePRT() :
365 _expanded(false), _next_expanded(NULL)
366 {
367 _cur = new RSHashTable(InitialCapacity);
368 _next = _cur;
369 }
370
371
372 SparsePRT::~SparsePRT() {
373 assert(_next != NULL && _cur != NULL, "Inv");
374 if (_cur != _next) { delete _cur; }
375 delete _next;
376 }
377
378
379 size_t SparsePRT::mem_size() const {
380 // We ignore "_cur" here, because it either = _next, or else it is
381 // on the deleted list.
382 return sizeof(SparsePRT) + _next->mem_size();
383 }
384
385 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
386 if (_next->should_expand()) {
387 expand();
388 }
389 return _next->add_card(region_id, card_index);
390 }
391
392 SparsePRTEntry* SparsePRT::get_entry(RegionIdx_t region_id) {
393 return _next->get_entry(region_id);
394 }
395
396 bool SparsePRT::delete_entry(RegionIdx_t region_id) {
397 return _next->delete_entry(region_id);
398 }
399
400 void SparsePRT::clear() {
401 // If they differ, _next is bigger then cur, so next has no chance of
402 // being the initial size.
403 if (_next != _cur) {
404 delete _next;
405 }
406
407 if (_cur->capacity() != InitialCapacity) {
408 delete _cur;
409 _cur = new RSHashTable(InitialCapacity);
410 } else {
411 _cur->clear();
412 }
413 _next = _cur;
414 _expanded = false;
415 }
416
417 void SparsePRT::cleanup() {
418 // Make sure that the current and next tables agree.
419 if (_cur != _next) {
420 delete _cur;
421 }
422 _cur = _next;
423 set_expanded(false);
424 }
425
426 void SparsePRT::expand() {
427 RSHashTable* last = _next;
428 _next = new RSHashTable(last->capacity() * 2);
429 for (size_t i = 0; i < last->num_entries(); i++) {
430 SparsePRTEntry* e = last->entry((int)i);
431 if (e->valid_entry()) {
432 _next->add_entry(e);
433 }
434 }
435 if (last != _cur) {
436 delete last;
437 }
438 add_to_expanded_list(this);
439 }
440
441 void SparsePRTCleanupTask::add(SparsePRT* sprt) {
442 assert(sprt->should_be_on_expanded_list(), "pre-condition");
443
444 sprt->set_next_expanded(NULL);
445 if (_tail != NULL) {
446 _tail->set_next_expanded(sprt);
447 } else {
448 _head = sprt;
449 }
450 _tail = sprt;
451 }
|
270 }
271 // Otherwise, try next entry.
272 _tbl_ind++;
273 }
274 // Otherwise, there were no entry.
275 return false;
276 }
277
278 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
279 SparsePRTEntry* e = get_entry(region_index);
280 return (e != NULL && e->contains_card(card_index));
281 }
282
283 size_t RSHashTable::mem_size() const {
284 return sizeof(RSHashTable) +
285 _num_entries * (SparsePRTEntry::size() + sizeof(int));
286 }
287
288 // ----------------------------------------------------------------------
289
290 SparsePRT::SparsePRT() :
291 _table(new RSHashTable(InitialCapacity)) {
292 }
293
294
295 SparsePRT::~SparsePRT() {
296 delete _table;
297 }
298
299
300 size_t SparsePRT::mem_size() const {
301 // We ignore "_cur" here, because it either = _next, or else it is
302 // on the deleted list.
303 return sizeof(SparsePRT) + _table->mem_size();
304 }
305
306 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
307 if (_table->should_expand()) {
308 expand();
309 }
310 return _table->add_card(region_id, card_index);
311 }
312
313 SparsePRTEntry* SparsePRT::get_entry(RegionIdx_t region_id) {
314 return _table->get_entry(region_id);
315 }
316
317 bool SparsePRT::delete_entry(RegionIdx_t region_id) {
318 return _table->delete_entry(region_id);
319 }
320
321 void SparsePRT::clear() {
322 // If the entry table is not at initial capacity, just create a new one.
323 if (_table->capacity() != InitialCapacity) {
324 delete _table;
325 _table = new RSHashTable(InitialCapacity);
326 } else {
327 _table->clear();
328 }
329 }
330
331 void SparsePRT::expand() {
332 RSHashTable* last = _table;
333 _table = new RSHashTable(last->capacity() * 2);
334 for (size_t i = 0; i < last->num_entries(); i++) {
335 SparsePRTEntry* e = last->entry((int)i);
336 if (e->valid_entry()) {
337 _table->add_entry(e);
338 }
339 }
340 delete last;
341 }
|