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