-
Bug
-
Resolution: Fixed
-
P4
-
19
-
b26
See:
```
class PLAB: public CHeapObj<mtGC> {
...
static size_t AlignmentReserve;
```
```
PLAB::PLAB(size_t desired_plab_sz_) :
_word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
_end(NULL), _hard_end(NULL), _allocated(0), _wasted(0), _undo_wasted(0)
{
AlignmentReserve = Universe::heap()->tlab_alloc_reserve();
assert(min_size() > AlignmentReserve,
"Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
"to be able to contain objects", min_size(), AlignmentReserve);
}
```
It's also not clear if AlignementReserve is always initialized when used. See this code in Shenandoah:
```
static void initialize_gclab(Thread* thread) {
assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs");
assert(data(thread)->_gclab == NULL, "Only initialize once");
data(thread)->_gclab = new PLAB(PLAB::min_size());
data(thread)->_gclab_size = 0;
}
```
```
size_t PLAB::min_size() {
// Make sure that we return something that is larger than AlignmentReserve
return align_object_size(MAX2(MinTLABSize / HeapWordSize, (size_t)oopDesc::header_size())) + AlignmentReserve;
}
```
The PLAB::min_size() call comes before the PLAB constructor call.
I wonder if putting AlignmentReserve initialization in set_object_alignment, would sort this out?
Note how it is currently set up:
AlignmentReserve = Universe::heap()->tlab_alloc_reserve();
I don't think we need to go through the CollectedHeap to initialize it. The only dynamic property in tlab_alloc_reserve seems to be MinObjAlignment.
And if AlignmentReserve gets initialized early, then we could probably use it in the TLAB code as well:
```
size_t ThreadLocalAllocBuffer::end_reserve() {
size_t reserve_size = Universe::heap()->tlab_alloc_reserve();
```
```
class PLAB: public CHeapObj<mtGC> {
...
static size_t AlignmentReserve;
```
```
PLAB::PLAB(size_t desired_plab_sz_) :
_word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
_end(NULL), _hard_end(NULL), _allocated(0), _wasted(0), _undo_wasted(0)
{
AlignmentReserve = Universe::heap()->tlab_alloc_reserve();
assert(min_size() > AlignmentReserve,
"Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
"to be able to contain objects", min_size(), AlignmentReserve);
}
```
It's also not clear if AlignementReserve is always initialized when used. See this code in Shenandoah:
```
static void initialize_gclab(Thread* thread) {
assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs");
assert(data(thread)->_gclab == NULL, "Only initialize once");
data(thread)->_gclab = new PLAB(PLAB::min_size());
data(thread)->_gclab_size = 0;
}
```
```
size_t PLAB::min_size() {
// Make sure that we return something that is larger than AlignmentReserve
return align_object_size(MAX2(MinTLABSize / HeapWordSize, (size_t)oopDesc::header_size())) + AlignmentReserve;
}
```
The PLAB::min_size() call comes before the PLAB constructor call.
I wonder if putting AlignmentReserve initialization in set_object_alignment, would sort this out?
Note how it is currently set up:
AlignmentReserve = Universe::heap()->tlab_alloc_reserve();
I don't think we need to go through the CollectedHeap to initialize it. The only dynamic property in tlab_alloc_reserve seems to be MinObjAlignment.
And if AlignmentReserve gets initialized early, then we could probably use it in the TLAB code as well:
```
size_t ThreadLocalAllocBuffer::end_reserve() {
size_t reserve_size = Universe::heap()->tlab_alloc_reserve();
```