25
25
26
26
#include " precompiled.hpp"
27
27
#include " gc/g1/g1Arguments.hpp"
28
+ #include " gc/g1/g1CardSet.hpp"
29
+ #include " gc/g1/g1CardSetContainers.inline.hpp"
28
30
#include " gc/g1/g1CollectedHeap.inline.hpp"
29
31
#include " gc/g1/g1HeapVerifier.hpp"
30
32
#include " gc/g1/heapRegion.hpp"
@@ -50,16 +52,17 @@ void G1Arguments::initialize_alignments() {
50
52
// around this we use the unaligned values for the heap.
51
53
HeapRegion::setup_heap_region_size (MaxHeapSize);
52
54
53
- // The remembered set needs the heap regions set up.
54
- HeapRegionRemSet::setup_remset_size ();
55
+ SpaceAlignment = HeapRegion::GrainBytes;
56
+ HeapAlignment = calculate_heap_alignment (SpaceAlignment);
57
+
58
+ // We need to initialize card set configuration as soon as heap region size is
59
+ // known as it depends on it and is used really early.
60
+ initialize_card_set_configuration ();
55
61
// Needs remembered set initialization as the ergonomics are based
56
62
// on it.
57
63
if (FLAG_IS_DEFAULT (G1EagerReclaimRemSetThreshold)) {
58
- FLAG_SET_ERGO (G1EagerReclaimRemSetThreshold, G1RSetSparseRegionEntries );
64
+ FLAG_SET_ERGO (G1EagerReclaimRemSetThreshold, G1RemSetArrayOfCardsEntries );
59
65
}
60
-
61
- SpaceAlignment = HeapRegion::GrainBytes;
62
- HeapAlignment = calculate_heap_alignment (SpaceAlignment);
63
66
}
64
67
65
68
size_t G1Arguments::conservative_max_heap_alignment () {
@@ -119,6 +122,40 @@ void G1Arguments::initialize_mark_stack_size() {
119
122
log_trace (gc)(" MarkStackSize: %uk MarkStackSizeMax: %uk" , (uint)(MarkStackSize / K), (uint)(MarkStackSizeMax / K));
120
123
}
121
124
125
+
126
+ void G1Arguments::initialize_card_set_configuration () {
127
+ assert (HeapRegion::LogOfHRGrainBytes != 0 , " not initialized" );
128
+ // Array of Cards card set container globals.
129
+ const int LOG_M = 20 ;
130
+ uint region_size_log_mb = (uint)MAX2 (HeapRegion::LogOfHRGrainBytes - LOG_M, 0 );
131
+
132
+ if (FLAG_IS_DEFAULT (G1RemSetArrayOfCardsEntries)) {
133
+ uint num_cards_in_inline_ptr = G1CardSetConfiguration::num_cards_in_inline_ptr (HeapRegion::LogOfHRGrainBytes - CardTable::card_shift);
134
+ FLAG_SET_ERGO (G1RemSetArrayOfCardsEntries, MAX2 (num_cards_in_inline_ptr * 2 ,
135
+ G1RemSetArrayOfCardsEntriesBase * (1u << (region_size_log_mb + 1 ))));
136
+ }
137
+
138
+ // Round to next 8 byte boundary for array to maximize space usage.
139
+ size_t const cur_size = G1CardSetArray::size_in_bytes (G1RemSetArrayOfCardsEntries);
140
+ FLAG_SET_ERGO (G1RemSetArrayOfCardsEntries,
141
+ G1RemSetArrayOfCardsEntries + (uint)(align_up (cur_size, G1CardSetAllocOptions::BufferAlignment) - cur_size) / sizeof (G1CardSetArray::EntryDataType));
142
+
143
+ // Howl card set container globals.
144
+ if (FLAG_IS_DEFAULT (G1RemSetHowlNumBuckets)) {
145
+ FLAG_SET_ERGO (G1RemSetHowlNumBuckets, G1CardSetHowl::num_buckets (HeapRegion::CardsPerRegion,
146
+ G1RemSetArrayOfCardsEntries,
147
+ G1RemSetHowlMaxNumBuckets));
148
+ }
149
+
150
+ if (FLAG_IS_DEFAULT (G1RemSetHowlMaxNumBuckets)) {
151
+ FLAG_SET_ERGO (G1RemSetHowlMaxNumBuckets, MAX2 (G1RemSetHowlMaxNumBuckets, G1RemSetHowlNumBuckets));
152
+ } else if (G1RemSetHowlMaxNumBuckets < G1RemSetHowlNumBuckets) {
153
+ FormatBuffer<> buf (" Maximum Howl card set container bucket size %u smaller than requested bucket size %u" ,
154
+ G1RemSetHowlMaxNumBuckets, G1RemSetHowlNumBuckets);
155
+ vm_exit_during_initialization (buf);
156
+ }
157
+ }
158
+
122
159
void G1Arguments::initialize () {
123
160
GCArguments::initialize ();
124
161
assert (UseG1GC, " Error" );
@@ -196,6 +233,14 @@ void G1Arguments::initialize() {
196
233
197
234
initialize_mark_stack_size ();
198
235
initialize_verification_types ();
236
+
237
+ // Verify that the maximum parallelism isn't too high to eventually overflow
238
+ // the refcount in G1CardSetContainer.
239
+ uint max_parallel_refinement_threads = G1ConcRefinementThreads + G1DirtyCardQueueSet::num_par_ids ();
240
+ uint const divisor = 3 ; // Safe divisor; we increment by 2 for each claim, but there is a small initial value.
241
+ if (max_parallel_refinement_threads > UINTPTR_MAX / divisor) {
242
+ vm_exit_during_initialization (" Too large parallelism for remembered sets." );
243
+ }
199
244
}
200
245
201
246
void G1Arguments::initialize_heap_flags_and_sizes () {
0 commit comments