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 #include "precompiled.hpp"
26 #include "gc/g1/g1AllocRegion.inline.hpp"
27 #include "gc/g1/g1EvacStats.inline.hpp"
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "runtime/orderAccess.inline.hpp"
30
31 G1CollectedHeap* G1AllocRegion::_g1h = NULL;
32 HeapRegion* G1AllocRegion::_dummy_region = NULL;
33
34 void G1AllocRegion::setup(G1CollectedHeap* g1h, HeapRegion* dummy_region) {
35 assert(_dummy_region == NULL, "should be set once");
36 assert(dummy_region != NULL, "pre-condition");
37 assert(dummy_region->free() == 0, "pre-condition");
38
39 // Make sure that any allocation attempt on this region will fail
40 // and will not trigger any asserts.
41 assert(allocate(dummy_region, 1, false) == NULL, "should fail");
42 assert(par_allocate(dummy_region, 1, false) == NULL, "should fail");
43 assert(allocate(dummy_region, 1, true) == NULL, "should fail");
44 assert(par_allocate(dummy_region, 1, true) == NULL, "should fail");
45
46 _g1h = g1h;
47 _dummy_region = dummy_region;
48 }
177 // We explicitly check that the region is not empty to make sure we
178 // maintain the "the alloc region cannot be empty" invariant.
179 assert_alloc_region(alloc_region != NULL && !alloc_region->is_empty(), "pre-condition");
180
181 _alloc_region = alloc_region;
182 _alloc_region->set_allocation_context(allocation_context());
183 _count += 1;
184 trace("updated");
185 }
186
187 HeapRegion* G1AllocRegion::release() {
188 trace("releasing");
189 HeapRegion* alloc_region = _alloc_region;
190 retire(false /* fill_up */);
191 assert_alloc_region(_alloc_region == _dummy_region, "post-condition of retire()");
192 _alloc_region = NULL;
193 trace("released");
194 return (alloc_region == _dummy_region) ? NULL : alloc_region;
195 }
196
197 #if G1_ALLOC_REGION_TRACING
198 void G1AllocRegion::trace(const char* str, size_t min_word_size, size_t desired_word_size, size_t actual_word_size, HeapWord* result) {
199 // All the calls to trace that set either just the size or the size
200 // and the result are considered part of level 2 tracing and are
201 // skipped during level 1 tracing.
202 if ((actual_word_size == 0 && result == NULL) || (G1_ALLOC_REGION_TRACING > 1)) {
203 const size_t buffer_length = 128;
204 char hr_buffer[buffer_length];
205 char rest_buffer[buffer_length];
206
207 HeapRegion* alloc_region = _alloc_region;
208 if (alloc_region == NULL) {
209 jio_snprintf(hr_buffer, buffer_length, "NULL");
210 } else if (alloc_region == _dummy_region) {
211 jio_snprintf(hr_buffer, buffer_length, "DUMMY");
212 } else {
213 jio_snprintf(hr_buffer, buffer_length,
214 HR_FORMAT, HR_FORMAT_PARAMS(alloc_region));
215 }
216
217 if (G1_ALLOC_REGION_TRACING > 1) {
218 if (result != NULL) {
219 jio_snprintf(rest_buffer, buffer_length, "min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
220 min_word_size, desired_word_size, actual_word_size, result);
221 } else if (min_word_size != 0) {
222 jio_snprintf(rest_buffer, buffer_length, "min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
223 } else {
224 jio_snprintf(rest_buffer, buffer_length, "");
225 }
226 } else {
227 jio_snprintf(rest_buffer, buffer_length, "");
228 }
229
230 tty->print_cr("[%s] %u %s : %s %s",
231 _name, _count, hr_buffer, str, rest_buffer);
232 }
233 }
234 #endif // G1_ALLOC_REGION_TRACING
235
236 G1AllocRegion::G1AllocRegion(const char* name,
237 bool bot_updates)
238 : _name(name), _bot_updates(bot_updates),
239 _alloc_region(NULL), _count(0), _used_bytes_before(0),
240 _allocation_context(AllocationContext::system()) { }
241
242
243 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
244 bool force) {
245 return _g1h->new_mutator_alloc_region(word_size, force);
246 }
247
248 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
249 size_t allocated_bytes) {
250 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
251 }
252
253 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size,
254 bool force) {
|
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 #include "precompiled.hpp"
26 #include "gc/g1/g1AllocRegion.inline.hpp"
27 #include "gc/g1/g1EvacStats.inline.hpp"
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "runtime/orderAccess.inline.hpp"
31
32 G1CollectedHeap* G1AllocRegion::_g1h = NULL;
33 HeapRegion* G1AllocRegion::_dummy_region = NULL;
34
35 void G1AllocRegion::setup(G1CollectedHeap* g1h, HeapRegion* dummy_region) {
36 assert(_dummy_region == NULL, "should be set once");
37 assert(dummy_region != NULL, "pre-condition");
38 assert(dummy_region->free() == 0, "pre-condition");
39
40 // Make sure that any allocation attempt on this region will fail
41 // and will not trigger any asserts.
42 assert(allocate(dummy_region, 1, false) == NULL, "should fail");
43 assert(par_allocate(dummy_region, 1, false) == NULL, "should fail");
44 assert(allocate(dummy_region, 1, true) == NULL, "should fail");
45 assert(par_allocate(dummy_region, 1, true) == NULL, "should fail");
46
47 _g1h = g1h;
48 _dummy_region = dummy_region;
49 }
178 // We explicitly check that the region is not empty to make sure we
179 // maintain the "the alloc region cannot be empty" invariant.
180 assert_alloc_region(alloc_region != NULL && !alloc_region->is_empty(), "pre-condition");
181
182 _alloc_region = alloc_region;
183 _alloc_region->set_allocation_context(allocation_context());
184 _count += 1;
185 trace("updated");
186 }
187
188 HeapRegion* G1AllocRegion::release() {
189 trace("releasing");
190 HeapRegion* alloc_region = _alloc_region;
191 retire(false /* fill_up */);
192 assert_alloc_region(_alloc_region == _dummy_region, "post-condition of retire()");
193 _alloc_region = NULL;
194 trace("released");
195 return (alloc_region == _dummy_region) ? NULL : alloc_region;
196 }
197
198 #ifndef PRODUCT
199 void G1AllocRegion::trace(const char* str, size_t min_word_size, size_t desired_word_size, size_t actual_word_size, HeapWord* result) {
200 // All the calls to trace that set either just the size or the size
201 // and the result are considered part of detailed tracing and are
202 // skipped during other tracing.
203
204 if (!log_develop_is_enabled(Debug, gc, alloc, region)) {
205 return;
206 }
207
208 bool detailed_info = log_develop_is_enabled(Trace, gc, alloc, region);
209
210 if ((actual_word_size == 0 && result == NULL) || detailed_info) {
211 LogHandle(gc, alloc, region) log;
212 ResourceMark rm;
213 outputStream* out;
214 if (detailed_info) {
215 out = log.trace_stream();
216 } else {
217 out = log.debug_stream();
218 }
219
220 out->print("%s: %u ", _name, _count);
221
222 if (_alloc_region == NULL) {
223 out->print("NULL");
224 } else if (_alloc_region == _dummy_region) {
225 out->print("DUMMY");
226 } else {
227 out->print(HR_FORMAT, HR_FORMAT_PARAMS(_alloc_region));
228 }
229
230 out->print(" : %s", str);
231
232 if (detailed_info) {
233 if (result != NULL) {
234 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
235 min_word_size, desired_word_size, actual_word_size, p2i(result));
236 } else if (min_word_size != 0) {
237 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
238 }
239 }
240 out->cr();
241 }
242 }
243 #endif // PRODUCT
244
245 G1AllocRegion::G1AllocRegion(const char* name,
246 bool bot_updates)
247 : _name(name), _bot_updates(bot_updates),
248 _alloc_region(NULL), _count(0), _used_bytes_before(0),
249 _allocation_context(AllocationContext::system()) { }
250
251
252 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
253 bool force) {
254 return _g1h->new_mutator_alloc_region(word_size, force);
255 }
256
257 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
258 size_t allocated_bytes) {
259 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
260 }
261
262 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size,
263 bool force) {
|