< 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  *

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

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


201 
202   // Macro-properties:
203   bool is_alloc_allowed()          const { return is_empty() || is_regular() || _state == _pinned; }
204   bool is_stw_move_allowed()       const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
205 
206   RegionState state()              const { return _state; }
207   int  state_ordinal()             const { return region_state_to_ordinal(_state); }
208 
209   void record_pin();
210   void record_unpin();
211   size_t pin_count() const;
212 




213 private:
214   static size_t RegionCount;
215   static size_t RegionSizeBytes;
216   static size_t RegionSizeWords;
217   static size_t RegionSizeBytesShift;
218   static size_t RegionSizeWordsShift;
219   static size_t RegionSizeBytesMask;
220   static size_t RegionSizeWordsMask;
221   static size_t HumongousThresholdBytes;
222   static size_t HumongousThresholdWords;
223   static size_t MaxTLABSizeBytes;
224   static size_t MaxTLABSizeWords;
225 
226   // Never updated fields
227   size_t const _index;
228   HeapWord* const _bottom;
229   HeapWord* const _end;
230 
231   // Rarely updated fields
232   HeapWord* _new_top;
233   double _empty_time;
234 
235   // Seldom updated fields
236   RegionState _state;

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



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


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

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



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


































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





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

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












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

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

  1 /*
  2  * Copyright (c) 2013, 2020, 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  *

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

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