diff -r 59f226da8d81 -r 70fb742e40aa hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Mon Jul 07 10:12:40 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp Mon Jul 07 12:37:11 2014 +0200 @@ -30,52 +30,23 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -G1CodeRootChunk::G1CodeRootChunk() : _top(NULL), _next(NULL), _prev(NULL), _free(NULL) { +G1CodeRootChunk::G1CodeRootChunk() : _top(NULL), _next(NULL), _prev(NULL) { _top = bottom(); } void G1CodeRootChunk::reset() { _next = _prev = NULL; - _free = NULL; _top = bottom(); } void G1CodeRootChunk::nmethods_do(CodeBlobClosure* cl) { - NmethodOrLink* cur = bottom(); + nmethod** cur = bottom(); while (cur != _top) { - if (is_nmethod(cur)) { - cl->do_code_blob(cur->_nmethod); - } + cl->do_code_blob(*cur); cur++; } } -bool G1CodeRootChunk::remove_lock_free(nmethod* method) { - NmethodOrLink* cur = bottom(); - - for (NmethodOrLink* cur = bottom(); cur != _top; cur++) { - if (cur->_nmethod == method) { - bool result = Atomic::cmpxchg_ptr(NULL, &cur->_nmethod, method) == method; - - if (!result) { - // Someone else cleared out this entry. - return false; - } - - // The method was cleared. Time to link it into the free list. - NmethodOrLink* prev_free; - do { - prev_free = (NmethodOrLink*)_free; - cur->_link = prev_free; - } while (Atomic::cmpxchg_ptr(cur, &_free, prev_free) != prev_free); - - return true; - } - } - - return false; -} - G1CodeRootChunkManager::G1CodeRootChunkManager() : _free_list(), _num_chunks_handed_out(0) { _free_list.initialize(); _free_list.set_size(G1CodeRootChunk::word_size()); @@ -169,43 +140,34 @@ void G1CodeRootSet::add(nmethod* method) { if (!contains(method)) { - // Find the first chunk thatisn't full. - G1CodeRootChunk* cur = _list.head(); - while (cur != NULL) { - if (!cur->is_full()) { - break; - } - cur = cur->next(); - } - - // All chunks are full, get a new chunk. - if (cur == NULL) { - cur = new_chunk(); + // Try to add the nmethod. If there is not enough space, get a new chunk. + if (_list.head() == NULL || _list.head()->is_full()) { + G1CodeRootChunk* cur = new_chunk(); _list.return_chunk_at_head(cur); } - - // Add the nmethod. - bool result = cur->add(method); - + bool result = _list.head()->add(method); guarantee(result, err_msg("Not able to add nmethod "PTR_FORMAT" to newly allocated chunk.", method)); - _length++; } } -void G1CodeRootSet::remove_lock_free(nmethod* method) { +void G1CodeRootSet::remove(nmethod* method) { G1CodeRootChunk* found = find(method); if (found != NULL) { - bool result = found->remove_lock_free(method); - if (result) { - Atomic::dec_ptr((volatile intptr_t*)&_length); + bool result = found->remove(method); + guarantee(result, err_msg("could not find nmethod "PTR_FORMAT" during removal although we previously found it", method)); + // eventually free completely emptied chunk + if (found->is_empty()) { + _list.remove_chunk(found); + free(found); } + _length--; } assert(!contains(method), err_msg(PTR_FORMAT" still contains nmethod "PTR_FORMAT, this, method)); } nmethod* G1CodeRootSet::pop() { - while (true) { + do { G1CodeRootChunk* cur = _list.head(); if (cur == NULL) { assert(_length == 0, "when there are no chunks, there should be no elements"); @@ -218,7 +180,7 @@ } else { free(_list.get_chunk_at_head()); } - } + } while (true); } G1CodeRootChunk* G1CodeRootSet::find(nmethod* method) {