22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP |
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP |
27 #include "gc_interface/collectedHeap.hpp" |
27 |
|
28 #include "gc_implementation/shared/gcUtil.hpp" |
28 #include "memory/allocation.hpp" |
29 #include "memory/allocation.hpp" |
29 #include "memory/blockOffsetTable.hpp" |
30 #include "runtime/atomic.hpp" |
30 #include "memory/threadLocalAllocBuffer.hpp" |
|
31 #include "utilities/globalDefinitions.hpp" |
31 #include "utilities/globalDefinitions.hpp" |
32 |
32 |
33 // Forward decl. |
33 // Forward declarations. |
34 |
|
35 class PLABStats; |
34 class PLABStats; |
36 |
35 |
37 // A per-thread allocation buffer used during GC. |
36 // A per-thread allocation buffer used during GC. |
38 class ParGCAllocBuffer: public CHeapObj<mtGC> { |
37 class ParGCAllocBuffer: public CHeapObj<mtGC> { |
39 protected: |
38 protected: |
40 char head[32]; |
39 char head[32]; |
41 size_t _word_sz; // in HeapWord units |
40 size_t _word_sz; // In HeapWord units |
42 HeapWord* _bottom; |
41 HeapWord* _bottom; |
43 HeapWord* _top; |
42 HeapWord* _top; |
44 HeapWord* _end; // last allocatable address + 1 |
43 HeapWord* _end; // Last allocatable address + 1 |
45 HeapWord* _hard_end; // _end + AlignmentReserve |
44 HeapWord* _hard_end; // _end + AlignmentReserve |
46 bool _retained; // whether we hold a _retained_filler |
|
47 MemRegion _retained_filler; |
|
48 // In support of ergonomic sizing of PLAB's |
45 // In support of ergonomic sizing of PLAB's |
49 size_t _allocated; // in HeapWord units |
46 size_t _allocated; // in HeapWord units |
50 size_t _wasted; // in HeapWord units |
47 size_t _wasted; // in HeapWord units |
51 char tail[32]; |
48 char tail[32]; |
52 static size_t FillerHeaderSize; |
|
53 static size_t AlignmentReserve; |
49 static size_t AlignmentReserve; |
54 |
50 |
55 // Flush the stats supporting ergonomic sizing of PLAB's |
51 // Force future allocations to fail and queries for contains() |
56 // Should not be called directly |
52 // to return false. Returns the amount of unused space in this PLAB. |
57 void flush_stats(PLABStats* stats); |
53 size_t invalidate() { |
|
54 _end = _hard_end; |
|
55 size_t remaining = pointer_delta(_end, _top); // Calculate remaining space. |
|
56 _top = _end; // Force future allocations to fail. |
|
57 _bottom = _end; // Force future contains() queries to return false. |
|
58 return remaining; |
|
59 } |
|
60 |
|
61 // Fill in remaining space with a dummy object and invalidate the PLAB. Returns |
|
62 // the amount of remaining space. |
|
63 size_t retire_internal(); |
58 |
64 |
59 public: |
65 public: |
60 // Initializes the buffer to be empty, but with the given "word_sz". |
66 // Initializes the buffer to be empty, but with the given "word_sz". |
61 // Must get initialized with "set_buf" for an allocation to succeed. |
67 // Must get initialized with "set_buf" for an allocation to succeed. |
62 ParGCAllocBuffer(size_t word_sz); |
68 ParGCAllocBuffer(size_t word_sz); |
63 virtual ~ParGCAllocBuffer() {} |
69 virtual ~ParGCAllocBuffer() {} |
64 |
70 |
65 static const size_t min_size() { |
71 // Minimum PLAB size. |
66 // Make sure that we return something that is larger than AlignmentReserve |
72 static size_t min_size(); |
67 return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve; |
73 // Maximum PLAB size. |
68 } |
74 static size_t max_size(); |
69 |
|
70 static const size_t max_size() { |
|
71 return ThreadLocalAllocBuffer::max_size(); |
|
72 } |
|
73 |
75 |
74 // If an allocation of the given "word_sz" can be satisfied within the |
76 // If an allocation of the given "word_sz" can be satisfied within the |
75 // buffer, do the allocation, returning a pointer to the start of the |
77 // buffer, do the allocation, returning a pointer to the start of the |
76 // allocated block. If the allocation request cannot be satisfied, |
78 // allocated block. If the allocation request cannot be satisfied, |
77 // return NULL. |
79 // return NULL. |
126 assert(_end >= _top, "Negative buffer"); |
128 assert(_end >= _top, "Negative buffer"); |
127 // In support of ergonomic sizing |
129 // In support of ergonomic sizing |
128 _allocated += word_sz(); |
130 _allocated += word_sz(); |
129 } |
131 } |
130 |
132 |
131 // Flush the stats supporting ergonomic sizing of PLAB's |
133 // Flush allocation statistics into the given PLABStats supporting ergonomic |
132 // and retire the current buffer. |
134 // sizing of PLAB's and retire the current buffer. To be called at the end of |
133 void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) { |
135 // GC. |
134 // We flush the stats first in order to get a reading of |
136 void flush_and_retire_stats(PLABStats* stats); |
135 // unused space in the last buffer. |
|
136 if (ResizePLAB) { |
|
137 flush_stats(stats); |
|
138 |
137 |
139 // Since we have flushed the stats we need to clear |
138 // Fills in the unallocated portion of the buffer with a garbage object and updates |
140 // the _allocated and _wasted fields. Not doing so |
139 // statistics. To be called during GC. |
141 // will artifically inflate the values in the stats |
140 virtual void retire(); |
142 // to which we add them. |
|
143 // The next time we flush these values, we will add |
|
144 // what we have just flushed in addition to the size |
|
145 // of the buffers allocated between now and then. |
|
146 _allocated = 0; |
|
147 _wasted = 0; |
|
148 } |
|
149 // Retire the last allocation buffer. |
|
150 retire(end_of_gc, retain); |
|
151 } |
|
152 |
|
153 // Force future allocations to fail and queries for contains() |
|
154 // to return false |
|
155 void invalidate() { |
|
156 assert(!_retained, "Shouldn't retain an invalidated buffer."); |
|
157 _end = _hard_end; |
|
158 _wasted += pointer_delta(_end, _top); // unused space |
|
159 _top = _end; // force future allocations to fail |
|
160 _bottom = _end; // force future contains() queries to return false |
|
161 } |
|
162 |
|
163 // Fills in the unallocated portion of the buffer with a garbage object. |
|
164 // If "end_of_gc" is TRUE, is after the last use in the GC. IF "retain" |
|
165 // is true, attempt to re-use the unused portion in the next GC. |
|
166 virtual void retire(bool end_of_gc, bool retain); |
|
167 |
141 |
168 void print() PRODUCT_RETURN; |
142 void print() PRODUCT_RETURN; |
169 }; |
143 }; |
170 |
144 |
171 // PLAB stats book-keeping |
145 // PLAB book-keeping. |
172 class PLABStats VALUE_OBJ_CLASS_SPEC { |
146 class PLABStats VALUE_OBJ_CLASS_SPEC { |
173 size_t _allocated; // total allocated |
147 size_t _allocated; // Total allocated |
174 size_t _wasted; // of which wasted (internal fragmentation) |
148 size_t _wasted; // of which wasted (internal fragmentation) |
175 size_t _unused; // Unused in last buffer |
149 size_t _unused; // Unused in last buffer |
176 size_t _used; // derived = allocated - wasted - unused |
150 size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized |
177 size_t _desired_plab_sz;// output of filter (below), suitably trimmed and quantized |
|
178 AdaptiveWeightedAverage |
151 AdaptiveWeightedAverage |
179 _filter; // integrator with decay |
152 _filter; // Integrator with decay |
180 |
153 |
|
154 void reset() { |
|
155 _allocated = 0; |
|
156 _wasted = 0; |
|
157 _unused = 0; |
|
158 } |
181 public: |
159 public: |
182 PLABStats(size_t desired_plab_sz_, unsigned wt) : |
160 PLABStats(size_t desired_plab_sz_, unsigned wt) : |
183 _allocated(0), |
161 _allocated(0), |
184 _wasted(0), |
162 _wasted(0), |
185 _unused(0), |
163 _unused(0), |
186 _used(0), |
|
187 _desired_plab_sz(desired_plab_sz_), |
164 _desired_plab_sz(desired_plab_sz_), |
188 _filter(wt) |
165 _filter(wt) |
189 { } |
166 { } |
190 |
167 |
191 static const size_t min_size() { |
168 static const size_t min_size() { |
198 |
175 |
199 size_t desired_plab_sz() { |
176 size_t desired_plab_sz() { |
200 return _desired_plab_sz; |
177 return _desired_plab_sz; |
201 } |
178 } |
202 |
179 |
|
180 // Updates the current desired PLAB size. Computes the new desired PLAB size, |
|
181 // updates _desired_plab_sz and clears sensor accumulators. |
203 void adjust_desired_plab_sz(uint no_of_gc_workers); |
182 void adjust_desired_plab_sz(uint no_of_gc_workers); |
204 // filter computation, latches output to |
|
205 // _desired_plab_sz, clears sensor accumulators |
|
206 |
183 |
207 void add_allocated(size_t v) { |
184 void add_allocated(size_t v) { |
208 Atomic::add_ptr(v, &_allocated); |
185 Atomic::add_ptr(v, &_allocated); |
209 } |
186 } |
210 |
187 |