1 /*
2 * Copyright (c) 2001, 2015, 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 *
55 }
56
57 bool HeapRegionManager::is_available(uint region) const {
58 return _available_map.at(region);
59 }
60
61 #ifdef ASSERT
62 bool HeapRegionManager::is_free(HeapRegion* hr) const {
63 return _free_list.contains(hr);
64 }
65 #endif
66
67 HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
68 G1CollectedHeap* g1h = G1CollectedHeap::heap();
69 HeapWord* bottom = g1h->bottom_addr_for_region(hrm_index);
70 MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
71 assert(reserved().contains(mr), "invariant");
72 return g1h->new_heap_region(hrm_index, mr);
73 }
74
75 void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
76 guarantee(num_regions > 0, "Must commit more than zero regions");
77 guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
78
79 _num_committed += (uint)num_regions;
80
81 _heap_mapper->commit_regions(index, num_regions);
82
83 // Also commit auxiliary data
84 _prev_bitmap_mapper->commit_regions(index, num_regions);
85 _next_bitmap_mapper->commit_regions(index, num_regions);
86
87 _bot_mapper->commit_regions(index, num_regions);
88 _cardtable_mapper->commit_regions(index, num_regions);
89
90 _card_counts_mapper->commit_regions(index, num_regions);
91 }
92
93 void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
94 guarantee(num_regions >= 1, "Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start);
95 guarantee(_num_committed >= num_regions, "pre-condition");
96
97 // Print before uncommitting.
98 if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
99 for (uint i = start; i < start + num_regions; i++) {
100 HeapRegion* hr = at(i);
101 G1CollectedHeap::heap()->hr_printer()->uncommit(hr);
102 }
103 }
104
105 _num_committed -= (uint)num_regions;
106
107 _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range);
108 _heap_mapper->uncommit_regions(start, num_regions);
109
110 // Also uncommit auxiliary data
111 _prev_bitmap_mapper->uncommit_regions(start, num_regions);
112 _next_bitmap_mapper->uncommit_regions(start, num_regions);
113
114 _bot_mapper->uncommit_regions(start, num_regions);
115 _cardtable_mapper->uncommit_regions(start, num_regions);
116
117 _card_counts_mapper->uncommit_regions(start, num_regions);
118 }
119
120 void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
121 guarantee(num_regions > 0, "No point in calling this for zero regions");
122 commit_regions(start, num_regions);
123 for (uint i = start; i < start + num_regions; i++) {
124 if (_regions.get_by_index(i) == NULL) {
125 HeapRegion* new_hr = new_heap_region(i);
126 _regions.set_by_index(i, new_hr);
127 _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
128 }
129 }
130
131 _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
132
133 for (uint i = start; i < start + num_regions; i++) {
134 assert(is_available(i), "Just made region %u available but is apparently not.", i);
135 HeapRegion* hr = at(i);
136 if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
137 G1CollectedHeap::heap()->hr_printer()->commit(hr);
138 }
139 HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
140 MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
141
142 hr->initialize(mr);
145 }
146
147 MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
148 size_t used_sz =
149 _prev_bitmap_mapper->committed_size() +
150 _next_bitmap_mapper->committed_size() +
151 _bot_mapper->committed_size() +
152 _cardtable_mapper->committed_size() +
153 _card_counts_mapper->committed_size();
154
155 size_t committed_sz =
156 _prev_bitmap_mapper->reserved_size() +
157 _next_bitmap_mapper->reserved_size() +
158 _bot_mapper->reserved_size() +
159 _cardtable_mapper->reserved_size() +
160 _card_counts_mapper->reserved_size();
161
162 return MemoryUsage(0, used_sz, committed_sz, committed_sz);
163 }
164
165 uint HeapRegionManager::expand_by(uint num_regions) {
166 return expand_at(0, num_regions);
167 }
168
169 uint HeapRegionManager::expand_at(uint start, uint num_regions) {
170 if (num_regions == 0) {
171 return 0;
172 }
173
174 uint cur = start;
175 uint idx_last_found = 0;
176 uint num_last_found = 0;
177
178 uint expanded = 0;
179
180 while (expanded < num_regions &&
181 (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
182 uint to_expand = MIN2(num_regions - expanded, num_last_found);
183 make_regions_available(idx_last_found, to_expand);
184 expanded += to_expand;
185 cur = idx_last_found + num_last_found + 1;
186 }
187
188 verify_optional();
189 return expanded;
190 }
191
192 uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
193 uint found = 0;
194 size_t length_found = 0;
195 uint cur = 0;
196
197 while (length_found < num && cur < max_length()) {
198 HeapRegion* hr = _regions.get_by_index(cur);
199 if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
200 // This region is a potential candidate for allocation into.
201 length_found++;
202 } else {
203 // This region is not a candidate. The next region is the next possible one.
|
1 /*
2 * Copyright (c) 2001, 2016, 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 *
55 }
56
57 bool HeapRegionManager::is_available(uint region) const {
58 return _available_map.at(region);
59 }
60
61 #ifdef ASSERT
62 bool HeapRegionManager::is_free(HeapRegion* hr) const {
63 return _free_list.contains(hr);
64 }
65 #endif
66
67 HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
68 G1CollectedHeap* g1h = G1CollectedHeap::heap();
69 HeapWord* bottom = g1h->bottom_addr_for_region(hrm_index);
70 MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
71 assert(reserved().contains(mr), "invariant");
72 return g1h->new_heap_region(hrm_index, mr);
73 }
74
75 void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
76 guarantee(num_regions > 0, "Must commit more than zero regions");
77 guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
78
79 _num_committed += (uint)num_regions;
80
81 _heap_mapper->commit_regions(index, num_regions, pretouch_gang);
82
83 // Also commit auxiliary data
84 _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
85 _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
86
87 _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
88 _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
89
90 _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
91 }
92
93 void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
94 guarantee(num_regions >= 1, "Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start);
95 guarantee(_num_committed >= num_regions, "pre-condition");
96
97 // Print before uncommitting.
98 if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
99 for (uint i = start; i < start + num_regions; i++) {
100 HeapRegion* hr = at(i);
101 G1CollectedHeap::heap()->hr_printer()->uncommit(hr);
102 }
103 }
104
105 _num_committed -= (uint)num_regions;
106
107 _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range);
108 _heap_mapper->uncommit_regions(start, num_regions);
109
110 // Also uncommit auxiliary data
111 _prev_bitmap_mapper->uncommit_regions(start, num_regions);
112 _next_bitmap_mapper->uncommit_regions(start, num_regions);
113
114 _bot_mapper->uncommit_regions(start, num_regions);
115 _cardtable_mapper->uncommit_regions(start, num_regions);
116
117 _card_counts_mapper->uncommit_regions(start, num_regions);
118 }
119
120 void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
121 guarantee(num_regions > 0, "No point in calling this for zero regions");
122 commit_regions(start, num_regions, pretouch_gang);
123 for (uint i = start; i < start + num_regions; i++) {
124 if (_regions.get_by_index(i) == NULL) {
125 HeapRegion* new_hr = new_heap_region(i);
126 _regions.set_by_index(i, new_hr);
127 _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
128 }
129 }
130
131 _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
132
133 for (uint i = start; i < start + num_regions; i++) {
134 assert(is_available(i), "Just made region %u available but is apparently not.", i);
135 HeapRegion* hr = at(i);
136 if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
137 G1CollectedHeap::heap()->hr_printer()->commit(hr);
138 }
139 HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
140 MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
141
142 hr->initialize(mr);
145 }
146
147 MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
148 size_t used_sz =
149 _prev_bitmap_mapper->committed_size() +
150 _next_bitmap_mapper->committed_size() +
151 _bot_mapper->committed_size() +
152 _cardtable_mapper->committed_size() +
153 _card_counts_mapper->committed_size();
154
155 size_t committed_sz =
156 _prev_bitmap_mapper->reserved_size() +
157 _next_bitmap_mapper->reserved_size() +
158 _bot_mapper->reserved_size() +
159 _cardtable_mapper->reserved_size() +
160 _card_counts_mapper->reserved_size();
161
162 return MemoryUsage(0, used_sz, committed_sz, committed_sz);
163 }
164
165 uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
166 return expand_at(0, num_regions, pretouch_workers);
167 }
168
169 uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
170 if (num_regions == 0) {
171 return 0;
172 }
173
174 uint cur = start;
175 uint idx_last_found = 0;
176 uint num_last_found = 0;
177
178 uint expanded = 0;
179
180 while (expanded < num_regions &&
181 (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
182 uint to_expand = MIN2(num_regions - expanded, num_last_found);
183 make_regions_available(idx_last_found, to_expand, pretouch_workers);
184 expanded += to_expand;
185 cur = idx_last_found + num_last_found + 1;
186 }
187
188 verify_optional();
189 return expanded;
190 }
191
192 uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
193 uint found = 0;
194 size_t length_found = 0;
195 uint cur = 0;
196
197 while (length_found < num && cur < max_length()) {
198 HeapRegion* hr = _regions.get_by_index(cur);
199 if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
200 // This region is a potential candidate for allocation into.
201 length_found++;
202 } else {
203 // This region is not a candidate. The next region is the next possible one.
|