8145037: Clean up FreeIdSet usage

Avoid wasting space for the unused sets

Reviewed-by: tschatzl
This commit is contained in:
Alexander Harlap 2016-01-08 15:41:44 -05:00
parent 7442fce79d
commit 22ad9cec84
5 changed files with 77 additions and 71 deletions

View File

@ -32,6 +32,72 @@
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
// Represents a set of free small integer ids.
class FreeIdSet : public CHeapObj<mtGC> {
enum {
end_of_list = UINT_MAX,
claimed = UINT_MAX - 1
};
uint _size;
Monitor* _mon;
uint* _ids;
uint _hd;
uint _waiters;
uint _claimed;
public:
FreeIdSet(uint size, Monitor* mon);
~FreeIdSet();
// Returns an unclaimed parallel id (waiting for one to be released if
// necessary).
uint claim_par_id();
void release_par_id(uint id);
};
FreeIdSet::FreeIdSet(uint size, Monitor* mon) :
_size(size), _mon(mon), _hd(0), _waiters(0), _claimed(0)
{
guarantee(size != 0, "must be");
_ids = NEW_C_HEAP_ARRAY(uint, size, mtGC);
for (uint i = 0; i < size - 1; i++) {
_ids[i] = i+1;
}
_ids[size-1] = end_of_list; // end of list.
}
FreeIdSet::~FreeIdSet() {
FREE_C_HEAP_ARRAY(uint, _ids);
}
uint FreeIdSet::claim_par_id() {
MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
while (_hd == end_of_list) {
_waiters++;
_mon->wait(Mutex::_no_safepoint_check_flag);
_waiters--;
}
uint res = _hd;
_hd = _ids[res];
_ids[res] = claimed; // For debugging.
_claimed++;
return res;
}
void FreeIdSet::release_par_id(uint id) {
MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
assert(_ids[id] == claimed, "Precondition.");
_ids[id] = _hd;
_hd = id;
_claimed--;
if (_waiters > 0) {
_mon->notify_all();
}
}
DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) :
// Dirty card queues are always active, so we create them with their
// active field set to true.
@ -103,7 +169,8 @@ void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
int process_completed_threshold,
int max_completed_queue,
Mutex* lock,
DirtyCardQueueSet* fl_owner) {
DirtyCardQueueSet* fl_owner,
bool init_free_ids) {
_mut_process_closure = cl;
PtrQueueSet::initialize(cbl_mon,
fl_lock,
@ -112,7 +179,9 @@ void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
fl_owner);
set_buffer_size(G1UpdateBufferSize);
_shared_dirty_card_queue.set_lock(lock);
_free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
if (init_free_ids) {
_free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
}
}
void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
@ -120,7 +189,7 @@ void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
}
bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
guarantee(_free_ids != NULL, "must be");
// Used to determine if we had already claimed a par_id
// before entering this method.
bool already_claimed = false;

View File

@ -116,7 +116,8 @@ public:
int process_completed_threshold,
int max_completed_queue,
Mutex* lock,
DirtyCardQueueSet* fl_owner = NULL);
DirtyCardQueueSet* fl_owner,
bool init_free_ids = false);
// The number of parallel ids that can be claimed to allow collector or
// mutator threads to do card-processing work.

View File

@ -1984,7 +1984,9 @@ jint G1CollectedHeap::initialize() {
DirtyCardQ_FL_lock,
concurrent_g1_refine()->yellow_zone(),
concurrent_g1_refine()->red_zone(),
Shared_DirtyCardQ_lock);
Shared_DirtyCardQ_lock,
NULL, // fl_owner
true); // init_free_ids
dirty_card_queue_set().initialize(NULL, // Should never be called by the Java code
DirtyCardQ_CBL_mon,

View File

@ -499,43 +499,3 @@ bool SequentialSubTasksDone::all_tasks_completed() {
}
return false;
}
FreeIdSet::FreeIdSet(uint size, Monitor* mon) :
_size(size), _mon(mon), _hd(0), _waiters(0), _claimed(0)
{
guarantee(size != 0, "must be");
_ids = NEW_C_HEAP_ARRAY(uint, size, mtGC);
for (uint i = 0; i < size - 1; i++) {
_ids[i] = i+1;
}
_ids[size-1] = end_of_list; // end of list.
}
FreeIdSet::~FreeIdSet() {
FREE_C_HEAP_ARRAY(uint, _ids);
}
uint FreeIdSet::claim_par_id() {
MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
while (_hd == end_of_list) {
_waiters++;
_mon->wait(Mutex::_no_safepoint_check_flag);
_waiters--;
}
uint res = _hd;
_hd = _ids[res];
_ids[res] = claimed; // For debugging.
_claimed++;
return res;
}
void FreeIdSet::release_par_id(uint id) {
MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
assert(_ids[id] == claimed, "Precondition.");
_ids[id] = _hd;
_hd = id;
_claimed--;
if (_waiters > 0) {
_mon->notify_all();
}
}

View File

@ -378,30 +378,4 @@ public:
bool all_tasks_completed();
};
// Represents a set of free small integer ids.
class FreeIdSet : public CHeapObj<mtGC> {
enum {
end_of_list = UINT_MAX,
claimed = UINT_MAX - 1
};
uint _size;
Monitor* _mon;
uint* _ids;
uint _hd;
uint _waiters;
uint _claimed;
public:
FreeIdSet(uint size, Monitor* mon);
~FreeIdSet();
// Returns an unclaimed parallel id (waiting for one to be released if
// necessary).
uint claim_par_id();
void release_par_id(uint id);
};
#endif // SHARE_VM_GC_SHARED_WORKGROUP_HPP