Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @ 482:7c2386d67889
6765745: par compact - allow young gen spaces to be split
Reviewed-by: jmasa
author | jcoomes |
---|---|
date | Thu, 11 Dec 2008 12:05:14 -0800 |
parents | 7d7a7c599c17 |
children | 0f773163217d |
comparison
equal
deleted
inserted
replaced
481:7d7a7c599c17 | 482:7c2386d67889 |
---|---|
34 class GCTaskQueue; | 34 class GCTaskQueue; |
35 class PreGCValues; | 35 class PreGCValues; |
36 class MoveAndUpdateClosure; | 36 class MoveAndUpdateClosure; |
37 class RefProcTaskExecutor; | 37 class RefProcTaskExecutor; |
38 | 38 |
39 // The SplitInfo class holds the information needed to 'split' a source region | |
40 // so that the live data can be copied to two destination *spaces*. Normally, | |
41 // all the live data in a region is copied to a single destination space (e.g., | |
42 // everything live in a region in eden is copied entirely into the old gen). | |
43 // However, when the heap is nearly full, all the live data in eden may not fit | |
44 // into the old gen. Copying only some of the regions from eden to old gen | |
45 // requires finding a region that does not contain a partial object (i.e., no | |
46 // live object crosses the region boundary) somewhere near the last object that | |
47 // does fit into the old gen. Since it's not always possible to find such a | |
48 // region, splitting is necessary for predictable behavior. | |
49 // | |
50 // A region is always split at the end of the partial object. This avoids | |
51 // additional tests when calculating the new location of a pointer, which is a | |
52 // very hot code path. The partial object and everything to its left will be | |
53 // copied to another space (call it dest_space_1). The live data to the right | |
54 // of the partial object will be copied either within the space itself, or to a | |
55 // different destination space (distinct from dest_space_1). | |
56 // | |
57 // Split points are identified during the summary phase, when region | |
58 // destinations are computed: data about the split, including the | |
59 // partial_object_size, is recorded in a SplitInfo record and the | |
60 // partial_object_size field in the summary data is set to zero. The zeroing is | |
61 // possible (and necessary) since the partial object will move to a different | |
62 // destination space than anything to its right, thus the partial object should | |
63 // not affect the locations of any objects to its right. | |
64 // | |
65 // The recorded data is used during the compaction phase, but only rarely: when | |
66 // the partial object on the split region will be copied across a destination | |
67 // region boundary. This test is made once each time a region is filled, and is | |
68 // a simple address comparison, so the overhead is negligible (see | |
69 // PSParallelCompact::first_src_addr()). | |
70 // | |
71 // Notes: | |
72 // | |
73 // Only regions with partial objects are split; a region without a partial | |
74 // object does not need any extra bookkeeping. | |
75 // | |
76 // At most one region is split per space, so the amount of data required is | |
77 // constant. | |
78 // | |
79 // A region is split only when the destination space would overflow. Once that | |
80 // happens, the destination space is abandoned and no other data (even from | |
81 // other source spaces) is targeted to that destination space. Abandoning the | |
82 // destination space may leave a somewhat large unused area at the end, if a | |
83 // large object caused the overflow. | |
84 // | |
85 // Future work: | |
86 // | |
87 // More bookkeeping would be required to continue to use the destination space. | |
88 // The most general solution would allow data from regions in two different | |
89 // source spaces to be "joined" in a single destination region. At the very | |
90 // least, additional code would be required in next_src_region() to detect the | |
91 // join and skip to an out-of-order source region. If the join region was also | |
92 // the last destination region to which a split region was copied (the most | |
93 // likely case), then additional work would be needed to get fill_region() to | |
94 // stop iteration and switch to a new source region at the right point. Basic | |
95 // idea would be to use a fake value for the top of the source space. It is | |
96 // doable, if a bit tricky. | |
97 // | |
98 // A simpler (but less general) solution would fill the remainder of the | |
99 // destination region with a dummy object and continue filling the next | |
100 // destination region. | |
101 | |
102 class SplitInfo | |
103 { | |
104 public: | |
105 // Return true if this split info is valid (i.e., if a split has been | |
106 // recorded). The very first region cannot have a partial object and thus is | |
107 // never split, so 0 is the 'invalid' value. | |
108 bool is_valid() const { return _src_region_idx > 0; } | |
109 | |
110 // Return true if this split holds data for the specified source region. | |
111 inline bool is_split(size_t source_region) const; | |
112 | |
113 // The index of the split region, the size of the partial object on that | |
114 // region and the destination of the partial object. | |
115 size_t src_region_idx() const { return _src_region_idx; } | |
116 size_t partial_obj_size() const { return _partial_obj_size; } | |
117 HeapWord* destination() const { return _destination; } | |
118 | |
119 // The destination count of the partial object referenced by this split | |
120 // (either 1 or 2). This must be added to the destination count of the | |
121 // remainder of the source region. | |
122 unsigned int destination_count() const { return _destination_count; } | |
123 | |
124 // If a word within the partial object will be written to the first word of a | |
125 // destination region, this is the address of the destination region; | |
126 // otherwise this is NULL. | |
127 HeapWord* dest_region_addr() const { return _dest_region_addr; } | |
128 | |
129 // If a word within the partial object will be written to the first word of a | |
130 // destination region, this is the address of that word within the partial | |
131 // object; otherwise this is NULL. | |
132 HeapWord* first_src_addr() const { return _first_src_addr; } | |
133 | |
134 // Record the data necessary to split the region src_region_idx. | |
135 void record(size_t src_region_idx, size_t partial_obj_size, | |
136 HeapWord* destination); | |
137 | |
138 void clear(); | |
139 | |
140 DEBUG_ONLY(void verify_clear();) | |
141 | |
142 private: | |
143 size_t _src_region_idx; | |
144 size_t _partial_obj_size; | |
145 HeapWord* _destination; | |
146 unsigned int _destination_count; | |
147 HeapWord* _dest_region_addr; | |
148 HeapWord* _first_src_addr; | |
149 }; | |
150 | |
151 inline bool SplitInfo::is_split(size_t region_idx) const | |
152 { | |
153 return _src_region_idx == region_idx && is_valid(); | |
154 } | |
155 | |
39 class SpaceInfo | 156 class SpaceInfo |
40 { | 157 { |
41 public: | 158 public: |
42 MutableSpace* space() const { return _space; } | 159 MutableSpace* space() const { return _space; } |
43 | 160 |
55 HeapWord* dense_prefix() const { return _dense_prefix; } | 172 HeapWord* dense_prefix() const { return _dense_prefix; } |
56 | 173 |
57 // The start array for the (generation containing the) space, or NULL if there | 174 // The start array for the (generation containing the) space, or NULL if there |
58 // is no start array. | 175 // is no start array. |
59 ObjectStartArray* start_array() const { return _start_array; } | 176 ObjectStartArray* start_array() const { return _start_array; } |
177 | |
178 SplitInfo& split_info() { return _split_info; } | |
60 | 179 |
61 void set_space(MutableSpace* s) { _space = s; } | 180 void set_space(MutableSpace* s) { _space = s; } |
62 void set_new_top(HeapWord* addr) { _new_top = addr; } | 181 void set_new_top(HeapWord* addr) { _new_top = addr; } |
63 void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; } | 182 void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; } |
64 void set_dense_prefix(HeapWord* addr) { _dense_prefix = addr; } | 183 void set_dense_prefix(HeapWord* addr) { _dense_prefix = addr; } |
65 void set_start_array(ObjectStartArray* s) { _start_array = s; } | 184 void set_start_array(ObjectStartArray* s) { _start_array = s; } |
185 | |
186 void publish_new_top() const { _space->set_top(_new_top); } | |
66 | 187 |
67 private: | 188 private: |
68 MutableSpace* _space; | 189 MutableSpace* _space; |
69 HeapWord* _new_top; | 190 HeapWord* _new_top; |
70 HeapWord* _min_dense_prefix; | 191 HeapWord* _min_dense_prefix; |
71 HeapWord* _dense_prefix; | 192 HeapWord* _dense_prefix; |
72 ObjectStartArray* _start_array; | 193 ObjectStartArray* _start_array; |
194 SplitInfo _split_info; | |
73 }; | 195 }; |
74 | 196 |
75 class ParallelCompactData | 197 class ParallelCompactData |
76 { | 198 { |
77 public: | 199 public: |
228 // Fill in the regions covering [beg, end) so that no data moves; i.e., the | 350 // Fill in the regions covering [beg, end) so that no data moves; i.e., the |
229 // destination of region n is simply the start of region n. The argument beg | 351 // destination of region n is simply the start of region n. The argument beg |
230 // must be region-aligned; end need not be. | 352 // must be region-aligned; end need not be. |
231 void summarize_dense_prefix(HeapWord* beg, HeapWord* end); | 353 void summarize_dense_prefix(HeapWord* beg, HeapWord* end); |
232 | 354 |
233 bool summarize(HeapWord* target_beg, HeapWord* target_end, | 355 HeapWord* summarize_split_space(size_t src_region, SplitInfo& split_info, |
356 HeapWord* destination, HeapWord* target_end, | |
357 HeapWord** target_next); | |
358 bool summarize(SplitInfo& split_info, | |
234 HeapWord* source_beg, HeapWord* source_end, | 359 HeapWord* source_beg, HeapWord* source_end, |
235 HeapWord** target_next, HeapWord** source_next = 0); | 360 HeapWord** source_next, |
361 HeapWord* target_beg, HeapWord* target_end, | |
362 HeapWord** target_next); | |
236 | 363 |
237 void clear(); | 364 void clear(); |
238 void clear_range(size_t beg_region, size_t end_region); | 365 void clear_range(size_t beg_region, size_t end_region); |
239 void clear_range(HeapWord* beg, HeapWord* end) { | 366 void clear_range(HeapWord* beg, HeapWord* end) { |
240 clear_range(addr_to_region_idx(beg), addr_to_region_idx(end)); | 367 clear_range(addr_to_region_idx(beg), addr_to_region_idx(end)); |
836 // Summary phase utility routine to fill dead space (if any) at the dense | 963 // Summary phase utility routine to fill dead space (if any) at the dense |
837 // prefix boundary. Should only be called if the the dense prefix is | 964 // prefix boundary. Should only be called if the the dense prefix is |
838 // non-empty. | 965 // non-empty. |
839 static void fill_dense_prefix_end(SpaceId id); | 966 static void fill_dense_prefix_end(SpaceId id); |
840 | 967 |
968 // Clear the summary data source_region field for the specified addresses. | |
969 static void clear_source_region(HeapWord* beg_addr, HeapWord* end_addr); | |
970 | |
841 static void summarize_spaces_quick(); | 971 static void summarize_spaces_quick(); |
842 static void summarize_space(SpaceId id, bool maximum_compaction); | 972 static void summarize_space(SpaceId id, bool maximum_compaction); |
843 static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); | 973 static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); |
844 | |
845 // The space that is compacted after space_id. | |
846 static SpaceId next_compaction_space_id(SpaceId space_id); | |
847 | 974 |
848 // Adjust addresses in roots. Does not adjust addresses in heap. | 975 // Adjust addresses in roots. Does not adjust addresses in heap. |
849 static void adjust_roots(); | 976 static void adjust_roots(); |
850 | 977 |
851 // Serial code executed in preparation for the compaction phase. | 978 // Serial code executed in preparation for the compaction phase. |
997 static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count); | 1124 static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count); |
998 | 1125 |
999 // Return the address of the word to be copied to dest_addr, which must be | 1126 // Return the address of the word to be copied to dest_addr, which must be |
1000 // aligned to a region boundary. | 1127 // aligned to a region boundary. |
1001 static HeapWord* first_src_addr(HeapWord* const dest_addr, | 1128 static HeapWord* first_src_addr(HeapWord* const dest_addr, |
1129 SpaceId src_space_id, | |
1002 size_t src_region_idx); | 1130 size_t src_region_idx); |
1003 | 1131 |
1004 // Determine the next source region, set closure.source() to the start of the | 1132 // Determine the next source region, set closure.source() to the start of the |
1005 // new region return the region index. Parameter end_addr is the address one | 1133 // new region return the region index. Parameter end_addr is the address one |
1006 // beyond the end of source range just processed. If necessary, switch to a | 1134 // beyond the end of source range just processed. If necessary, switch to a |
1079 static void print_region_ranges(); | 1207 static void print_region_ranges(); |
1080 static void print_dense_prefix_stats(const char* const algorithm, | 1208 static void print_dense_prefix_stats(const char* const algorithm, |
1081 const SpaceId id, | 1209 const SpaceId id, |
1082 const bool maximum_compaction, | 1210 const bool maximum_compaction, |
1083 HeapWord* const addr); | 1211 HeapWord* const addr); |
1212 static void summary_phase_msg(SpaceId dst_space_id, | |
1213 HeapWord* dst_beg, HeapWord* dst_end, | |
1214 SpaceId src_space_id, | |
1215 HeapWord* src_beg, HeapWord* src_end); | |
1084 #endif // #ifndef PRODUCT | 1216 #endif // #ifndef PRODUCT |
1085 | 1217 |
1086 #ifdef ASSERT | 1218 #ifdef ASSERT |
1087 // Verify that all the regions have been emptied. | 1219 // Verify that all the regions have been emptied. |
1088 static void verify_complete(SpaceId space_id); | 1220 static void verify_complete(SpaceId space_id); |