48 class CompactibleSpace; |
48 class CompactibleSpace; |
49 class ContiguousSpace; |
49 class ContiguousSpace; |
50 class HeapRegionRemSet; |
50 class HeapRegionRemSet; |
51 class HeapRegionRemSetIterator; |
51 class HeapRegionRemSetIterator; |
52 class HeapRegion; |
52 class HeapRegion; |
|
53 class HeapRegionSetBase; |
|
54 |
|
55 #define HR_FORMAT "%d:["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]" |
|
56 #define HR_FORMAT_PARAMS(__hr) (__hr)->hrs_index(), (__hr)->bottom(), \ |
|
57 (__hr)->top(), (__hr)->end() |
53 |
58 |
54 // A dirty card to oop closure for heap regions. It |
59 // A dirty card to oop closure for heap regions. It |
55 // knows how to get the G1 heap and how to use the bitmap |
60 // knows how to get the G1 heap and how to use the bitmap |
56 // in the concurrent marker used by G1 to filter remembered |
61 // in the concurrent marker used by G1 to filter remembered |
57 // sets. |
62 // sets. |
303 _prev_top_at_mark_start = bot; |
309 _prev_top_at_mark_start = bot; |
304 _next_top_at_mark_start = bot; |
310 _next_top_at_mark_start = bot; |
305 _top_at_conc_mark_count = bot; |
311 _top_at_conc_mark_count = bot; |
306 } |
312 } |
307 |
313 |
308 jint _zfs; // A member of ZeroFillState. Protected by ZF_lock. |
|
309 Thread* _zero_filler; // If _zfs is ZeroFilling, the thread that (last) |
|
310 // made it so. |
|
311 |
|
312 void set_young_type(YoungType new_type) { |
314 void set_young_type(YoungType new_type) { |
313 //assert(_young_type != new_type, "setting the same type" ); |
315 //assert(_young_type != new_type, "setting the same type" ); |
314 // TODO: add more assertions here |
316 // TODO: add more assertions here |
315 _young_type = new_type; |
317 _young_type = new_type; |
316 } |
318 } |
358 FinalCountClaimValue = 1, |
360 FinalCountClaimValue = 1, |
359 NoteEndClaimValue = 2, |
361 NoteEndClaimValue = 2, |
360 ScrubRemSetClaimValue = 3, |
362 ScrubRemSetClaimValue = 3, |
361 ParVerifyClaimValue = 4, |
363 ParVerifyClaimValue = 4, |
362 RebuildRSClaimValue = 5 |
364 RebuildRSClaimValue = 5 |
363 }; |
|
364 |
|
365 // Concurrent refinement requires contiguous heap regions (in which TLABs |
|
366 // might be allocated) to be zero-filled. Each region therefore has a |
|
367 // zero-fill-state. |
|
368 enum ZeroFillState { |
|
369 NotZeroFilled, |
|
370 ZeroFilling, |
|
371 ZeroFilled, |
|
372 Allocated |
|
373 }; |
365 }; |
374 |
366 |
375 inline HeapWord* par_allocate_no_bot_updates(size_t word_size) { |
367 inline HeapWord* par_allocate_no_bot_updates(size_t word_size) { |
376 assert(is_young(), "we can only skip BOT updates on young regions"); |
368 assert(is_young(), "we can only skip BOT updates on young regions"); |
377 return ContiguousSpace::par_allocate(word_size); |
369 return ContiguousSpace::par_allocate(word_size); |
500 assert(is_gc_alloc_region(), "should only invoke on member of CS."); |
495 assert(is_gc_alloc_region(), "should only invoke on member of CS."); |
501 assert(r == NULL || r->is_gc_alloc_region(), "Malformed CS."); |
496 assert(r == NULL || r->is_gc_alloc_region(), "Malformed CS."); |
502 _next_in_special_set = r; |
497 _next_in_special_set = r; |
503 } |
498 } |
504 |
499 |
505 bool is_on_free_list() { |
500 // Methods used by the HeapRegionSetBase class and subclasses. |
506 return _is_on_free_list; |
501 |
507 } |
502 // Getter and setter for the next field used to link regions into |
508 |
503 // linked lists. |
509 void set_on_free_list(bool b) { |
504 HeapRegion* next() { return _next; } |
510 _is_on_free_list = b; |
505 |
511 } |
506 void set_next(HeapRegion* next) { _next = next; } |
512 |
507 |
513 HeapRegion* next_from_free_list() { |
508 // Every region added to a set is tagged with a reference to that |
514 assert(is_on_free_list(), |
509 // set. This is used for doing consistency checking to make sure that |
515 "Should only invoke on free space."); |
510 // the contents of a set are as they should be and it's only |
516 assert(_next_in_special_set == NULL || |
511 // available in non-product builds. |
517 _next_in_special_set->is_on_free_list(), |
512 #ifdef ASSERT |
518 "Malformed Free List."); |
513 void set_containing_set(HeapRegionSetBase* containing_set) { |
519 return _next_in_special_set; |
514 assert((containing_set == NULL && _containing_set != NULL) || |
520 } |
515 (containing_set != NULL && _containing_set == NULL), |
521 |
516 err_msg("containing_set: "PTR_FORMAT" " |
522 void set_next_on_free_list(HeapRegion* r) { |
517 "_containing_set: "PTR_FORMAT, |
523 assert(r == NULL || r->is_on_free_list(), "Malformed free list."); |
518 containing_set, _containing_set)); |
524 _next_in_special_set = r; |
519 |
525 } |
520 _containing_set = containing_set; |
526 |
521 } |
527 bool is_on_unclean_list() { |
522 |
528 return _is_on_unclean_list; |
523 HeapRegionSetBase* containing_set() { return _containing_set; } |
529 } |
524 #else // ASSERT |
530 |
525 void set_containing_set(HeapRegionSetBase* containing_set) { } |
531 void set_on_unclean_list(bool b); |
526 |
532 |
527 // containing_set() is only used in asserts so there's not reason |
533 HeapRegion* next_from_unclean_list() { |
528 // to provide a dummy version of it. |
534 assert(is_on_unclean_list(), |
529 #endif // ASSERT |
535 "Should only invoke on unclean space."); |
530 |
536 assert(_next_in_special_set == NULL || |
531 // If we want to remove regions from a list in bulk we can simply tag |
537 _next_in_special_set->is_on_unclean_list(), |
532 // them with the pending_removal tag and call the |
538 "Malformed unclean List."); |
533 // remove_all_pending() method on the list. |
539 return _next_in_special_set; |
534 |
540 } |
535 bool pending_removal() { return _pending_removal; } |
541 |
536 |
542 void set_next_on_unclean_list(HeapRegion* r); |
537 void set_pending_removal(bool pending_removal) { |
|
538 // We can only set pending_removal to true, if it's false and the |
|
539 // region belongs to a set. |
|
540 assert(!pending_removal || |
|
541 (!_pending_removal && containing_set() != NULL), "pre-condition"); |
|
542 // We can only set pending_removal to false, if it's true and the |
|
543 // region does not belong to a set. |
|
544 assert( pending_removal || |
|
545 ( _pending_removal && containing_set() == NULL), "pre-condition"); |
|
546 |
|
547 _pending_removal = pending_removal; |
|
548 } |
543 |
549 |
544 HeapRegion* get_next_young_region() { return _next_young_region; } |
550 HeapRegion* get_next_young_region() { return _next_young_region; } |
545 void set_next_young_region(HeapRegion* hr) { |
551 void set_next_young_region(HeapRegion* hr) { |
546 _next_young_region = hr; |
552 _next_young_region = hr; |
547 } |
553 } |
556 |
562 |
557 // Reset HR stuff to default values. |
563 // Reset HR stuff to default values. |
558 void hr_clear(bool par, bool clear_space); |
564 void hr_clear(bool par, bool clear_space); |
559 |
565 |
560 void initialize(MemRegion mr, bool clear_space, bool mangle_space); |
566 void initialize(MemRegion mr, bool clear_space, bool mangle_space); |
561 |
|
562 // Ensure that "this" is zero-filled. |
|
563 void ensure_zero_filled(); |
|
564 // This one requires that the calling thread holds ZF_mon. |
|
565 void ensure_zero_filled_locked(); |
|
566 |
567 |
567 // Get the start of the unmarked area in this region. |
568 // Get the start of the unmarked area in this region. |
568 HeapWord* prev_top_at_mark_start() const { return _prev_top_at_mark_start; } |
569 HeapWord* prev_top_at_mark_start() const { return _prev_top_at_mark_start; } |
569 HeapWord* next_top_at_mark_start() const { return _next_top_at_mark_start; } |
570 HeapWord* next_top_at_mark_start() const { return _next_top_at_mark_start; } |
570 |
571 |
796 // Requires that "addr" is within the region. Returns the start of the |
797 // Requires that "addr" is within the region. Returns the start of the |
797 // first ("careful") block that starts at or after "addr", or else the |
798 // first ("careful") block that starts at or after "addr", or else the |
798 // "end" of the region if there is no such block. |
799 // "end" of the region if there is no such block. |
799 HeapWord* next_block_start_careful(HeapWord* addr); |
800 HeapWord* next_block_start_careful(HeapWord* addr); |
800 |
801 |
801 // Returns the zero-fill-state of the current region. |
|
802 ZeroFillState zero_fill_state() { return (ZeroFillState)_zfs; } |
|
803 bool zero_fill_is_allocated() { return _zfs == Allocated; } |
|
804 Thread* zero_filler() { return _zero_filler; } |
|
805 |
|
806 // Indicate that the contents of the region are unknown, and therefore |
|
807 // might require zero-filling. |
|
808 void set_zero_fill_needed() { |
|
809 set_zero_fill_state_work(NotZeroFilled); |
|
810 } |
|
811 void set_zero_fill_in_progress(Thread* t) { |
|
812 set_zero_fill_state_work(ZeroFilling); |
|
813 _zero_filler = t; |
|
814 } |
|
815 void set_zero_fill_complete(); |
|
816 void set_zero_fill_allocated() { |
|
817 set_zero_fill_state_work(Allocated); |
|
818 } |
|
819 |
|
820 void set_zero_fill_state_work(ZeroFillState zfs); |
|
821 |
|
822 // This is called when a full collection shrinks the heap. |
|
823 // We want to set the heap region to a value which says |
|
824 // it is no longer part of the heap. For now, we'll let "NotZF" fill |
|
825 // that role. |
|
826 void reset_zero_fill() { |
|
827 set_zero_fill_state_work(NotZeroFilled); |
|
828 _zero_filler = NULL; |
|
829 } |
|
830 |
|
831 size_t recorded_rs_length() const { return _recorded_rs_length; } |
802 size_t recorded_rs_length() const { return _recorded_rs_length; } |
832 double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } |
803 double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } |
833 size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; } |
804 size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; } |
834 |
805 |
835 void set_recorded_rs_length(size_t rs_length) { |
806 void set_recorded_rs_length(size_t rs_length) { |
864 // the "next" marking information at the end of remark. |
835 // the "next" marking information at the end of remark. |
865 void verify(bool allow_dirty, bool use_prev_marking, bool *failures) const; |
836 void verify(bool allow_dirty, bool use_prev_marking, bool *failures) const; |
866 |
837 |
867 // Override; it uses the "prev" marking information |
838 // Override; it uses the "prev" marking information |
868 virtual void verify(bool allow_dirty) const; |
839 virtual void verify(bool allow_dirty) const; |
869 |
|
870 #ifdef DEBUG |
|
871 HeapWord* allocate(size_t size); |
|
872 #endif |
|
873 }; |
840 }; |
874 |
841 |
875 // HeapRegionClosure is used for iterating over regions. |
842 // HeapRegionClosure is used for iterating over regions. |
876 // Terminates the iteration when the "doHeapRegion" method returns "true". |
843 // Terminates the iteration when the "doHeapRegion" method returns "true". |
877 class HeapRegionClosure : public StackObj { |
844 class HeapRegionClosure : public StackObj { |
890 // True after iteration if the closure was applied to all heap regions |
857 // True after iteration if the closure was applied to all heap regions |
891 // and returned "false" in all cases. |
858 // and returned "false" in all cases. |
892 bool complete() { return _complete; } |
859 bool complete() { return _complete; } |
893 }; |
860 }; |
894 |
861 |
895 // A linked lists of heap regions. It leaves the "next" field |
|
896 // unspecified; that's up to subtypes. |
|
897 class RegionList VALUE_OBJ_CLASS_SPEC { |
|
898 protected: |
|
899 virtual HeapRegion* get_next(HeapRegion* chr) = 0; |
|
900 virtual void set_next(HeapRegion* chr, |
|
901 HeapRegion* new_next) = 0; |
|
902 |
|
903 HeapRegion* _hd; |
|
904 HeapRegion* _tl; |
|
905 size_t _sz; |
|
906 |
|
907 // Protected constructor because this type is only meaningful |
|
908 // when the _get/_set next functions are defined. |
|
909 RegionList() : _hd(NULL), _tl(NULL), _sz(0) {} |
|
910 public: |
|
911 void reset() { |
|
912 _hd = NULL; |
|
913 _tl = NULL; |
|
914 _sz = 0; |
|
915 } |
|
916 HeapRegion* hd() { return _hd; } |
|
917 HeapRegion* tl() { return _tl; } |
|
918 size_t sz() { return _sz; } |
|
919 size_t length(); |
|
920 |
|
921 bool well_formed() { |
|
922 return |
|
923 ((hd() == NULL && tl() == NULL && sz() == 0) |
|
924 || (hd() != NULL && tl() != NULL && sz() > 0)) |
|
925 && (sz() == length()); |
|
926 } |
|
927 virtual void insert_before_head(HeapRegion* r); |
|
928 void prepend_list(RegionList* new_list); |
|
929 virtual HeapRegion* pop(); |
|
930 void dec_sz() { _sz--; } |
|
931 // Requires that "r" is an element of the list, and is not the tail. |
|
932 void delete_after(HeapRegion* r); |
|
933 }; |
|
934 |
|
935 class EmptyNonHRegionList: public RegionList { |
|
936 protected: |
|
937 // Protected constructor because this type is only meaningful |
|
938 // when the _get/_set next functions are defined. |
|
939 EmptyNonHRegionList() : RegionList() {} |
|
940 |
|
941 public: |
|
942 void insert_before_head(HeapRegion* r) { |
|
943 // assert(r->is_empty(), "Better be empty"); |
|
944 assert(!r->isHumongous(), "Better not be humongous."); |
|
945 RegionList::insert_before_head(r); |
|
946 } |
|
947 void prepend_list(EmptyNonHRegionList* new_list) { |
|
948 // assert(new_list->hd() == NULL || new_list->hd()->is_empty(), |
|
949 // "Better be empty"); |
|
950 assert(new_list->hd() == NULL || !new_list->hd()->isHumongous(), |
|
951 "Better not be humongous."); |
|
952 // assert(new_list->tl() == NULL || new_list->tl()->is_empty(), |
|
953 // "Better be empty"); |
|
954 assert(new_list->tl() == NULL || !new_list->tl()->isHumongous(), |
|
955 "Better not be humongous."); |
|
956 RegionList::prepend_list(new_list); |
|
957 } |
|
958 }; |
|
959 |
|
960 class UncleanRegionList: public EmptyNonHRegionList { |
|
961 public: |
|
962 HeapRegion* get_next(HeapRegion* hr) { |
|
963 return hr->next_from_unclean_list(); |
|
964 } |
|
965 void set_next(HeapRegion* hr, HeapRegion* new_next) { |
|
966 hr->set_next_on_unclean_list(new_next); |
|
967 } |
|
968 |
|
969 UncleanRegionList() : EmptyNonHRegionList() {} |
|
970 |
|
971 void insert_before_head(HeapRegion* r) { |
|
972 assert(!r->is_on_free_list(), |
|
973 "Better not already be on free list"); |
|
974 assert(!r->is_on_unclean_list(), |
|
975 "Better not already be on unclean list"); |
|
976 r->set_zero_fill_needed(); |
|
977 r->set_on_unclean_list(true); |
|
978 EmptyNonHRegionList::insert_before_head(r); |
|
979 } |
|
980 void prepend_list(UncleanRegionList* new_list) { |
|
981 assert(new_list->tl() == NULL || !new_list->tl()->is_on_free_list(), |
|
982 "Better not already be on free list"); |
|
983 assert(new_list->tl() == NULL || new_list->tl()->is_on_unclean_list(), |
|
984 "Better already be marked as on unclean list"); |
|
985 assert(new_list->hd() == NULL || !new_list->hd()->is_on_free_list(), |
|
986 "Better not already be on free list"); |
|
987 assert(new_list->hd() == NULL || new_list->hd()->is_on_unclean_list(), |
|
988 "Better already be marked as on unclean list"); |
|
989 EmptyNonHRegionList::prepend_list(new_list); |
|
990 } |
|
991 HeapRegion* pop() { |
|
992 HeapRegion* res = RegionList::pop(); |
|
993 if (res != NULL) res->set_on_unclean_list(false); |
|
994 return res; |
|
995 } |
|
996 }; |
|
997 |
|
998 // Local Variables: *** |
|
999 // c-indentation-style: gnu *** |
|
1000 // End: *** |
|
1001 |
|
1002 #endif // SERIALGC |
862 #endif // SERIALGC |
1003 |
863 |
1004 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP |
864 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP |