< prev index next >
src/share/vm/gc/g1/g1ConcurrentMark.cpp
Print this page
rev 12508 : imported patch 8162104-use-is_in_cset-instead-of-obj_in_cs
rev 12511 : [mq]: 8168467-use-taskentry-as-mark-stack-elem
*** 269,279 ****
OopChunk* result = ::new (&_base[cur_idx]) OopChunk;
result->next = NULL;
return result;
}
! bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) {
// Get a new chunk.
OopChunk* new_chunk = remove_chunk_from_free_list();
if (new_chunk == NULL) {
// Did not get a chunk from the free list. Allocate from backing memory.
--- 269,279 ----
OopChunk* result = ::new (&_base[cur_idx]) OopChunk;
result->next = NULL;
return result;
}
! bool G1CMMarkStack::par_push_chunk(G1TaskQueueEntry* ptr_arr) {
// Get a new chunk.
OopChunk* new_chunk = remove_chunk_from_free_list();
if (new_chunk == NULL) {
// Did not get a chunk from the free list. Allocate from backing memory.
*** 283,307 ****
if (new_chunk == NULL) {
_out_of_memory = true;
return false;
}
! Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop));
add_chunk_to_chunk_list(new_chunk);
return true;
}
! bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) {
OopChunk* cur = remove_chunk_from_chunk_list();
if (cur == NULL) {
return false;
}
! Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop));
add_chunk_to_free_list(cur);
return true;
}
--- 283,307 ----
if (new_chunk == NULL) {
_out_of_memory = true;
return false;
}
! Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, EntriesPerChunk * sizeof(G1TaskQueueEntry));
add_chunk_to_chunk_list(new_chunk);
return true;
}
! bool G1CMMarkStack::par_pop_chunk(G1TaskQueueEntry* ptr_arr) {
OopChunk* cur = remove_chunk_from_chunk_list();
if (cur == NULL) {
return false;
}
! Copy::conjoint_memory_atomic(cur->data, ptr_arr, EntriesPerChunk * sizeof(G1TaskQueueEntry));
add_chunk_to_free_list(cur);
return true;
}
*** 2006,2022 ****
_g1h(G1CollectedHeap::heap()),
_phase(phase),
_info(info)
{ }
! void operator()(oop obj) const {
! guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || obj->is_oop(),
"Non-oop " PTR_FORMAT ", phase: %s, info: %d",
! p2i(obj), _phase, _info);
! guarantee(G1CMObjArrayProcessor::is_array_slice(obj) || !_g1h->is_in_cset(obj),
"obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
! p2i(obj), _phase, _info);
}
};
void G1ConcurrentMark::verify_no_cset_oops() {
assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
--- 2006,2022 ----
_g1h(G1CollectedHeap::heap()),
_phase(phase),
_info(info)
{ }
! void operator()(G1TaskQueueEntry task_entry) const {
! guarantee(task_entry.is_array_slice() || task_entry.obj()->is_oop(),
"Non-oop " PTR_FORMAT ", phase: %s, info: %d",
! p2i(task_entry.obj()), _phase, _info);
! guarantee(task_entry.is_array_slice() || !_g1h->is_in_cset(task_entry.obj()),
"obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
! p2i(task_entry.obj()), _phase, _info);
}
};
void G1ConcurrentMark::verify_no_cset_oops() {
assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
*** 2397,2416 ****
}
void G1CMTask::move_entries_to_global_stack() {
// Local array where we'll store the entries that will be popped
// from the local queue.
! oop buffer[G1CMMarkStack::OopsPerChunk];
size_t n = 0;
! oop obj;
! while (n < G1CMMarkStack::OopsPerChunk && _task_queue->pop_local(obj)) {
! buffer[n] = obj;
++n;
}
! if (n < G1CMMarkStack::OopsPerChunk) {
! buffer[n] = NULL;
}
if (n > 0) {
if (!_cm->mark_stack_push(buffer)) {
set_has_aborted();
--- 2397,2416 ----
}
void G1CMTask::move_entries_to_global_stack() {
// Local array where we'll store the entries that will be popped
// from the local queue.
! G1TaskQueueEntry buffer[G1CMMarkStack::EntriesPerChunk];
size_t n = 0;
! G1TaskQueueEntry task_entry;
! while (n < G1CMMarkStack::EntriesPerChunk && _task_queue->pop_local(task_entry)) {
! buffer[n] = task_entry;
++n;
}
! if (n < G1CMMarkStack::EntriesPerChunk) {
! buffer[n] = G1TaskQueueEntry();
}
if (n > 0) {
if (!_cm->mark_stack_push(buffer)) {
set_has_aborted();
*** 2422,2445 ****
}
bool G1CMTask::get_entries_from_global_stack() {
// Local array where we'll store the entries that will be popped
// from the global stack.
! oop buffer[G1CMMarkStack::OopsPerChunk];
if (!_cm->mark_stack_pop(buffer)) {
return false;
}
// We did actually pop at least one entry.
! for (size_t i = 0; i < G1CMMarkStack::OopsPerChunk; ++i) {
! oop elem = buffer[i];
! if (elem == NULL) {
break;
}
! assert(G1CMObjArrayProcessor::is_array_slice(elem) || elem->is_oop(), "Element " PTR_FORMAT " must be an array slice or oop", p2i(elem));
! bool success = _task_queue->push(elem);
// We only call this when the local queue is empty or under a
// given target limit. So, we do not expect this push to fail.
assert(success, "invariant");
}
--- 2422,2445 ----
}
bool G1CMTask::get_entries_from_global_stack() {
// Local array where we'll store the entries that will be popped
// from the global stack.
! G1TaskQueueEntry buffer[G1CMMarkStack::EntriesPerChunk];
if (!_cm->mark_stack_pop(buffer)) {
return false;
}
// We did actually pop at least one entry.
! for (size_t i = 0; i < G1CMMarkStack::EntriesPerChunk; ++i) {
! G1TaskQueueEntry task_entry = buffer[i];
! if (task_entry.is_null()) {
break;
}
! assert(task_entry.is_array_slice() || task_entry.obj()->is_oop(), "Element " PTR_FORMAT " must be an array slice or oop", p2i(task_entry.obj()));
! bool success = _task_queue->push(task_entry);
// We only call this when the local queue is empty or under a
// given target limit. So, we do not expect this push to fail.
assert(success, "invariant");
}
*** 2462,2472 ****
} else {
target_size = 0;
}
if (_task_queue->size() > target_size) {
! oop obj;
bool ret = _task_queue->pop_local(obj);
while (ret) {
scan_object(obj);
if (_task_queue->size() <= target_size || has_aborted()) {
ret = false;
--- 2462,2472 ----
} else {
target_size = 0;
}
if (_task_queue->size() > target_size) {
! G1TaskQueueEntry obj;
bool ret = _task_queue->pop_local(obj);
while (ret) {
scan_object(obj);
if (_task_queue->size() <= target_size || has_aborted()) {
ret = false;
*** 2550,2561 ****
_step_times_ms.sd());
log_debug(gc, stats)(" max = %1.2lfms, total = %1.2lfms",
_step_times_ms.maximum(), _step_times_ms.sum());
}
! bool G1ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) {
! return _task_queues->steal(worker_id, hash_seed, obj);
}
/*****************************************************************************
The do_marking_step(time_target_ms, ...) method is the building
--- 2550,2561 ----
_step_times_ms.sd());
log_debug(gc, stats)(" max = %1.2lfms, total = %1.2lfms",
_step_times_ms.maximum(), _step_times_ms.sum());
}
! bool G1ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, G1TaskQueueEntry& task_entry) {
! return _task_queues->steal(worker_id, hash_seed, task_entry);
}
/*****************************************************************************
The do_marking_step(time_target_ms, ...) method is the building
*** 2874,2884 ****
// We cannot check whether the global stack is empty, since other
// tasks might be pushing objects to it concurrently.
assert(_cm->out_of_regions() && _task_queue->size() == 0,
"only way to reach here");
while (!has_aborted()) {
! oop obj;
if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
scan_object(obj);
// And since we're towards the end, let's totally drain the
// local queue and global stack.
--- 2874,2884 ----
// We cannot check whether the global stack is empty, since other
// tasks might be pushing objects to it concurrently.
assert(_cm->out_of_regions() && _task_queue->size() == 0,
"only way to reach here");
while (!has_aborted()) {
! G1TaskQueueEntry obj;
if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
scan_object(obj);
// And since we're towards the end, let's totally drain the
// local queue and global stack.
< prev index next >