< prev index next > src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
Print this page
/*
- * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
size_t size = obj->size();
// Copy object and reinit its mark.
HeapWord* obj_addr = cast_from_oop<HeapWord*>(obj);
HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
+ assert(obj_addr != destination, "only copy actually-moving objects");
Copy::aligned_conjoint_words(obj_addr, destination, size);
// There is no need to transform stack chunks - marking already did that.
- cast_to_oop(destination)->init_mark();
+ cast_to_oop(destination)->reinit_mark();
+ cast_to_oop(destination)->initialize_hash_if_necessary(obj);
assert(cast_to_oop(destination)->klass() != nullptr, "should have a class");
}
void G1FullGCCompactTask::compact_region(G1HeapRegion* hr) {
assert(!hr->has_pinned_objects(), "Should be no region with pinned objects in compaction queue");
void G1FullGCCompactTask::compact_humongous_obj(G1HeapRegion* src_hr) {
assert(src_hr->is_starts_humongous(), "Should be start region of the humongous object");
oop obj = cast_to_oop(src_hr->bottom());
- size_t word_size = obj->size();
-
- uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(word_size);
+ size_t src_word_size = obj->size();
+ size_t dest_word_size = obj->copy_size(src_word_size, obj->mark());
+
+ uint src_num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(src_word_size);
+ uint dest_num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(dest_word_size);
+ if (dest_num_regions > src_num_regions) {
+ // If the object has grown just over the region boundary, due to hash-code expansion, we'll
+ // need a new region. Track it for heuristics.
+ assert(UseCompactObjectHeaders, "only possible through hash-code expansion");
+ uint new_regions = dest_num_regions - src_num_regions;
+ assert(new_regions == 1, "can only possibly grow by 1 region");
+ _g1h->policy()->old_gen_alloc_tracker()->record_collection_pause_humongous_allocation(G1HeapRegion::GrainBytes);
+ }
HeapWord* destination = cast_from_oop<HeapWord*>(FullGCForwarding::forwardee(obj));
assert(collector()->mark_bitmap()->is_marked(obj), "Should only compact marked objects");
collector()->mark_bitmap()->clear(obj);
copy_object_to_new_location(obj);
uint dest_start_idx = _g1h->addr_to_region(destination);
// Update the metadata for the destination regions.
- _g1h->set_humongous_metadata(_g1h->region_at(dest_start_idx), num_regions, word_size, false);
+ _g1h->set_humongous_metadata(_g1h->region_at(dest_start_idx), dest_num_regions, dest_word_size, false);
// Free the source regions that do not overlap with the destination regions.
uint src_start_idx = src_hr->hrm_index();
- free_non_overlapping_regions(src_start_idx, dest_start_idx, num_regions);
+ free_non_overlapping_regions(src_start_idx, dest_start_idx, src_num_regions, dest_num_regions);
}
- void G1FullGCCompactTask::free_non_overlapping_regions(uint src_start_idx, uint dest_start_idx, uint num_regions) {
- uint dest_end_idx = dest_start_idx + num_regions -1;
- uint src_end_idx = src_start_idx + num_regions - 1;
+ void G1FullGCCompactTask::free_non_overlapping_regions(uint src_start_idx, uint dest_start_idx, uint src_num_regions, uint dest_num_regions) {
+ uint dest_end_idx = dest_start_idx + dest_num_regions - 1;
+ uint src_end_idx = src_start_idx + src_num_regions - 1;
uint non_overlapping_start = dest_end_idx < src_start_idx ?
src_start_idx :
dest_end_idx + 1;
< prev index next >