1 /*
2 * Copyright (c) 2014, 2018, 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 #include "precompiled.hpp"
26 #include "gc/g1/g1Allocator.inline.hpp"
27 #include "gc/g1/g1AllocRegion.inline.hpp"
28 #include "gc/g1/g1EvacStats.inline.hpp"
29 #include "gc/g1/g1CollectedHeap.inline.hpp"
30 #include "gc/g1/g1Policy.hpp"
31 #include "gc/g1/heapRegion.inline.hpp"
32 #include "gc/g1/heapRegionSet.inline.hpp"
33 #include "gc/g1/heapRegionType.hpp"
34 #include "utilities/align.hpp"
35
36 G1Allocator::G1Allocator(G1CollectedHeap* heap) :
37 _g1h(heap),
38 _survivor_is_full(false),
39 _old_is_full(false),
40 _mutator_alloc_region(),
41 _survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)),
42 _old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)),
43 _retained_old_gc_alloc_region(NULL) {
44 }
45
46 void G1Allocator::init_mutator_alloc_region() {
47 assert(_mutator_alloc_region.get() == NULL, "pre-condition");
48 _mutator_alloc_region.init();
49 }
50
51 void G1Allocator::release_mutator_alloc_region() {
52 _mutator_alloc_region.release();
53 assert(_mutator_alloc_region.get() == NULL, "post-condition");
54 }
55
56 bool G1Allocator::is_retained_old_region(HeapRegion* hr) {
57 return _retained_old_gc_alloc_region == hr;
58 }
59
60 void G1Allocator::reuse_retained_old_region(EvacuationInfo& evacuation_info,
61 OldGCAllocRegion* old,
62 HeapRegion** retained_old) {
63 HeapRegion* retained_region = *retained_old;
64 *retained_old = NULL;
65 assert(retained_region == NULL || !retained_region->is_archive(),
66 "Archive region should not be alloc region (index %u)", retained_region->hrm_index());
67
68 // We will discard the current GC alloc region if:
69 // a) it's in the collection set (it can happen!),
70 // b) it's already full (no point in using it),
71 // c) it's empty (this means that it was emptied during
72 // a cleanup and it should be on the free list now), or
73 // d) it's humongous (this means that it was emptied
74 // during a cleanup and was added to the free list, but
75 // has been subsequently used to allocate a humongous
76 // object that may be less than the region size).
77 if (retained_region != NULL &&
78 !retained_region->in_collection_set() &&
79 !(retained_region->top() == retained_region->end()) &&
80 !retained_region->is_empty() &&
81 !retained_region->is_humongous()) {
82 // The retained region was added to the old region set when it was
83 // retired. We have to remove it now, since we don't allow regions
84 // we allocate to in the region sets. We'll re-add it later, when
85 // it's retired again.
86 _g1h->old_set_remove(retained_region);
87 old->set(retained_region);
88 _g1h->hr_printer()->reuse(retained_region);
89 evacuation_info.set_alloc_regions_used_before(retained_region->used());
90 }
91 }
92
93 void G1Allocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
94 assert_at_safepoint_on_vm_thread();
95
96 _survivor_is_full = false;
97 _old_is_full = false;
98
99 _survivor_gc_alloc_region.init();
100 _old_gc_alloc_region.init();
101 reuse_retained_old_region(evacuation_info,
102 &_old_gc_alloc_region,
103 &_retained_old_gc_alloc_region);
104 }
105
106 void G1Allocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) {
107 evacuation_info.set_allocation_regions(survivor_gc_alloc_region()->count() +
108 old_gc_alloc_region()->count());
109 survivor_gc_alloc_region()->release();
110 // If we have an old GC alloc region to release, we'll save it in
111 // _retained_old_gc_alloc_region. If we don't
112 // _retained_old_gc_alloc_region will become NULL. This is what we
113 // want either way so no reason to check explicitly for either
114 // condition.
115 _retained_old_gc_alloc_region = old_gc_alloc_region()->release();
116 }
117
118 void G1Allocator::abandon_gc_alloc_regions() {
119 assert(survivor_gc_alloc_region()->get() == NULL, "pre-condition");
120 assert(old_gc_alloc_region()->get() == NULL, "pre-condition");
121 _retained_old_gc_alloc_region = NULL;
122 }
123
124 bool G1Allocator::survivor_is_full() const {
125 return _survivor_is_full;
126 }
|
1 /*
2 * Copyright (c) 2014, 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 #include "precompiled.hpp"
26 #include "gc/g1/g1Allocator.inline.hpp"
27 #include "gc/g1/g1AllocRegion.inline.hpp"
28 #include "gc/g1/g1EvacStats.inline.hpp"
29 #include "gc/g1/g1EvacuationInfo.hpp"
30 #include "gc/g1/g1CollectedHeap.inline.hpp"
31 #include "gc/g1/g1Policy.hpp"
32 #include "gc/g1/heapRegion.inline.hpp"
33 #include "gc/g1/heapRegionSet.inline.hpp"
34 #include "gc/g1/heapRegionType.hpp"
35 #include "utilities/align.hpp"
36
37 G1Allocator::G1Allocator(G1CollectedHeap* heap) :
38 _g1h(heap),
39 _survivor_is_full(false),
40 _old_is_full(false),
41 _mutator_alloc_region(),
42 _survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)),
43 _old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)),
44 _retained_old_gc_alloc_region(NULL) {
45 }
46
47 void G1Allocator::init_mutator_alloc_region() {
48 assert(_mutator_alloc_region.get() == NULL, "pre-condition");
49 _mutator_alloc_region.init();
50 }
51
52 void G1Allocator::release_mutator_alloc_region() {
53 _mutator_alloc_region.release();
54 assert(_mutator_alloc_region.get() == NULL, "post-condition");
55 }
56
57 bool G1Allocator::is_retained_old_region(HeapRegion* hr) {
58 return _retained_old_gc_alloc_region == hr;
59 }
60
61 void G1Allocator::reuse_retained_old_region(G1EvacuationInfo& evacuation_info,
62 OldGCAllocRegion* old,
63 HeapRegion** retained_old) {
64 HeapRegion* retained_region = *retained_old;
65 *retained_old = NULL;
66 assert(retained_region == NULL || !retained_region->is_archive(),
67 "Archive region should not be alloc region (index %u)", retained_region->hrm_index());
68
69 // We will discard the current GC alloc region if:
70 // a) it's in the collection set (it can happen!),
71 // b) it's already full (no point in using it),
72 // c) it's empty (this means that it was emptied during
73 // a cleanup and it should be on the free list now), or
74 // d) it's humongous (this means that it was emptied
75 // during a cleanup and was added to the free list, but
76 // has been subsequently used to allocate a humongous
77 // object that may be less than the region size).
78 if (retained_region != NULL &&
79 !retained_region->in_collection_set() &&
80 !(retained_region->top() == retained_region->end()) &&
81 !retained_region->is_empty() &&
82 !retained_region->is_humongous()) {
83 // The retained region was added to the old region set when it was
84 // retired. We have to remove it now, since we don't allow regions
85 // we allocate to in the region sets. We'll re-add it later, when
86 // it's retired again.
87 _g1h->old_set_remove(retained_region);
88 old->set(retained_region);
89 _g1h->hr_printer()->reuse(retained_region);
90 evacuation_info.set_alloc_regions_used_before(retained_region->used());
91 }
92 }
93
94 void G1Allocator::init_gc_alloc_regions(G1EvacuationInfo& evacuation_info) {
95 assert_at_safepoint_on_vm_thread();
96
97 _survivor_is_full = false;
98 _old_is_full = false;
99
100 _survivor_gc_alloc_region.init();
101 _old_gc_alloc_region.init();
102 reuse_retained_old_region(evacuation_info,
103 &_old_gc_alloc_region,
104 &_retained_old_gc_alloc_region);
105 }
106
107 void G1Allocator::release_gc_alloc_regions(G1EvacuationInfo& evacuation_info) {
108 evacuation_info.set_allocation_regions(survivor_gc_alloc_region()->count() +
109 old_gc_alloc_region()->count());
110 survivor_gc_alloc_region()->release();
111 // If we have an old GC alloc region to release, we'll save it in
112 // _retained_old_gc_alloc_region. If we don't
113 // _retained_old_gc_alloc_region will become NULL. This is what we
114 // want either way so no reason to check explicitly for either
115 // condition.
116 _retained_old_gc_alloc_region = old_gc_alloc_region()->release();
117 }
118
119 void G1Allocator::abandon_gc_alloc_regions() {
120 assert(survivor_gc_alloc_region()->get() == NULL, "pre-condition");
121 assert(old_gc_alloc_region()->get() == NULL, "pre-condition");
122 _retained_old_gc_alloc_region = NULL;
123 }
124
125 bool G1Allocator::survivor_is_full() const {
126 return _survivor_is_full;
127 }
|