< prev index next >

src/share/vm/gc/g1/satbMarkQueue.cpp

Print this page
rev 10335 : imported patch bufnode_params
rev 10336 : [mq]: inc1

*** 1,7 **** /* ! * Copyright (c) 2001, 2015, 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, 2016, 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.
*** 98,107 **** --- 98,111 ---- "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)); return true; } + inline bool retain_entry(const void* entry, G1CollectedHeap* heap) { + return requires_marking(entry, heap) && !heap->isMarkedNext((oop)entry); + } + // This method removes entries from a SATB buffer that will not be // useful to the concurrent marking threads. Entries are retained if // they require marking and are not already marked. Retained entries // are compacted toward the top of the buffer.
*** 112,158 **** if (buf == NULL) { // nothing to do return; } - // Used for sanity checking at the end of the loop. - DEBUG_ONLY(size_t entries = 0; size_t retained = 0;) - assert(_index <= _sz, "invariant"); ! void** limit = &buf[byte_index_to_index(_index)]; ! void** src = &buf[byte_index_to_index(_sz)]; ! void** dst = src; ! ! while (limit < src) { ! DEBUG_ONLY(entries += 1;) ! --src; void* entry = *src; ! // NULL the entry so that unused parts of the buffer contain NULLs ! // at the end. If we are going to retain it we will copy it to its ! // final place. If we have retained all entries we have visited so ! // far, we'll just end up copying it to the same place. ! *src = NULL; ! ! if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) { ! --dst; ! assert(*dst == NULL, "filtering destination should be clear"); ! *dst = entry; ! DEBUG_ONLY(retained += 1;); } } ! size_t new_index = pointer_delta(dst, buf, 1); ! ! #ifdef ASSERT ! size_t entries_calc = (_sz - _index) / sizeof(void*); ! assert(entries == entries_calc, "the number of entries we counted " ! "should match the number of entries we calculated"); ! size_t retained_calc = (_sz - new_index) / sizeof(void*); ! assert(retained == retained_calc, "the number of retained entries we counted " ! "should match the number of retained entries we calculated"); ! #endif // ASSERT ! ! _index = new_index; } // This method will first apply the above filtering to the buffer. If // post-filtering a large enough chunk of the buffer has been cleared // we can re-use the buffer (instead of enqueueing it) and we can just --- 116,147 ---- if (buf == NULL) { // nothing to do return; } assert(_index <= _sz, "invariant"); ! ! // Two-fingered compaction toward the end. ! void** src = &buf[byte_index_to_index(_index)]; ! void** dst = &buf[byte_index_to_index(_sz)]; ! for ( ; src < dst; ++src) { ! // Search low to high for an entry to keep. void* entry = *src; ! if (retain_entry(entry, g1h)) { ! // Found keeper. Search high to low for an entry to discard. ! while (src < --dst) { ! if (!retain_entry(*dst, g1h)) { ! *dst = entry; // Replace discard with keeper. ! break; } } ! // If discard search failed (src == dst), the outer loop will also end. ! } ! } ! // dst points to the lowest retained entry, or the end of the buffer ! // if all the entries were filtered out. ! _index = pointer_delta(dst, buf, 1); } // This method will first apply the above filtering to the buffer. If // post-filtering a large enough chunk of the buffer has been cleared // we can re-use the buffer (instead of enqueueing it) and we can just
*** 284,306 **** if (_n_completed_buffers == 0) _process_completed = false; } } if (nd != NULL) { void **buf = BufferNode::make_buffer_from_node(nd); ! // Skip over NULL entries at beginning (e.g. push end) of buffer. ! // Filtering can result in non-full completed buffers; see ! // should_enqueue_buffer. ! assert(_sz % sizeof(void*) == 0, "invariant"); ! size_t limit = SATBMarkQueue::byte_index_to_index(_sz); ! for (size_t i = 0; i < limit; ++i) { ! if (buf[i] != NULL) { ! // Found the end of the block of NULLs; process the remainder. ! cl->do_buffer(buf + i, limit - i); ! break; ! } ! } ! deallocate_buffer(buf); return true; } else { return false; } } --- 273,287 ---- if (_n_completed_buffers == 0) _process_completed = false; } } if (nd != NULL) { void **buf = BufferNode::make_buffer_from_node(nd); ! size_t index = SATBMarkQueue::byte_index_to_index(nd->index()); ! size_t size = SATBMarkQueue::byte_index_to_index(_sz); ! assert(index <= size, "invariant"); ! cl->do_buffer(buf + index, size - index); ! deallocate_buffer(nd); return true; } else { return false; } }
*** 353,363 **** DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); } while (buffers_to_delete != NULL) { BufferNode* nd = buffers_to_delete; buffers_to_delete = nd->next(); ! deallocate_buffer(BufferNode::make_buffer_from_node(nd)); } assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); // So we can safely manipulate these queues. for (JavaThread* t = Threads::first(); t; t = t->next()) { t->satb_mark_queue().reset(); --- 334,344 ---- DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); } while (buffers_to_delete != NULL) { BufferNode* nd = buffers_to_delete; buffers_to_delete = nd->next(); ! deallocate_buffer(nd); } assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); // So we can safely manipulate these queues. for (JavaThread* t = Threads::first(); t; t = t->next()) { t->satb_mark_queue().reset();
< prev index next >