1 /*
2 * Copyright (c) 2017, 2025, 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 *
42 size_t G1FullGCCompactTask::G1CompactRegionClosure::apply(oop obj) {
43 size_t size = obj->size();
44 if (FullGCForwarding::is_forwarded(obj)) {
45 G1FullGCCompactTask::copy_object_to_new_location(obj);
46 }
47
48 // Clear the mark for the compacted object to allow reuse of the
49 // bitmap without an additional clearing step.
50 clear_in_bitmap(obj);
51 return size;
52 }
53
54 void G1FullGCCompactTask::copy_object_to_new_location(oop obj) {
55 assert(FullGCForwarding::is_forwarded(obj), "Sanity!");
56 assert(FullGCForwarding::forwardee(obj) != obj, "Object must have a new location");
57
58 size_t size = obj->size();
59 // Copy object and reinit its mark.
60 HeapWord* obj_addr = cast_from_oop<HeapWord*>(obj);
61 HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
62 Copy::aligned_conjoint_words(obj_addr, destination, size);
63
64 // There is no need to transform stack chunks - marking already did that.
65 cast_to_oop(destination)->init_mark();
66 assert(cast_to_oop(destination)->klass() != nullptr, "should have a class");
67 }
68
69 void G1FullGCCompactTask::compact_region(G1HeapRegion* hr) {
70 assert(!hr->has_pinned_objects(), "Should be no region with pinned objects in compaction queue");
71 assert(!hr->is_humongous(), "Should be no humongous regions in compaction queue");
72
73 if (!collector()->is_free(hr->hrm_index())) {
74 // The compaction closure not only copies the object to the new
75 // location, but also clears the bitmap for it. This is needed
76 // for bitmap verification and to be able to use the bitmap
77 // for evacuation failures in the next young collection. Testing
78 // showed that it was better overall to clear bit by bit, compared
79 // to clearing the whole region at the end. This difference was
80 // clearly seen for regions with few marks.
81 G1CompactRegionClosure compact(collector()->mark_bitmap());
82 hr->apply_to_marked_objects(collector()->mark_bitmap(), &compact);
83 }
84
85 hr->reset_compacted_after_full_gc(_collector->compaction_top(hr));
101 for (GrowableArrayIterator<G1HeapRegion*> it = compaction_queue->begin();
102 it != compaction_queue->end();
103 ++it) {
104 compact_region(*it);
105 }
106 }
107
108 void G1FullGCCompactTask::humongous_compaction() {
109 GCTraceTime(Debug, gc, phases) tm("Phase 4: Humonguous Compaction", collector()->scope()->timer());
110
111 for (G1HeapRegion* hr : collector()->humongous_compaction_regions()) {
112 assert(collector()->is_compaction_target(hr->hrm_index()), "Sanity");
113 compact_humongous_obj(hr);
114 }
115 }
116
117 void G1FullGCCompactTask::compact_humongous_obj(G1HeapRegion* src_hr) {
118 assert(src_hr->is_starts_humongous(), "Should be start region of the humongous object");
119
120 oop obj = cast_to_oop(src_hr->bottom());
121 size_t word_size = obj->size();
122
123 uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(word_size);
124 HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
125
126 assert(collector()->mark_bitmap()->is_marked(obj), "Should only compact marked objects");
127 collector()->mark_bitmap()->clear(obj);
128
129 copy_object_to_new_location(obj);
130
131 uint dest_start_idx = _g1h->addr_to_region(destination);
132 // Update the metadata for the destination regions.
133 _g1h->set_humongous_metadata(_g1h->region_at(dest_start_idx), num_regions, word_size, false);
134
135 // Free the source regions that do not overlap with the destination regions.
136 uint src_start_idx = src_hr->hrm_index();
137 free_non_overlapping_regions(src_start_idx, dest_start_idx, num_regions);
138 }
139
140 void G1FullGCCompactTask::free_non_overlapping_regions(uint src_start_idx, uint dest_start_idx, uint num_regions) {
141 uint dest_end_idx = dest_start_idx + num_regions -1;
142 uint src_end_idx = src_start_idx + num_regions - 1;
143
144 uint non_overlapping_start = dest_end_idx < src_start_idx ?
145 src_start_idx :
146 dest_end_idx + 1;
147
148 for (uint i = non_overlapping_start; i <= src_end_idx; ++i) {
149 G1HeapRegion* hr = _g1h->region_at(i);
150 if (VerifyDuringGC) {
151 // Satisfy some asserts in free_..._region
152 hr->clear_both_card_tables();
153 }
154 _g1h->free_humongous_region(hr, nullptr);
155 }
156 }
|
1 /*
2 * Copyright (c) 2017, 2026, 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 *
42 size_t G1FullGCCompactTask::G1CompactRegionClosure::apply(oop obj) {
43 size_t size = obj->size();
44 if (FullGCForwarding::is_forwarded(obj)) {
45 G1FullGCCompactTask::copy_object_to_new_location(obj);
46 }
47
48 // Clear the mark for the compacted object to allow reuse of the
49 // bitmap without an additional clearing step.
50 clear_in_bitmap(obj);
51 return size;
52 }
53
54 void G1FullGCCompactTask::copy_object_to_new_location(oop obj) {
55 assert(FullGCForwarding::is_forwarded(obj), "Sanity!");
56 assert(FullGCForwarding::forwardee(obj) != obj, "Object must have a new location");
57
58 size_t size = obj->size();
59 // Copy object and reinit its mark.
60 HeapWord* obj_addr = cast_from_oop<HeapWord*>(obj);
61 HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
62 assert(obj_addr != destination, "only copy actually-moving objects");
63 Copy::aligned_conjoint_words(obj_addr, destination, size);
64
65 // There is no need to transform stack chunks - marking already did that.
66 cast_to_oop(destination)->reinit_mark();
67 cast_to_oop(destination)->initialize_hash_if_necessary(obj);
68 assert(cast_to_oop(destination)->klass() != nullptr, "should have a class");
69 }
70
71 void G1FullGCCompactTask::compact_region(G1HeapRegion* hr) {
72 assert(!hr->has_pinned_objects(), "Should be no region with pinned objects in compaction queue");
73 assert(!hr->is_humongous(), "Should be no humongous regions in compaction queue");
74
75 if (!collector()->is_free(hr->hrm_index())) {
76 // The compaction closure not only copies the object to the new
77 // location, but also clears the bitmap for it. This is needed
78 // for bitmap verification and to be able to use the bitmap
79 // for evacuation failures in the next young collection. Testing
80 // showed that it was better overall to clear bit by bit, compared
81 // to clearing the whole region at the end. This difference was
82 // clearly seen for regions with few marks.
83 G1CompactRegionClosure compact(collector()->mark_bitmap());
84 hr->apply_to_marked_objects(collector()->mark_bitmap(), &compact);
85 }
86
87 hr->reset_compacted_after_full_gc(_collector->compaction_top(hr));
103 for (GrowableArrayIterator<G1HeapRegion*> it = compaction_queue->begin();
104 it != compaction_queue->end();
105 ++it) {
106 compact_region(*it);
107 }
108 }
109
110 void G1FullGCCompactTask::humongous_compaction() {
111 GCTraceTime(Debug, gc, phases) tm("Phase 4: Humonguous Compaction", collector()->scope()->timer());
112
113 for (G1HeapRegion* hr : collector()->humongous_compaction_regions()) {
114 assert(collector()->is_compaction_target(hr->hrm_index()), "Sanity");
115 compact_humongous_obj(hr);
116 }
117 }
118
119 void G1FullGCCompactTask::compact_humongous_obj(G1HeapRegion* src_hr) {
120 assert(src_hr->is_starts_humongous(), "Should be start region of the humongous object");
121
122 oop obj = cast_to_oop(src_hr->bottom());
123 size_t src_word_size = obj->size();
124 size_t dest_word_size = obj->copy_size(src_word_size, obj->mark());
125
126 uint src_num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(src_word_size);
127 uint dest_num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(dest_word_size);
128 if (dest_num_regions > src_num_regions) {
129 // If the object has grown just over the region boundary, due to hash-code expansion, we'll
130 // need a new region. Track it for heuristics.
131 assert(UseCompactObjectHeaders, "only possible through hash-code expansion");
132 uint new_regions = dest_num_regions - src_num_regions;
133 assert(new_regions == 1, "can only possibly grow by 1 region");
134 _g1h->policy()->old_gen_alloc_tracker()->record_collection_pause_humongous_allocation(G1HeapRegion::GrainBytes);
135 }
136 HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
137
138 assert(collector()->mark_bitmap()->is_marked(obj), "Should only compact marked objects");
139 collector()->mark_bitmap()->clear(obj);
140
141 copy_object_to_new_location(obj);
142
143 uint dest_start_idx = _g1h->addr_to_region(destination);
144 // Update the metadata for the destination regions.
145 _g1h->set_humongous_metadata(_g1h->region_at(dest_start_idx), dest_num_regions, dest_word_size, false);
146
147 // Free the source regions that do not overlap with the destination regions.
148 uint src_start_idx = src_hr->hrm_index();
149 free_non_overlapping_regions(src_start_idx, dest_start_idx, src_num_regions, dest_num_regions);
150 }
151
152 void G1FullGCCompactTask::free_non_overlapping_regions(uint src_start_idx, uint dest_start_idx, uint src_num_regions, uint dest_num_regions) {
153 uint dest_end_idx = dest_start_idx + dest_num_regions - 1;
154 uint src_end_idx = src_start_idx + src_num_regions - 1;
155
156 uint non_overlapping_start = dest_end_idx < src_start_idx ?
157 src_start_idx :
158 dest_end_idx + 1;
159
160 for (uint i = non_overlapping_start; i <= src_end_idx; ++i) {
161 G1HeapRegion* hr = _g1h->region_at(i);
162 if (VerifyDuringGC) {
163 // Satisfy some asserts in free_..._region
164 hr->clear_both_card_tables();
165 }
166 _g1h->free_humongous_region(hr, nullptr);
167 }
168 }
|