< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp

Print this page
@@ -1,7 +1,8 @@
  /*
   * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
+  * Copyright Amazon.com Inc. 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.

@@ -25,10 +26,11 @@
  #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
  #define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
  
  #include "gc/shared/gc_globals.hpp"
  #include "gc/shared/spaceDecorator.hpp"
+ #include "gc/shenandoah/shenandoahAffiliation.hpp"
  #include "gc/shenandoah/shenandoahAllocRequest.hpp"
  #include "gc/shenandoah/shenandoahAsserts.hpp"
  #include "gc/shenandoah/shenandoahHeap.hpp"
  #include "gc/shenandoah/shenandoahPacer.hpp"
  #include "gc/shenandoah/shenandoahPadding.hpp"

@@ -166,16 +168,17 @@
    static int region_states_num() {
      return _REGION_STATES_NUM;
    }
  
    // Allowed transitions from the outside code:
-   void make_regular_allocation();
+   void make_regular_allocation(ShenandoahAffiliation affiliation);
+   void make_young_maybe();
    void make_regular_bypass();
    void make_humongous_start();
    void make_humongous_cont();
-   void make_humongous_start_bypass();
-   void make_humongous_cont_bypass();
+   void make_humongous_start_bypass(ShenandoahAffiliation affiliation);
+   void make_humongous_cont_bypass(ShenandoahAffiliation affiliation);
    void make_pinned();
    void make_unpinned();
    void make_cset();
    void make_trash();
    void make_trash_immediate();

@@ -196,10 +199,13 @@
    bool is_humongous_start()        const { return _state == _humongous_start || _state == _pinned_humongous_start; }
    bool is_humongous()              const { return is_humongous_start() || is_humongous_continuation(); }
    bool is_committed()              const { return !is_empty_uncommitted(); }
    bool is_cset()                   const { return _state == _cset   || _state == _pinned_cset; }
    bool is_pinned()                 const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }
+   inline bool is_young() const;
+   inline bool is_old() const;
+   inline bool is_affiliated() const;
  
    // Macro-properties:
    bool is_alloc_allowed()          const { return is_empty() || is_regular() || _state == _pinned; }
    bool is_stw_move_allowed()       const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
  

@@ -208,10 +214,14 @@
  
    void record_pin();
    void record_unpin();
    size_t pin_count() const;
  
+   void clear_young_lab_flags();
+   void set_young_lab_flag();
+   bool has_young_lab_flag();
+ 
  private:
    static size_t RegionCount;
    static size_t RegionSizeBytes;
    static size_t RegionSizeWords;
    static size_t RegionSizeBytesShift;

@@ -230,24 +240,33 @@
  
    // Rarely updated fields
    HeapWord* _new_top;
    double _empty_time;
  
+   HeapWord* _top_before_promoted;
+ 
    // Seldom updated fields
    RegionState _state;
+   HeapWord* _coalesce_and_fill_boundary; // for old regions not selected as collection set candidates.
  
    // Frequently updated fields
    HeapWord* _top;
  
    size_t _tlab_allocs;
    size_t _gclab_allocs;
+   size_t _plab_allocs;
+ 
+   bool _has_young_lab;
  
    volatile size_t _live_data;
    volatile size_t _critical_pins;
  
    HeapWord* volatile _update_watermark;
  
+   uint _age;
+   CENSUS_NOISE(uint _youth;)   // tracks epochs of retrograde ageing (rejuvenation)
+ 
  public:
    ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
  
    static const size_t MIN_NUM_REGIONS = 10;
  

@@ -332,12 +351,20 @@
  
    inline size_t index() const {
      return _index;
    }
  
-   // Allocation (return null if full)
-   inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);
+   inline void save_top_before_promote();
+   inline HeapWord* get_top_before_promote() const { return _top_before_promoted; }
+   inline void restore_top_before_promote();
+   inline size_t garbage_before_padded_for_promote() const;
+ 
+   // Allocation (return nullptr if full)
+   inline HeapWord* allocate_aligned(size_t word_size, ShenandoahAllocRequest &req, size_t alignment_in_words);
+ 
+   // Allocation (return nullptr if full)
+   inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest req);
  
    inline void clear_live_data();
    void set_live_data(size_t s);
  
    // Increase live data for newly allocated region

@@ -354,11 +381,45 @@
  
    void print_on(outputStream* st) const;
  
    void recycle();
  
-   void oop_iterate(OopIterateClosure* cl);
+   inline void begin_preemptible_coalesce_and_fill() {
+     _coalesce_and_fill_boundary = _bottom;
+   }
+ 
+   inline void end_preemptible_coalesce_and_fill() {
+     _coalesce_and_fill_boundary = _end;
+   }
+ 
+   inline void suspend_coalesce_and_fill(HeapWord* next_focus) {
+     _coalesce_and_fill_boundary = next_focus;
+   }
+ 
+   inline HeapWord* resume_coalesce_and_fill() {
+     return _coalesce_and_fill_boundary;
+   }
+ 
+   // Coalesce contiguous spans of garbage objects by filling header and reregistering start locations with remembered set.
+   // This is used by old-gen GC following concurrent marking to make old-gen HeapRegions parseable.  Return true iff
+   // region is completely coalesced and filled.  Returns false if cancelled before task is complete.
+   bool oop_fill_and_coalesce();
+ 
+   // Like oop_fill_and_coalesce(), but without honoring cancellation requests.
+   bool oop_fill_and_coalesce_without_cancel();
+ 
+   // During global collections, this service iterates through an old-gen heap region that is not part of collection
+   // set to fill and register ranges of dead memory.  Note that live objects were previously registered.  Some dead objects
+   // that are subsumed into coalesced ranges of dead memory need to be "unregistered".
+   void global_oop_iterate_and_fill_dead(OopIterateClosure* cl);
+   void oop_iterate_humongous(OopIterateClosure* cl);
+   void oop_iterate_humongous(OopIterateClosure* cl, HeapWord* start, size_t words);
+ 
+   // Invoke closure on every reference contained within the humongous object that spans this humongous
+   // region if the reference is contained within a DIRTY card and the reference is no more than words following
+   // start within the humongous object.
+   void oop_iterate_humongous_slice(OopIterateClosure* cl, bool dirty_only, HeapWord* start, size_t words, bool write_table);
  
    HeapWord* block_start(const void* p) const;
    size_t block_size(const HeapWord* p) const;
    bool block_is_obj(const HeapWord* p) const { return p < top(); }
  

@@ -374,28 +435,65 @@
    HeapWord* bottom() const      { return _bottom;  }
    HeapWord* end() const         { return _end;     }
  
    size_t capacity() const       { return byte_size(bottom(), end()); }
    size_t used() const           { return byte_size(bottom(), top()); }
+   size_t used_before_promote() const { return byte_size(bottom(), get_top_before_promote()); }
    size_t free() const           { return byte_size(top(),    end()); }
  
+   // Does this region contain this address?
+   bool contains(HeapWord* p) const {
+     return (bottom() <= p) && (p < top());
+   }
+ 
    inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
    void reset_alloc_metadata();
    size_t get_shared_allocs() const;
    size_t get_tlab_allocs() const;
    size_t get_gclab_allocs() const;
+   size_t get_plab_allocs() const;
  
    inline HeapWord* get_update_watermark() const;
    inline void set_update_watermark(HeapWord* w);
    inline void set_update_watermark_at_safepoint(HeapWord* w);
  
+   inline ShenandoahAffiliation affiliation() const;
+   inline const char* affiliation_name() const;
+ 
+   void set_affiliation(ShenandoahAffiliation new_affiliation);
+ 
+   // Region ageing and rejuvenation
+   uint age() { return _age; }
+   CENSUS_NOISE(uint youth() { return _youth; })
+ 
+   void increment_age() {
+     const uint max_age = markWord::max_age;
+     assert(_age <= max_age, "Error");
+     if (_age++ >= max_age) {
+       _age = max_age;   // clamp
+     }
+   }
+ 
+   void reset_age() {
+     CENSUS_NOISE(_youth += _age;)
+     _age = 0;
+   }
+ 
+   CENSUS_NOISE(void clear_youth() { _youth = 0; })
+ 
+   // Register all objects.  Set all remembered set cards to dirty.
+   void promote_humongous();
+   void promote_in_place();
+ 
  private:
+   void decrement_humongous_waste() const;
    void do_commit();
    void do_uncommit();
  
-   void oop_iterate_objects(OopIterateClosure* cl);
-   void oop_iterate_humongous(OopIterateClosure* cl);
+   // This is an old-region that was not part of the collection set during a GLOBAL collection.  We coalesce the dead
+   // objects, but do not need to register the live objects as they are already registered.
+   void global_oop_iterate_objects_and_fill_dead(OopIterateClosure* cl);
  
    inline void internal_increase_live_data(size_t s);
  
    void set_state(RegionState to);
  };
< prev index next >