< prev index next >

src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp

Print this page
@@ -1,7 +1,7 @@
  /*
-  * 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.

@@ -57,14 +57,16 @@
  
    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");

@@ -116,32 +118,42 @@
  
  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 >