src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp

Print this page
rev 5869 : [mq]: free-cset-base

*** 1,7 **** /* ! * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 257,270 **** size_t OtherRegionsTable::_max_fine_entries = 0; size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0; size_t OtherRegionsTable::_fine_eviction_stride = 0; size_t OtherRegionsTable::_fine_eviction_sample_size = 0; ! OtherRegionsTable::OtherRegionsTable(HeapRegion* hr) : _g1h(G1CollectedHeap::heap()), ! _m(Mutex::leaf, "An OtherRegionsTable lock", true), ! _hr(hr), _coarse_map(G1CollectedHeap::heap()->max_regions(), false /* in-resource-area */), _fine_grain_regions(NULL), _first_all_fine_prts(NULL), _last_all_fine_prts(NULL), _n_fine_entries(0), _n_coarse_entries(0), --- 257,269 ---- size_t OtherRegionsTable::_max_fine_entries = 0; size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0; size_t OtherRegionsTable::_fine_eviction_stride = 0; size_t OtherRegionsTable::_fine_eviction_sample_size = 0; ! OtherRegionsTable::OtherRegionsTable(HeapRegion* hr, Mutex* m) : _g1h(G1CollectedHeap::heap()), ! _hr(hr), _m(m), _coarse_map(G1CollectedHeap::heap()->max_regions(), false /* in-resource-area */), _fine_grain_regions(NULL), _first_all_fine_prts(NULL), _last_all_fine_prts(NULL), _n_fine_entries(0), _n_coarse_entries(0),
*** 361,381 **** int** OtherRegionsTable::_from_card_cache = NULL; size_t OtherRegionsTable::_from_card_cache_max_regions = 0; size_t OtherRegionsTable::_from_card_cache_mem_size = 0; void OtherRegionsTable::init_from_card_cache(size_t max_regions) { ! _from_card_cache_max_regions = max_regions; int n_par_rs = HeapRegionRemSet::num_par_rem_sets(); _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC); for (int i = 0; i < n_par_rs; i++) { ! _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions, mtGC); ! for (size_t j = 0; j < max_regions; j++) { _from_card_cache[i][j] = -1; // An invalid value. } } ! _from_card_cache_mem_size = n_par_rs * max_regions * sizeof(int); } void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) { for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max."); --- 360,381 ---- int** OtherRegionsTable::_from_card_cache = NULL; size_t OtherRegionsTable::_from_card_cache_max_regions = 0; size_t OtherRegionsTable::_from_card_cache_mem_size = 0; void OtherRegionsTable::init_from_card_cache(size_t max_regions) { ! // pad rows to cache line sizes. ! _from_card_cache_max_regions = align_size_up(max_regions, DEFAULT_CACHE_LINE_SIZE / sizeof(int)); int n_par_rs = HeapRegionRemSet::num_par_rem_sets(); _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC); for (int i = 0; i < n_par_rs; i++) { ! _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, _from_card_cache_max_regions, mtGC); ! for (size_t j = 0; j < _from_card_cache_max_regions; j++) { _from_card_cache[i][j] = -1; // An invalid value. } } ! _from_card_cache_mem_size = n_par_rs * _from_card_cache_max_regions * sizeof(int); } void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) { for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max.");
*** 440,450 **** // Otherwise find a per-region table to add it to. size_t ind = from_hrs_ind & _mod_max_fine_entries_mask; PerRegionTable* prt = find_region_table(ind, from_hr); if (prt == NULL) { ! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); // Confirm that it's really not there... prt = find_region_table(ind, from_hr); if (prt == NULL) { uintptr_t from_hr_bot_card_index = --- 440,450 ---- // Otherwise find a per-region table to add it to. size_t ind = from_hrs_ind & _mod_max_fine_entries_mask; PerRegionTable* prt = find_region_table(ind, from_hr); if (prt == NULL) { ! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); // Confirm that it's really not there... prt = find_region_table(ind, from_hr); if (prt == NULL) { uintptr_t from_hr_bot_card_index =
*** 542,552 **** } jint OtherRegionsTable::_n_coarsenings = 0; PerRegionTable* OtherRegionsTable::delete_region_table() { ! assert(_m.owned_by_self(), "Precondition"); assert(_n_fine_entries == _max_fine_entries, "Precondition"); PerRegionTable* max = NULL; jint max_occ = 0; PerRegionTable** max_prev; size_t max_ind; --- 542,552 ---- } jint OtherRegionsTable::_n_coarsenings = 0; PerRegionTable* OtherRegionsTable::delete_region_table() { ! assert(_m->owned_by_self(), "Precondition"); assert(_n_fine_entries == _max_fine_entries, "Precondition"); PerRegionTable* max = NULL; jint max_occ = 0; PerRegionTable** max_prev; size_t max_ind;
*** 674,685 **** clear_fcc(); } size_t OtherRegionsTable::occupied() const { - // Cast away const in this case. - MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag); size_t sum = occ_fine(); sum += occ_sparse(); sum += occ_coarse(); return sum; } --- 674,683 ----
*** 705,716 **** size_t OtherRegionsTable::occ_sparse() const { return _sparse_table.occupied(); } size_t OtherRegionsTable::mem_size() const { ! // Cast away const in this case. ! MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag); size_t sum = 0; // all PRTs are of the same size so it is sufficient to query only one of them. if (_first_all_fine_prts != NULL) { assert(_last_all_fine_prts != NULL && _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant"); --- 703,713 ---- size_t OtherRegionsTable::occ_sparse() const { return _sparse_table.occupied(); } size_t OtherRegionsTable::mem_size() const { ! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); size_t sum = 0; // all PRTs are of the same size so it is sufficient to query only one of them. if (_first_all_fine_prts != NULL) { assert(_last_all_fine_prts != NULL && _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
*** 731,747 **** return PerRegionTable::fl_mem_size(); } void OtherRegionsTable::clear_fcc() { size_t hrs_idx = hr()->hrs_index(); ! for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { _from_card_cache[i][hrs_idx] = -1; } } void OtherRegionsTable::clear() { - MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); // if there are no entries, skip this step if (_first_all_fine_prts != NULL) { guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking"); PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts); memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0])); --- 728,744 ---- return PerRegionTable::fl_mem_size(); } void OtherRegionsTable::clear_fcc() { size_t hrs_idx = hr()->hrs_index(); ! uint num_par_remsets = HeapRegionRemSet::num_par_rem_sets(); ! for (uint i = 0; i < num_par_remsets; i++) { _from_card_cache[i][hrs_idx] = -1; } } void OtherRegionsTable::clear() { // if there are no entries, skip this step if (_first_all_fine_prts != NULL) { guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking"); PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts); memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
*** 757,767 **** clear_fcc(); } void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) { ! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); size_t hrs_ind = (size_t) from_hr->hrs_index(); size_t ind = hrs_ind & _mod_max_fine_entries_mask; if (del_single_region_table(ind, from_hr)) { assert(!_coarse_map.at(hrs_ind), "Inv"); } else { --- 754,764 ---- clear_fcc(); } void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) { ! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); size_t hrs_ind = (size_t) from_hr->hrs_index(); size_t ind = hrs_ind & _mod_max_fine_entries_mask; if (del_single_region_table(ind, from_hr)) { assert(!_coarse_map.at(hrs_ind), "Inv"); } else {
*** 802,813 **** return false; } } bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const { ! // Cast away const in this case. ! MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag); return contains_reference_locked(from); } bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { HeapRegion* hr = _g1h->heap_region_containing_raw(from); --- 799,809 ---- return false; } } bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const { ! MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); return contains_reference_locked(from); } bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { HeapRegion* hr = _g1h->heap_region_containing_raw(from);
*** 848,858 **** return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); } HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) ! : _bosa(bosa), _strong_code_roots_list(NULL), _other_regions(hr) { reset_for_par_iteration(); } void HeapRegionRemSet::setup_remset_size() { // Setup sparse and fine-grain tables sizes. --- 844,855 ---- return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); } HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) ! : _bosa(bosa), _m(Mutex::leaf, "An OtherRegionsTable lock", true), ! _other_regions(hr, &_m), _code_roots() { reset_for_par_iteration(); } void HeapRegionRemSet::setup_remset_size() { // Setup sparse and fine-grain tables sizes.
*** 881,891 **** bool HeapRegionRemSet::iter_is_complete() { return _iter_state == Complete; } #ifndef PRODUCT ! void HeapRegionRemSet::print() const { HeapRegionRemSetIterator iter(this); size_t card_index; while (iter.has_next(card_index)) { HeapWord* card_start = G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index); --- 878,888 ---- bool HeapRegionRemSet::iter_is_complete() { return _iter_state == Complete; } #ifndef PRODUCT ! void HeapRegionRemSet::print() { HeapRegionRemSetIterator iter(this); size_t card_index; while (iter.has_next(card_index)) { HeapWord* card_start = G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
*** 907,924 **** void HeapRegionRemSet::cleanup() { SparsePRT::cleanup_all(); } void HeapRegionRemSet::clear() { ! if (_strong_code_roots_list != NULL) { ! delete _strong_code_roots_list; ! } ! _strong_code_roots_list = new (ResourceObj::C_HEAP, mtGC) ! GrowableArray<nmethod*>(10, 0, NULL, true); _other_regions.clear(); ! assert(occupied() == 0, "Should be clear."); reset_for_par_iteration(); } void HeapRegionRemSet::reset_for_par_iteration() { _iter_state = Unclaimed; --- 904,921 ---- void HeapRegionRemSet::cleanup() { SparsePRT::cleanup_all(); } void HeapRegionRemSet::clear() { ! MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); ! clear_locked(); ! } + void HeapRegionRemSet::clear_locked() { + _code_roots.clear(); _other_regions.clear(); ! assert(occupied_locked() == 0, "Should be clear."); reset_for_par_iteration(); } void HeapRegionRemSet::reset_for_par_iteration() { _iter_state = Unclaimed;
*** 935,960 **** // Code roots support void HeapRegionRemSet::add_strong_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); ! // Search for the code blob from the RHS to avoid ! // duplicate entries as much as possible ! if (_strong_code_roots_list->find_from_end(nm) < 0) { ! // Code blob isn't already in the list ! _strong_code_roots_list->push(nm); ! } } void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); ! int idx = _strong_code_roots_list->find(nm); ! if (idx >= 0) { ! _strong_code_roots_list->remove_at(idx); ! } // Check that there were no duplicates ! guarantee(_strong_code_roots_list->find(nm) < 0, "duplicate entry found"); } class NMethodMigrationOopClosure : public OopClosure { G1CollectedHeap* _g1h; HeapRegion* _from; --- 932,949 ---- // Code roots support void HeapRegionRemSet::add_strong_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); ! _code_roots.add(nm); } void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); ! _code_roots.remove(nm); // Check that there were no duplicates ! guarantee(!_code_roots.contains(nm), "duplicate entry found"); } class NMethodMigrationOopClosure : public OopClosure { G1CollectedHeap* _g1h; HeapRegion* _from;
*** 1012,1023 **** // List of code blobs to retain for this region GrowableArray<nmethod*> to_be_retained(10); G1CollectedHeap* g1h = G1CollectedHeap::heap(); ! while (_strong_code_roots_list->is_nonempty()) { ! nmethod *nm = _strong_code_roots_list->pop(); if (nm != NULL) { NMethodMigrationOopClosure oop_cl(g1h, hr(), nm); nm->oops_do(&oop_cl); if (oop_cl.retain()) { to_be_retained.push(nm); --- 1001,1012 ---- // List of code blobs to retain for this region GrowableArray<nmethod*> to_be_retained(10); G1CollectedHeap* g1h = G1CollectedHeap::heap(); ! while (!_code_roots.is_empty()) { ! nmethod *nm = _code_roots.pop(); if (nm != NULL) { NMethodMigrationOopClosure oop_cl(g1h, hr(), nm); nm->oops_do(&oop_cl); if (oop_cl.retain()) { to_be_retained.push(nm);
*** 1035,1059 **** assert(nm != NULL, "sanity"); add_strong_code_root(nm); } } ! void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const { ! for (int i = 0; i < _strong_code_roots_list->length(); i += 1) { ! nmethod* nm = _strong_code_roots_list->at(i); ! blk->do_code_blob(nm); ! } } size_t HeapRegionRemSet::strong_code_roots_mem_size() { ! return sizeof(GrowableArray<nmethod*>) + ! _strong_code_roots_list->max_length() * sizeof(nmethod*); } //-------------------- Iteration -------------------- ! HeapRegionRemSetIterator:: HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs) : _hrrs(hrrs), _g1h(G1CollectedHeap::heap()), _coarse_map(&hrrs->_other_regions._coarse_map), _fine_grain_regions(hrrs->_other_regions._fine_grain_regions), _bosa(hrrs->bosa()), --- 1024,1044 ---- assert(nm != NULL, "sanity"); add_strong_code_root(nm); } } ! void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) { ! _code_roots.nmethods_do(blk); } size_t HeapRegionRemSet::strong_code_roots_mem_size() { ! return _code_roots.mem_size(); } //-------------------- Iteration -------------------- ! HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) : _hrrs(hrrs), _g1h(G1CollectedHeap::heap()), _coarse_map(&hrrs->_other_regions._coarse_map), _fine_grain_regions(hrrs->_other_regions._fine_grain_regions), _bosa(hrrs->bosa()),