< prev index next >

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

Print this page

  1 /*
  2  * Copyright (c) 2013, 2019, Red Hat, Inc. 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  *
 23  */
 24 
 25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
 27 
 28 #include "gc/shared/gc_globals.hpp"
 29 #include "gc/shared/spaceDecorator.hpp"

 30 #include "gc/shenandoah/shenandoahAllocRequest.hpp"
 31 #include "gc/shenandoah/shenandoahAsserts.hpp"
 32 #include "gc/shenandoah/shenandoahHeap.hpp"
 33 #include "gc/shenandoah/shenandoahPadding.hpp"
 34 #include "utilities/sizes.hpp"
 35 
 36 class VMStructs;
 37 class ShenandoahHeapRegionStateConstant;
 38 
 39 class ShenandoahHeapRegion {
 40   friend class VMStructs;
 41   friend class ShenandoahHeapRegionStateConstant;
 42 private:
 43   /*
 44     Region state is described by a state machine. Transitions are guarded by
 45     heap lock, which allows changing the state of several regions atomically.
 46     Region states can be logically aggregated in groups.
 47 
 48       "Empty":
 49       .................................................................

150       case _humongous_cont:         return 4;
151       case _cset:                   return 5;
152       case _pinned:                 return 6;
153       case _trash:                  return 7;
154       case _pinned_cset:            return 8;
155       case _pinned_humongous_start: return 9;
156       default:
157         ShouldNotReachHere();
158         return -1;
159     }
160   }
161 
162   void report_illegal_transition(const char* method);
163 
164 public:
165   static int region_states_num() {
166     return _REGION_STATES_NUM;
167   }
168 
169   // Allowed transitions from the outside code:
170   void make_regular_allocation();

171   void make_regular_bypass();
172   void make_humongous_start();
173   void make_humongous_cont();
174   void make_humongous_start_bypass();
175   void make_humongous_cont_bypass();
176   void make_pinned();
177   void make_unpinned();
178   void make_cset();
179   void make_trash();
180   void make_trash_immediate();
181   void make_empty();
182   void make_uncommitted();
183   void make_committed_bypass();
184 
185   // Individual states:
186   bool is_empty_uncommitted()      const { return _state == _empty_uncommitted; }
187   bool is_empty_committed()        const { return _state == _empty_committed; }
188   bool is_regular()                const { return _state == _regular; }
189   bool is_humongous_continuation() const { return _state == _humongous_cont; }
190 
191   // Participation in logical groups:
192   bool is_empty()                  const { return is_empty_committed() || is_empty_uncommitted(); }
193   bool is_active()                 const { return !is_empty() && !is_trash(); }
194   bool is_trash()                  const { return _state == _trash; }
195   bool is_humongous_start()        const { return _state == _humongous_start || _state == _pinned_humongous_start; }
196   bool is_humongous()              const { return is_humongous_start() || is_humongous_continuation(); }
197   bool is_committed()              const { return !is_empty_uncommitted(); }
198   bool is_cset()                   const { return _state == _cset   || _state == _pinned_cset; }
199   bool is_pinned()                 const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }



200 
201   // Macro-properties:
202   bool is_alloc_allowed()          const { return is_empty() || is_regular() || _state == _pinned; }
203   bool is_stw_move_allowed()       const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
204 
205   RegionState state()              const { return _state; }
206   int  state_ordinal()             const { return region_state_to_ordinal(_state); }
207 
208   void record_pin();
209   void record_unpin();
210   size_t pin_count() const;
211 
212 private:
213   static size_t RegionCount;
214   static size_t RegionSizeBytes;
215   static size_t RegionSizeWords;
216   static size_t RegionSizeBytesShift;
217   static size_t RegionSizeWordsShift;
218   static size_t RegionSizeBytesMask;
219   static size_t RegionSizeWordsMask;
220   static size_t HumongousThresholdBytes;
221   static size_t HumongousThresholdWords;
222   static size_t MaxTLABSizeBytes;
223   static size_t MaxTLABSizeWords;
224 
225   // Never updated fields
226   size_t const _index;
227   HeapWord* const _bottom;
228   HeapWord* const _end;
229 
230   // Rarely updated fields
231   HeapWord* _new_top;
232   double _empty_time;
233 


234   // Seldom updated fields
235   RegionState _state;

236 
237   // Frequently updated fields
238   HeapWord* _top;
239 
240   size_t _tlab_allocs;
241   size_t _gclab_allocs;

242 
243   volatile size_t _live_data;
244   volatile size_t _critical_pins;
245 
246   HeapWord* volatile _update_watermark;
247 



248 public:
249   ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
250 
251   static const size_t MIN_NUM_REGIONS = 10;
252 
253   // Return adjusted max heap size
254   static size_t setup_sizes(size_t max_heap_size);
255 
256   double empty_time() {
257     return _empty_time;
258   }
259 
260   inline static size_t required_regions(size_t bytes) {
261     return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
262   }
263 
264   inline static size_t region_count() {
265     return ShenandoahHeapRegion::RegionCount;
266   }
267 

316   inline static size_t humongous_threshold_bytes() {
317     return ShenandoahHeapRegion::HumongousThresholdBytes;
318   }
319 
320   inline static size_t humongous_threshold_words() {
321     return ShenandoahHeapRegion::HumongousThresholdWords;
322   }
323 
324   inline static size_t max_tlab_size_bytes() {
325     return ShenandoahHeapRegion::MaxTLABSizeBytes;
326   }
327 
328   inline static size_t max_tlab_size_words() {
329     return ShenandoahHeapRegion::MaxTLABSizeWords;
330   }
331 
332   inline size_t index() const {
333     return _index;
334   }
335 
336   // Allocation (return null if full)
337   inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);











338 
339   inline void clear_live_data();
340   void set_live_data(size_t s);
341 
342   // Increase live data for newly allocated region
343   inline void increase_live_data_alloc_words(size_t s);
344 
345   // Increase live data for region scanned with GC
346   inline void increase_live_data_gc_words(size_t s);
347 
348   inline bool has_live() const;
349   inline size_t get_live_data_bytes() const;
350   inline size_t get_live_data_words() const;
351 
352   inline size_t garbage() const;
353 
354   void print_on(outputStream* st) const;
355 
356   void recycle();
357 
358   void oop_iterate(OopIterateClosure* cl);


































359 
360   HeapWord* block_start(const void* p) const;
361   size_t block_size(const HeapWord* p) const;
362   bool block_is_obj(const HeapWord* p) const { return p < top(); }
363 
364   // Find humongous start region that this region belongs to
365   ShenandoahHeapRegion* humongous_start_region() const;
366 
367   HeapWord* top() const         { return _top;     }
368   void set_top(HeapWord* v)     { _top = v;        }
369 
370   HeapWord* new_top() const     { return _new_top; }
371   void set_new_top(HeapWord* v) { _new_top = v;    }
372 
373   HeapWord* bottom() const      { return _bottom;  }
374   HeapWord* end() const         { return _end;     }
375 
376   size_t capacity() const       { return byte_size(bottom(), end()); }
377   size_t used() const           { return byte_size(bottom(), top()); }

378   size_t free() const           { return byte_size(top(),    end()); }
379 





380   inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
381   void reset_alloc_metadata();
382   size_t get_shared_allocs() const;
383   size_t get_tlab_allocs() const;
384   size_t get_gclab_allocs() const;

385 
386   inline HeapWord* get_update_watermark() const;
387   inline void set_update_watermark(HeapWord* w);
388   inline void set_update_watermark_at_safepoint(HeapWord* w);
389 




























390 private:

391   void do_commit();
392   void do_uncommit();
393 
394   void oop_iterate_objects(OopIterateClosure* cl);
395   void oop_iterate_humongous(OopIterateClosure* cl);

396 
397   inline void internal_increase_live_data(size_t s);
398 
399   void set_state(RegionState to);
400 };
401 
402 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP

  1 /*
  2  * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
  3  * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
 27 #define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
 28 
 29 #include "gc/shared/gc_globals.hpp"
 30 #include "gc/shared/spaceDecorator.hpp"
 31 #include "gc/shenandoah/shenandoahAffiliation.hpp"
 32 #include "gc/shenandoah/shenandoahAllocRequest.hpp"
 33 #include "gc/shenandoah/shenandoahAsserts.hpp"
 34 #include "gc/shenandoah/shenandoahHeap.hpp"
 35 #include "gc/shenandoah/shenandoahPadding.hpp"
 36 #include "utilities/sizes.hpp"
 37 
 38 class VMStructs;
 39 class ShenandoahHeapRegionStateConstant;
 40 
 41 class ShenandoahHeapRegion {
 42   friend class VMStructs;
 43   friend class ShenandoahHeapRegionStateConstant;
 44 private:
 45   /*
 46     Region state is described by a state machine. Transitions are guarded by
 47     heap lock, which allows changing the state of several regions atomically.
 48     Region states can be logically aggregated in groups.
 49 
 50       "Empty":
 51       .................................................................

152       case _humongous_cont:         return 4;
153       case _cset:                   return 5;
154       case _pinned:                 return 6;
155       case _trash:                  return 7;
156       case _pinned_cset:            return 8;
157       case _pinned_humongous_start: return 9;
158       default:
159         ShouldNotReachHere();
160         return -1;
161     }
162   }
163 
164   void report_illegal_transition(const char* method);
165 
166 public:
167   static int region_states_num() {
168     return _REGION_STATES_NUM;
169   }
170 
171   // Allowed transitions from the outside code:
172   void make_regular_allocation(ShenandoahAffiliation affiliation);
173   void make_young_maybe();
174   void make_regular_bypass();
175   void make_humongous_start();
176   void make_humongous_cont();
177   void make_humongous_start_bypass(ShenandoahAffiliation affiliation);
178   void make_humongous_cont_bypass(ShenandoahAffiliation affiliation);
179   void make_pinned();
180   void make_unpinned();
181   void make_cset();
182   void make_trash();
183   void make_trash_immediate();
184   void make_empty();
185   void make_uncommitted();
186   void make_committed_bypass();
187 
188   // Individual states:
189   bool is_empty_uncommitted()      const { return _state == _empty_uncommitted; }
190   bool is_empty_committed()        const { return _state == _empty_committed; }
191   bool is_regular()                const { return _state == _regular; }
192   bool is_humongous_continuation() const { return _state == _humongous_cont; }
193 
194   // Participation in logical groups:
195   bool is_empty()                  const { return is_empty_committed() || is_empty_uncommitted(); }
196   bool is_active()                 const { return !is_empty() && !is_trash(); }
197   bool is_trash()                  const { return _state == _trash; }
198   bool is_humongous_start()        const { return _state == _humongous_start || _state == _pinned_humongous_start; }
199   bool is_humongous()              const { return is_humongous_start() || is_humongous_continuation(); }
200   bool is_committed()              const { return !is_empty_uncommitted(); }
201   bool is_cset()                   const { return _state == _cset   || _state == _pinned_cset; }
202   bool is_pinned()                 const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }
203   inline bool is_young() const;
204   inline bool is_old() const;
205   inline bool is_affiliated() const;
206 
207   // Macro-properties:
208   bool is_alloc_allowed()          const { return is_empty() || is_regular() || _state == _pinned; }
209   bool is_stw_move_allowed()       const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
210 
211   RegionState state()              const { return _state; }
212   int  state_ordinal()             const { return region_state_to_ordinal(_state); }
213 
214   void record_pin();
215   void record_unpin();
216   size_t pin_count() const;
217 
218 private:
219   static size_t RegionCount;
220   static size_t RegionSizeBytes;
221   static size_t RegionSizeWords;
222   static size_t RegionSizeBytesShift;
223   static size_t RegionSizeWordsShift;
224   static size_t RegionSizeBytesMask;
225   static size_t RegionSizeWordsMask;
226   static size_t HumongousThresholdBytes;
227   static size_t HumongousThresholdWords;
228   static size_t MaxTLABSizeBytes;
229   static size_t MaxTLABSizeWords;
230 
231   // Never updated fields
232   size_t const _index;
233   HeapWord* const _bottom;
234   HeapWord* const _end;
235 
236   // Rarely updated fields
237   HeapWord* _new_top;
238   double _empty_time;
239 
240   HeapWord* _top_before_promoted;
241 
242   // Seldom updated fields
243   RegionState _state;
244   HeapWord* _coalesce_and_fill_boundary; // for old regions not selected as collection set candidates.
245 
246   // Frequently updated fields
247   HeapWord* _top;
248 
249   size_t _tlab_allocs;
250   size_t _gclab_allocs;
251   size_t _plab_allocs;
252 
253   volatile size_t _live_data;
254   volatile size_t _critical_pins;
255 
256   HeapWord* volatile _update_watermark;
257 
258   uint _age;
259   CENSUS_NOISE(uint _youth;)   // tracks epochs of retrograde ageing (rejuvenation)
260 
261 public:
262   ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
263 
264   static const size_t MIN_NUM_REGIONS = 10;
265 
266   // Return adjusted max heap size
267   static size_t setup_sizes(size_t max_heap_size);
268 
269   double empty_time() {
270     return _empty_time;
271   }
272 
273   inline static size_t required_regions(size_t bytes) {
274     return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
275   }
276 
277   inline static size_t region_count() {
278     return ShenandoahHeapRegion::RegionCount;
279   }
280 

329   inline static size_t humongous_threshold_bytes() {
330     return ShenandoahHeapRegion::HumongousThresholdBytes;
331   }
332 
333   inline static size_t humongous_threshold_words() {
334     return ShenandoahHeapRegion::HumongousThresholdWords;
335   }
336 
337   inline static size_t max_tlab_size_bytes() {
338     return ShenandoahHeapRegion::MaxTLABSizeBytes;
339   }
340 
341   inline static size_t max_tlab_size_words() {
342     return ShenandoahHeapRegion::MaxTLABSizeWords;
343   }
344 
345   inline size_t index() const {
346     return _index;
347   }
348 
349   inline void save_top_before_promote();
350   inline HeapWord* get_top_before_promote() const { return _top_before_promoted; }
351   inline void restore_top_before_promote();
352   inline size_t garbage_before_padded_for_promote() const;
353 
354   // If next available memory is not aligned on address that is multiple of alignment, fill the empty space
355   // so that returned object is aligned on an address that is a multiple of alignment_in_bytes.  Requested
356   // size is in words.  It is assumed that this->is_old().  A pad object is allocated, filled, and registered
357   // if necessary to assure the new allocation is properly aligned.  Return nullptr if memory is not available.
358   inline HeapWord* allocate_aligned(size_t word_size, ShenandoahAllocRequest &req, size_t alignment_in_bytes);
359 
360   // Allocation (return nullptr if full)
361   inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest req);
362 
363   inline void clear_live_data();
364   void set_live_data(size_t s);
365 
366   // Increase live data for newly allocated region
367   inline void increase_live_data_alloc_words(size_t s);
368 
369   // Increase live data for region scanned with GC
370   inline void increase_live_data_gc_words(size_t s);
371 
372   inline bool has_live() const;
373   inline size_t get_live_data_bytes() const;
374   inline size_t get_live_data_words() const;
375 
376   inline size_t garbage() const;
377 
378   void print_on(outputStream* st) const;
379 
380   void recycle();
381 
382   inline void begin_preemptible_coalesce_and_fill() {
383     _coalesce_and_fill_boundary = _bottom;
384   }
385 
386   inline void end_preemptible_coalesce_and_fill() {
387     _coalesce_and_fill_boundary = _end;
388   }
389 
390   inline void suspend_coalesce_and_fill(HeapWord* next_focus) {
391     _coalesce_and_fill_boundary = next_focus;
392   }
393 
394   inline HeapWord* resume_coalesce_and_fill() {
395     return _coalesce_and_fill_boundary;
396   }
397 
398   // Coalesce contiguous spans of garbage objects by filling header and reregistering start locations with remembered set.
399   // This is used by old-gen GC following concurrent marking to make old-gen HeapRegions parsable.  Return true iff
400   // region is completely coalesced and filled.  Returns false if cancelled before task is complete.
401   bool oop_fill_and_coalesce();
402 
403   // Like oop_fill_and_coalesce(), but without honoring cancellation requests.
404   bool oop_fill_and_coalesce_without_cancel();
405 
406   // During global collections, this service iterates through an old-gen heap region that is not part of collection
407   // set to fill and register ranges of dead memory.  Note that live objects were previously registered.  Some dead objects
408   // that are subsumed into coalesced ranges of dead memory need to be "unregistered".
409   void global_oop_iterate_and_fill_dead(OopIterateClosure* cl);
410   void oop_iterate_humongous(OopIterateClosure* cl);
411   void oop_iterate_humongous(OopIterateClosure* cl, HeapWord* start, size_t words);
412 
413   // Invoke closure on every reference contained within the humongous object that spans this humongous
414   // region if the reference is contained within a DIRTY card and the reference is no more than words following
415   // start within the humongous object.
416   void oop_iterate_humongous_slice(OopIterateClosure* cl, bool dirty_only, HeapWord* start, size_t words, bool write_table);
417 
418   HeapWord* block_start(const void* p) const;
419   size_t block_size(const HeapWord* p) const;
420   bool block_is_obj(const HeapWord* p) const { return p < top(); }
421 
422   // Find humongous start region that this region belongs to
423   ShenandoahHeapRegion* humongous_start_region() const;
424 
425   HeapWord* top() const         { return _top;     }
426   void set_top(HeapWord* v)     { _top = v;        }
427 
428   HeapWord* new_top() const     { return _new_top; }
429   void set_new_top(HeapWord* v) { _new_top = v;    }
430 
431   HeapWord* bottom() const      { return _bottom;  }
432   HeapWord* end() const         { return _end;     }
433 
434   size_t capacity() const       { return byte_size(bottom(), end()); }
435   size_t used() const           { return byte_size(bottom(), top()); }
436   size_t used_before_promote() const { return byte_size(bottom(), get_top_before_promote()); }
437   size_t free() const           { return byte_size(top(),    end()); }
438 
439   // Does this region contain this address?
440   bool contains(HeapWord* p) const {
441     return (bottom() <= p) && (p < top());
442   }
443 
444   inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
445   void reset_alloc_metadata();
446   size_t get_shared_allocs() const;
447   size_t get_tlab_allocs() const;
448   size_t get_gclab_allocs() const;
449   size_t get_plab_allocs() const;
450 
451   inline HeapWord* get_update_watermark() const;
452   inline void set_update_watermark(HeapWord* w);
453   inline void set_update_watermark_at_safepoint(HeapWord* w);
454 
455   inline ShenandoahAffiliation affiliation() const;
456   inline const char* affiliation_name() const;
457 
458   void set_affiliation(ShenandoahAffiliation new_affiliation);
459 
460   // Region ageing and rejuvenation
461   uint age() { return _age; }
462   CENSUS_NOISE(uint youth() { return _youth; })
463 
464   void increment_age() {
465     const uint max_age = markWord::max_age;
466     assert(_age <= max_age, "Error");
467     if (_age++ >= max_age) {
468       _age = max_age;   // clamp
469     }
470   }
471 
472   void reset_age() {
473     CENSUS_NOISE(_youth += _age;)
474     _age = 0;
475   }
476 
477   CENSUS_NOISE(void clear_youth() { _youth = 0; })
478 
479   // Register all objects.  Set all remembered set cards to dirty.
480   void promote_humongous();
481   void promote_in_place();
482 
483 private:
484   void decrement_humongous_waste() const;
485   void do_commit();
486   void do_uncommit();
487 
488   // This is an old-region that was not part of the collection set during a GLOBAL collection.  We coalesce the dead
489   // objects, but do not need to register the live objects as they are already registered.
490   void global_oop_iterate_objects_and_fill_dead(OopIterateClosure* cl);
491 
492   inline void internal_increase_live_data(size_t s);
493 
494   void set_state(RegionState to);
495 };
496 
497 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
< prev index next >