1901
1902 #ifndef PRODUCT
1903 class VerifyNoCSetOops VALUE_OBJ_CLASS_SPEC {
1904 private:
1905 G1CollectedHeap* _g1h;
1906 const char* _phase;
1907 int _info;
1908
1909 public:
1910 VerifyNoCSetOops(const char* phase, int info = -1) :
1911 _g1h(G1CollectedHeap::heap()),
1912 _phase(phase),
1913 _info(info)
1914 { }
1915
1916 void operator()(G1TaskQueueEntry task_entry) const {
1917 if (task_entry.is_array_slice()) {
1918 guarantee(_g1h->is_in_reserved(task_entry.slice()), "Slice " PTR_FORMAT " must be in heap.", p2i(task_entry.slice()));
1919 return;
1920 }
1921 guarantee(task_entry.obj()->is_oop(),
1922 "Non-oop " PTR_FORMAT ", phase: %s, info: %d",
1923 p2i(task_entry.obj()), _phase, _info);
1924 guarantee(!_g1h->is_in_cset(task_entry.obj()),
1925 "obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
1926 p2i(task_entry.obj()), _phase, _info);
1927 }
1928 };
1929
1930 void G1ConcurrentMark::verify_no_cset_oops() {
1931 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
1932 if (!G1CollectedHeap::heap()->collector_state()->mark_in_progress()) {
1933 return;
1934 }
1935
1936 // Verify entries on the global mark stack
1937 _global_mark_stack.iterate(VerifyNoCSetOops("Stack"));
1938
1939 // Verify entries on the task queues
1940 for (uint i = 0; i < _max_worker_id; ++i) {
1941 G1CMTaskQueue* queue = _task_queues->queue(i);
2296
2297 // This operation was quite expensive, so decrease the limits.
2298 decrease_limits();
2299 }
2300
2301 bool G1CMTask::get_entries_from_global_stack() {
2302 // Local array where we'll store the entries that will be popped
2303 // from the global stack.
2304 G1TaskQueueEntry buffer[G1CMMarkStack::EntriesPerChunk];
2305
2306 if (!_cm->mark_stack_pop(buffer)) {
2307 return false;
2308 }
2309
2310 // We did actually pop at least one entry.
2311 for (size_t i = 0; i < G1CMMarkStack::EntriesPerChunk; ++i) {
2312 G1TaskQueueEntry task_entry = buffer[i];
2313 if (task_entry.is_null()) {
2314 break;
2315 }
2316 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()));
2317 bool success = _task_queue->push(task_entry);
2318 // We only call this when the local queue is empty or under a
2319 // given target limit. So, we do not expect this push to fail.
2320 assert(success, "invariant");
2321 }
2322
2323 // This operation was quite expensive, so decrease the limits
2324 decrease_limits();
2325 return true;
2326 }
2327
2328 void G1CMTask::drain_local_queue(bool partially) {
2329 if (has_aborted()) {
2330 return;
2331 }
2332
2333 // Decide what the target size is, depending whether we're going to
2334 // drain it partially (so that other tasks can steal if they run out
2335 // of things to do) or totally (at the very end).
2336 size_t target_size;
|
1901
1902 #ifndef PRODUCT
1903 class VerifyNoCSetOops VALUE_OBJ_CLASS_SPEC {
1904 private:
1905 G1CollectedHeap* _g1h;
1906 const char* _phase;
1907 int _info;
1908
1909 public:
1910 VerifyNoCSetOops(const char* phase, int info = -1) :
1911 _g1h(G1CollectedHeap::heap()),
1912 _phase(phase),
1913 _info(info)
1914 { }
1915
1916 void operator()(G1TaskQueueEntry task_entry) const {
1917 if (task_entry.is_array_slice()) {
1918 guarantee(_g1h->is_in_reserved(task_entry.slice()), "Slice " PTR_FORMAT " must be in heap.", p2i(task_entry.slice()));
1919 return;
1920 }
1921 guarantee(oopDesc::is_oop(task_entry.obj()),
1922 "Non-oop " PTR_FORMAT ", phase: %s, info: %d",
1923 p2i(task_entry.obj()), _phase, _info);
1924 guarantee(!_g1h->is_in_cset(task_entry.obj()),
1925 "obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
1926 p2i(task_entry.obj()), _phase, _info);
1927 }
1928 };
1929
1930 void G1ConcurrentMark::verify_no_cset_oops() {
1931 assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
1932 if (!G1CollectedHeap::heap()->collector_state()->mark_in_progress()) {
1933 return;
1934 }
1935
1936 // Verify entries on the global mark stack
1937 _global_mark_stack.iterate(VerifyNoCSetOops("Stack"));
1938
1939 // Verify entries on the task queues
1940 for (uint i = 0; i < _max_worker_id; ++i) {
1941 G1CMTaskQueue* queue = _task_queues->queue(i);
2296
2297 // This operation was quite expensive, so decrease the limits.
2298 decrease_limits();
2299 }
2300
2301 bool G1CMTask::get_entries_from_global_stack() {
2302 // Local array where we'll store the entries that will be popped
2303 // from the global stack.
2304 G1TaskQueueEntry buffer[G1CMMarkStack::EntriesPerChunk];
2305
2306 if (!_cm->mark_stack_pop(buffer)) {
2307 return false;
2308 }
2309
2310 // We did actually pop at least one entry.
2311 for (size_t i = 0; i < G1CMMarkStack::EntriesPerChunk; ++i) {
2312 G1TaskQueueEntry task_entry = buffer[i];
2313 if (task_entry.is_null()) {
2314 break;
2315 }
2316 assert(task_entry.is_array_slice() || oopDesc::is_oop(task_entry.obj()), "Element " PTR_FORMAT " must be an array slice or oop", p2i(task_entry.obj()));
2317 bool success = _task_queue->push(task_entry);
2318 // We only call this when the local queue is empty or under a
2319 // given target limit. So, we do not expect this push to fail.
2320 assert(success, "invariant");
2321 }
2322
2323 // This operation was quite expensive, so decrease the limits
2324 decrease_limits();
2325 return true;
2326 }
2327
2328 void G1CMTask::drain_local_queue(bool partially) {
2329 if (has_aborted()) {
2330 return;
2331 }
2332
2333 // Decide what the target size is, depending whether we're going to
2334 // drain it partially (so that other tasks can steal if they run out
2335 // of things to do) or totally (at the very end).
2336 size_t target_size;
|