# HG changeset patch # User mgerdin # Date 1403707993 -7200 # Node ID 9441d22e429a139b57e02de4184afaae50e81d1e # Parent e635a728f9da68b870f0330d70869f2a53f59223 8047820: G1 Block offset table does not need to support generic Space classes Reviewed-by: tschatzl, stefank diff -r e635a728f9da -r 9441d22e429a src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp --- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Wed Jun 25 10:55:10 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp Wed Jun 25 16:53:13 2014 +0200 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" +#include "gc_implementation/g1/heapRegion.hpp" #include "memory/space.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" @@ -98,6 +99,20 @@ return (delta & right_n_bits(LogN_words)) == (size_t)NoBits; } +void G1BlockOffsetSharedArray::set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { + check_index(index_for(right - 1), "right address out of range"); + assert(left < right, "Heap addresses out of order"); + size_t num_cards = pointer_delta(right, left) >> LogN_words; + if (UseMemSetInBOT) { + memset(&_offset_array[index_for(left)], offset, num_cards); + } else { + size_t i = index_for(left); + const size_t end = i + num_cards; + for (; i < end; i++) { + _offset_array[i] = offset; + } + } +} ////////////////////////////////////////////////////////////////////// // G1BlockOffsetArray @@ -107,7 +122,7 @@ MemRegion mr, bool init_to_zero) : G1BlockOffsetTable(mr.start(), mr.end()), _unallocated_block(_bottom), - _array(array), _csp(NULL), + _array(array), _gsp(NULL), _init_to_zero(init_to_zero) { assert(_bottom <= _end, "arguments out of order"); if (!_init_to_zero) { @@ -117,9 +132,8 @@ } } -void G1BlockOffsetArray::set_space(Space* sp) { - _sp = sp; - _csp = sp->toContiguousSpace(); +void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) { + _gsp = sp; } // The arguments follow the normal convention of denoting @@ -378,7 +392,7 @@ } // Otherwise, find the block start using the table. HeapWord* q = block_at_or_preceding(addr, false, 0); - HeapWord* n = q + _sp->block_size(q); + HeapWord* n = q + block_size(q); return forward_to_block_containing_addr_const(q, n, addr); } @@ -406,31 +420,17 @@ err_msg("next_boundary is beyond the end of the covered region " " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT, next_boundary, _array->_end)); - if (csp() != NULL) { - if (addr >= csp()->top()) return csp()->top(); - while (next_boundary < addr) { - while (n <= next_boundary) { - q = n; - oop obj = oop(q); - if (obj->klass_or_null() == NULL) return q; - n += obj->size(); - } - assert(q <= next_boundary && n > next_boundary, "Consequence of loop"); - // [q, n) is the block that crosses the boundary. - alloc_block_work2(&next_boundary, &next_index, q, n); + if (addr >= gsp()->top()) return gsp()->top(); + while (next_boundary < addr) { + while (n <= next_boundary) { + q = n; + oop obj = oop(q); + if (obj->klass_or_null() == NULL) return q; + n += obj->size(); } - } else { - while (next_boundary < addr) { - while (n <= next_boundary) { - q = n; - oop obj = oop(q); - if (obj->klass_or_null() == NULL) return q; - n += _sp->block_size(q); - } - assert(q <= next_boundary && n > next_boundary, "Consequence of loop"); - // [q, n) is the block that crosses the boundary. - alloc_block_work2(&next_boundary, &next_index, q, n); - } + assert(q <= next_boundary && n > next_boundary, "Consequence of loop"); + // [q, n) is the block that crosses the boundary. + alloc_block_work2(&next_boundary, &next_index, q, n); } return forward_to_block_containing_addr_const(q, n, addr); } @@ -638,7 +638,7 @@ assert(_bottom <= addr && addr < _end, "addr must be covered by this Array"); HeapWord* q = block_at_or_preceding(addr, true, _next_offset_index-1); - HeapWord* n = q + _sp->block_size(q); + HeapWord* n = q + block_size(q); return forward_to_block_containing_addr_const(q, n, addr); } diff -r e635a728f9da -r 9441d22e429a src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp --- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Wed Jun 25 10:55:10 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Wed Jun 25 16:53:13 2014 +0200 @@ -52,8 +52,8 @@ // consolidation. // Forward declarations -class ContiguousSpace; class G1BlockOffsetSharedArray; +class G1OffsetTableContigSpace; class G1BlockOffsetTable VALUE_OBJ_CLASS_SPEC { friend class VMStructs; @@ -157,6 +157,8 @@ return _offset_array[index]; } + void set_offset_array(HeapWord* left, HeapWord* right, u_char offset); + void set_offset_array(size_t index, u_char offset) { check_index(index, "index out of range"); check_offset(offset, "offset too large"); @@ -170,21 +172,6 @@ _offset_array[index] = (u_char) pointer_delta(high, low); } - void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { - check_index(index_for(right - 1), "right address out of range"); - assert(left < right, "Heap addresses out of order"); - size_t num_cards = pointer_delta(right, left) >> LogN_words; - if (UseMemSetInBOT) { - memset(&_offset_array[index_for(left)], offset, num_cards); - } else { - size_t i = index_for(left); - const size_t end = i + num_cards; - for (; i < end; i++) { - _offset_array[i] = offset; - } - } - } - void set_offset_array(size_t left, size_t right, u_char offset) { check_index(right, "right index out of range"); assert(left <= right, "indexes out of order"); @@ -281,11 +268,7 @@ G1BlockOffsetSharedArray* _array; // The space that owns this subregion. - Space* _sp; - - // If "_sp" is a contiguous space, the field below is the view of "_sp" - // as a contiguous space, else NULL. - ContiguousSpace* _csp; + G1OffsetTableContigSpace* _gsp; // If true, array entries are initialized to 0; otherwise, they are // initialized to point backwards to the beginning of the covered region. @@ -310,7 +293,9 @@ protected: - ContiguousSpace* csp() const { return _csp; } + G1OffsetTableContigSpace* gsp() const { return _gsp; } + + inline size_t block_size(const HeapWord* p) const; // Returns the address of a block whose start is at most "addr". // If "has_max_index" is true, "assumes "max_index" is the last valid one @@ -363,7 +348,7 @@ // "this" to be passed as a parameter to a member constructor for // the containing concrete subtype of Space. // This would be legal C++, but MS VC++ doesn't allow it. - void set_space(Space* sp); + void set_space(G1OffsetTableContigSpace* sp); // Resets the covered region to the given "mr". void set_region(MemRegion mr); diff -r e635a728f9da -r 9441d22e429a src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp --- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp Wed Jun 25 10:55:10 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp Wed Jun 25 16:53:13 2014 +0200 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP #include "gc_implementation/g1/g1BlockOffsetTable.hpp" +#include "gc_implementation/g1/heapRegion.hpp" #include "memory/space.hpp" inline HeapWord* G1BlockOffsetTable::block_start(const void* addr) { @@ -69,6 +70,11 @@ return result; } +inline size_t +G1BlockOffsetArray::block_size(const HeapWord* p) const { + return gsp()->block_size(p); +} + inline HeapWord* G1BlockOffsetArray::block_at_or_preceding(const void* addr, bool has_max_index, @@ -88,7 +94,7 @@ // to go back by. size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset); q -= (N_words * n_cards_back); - assert(q >= _sp->bottom(), "Went below bottom!"); + assert(q >= gsp()->bottom(), "Went below bottom!"); index -= n_cards_back; offset = _array->offset_array(index); } @@ -101,21 +107,12 @@ G1BlockOffsetArray:: forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n, const void* addr) const { - if (csp() != NULL) { - if (addr >= csp()->top()) return csp()->top(); - while (n <= addr) { - q = n; - oop obj = oop(q); - if (obj->klass_or_null() == NULL) return q; - n += obj->size(); - } - } else { - while (n <= addr) { - q = n; - oop obj = oop(q); - if (obj->klass_or_null() == NULL) return q; - n += _sp->block_size(q); - } + if (addr >= gsp()->top()) return gsp()->top(); + while (n <= addr) { + q = n; + oop obj = oop(q); + if (obj->klass_or_null() == NULL) return q; + n += obj->size(); } assert(q <= n, "wrong order for q and addr"); assert(addr < n, "wrong order for addr and n"); @@ -126,7 +123,7 @@ G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, const void* addr) { if (oop(q)->klass_or_null() == NULL) return q; - HeapWord* n = q + _sp->block_size(q); + HeapWord* n = q + block_size(q); // In the normal case, where the query "addr" is a card boundary, and the // offset table chunks are the same size as cards, the block starting at // "q" will contain addr, so the test below will fail, and we'll fall diff -r e635a728f9da -r 9441d22e429a src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jun 25 10:55:10 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jun 25 16:53:13 2014 +0200 @@ -25,7 +25,7 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP -#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" +#include "gc_implementation/g1/g1BlockOffsetTable.hpp" #include "gc_implementation/g1/g1_specialized_oop_closures.hpp" #include "gc_implementation/g1/survRateGroup.hpp" #include "gc_implementation/shared/ageTable.hpp" diff -r e635a728f9da -r 9441d22e429a src/share/vm/gc_implementation/g1/heapRegion.inline.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Wed Jun 25 10:55:10 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp Wed Jun 25 16:53:13 2014 +0200 @@ -25,6 +25,8 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP +#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" + inline HeapWord* G1OffsetTableContigSpace::allocate(size_t size) { HeapWord* res = ContiguousSpace::allocate(size); if (res != NULL) {