1 | /* |
2 | * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_GC_SHARED_PLAB_HPP |
26 | #define SHARE_GC_SHARED_PLAB_HPP |
27 | |
28 | #include "gc/shared/gcUtil.hpp" |
29 | #include "memory/allocation.hpp" |
30 | #include "utilities/globalDefinitions.hpp" |
31 | |
32 | // Forward declarations. |
33 | class PLABStats; |
34 | |
35 | // A per-thread allocation buffer used during GC. |
36 | class PLAB: public CHeapObj<mtGC> { |
37 | protected: |
38 | char head[32]; |
39 | size_t _word_sz; // In HeapWord units |
40 | HeapWord* _bottom; |
41 | HeapWord* _top; |
42 | HeapWord* _end; // Last allocatable address + 1 |
43 | HeapWord* _hard_end; // _end + AlignmentReserve |
44 | // In support of ergonomic sizing of PLAB's |
45 | size_t _allocated; // in HeapWord units |
46 | size_t _wasted; // in HeapWord units |
47 | size_t _undo_wasted; |
48 | char tail[32]; |
49 | static size_t AlignmentReserve; |
50 | |
51 | // Force future allocations to fail and queries for contains() |
52 | // to return false. Returns the amount of unused space in this PLAB. |
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(); |
64 | |
65 | void add_undo_waste(HeapWord* obj, size_t word_sz); |
66 | |
67 | // Undo the last allocation in the buffer, which is required to be of the |
68 | // "obj" of the given "word_sz". |
69 | void undo_last_allocation(HeapWord* obj, size_t word_sz); |
70 | |
71 | public: |
72 | // Initializes the buffer to be empty, but with the given "word_sz". |
73 | // Must get initialized with "set_buf" for an allocation to succeed. |
74 | PLAB(size_t word_sz); |
75 | |
76 | static size_t size_required_for_allocation(size_t word_size) { return word_size + AlignmentReserve; } |
77 | |
78 | // Minimum PLAB size. |
79 | static size_t min_size(); |
80 | // Maximum PLAB size. |
81 | static size_t max_size(); |
82 | |
83 | // If an allocation of the given "word_sz" can be satisfied within the |
84 | // buffer, do the allocation, returning a pointer to the start of the |
85 | // allocated block. If the allocation request cannot be satisfied, |
86 | // return NULL. |
87 | HeapWord* allocate(size_t word_sz) { |
88 | HeapWord* res = _top; |
89 | if (pointer_delta(_end, _top) >= word_sz) { |
90 | _top = _top + word_sz; |
91 | return res; |
92 | } else { |
93 | return NULL; |
94 | } |
95 | } |
96 | |
97 | // Allocate the object aligned to "alignment_in_bytes". |
98 | inline HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes); |
99 | |
100 | // Undo any allocation in the buffer, which is required to be of the |
101 | // "obj" of the given "word_sz". |
102 | void undo_allocation(HeapWord* obj, size_t word_sz); |
103 | |
104 | // The total (word) size of the buffer, including both allocated and |
105 | // unallocated space. |
106 | size_t word_sz() { return _word_sz; } |
107 | |
108 | size_t waste() { return _wasted; } |
109 | size_t undo_waste() { return _undo_wasted; } |
110 | |
111 | // The number of words of unallocated space remaining in the buffer. |
112 | size_t words_remaining() { |
113 | assert(_end >= _top, "Negative buffer" ); |
114 | return pointer_delta(_end, _top, HeapWordSize); |
115 | } |
116 | |
117 | bool contains(void* addr) { |
118 | return (void*)_bottom <= addr && addr < (void*)_hard_end; |
119 | } |
120 | |
121 | // Sets the space of the buffer to be [buf, space+word_sz()). |
122 | void set_buf(HeapWord* buf, size_t new_word_sz) { |
123 | assert(new_word_sz > AlignmentReserve, "Too small" ); |
124 | _word_sz = new_word_sz; |
125 | |
126 | _bottom = buf; |
127 | _top = _bottom; |
128 | _hard_end = _bottom + word_sz(); |
129 | _end = _hard_end - AlignmentReserve; |
130 | assert(_end >= _top, "Negative buffer" ); |
131 | // In support of ergonomic sizing |
132 | _allocated += word_sz(); |
133 | } |
134 | |
135 | // Flush allocation statistics into the given PLABStats supporting ergonomic |
136 | // sizing of PLAB's and retire the current buffer. To be called at the end of |
137 | // GC. |
138 | void flush_and_retire_stats(PLABStats* stats); |
139 | |
140 | // Fills in the unallocated portion of the buffer with a garbage object and updates |
141 | // statistics. To be called during GC. |
142 | void retire(); |
143 | }; |
144 | |
145 | // PLAB book-keeping. |
146 | class PLABStats : public CHeapObj<mtGC> { |
147 | protected: |
148 | const char* _description; // Identifying string. |
149 | |
150 | size_t _allocated; // Total allocated |
151 | size_t _wasted; // of which wasted (internal fragmentation) |
152 | size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) |
153 | size_t _unused; // Unused in last buffer |
154 | size_t _desired_net_plab_sz;// Output of filter (below), suitably trimmed and quantized |
155 | AdaptiveWeightedAverage |
156 | _filter; // Integrator with decay |
157 | |
158 | virtual void reset() { |
159 | _allocated = 0; |
160 | _wasted = 0; |
161 | _undo_wasted = 0; |
162 | _unused = 0; |
163 | } |
164 | |
165 | virtual void log_plab_allocation(); |
166 | virtual void log_sizing(size_t calculated, size_t net_desired); |
167 | |
168 | // helper for adjust_desired_plab_sz(). |
169 | virtual size_t compute_desired_plab_sz(); |
170 | |
171 | public: |
172 | PLABStats(const char* description, size_t desired_net_plab_sz_, unsigned wt) : |
173 | _description(description), |
174 | _allocated(0), |
175 | _wasted(0), |
176 | _undo_wasted(0), |
177 | _unused(0), |
178 | _desired_net_plab_sz(desired_net_plab_sz_), |
179 | _filter(wt) |
180 | { } |
181 | |
182 | virtual ~PLABStats() { } |
183 | |
184 | size_t allocated() const { return _allocated; } |
185 | size_t wasted() const { return _wasted; } |
186 | size_t unused() const { return _unused; } |
187 | size_t used() const { return allocated() - (wasted() + unused()); } |
188 | size_t undo_wasted() const { return _undo_wasted; } |
189 | |
190 | static const size_t min_size() { |
191 | return PLAB::min_size(); |
192 | } |
193 | |
194 | static const size_t max_size() { |
195 | return PLAB::max_size(); |
196 | } |
197 | |
198 | // Calculates plab size for current number of gc worker threads. |
199 | size_t desired_plab_sz(uint no_of_gc_workers); |
200 | |
201 | // Updates the current desired PLAB size. Computes the new desired PLAB size with one gc worker thread, |
202 | // updates _desired_plab_sz and clears sensor accumulators. |
203 | void adjust_desired_plab_sz(); |
204 | |
205 | inline void add_allocated(size_t v); |
206 | |
207 | inline void add_unused(size_t v); |
208 | |
209 | inline void add_wasted(size_t v); |
210 | |
211 | inline void add_undo_wasted(size_t v); |
212 | }; |
213 | |
214 | #endif // SHARE_GC_SHARED_PLAB_HPP |
215 | |