80 GrowableArray<G1HeapRegion*>* G1FullGCCompactionPoint::regions() {
81 return _compaction_regions;
82 }
83
84 bool G1FullGCCompactionPoint::object_will_fit(size_t size) {
85 size_t space_left = pointer_delta(_current_region->end(), _compaction_top);
86 return size <= space_left;
87 }
88
89 void G1FullGCCompactionPoint::switch_region() {
90 // Save compaction top in the region.
91 _collector->set_compaction_top(_current_region, _compaction_top);
92 // Get the next region and re-initialize the values.
93 _current_region = next_region();
94 initialize_values();
95 }
96
97 void G1FullGCCompactionPoint::forward(oop object, size_t size) {
98 assert(_current_region != nullptr, "Must have been initialized");
99
100 // Ensure the object fit in the current region.
101 while (!object_will_fit(size)) {
102 switch_region();
103 }
104
105 // Store a forwarding pointer if the object should be moved.
106 if (cast_from_oop<HeapWord*>(object) != _compaction_top) {
107 if (!object->is_forwarded()) {
108 preserved_stack()->push_if_necessary(object, object->mark());
109 }
110 FullGCForwarding::forward_to(object, cast_to_oop(_compaction_top));
111 assert(FullGCForwarding::is_forwarded(object), "must be forwarded");
112 } else {
113 assert(!FullGCForwarding::is_forwarded(object), "must not be forwarded");
114 }
115
116 // Update compaction values.
117 _compaction_top += size;
118 _current_region->update_bot_for_block(_compaction_top - size, _compaction_top);
119 }
120
121 void G1FullGCCompactionPoint::add(G1HeapRegion* hr) {
122 _compaction_regions->append(hr);
137 _compaction_regions->trunc_to(start_index);
138 }
139
140 void G1FullGCCompactionPoint::add_humongous(G1HeapRegion* hr) {
141 assert(hr->is_starts_humongous(), "Sanity!");
142
143 _collector->add_humongous_region(hr);
144
145 G1CollectedHeap* g1h = G1CollectedHeap::heap();
146 g1h->humongous_obj_regions_iterate(hr,
147 [&] (G1HeapRegion* r) {
148 add(r);
149 _collector->update_from_skip_compacting_to_compacting(r->hrm_index());
150 });
151 }
152
153 void G1FullGCCompactionPoint::forward_humongous(G1HeapRegion* hr) {
154 assert(hr->is_starts_humongous(), "Sanity!");
155
156 oop obj = cast_to_oop(hr->bottom());
157 size_t obj_size = obj->size();
158 uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(obj_size);
159
160 if (!has_regions()) {
161 return;
162 }
163
164 // Find contiguous compaction target regions for the humongous object.
165 uint range_begin = find_contiguous_before(hr, num_regions);
166
167 if (range_begin == UINT_MAX) {
168 // No contiguous compaction target regions found, so the object cannot be moved.
169 return;
170 }
171
172 // Preserve the mark for the humongous object as the region was initially not compacting.
173 preserved_stack()->push_if_necessary(obj, obj->mark());
174
175 G1HeapRegion* dest_hr = _compaction_regions->at(range_begin);
176 FullGCForwarding::forward_to(obj, cast_to_oop(dest_hr->bottom()));
177 assert(FullGCForwarding::is_forwarded(obj), "Object must be forwarded!");
178
179 // Add the humongous object regions to the compaction point.
180 add_humongous(hr);
181
182 // Remove covered regions from compaction target candidates.
183 _compaction_regions->remove_range(range_begin, (range_begin + num_regions));
184
185 return;
186 }
187
188 uint G1FullGCCompactionPoint::find_contiguous_before(G1HeapRegion* hr, uint num_regions) {
189 assert(num_regions > 0, "Sanity!");
190 assert(has_regions(), "Sanity!");
191
192 if (num_regions == 1) {
193 // If only one region, return the first region.
194 return 0;
195 }
|
80 GrowableArray<G1HeapRegion*>* G1FullGCCompactionPoint::regions() {
81 return _compaction_regions;
82 }
83
84 bool G1FullGCCompactionPoint::object_will_fit(size_t size) {
85 size_t space_left = pointer_delta(_current_region->end(), _compaction_top);
86 return size <= space_left;
87 }
88
89 void G1FullGCCompactionPoint::switch_region() {
90 // Save compaction top in the region.
91 _collector->set_compaction_top(_current_region, _compaction_top);
92 // Get the next region and re-initialize the values.
93 _current_region = next_region();
94 initialize_values();
95 }
96
97 void G1FullGCCompactionPoint::forward(oop object, size_t size) {
98 assert(_current_region != nullptr, "Must have been initialized");
99
100 size_t old_size = size;
101 size_t new_size = object->copy_size(old_size, object->mark());
102 size = cast_from_oop<HeapWord*>(object) != _compaction_top ? new_size : old_size;
103
104 // Ensure the object fit in the current region.
105 while (!object_will_fit(size)) {
106 switch_region();
107 size = cast_from_oop<HeapWord*>(object) != _compaction_top ? new_size : old_size;
108 }
109
110 // Store a forwarding pointer if the object should be moved.
111 if (cast_from_oop<HeapWord*>(object) != _compaction_top) {
112 if (!object->is_forwarded()) {
113 preserved_stack()->push_if_necessary(object, object->mark());
114 }
115 FullGCForwarding::forward_to(object, cast_to_oop(_compaction_top));
116 assert(FullGCForwarding::is_forwarded(object), "must be forwarded");
117 } else {
118 assert(!FullGCForwarding::is_forwarded(object), "must not be forwarded");
119 }
120
121 // Update compaction values.
122 _compaction_top += size;
123 _current_region->update_bot_for_block(_compaction_top - size, _compaction_top);
124 }
125
126 void G1FullGCCompactionPoint::add(G1HeapRegion* hr) {
127 _compaction_regions->append(hr);
142 _compaction_regions->trunc_to(start_index);
143 }
144
145 void G1FullGCCompactionPoint::add_humongous(G1HeapRegion* hr) {
146 assert(hr->is_starts_humongous(), "Sanity!");
147
148 _collector->add_humongous_region(hr);
149
150 G1CollectedHeap* g1h = G1CollectedHeap::heap();
151 g1h->humongous_obj_regions_iterate(hr,
152 [&] (G1HeapRegion* r) {
153 add(r);
154 _collector->update_from_skip_compacting_to_compacting(r->hrm_index());
155 });
156 }
157
158 void G1FullGCCompactionPoint::forward_humongous(G1HeapRegion* hr) {
159 assert(hr->is_starts_humongous(), "Sanity!");
160
161 oop obj = cast_to_oop(hr->bottom());
162 size_t old_size = obj->size();
163 size_t new_size = obj->copy_size(old_size, obj->mark());
164 uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(new_size);
165
166 if (!has_regions()) {
167 return;
168 }
169
170 // Find contiguous compaction target regions for the humongous object.
171 uint range_begin = find_contiguous_before(hr, num_regions);
172
173 if (range_begin == UINT_MAX) {
174 // No contiguous compaction target regions found, so the object cannot be moved.
175 return;
176 }
177
178 // Preserve the mark for the humongous object as the region was initially not compacting.
179 preserved_stack()->push_if_necessary(obj, obj->mark());
180
181 G1HeapRegion* dest_hr = _compaction_regions->at(range_begin);
182 assert(hr->bottom() != dest_hr->bottom(), "assuming actual humongous move");
183 FullGCForwarding::forward_to(obj, cast_to_oop(dest_hr->bottom()));
184 assert(FullGCForwarding::is_forwarded(obj), "Object must be forwarded!");
185
186 // Add the humongous object regions to the compaction point.
187 add_humongous(hr);
188
189 // Remove covered regions from compaction target candidates.
190 _compaction_regions->remove_range(range_begin, (range_begin + num_regions));
191
192 return;
193 }
194
195 uint G1FullGCCompactionPoint::find_contiguous_before(G1HeapRegion* hr, uint num_regions) {
196 assert(num_regions > 0, "Sanity!");
197 assert(has_regions(), "Sanity!");
198
199 if (num_regions == 1) {
200 // If only one region, return the first region.
201 return 0;
202 }
|