提交 5bbd4e2a 编写于 作者: M mgerdin

8047820: G1 Block offset table does not need to support generic Space classes

Reviewed-by: tschatzl, stefank
上级 8f3fa589
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
#include "memory/space.hpp" #include "memory/space.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
...@@ -98,6 +99,20 @@ bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const { ...@@ -98,6 +99,20 @@ bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
return (delta & right_n_bits(LogN_words)) == (size_t)NoBits; 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 // G1BlockOffsetArray
...@@ -107,7 +122,7 @@ G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array, ...@@ -107,7 +122,7 @@ G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
MemRegion mr, bool init_to_zero) : MemRegion mr, bool init_to_zero) :
G1BlockOffsetTable(mr.start(), mr.end()), G1BlockOffsetTable(mr.start(), mr.end()),
_unallocated_block(_bottom), _unallocated_block(_bottom),
_array(array), _csp(NULL), _array(array), _gsp(NULL),
_init_to_zero(init_to_zero) { _init_to_zero(init_to_zero) {
assert(_bottom <= _end, "arguments out of order"); assert(_bottom <= _end, "arguments out of order");
if (!_init_to_zero) { if (!_init_to_zero) {
...@@ -117,9 +132,8 @@ G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array, ...@@ -117,9 +132,8 @@ G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
} }
} }
void G1BlockOffsetArray::set_space(Space* sp) { void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
_sp = sp; _gsp = sp;
_csp = sp->toContiguousSpace();
} }
// The arguments follow the normal convention of denoting // The arguments follow the normal convention of denoting
...@@ -378,7 +392,7 @@ G1BlockOffsetArray::block_start_unsafe_const(const void* addr) const { ...@@ -378,7 +392,7 @@ G1BlockOffsetArray::block_start_unsafe_const(const void* addr) const {
} }
// Otherwise, find the block start using the table. // Otherwise, find the block start using the table.
HeapWord* q = block_at_or_preceding(addr, false, 0); 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); return forward_to_block_containing_addr_const(q, n, addr);
} }
...@@ -406,31 +420,17 @@ G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q, ...@@ -406,31 +420,17 @@ G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
err_msg("next_boundary is beyond the end of the covered region " err_msg("next_boundary is beyond the end of the covered region "
" next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT, " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
next_boundary, _array->_end)); next_boundary, _array->_end));
if (csp() != NULL) { if (addr >= gsp()->top()) return gsp()->top();
if (addr >= csp()->top()) return csp()->top(); while (next_boundary < addr) {
while (next_boundary < addr) { while (n <= next_boundary) {
while (n <= next_boundary) { q = n;
q = n; oop obj = oop(q);
oop obj = oop(q); if (obj->klass_or_null() == NULL) return q;
if (obj->klass_or_null() == NULL) return q; n += obj->size();
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);
}
} 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); return forward_to_block_containing_addr_const(q, n, addr);
} }
...@@ -638,7 +638,7 @@ block_start_unsafe_const(const void* addr) const { ...@@ -638,7 +638,7 @@ block_start_unsafe_const(const void* addr) const {
assert(_bottom <= addr && addr < _end, assert(_bottom <= addr && addr < _end,
"addr must be covered by this Array"); "addr must be covered by this Array");
HeapWord* q = block_at_or_preceding(addr, true, _next_offset_index-1); 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); return forward_to_block_containing_addr_const(q, n, addr);
} }
......
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
// consolidation. // consolidation.
// Forward declarations // Forward declarations
class ContiguousSpace;
class G1BlockOffsetSharedArray; class G1BlockOffsetSharedArray;
class G1OffsetTableContigSpace;
class G1BlockOffsetTable VALUE_OBJ_CLASS_SPEC { class G1BlockOffsetTable VALUE_OBJ_CLASS_SPEC {
friend class VMStructs; friend class VMStructs;
...@@ -157,6 +157,8 @@ private: ...@@ -157,6 +157,8 @@ private:
return _offset_array[index]; 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) { void set_offset_array(size_t index, u_char offset) {
check_index(index, "index out of range"); check_index(index, "index out of range");
check_offset(offset, "offset too large"); check_offset(offset, "offset too large");
...@@ -170,21 +172,6 @@ private: ...@@ -170,21 +172,6 @@ private:
_offset_array[index] = (u_char) pointer_delta(high, low); _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) { void set_offset_array(size_t left, size_t right, u_char offset) {
check_index(right, "right index out of range"); check_index(right, "right index out of range");
assert(left <= right, "indexes out of order"); assert(left <= right, "indexes out of order");
...@@ -281,11 +268,7 @@ private: ...@@ -281,11 +268,7 @@ private:
G1BlockOffsetSharedArray* _array; G1BlockOffsetSharedArray* _array;
// The space that owns this subregion. // The space that owns this subregion.
Space* _sp; G1OffsetTableContigSpace* _gsp;
// If "_sp" is a contiguous space, the field below is the view of "_sp"
// as a contiguous space, else NULL.
ContiguousSpace* _csp;
// If true, array entries are initialized to 0; otherwise, they are // If true, array entries are initialized to 0; otherwise, they are
// initialized to point backwards to the beginning of the covered region. // initialized to point backwards to the beginning of the covered region.
...@@ -310,7 +293,9 @@ private: ...@@ -310,7 +293,9 @@ private:
protected: 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". // 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 // If "has_max_index" is true, "assumes "max_index" is the last valid one
...@@ -363,7 +348,7 @@ public: ...@@ -363,7 +348,7 @@ public:
// "this" to be passed as a parameter to a member constructor for // "this" to be passed as a parameter to a member constructor for
// the containing concrete subtype of Space. // the containing concrete subtype of Space.
// This would be legal C++, but MS VC++ doesn't allow it. // 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". // Resets the covered region to the given "mr".
void set_region(MemRegion mr); void set_region(MemRegion mr);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP
#include "gc_implementation/g1/g1BlockOffsetTable.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.hpp"
#include "gc_implementation/g1/heapRegion.hpp"
#include "memory/space.hpp" #include "memory/space.hpp"
inline HeapWord* G1BlockOffsetTable::block_start(const void* addr) { inline HeapWord* G1BlockOffsetTable::block_start(const void* addr) {
...@@ -69,6 +70,11 @@ G1BlockOffsetSharedArray::address_for_index(size_t index) const { ...@@ -69,6 +70,11 @@ G1BlockOffsetSharedArray::address_for_index(size_t index) const {
return result; return result;
} }
inline size_t
G1BlockOffsetArray::block_size(const HeapWord* p) const {
return gsp()->block_size(p);
}
inline HeapWord* inline HeapWord*
G1BlockOffsetArray::block_at_or_preceding(const void* addr, G1BlockOffsetArray::block_at_or_preceding(const void* addr,
bool has_max_index, bool has_max_index,
...@@ -88,7 +94,7 @@ G1BlockOffsetArray::block_at_or_preceding(const void* addr, ...@@ -88,7 +94,7 @@ G1BlockOffsetArray::block_at_or_preceding(const void* addr,
// to go back by. // to go back by.
size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset); size_t n_cards_back = BlockOffsetArray::entry_to_cards_back(offset);
q -= (N_words * n_cards_back); q -= (N_words * n_cards_back);
assert(q >= _sp->bottom(), "Went below bottom!"); assert(q >= gsp()->bottom(), "Went below bottom!");
index -= n_cards_back; index -= n_cards_back;
offset = _array->offset_array(index); offset = _array->offset_array(index);
} }
...@@ -101,21 +107,12 @@ inline HeapWord* ...@@ -101,21 +107,12 @@ inline HeapWord*
G1BlockOffsetArray:: G1BlockOffsetArray::
forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n, forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n,
const void* addr) const { const void* addr) const {
if (csp() != NULL) { if (addr >= gsp()->top()) return gsp()->top();
if (addr >= csp()->top()) return csp()->top(); while (n <= addr) {
while (n <= addr) { q = n;
q = n; oop obj = oop(q);
oop obj = oop(q); if (obj->klass_or_null() == NULL) return q;
if (obj->klass_or_null() == NULL) return q; n += obj->size();
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);
}
} }
assert(q <= n, "wrong order for q and addr"); assert(q <= n, "wrong order for q and addr");
assert(addr < n, "wrong order for addr and n"); assert(addr < n, "wrong order for addr and n");
...@@ -126,7 +123,7 @@ inline HeapWord* ...@@ -126,7 +123,7 @@ inline HeapWord*
G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q,
const void* addr) { const void* addr) {
if (oop(q)->klass_or_null() == NULL) return q; 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 // 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 // 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 // "q" will contain addr, so the test below will fail, and we'll fall
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
#define 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/g1_specialized_oop_closures.hpp"
#include "gc_implementation/g1/survRateGroup.hpp" #include "gc_implementation/g1/survRateGroup.hpp"
#include "gc_implementation/shared/ageTable.hpp" #include "gc_implementation/shared/ageTable.hpp"
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_INLINE_HPP
#define 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) { inline HeapWord* G1OffsetTableContigSpace::allocate(size_t size) {
HeapWord* res = ContiguousSpace::allocate(size); HeapWord* res = ContiguousSpace::allocate(size);
if (res != NULL) { if (res != NULL) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册