22 * questions. |
22 * questions. |
23 * |
23 * |
24 */ |
24 */ |
25 |
25 |
26 #include "precompiled.hpp" |
26 #include "precompiled.hpp" |
|
27 #include "gc/shared/cardTableRS.hpp" |
27 #include "gc/shared/gcArguments.hpp" |
28 #include "gc/shared/gcArguments.hpp" |
|
29 #include "logging/log.hpp" |
28 #include "runtime/arguments.hpp" |
30 #include "runtime/arguments.hpp" |
29 #include "runtime/globals.hpp" |
31 #include "runtime/globals.hpp" |
30 #include "runtime/globals_extension.hpp" |
32 #include "runtime/globals_extension.hpp" |
31 #include "utilities/defaultStream.hpp" |
33 #include "utilities/defaultStream.hpp" |
32 #include "utilities/macros.hpp" |
34 #include "utilities/macros.hpp" |
|
35 |
|
36 size_t MinHeapSize = 0; |
|
37 |
|
38 size_t HeapAlignment = 0; |
|
39 size_t SpaceAlignment = 0; |
33 |
40 |
34 void GCArguments::initialize() { |
41 void GCArguments::initialize() { |
35 if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) { |
42 if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) { |
36 MarkSweepAlwaysCompactCount = 1; // Move objects every gc. |
43 MarkSweepAlwaysCompactCount = 1; // Move objects every gc. |
37 } |
44 } |
63 // Only young gen which is allocated in dram can use large pages, but we currently don't support that. |
70 // Only young gen which is allocated in dram can use large pages, but we currently don't support that. |
64 FLAG_SET_DEFAULT(UseLargePages, false); |
71 FLAG_SET_DEFAULT(UseLargePages, false); |
65 } |
72 } |
66 } |
73 } |
67 |
74 |
|
75 void GCArguments::initialize_heap_sizes() { |
|
76 initialize_alignments(); |
|
77 initialize_heap_flags_and_sizes(); |
|
78 initialize_size_info(); |
|
79 } |
|
80 |
|
81 size_t GCArguments::compute_heap_alignment() { |
|
82 // The card marking array and the offset arrays for old generations are |
|
83 // committed in os pages as well. Make sure they are entirely full (to |
|
84 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 |
|
85 // byte entry and the os page size is 4096, the maximum heap size should |
|
86 // be 512*4096 = 2MB aligned. |
|
87 |
|
88 size_t alignment = CardTableRS::ct_max_alignment_constraint(); |
|
89 |
|
90 if (UseLargePages) { |
|
91 // In presence of large pages we have to make sure that our |
|
92 // alignment is large page aware. |
|
93 alignment = lcm(os::large_page_size(), alignment); |
|
94 } |
|
95 |
|
96 return alignment; |
|
97 } |
|
98 |
68 bool GCArguments::check_args_consistency() { |
99 bool GCArguments::check_args_consistency() { |
69 bool status = true; |
100 bool status = true; |
70 if (!FLAG_IS_DEFAULT(AllocateHeapAt) && !FLAG_IS_DEFAULT(AllocateOldGenAt)) { |
101 if (!FLAG_IS_DEFAULT(AllocateHeapAt) && !FLAG_IS_DEFAULT(AllocateOldGenAt)) { |
71 jio_fprintf(defaultStream::error_stream(), |
102 jio_fprintf(defaultStream::error_stream(), |
72 "AllocateHeapAt and AllocateOldGenAt cannot be used together.\n"); |
103 "AllocateHeapAt and AllocateOldGenAt cannot be used together.\n"); |
77 "AllocateOldGenAt is not supported for selected GC.\n"); |
108 "AllocateOldGenAt is not supported for selected GC.\n"); |
78 status = false; |
109 status = false; |
79 } |
110 } |
80 return status; |
111 return status; |
81 } |
112 } |
|
113 |
|
114 #ifdef ASSERT |
|
115 void GCArguments::assert_flags() { |
|
116 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes"); |
|
117 assert(InitialHeapSize % HeapAlignment == 0, "InitialHeapSize alignment"); |
|
118 assert(MaxHeapSize % HeapAlignment == 0, "MaxHeapSize alignment"); |
|
119 } |
|
120 |
|
121 void GCArguments::assert_size_info() { |
|
122 assert(MaxHeapSize >= MinHeapSize, "Ergonomics decided on incompatible minimum and maximum heap sizes"); |
|
123 assert(InitialHeapSize >= MinHeapSize, "Ergonomics decided on incompatible initial and minimum heap sizes"); |
|
124 assert(MaxHeapSize >= InitialHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes"); |
|
125 assert(MaxHeapSize % HeapAlignment == 0, "MinHeapSize alignment"); |
|
126 assert(InitialHeapSize % HeapAlignment == 0, "InitialHeapSize alignment"); |
|
127 assert(MaxHeapSize % HeapAlignment == 0, "MaxHeapSize alignment"); |
|
128 } |
|
129 #endif // ASSERT |
|
130 |
|
131 void GCArguments::initialize_size_info() { |
|
132 log_debug(gc, heap)("Minimum heap " SIZE_FORMAT " Initial heap " SIZE_FORMAT " Maximum heap " SIZE_FORMAT, |
|
133 MinHeapSize, InitialHeapSize, MaxHeapSize); |
|
134 |
|
135 DEBUG_ONLY(assert_size_info();) |
|
136 } |
|
137 |
|
138 void GCArguments::initialize_heap_flags_and_sizes() { |
|
139 assert(SpaceAlignment != 0, "Space alignment not set up properly"); |
|
140 assert(HeapAlignment != 0, "Heap alignment not set up properly"); |
|
141 assert(HeapAlignment >= SpaceAlignment, |
|
142 "HeapAlignment: " SIZE_FORMAT " less than SpaceAlignment: " SIZE_FORMAT, |
|
143 HeapAlignment, SpaceAlignment); |
|
144 assert(HeapAlignment % SpaceAlignment == 0, |
|
145 "HeapAlignment: " SIZE_FORMAT " not aligned by SpaceAlignment: " SIZE_FORMAT, |
|
146 HeapAlignment, SpaceAlignment); |
|
147 |
|
148 if (FLAG_IS_CMDLINE(MaxHeapSize)) { |
|
149 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) { |
|
150 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size"); |
|
151 } |
|
152 if (MinHeapSize != 0 && MaxHeapSize < MinHeapSize) { |
|
153 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); |
|
154 } |
|
155 } |
|
156 |
|
157 // Check heap parameter properties |
|
158 if (MaxHeapSize < 2 * M) { |
|
159 vm_exit_during_initialization("Too small maximum heap"); |
|
160 } |
|
161 if (InitialHeapSize < M) { |
|
162 vm_exit_during_initialization("Too small initial heap"); |
|
163 } |
|
164 if (MinHeapSize < M) { |
|
165 vm_exit_during_initialization("Too small minimum heap"); |
|
166 } |
|
167 |
|
168 // User inputs from -Xmx and -Xms must be aligned |
|
169 MinHeapSize = align_up(MinHeapSize, HeapAlignment); |
|
170 size_t aligned_initial_heap_size = align_up(InitialHeapSize, HeapAlignment); |
|
171 size_t aligned_max_heap_size = align_up(MaxHeapSize, HeapAlignment); |
|
172 |
|
173 // Write back to flags if the values changed |
|
174 if (aligned_initial_heap_size != InitialHeapSize) { |
|
175 FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size); |
|
176 } |
|
177 if (aligned_max_heap_size != MaxHeapSize) { |
|
178 FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size); |
|
179 } |
|
180 |
|
181 if (FLAG_IS_CMDLINE(InitialHeapSize) && MinHeapSize != 0 && |
|
182 InitialHeapSize < MinHeapSize) { |
|
183 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); |
|
184 } |
|
185 if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) { |
|
186 FLAG_SET_ERGO(size_t, MaxHeapSize, InitialHeapSize); |
|
187 } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) { |
|
188 FLAG_SET_ERGO(size_t, InitialHeapSize, MaxHeapSize); |
|
189 if (InitialHeapSize < MinHeapSize) { |
|
190 MinHeapSize = InitialHeapSize; |
|
191 } |
|
192 } |
|
193 |
|
194 FLAG_SET_ERGO(size_t, MinHeapDeltaBytes, align_up(MinHeapDeltaBytes, SpaceAlignment)); |
|
195 |
|
196 DEBUG_ONLY(assert_flags();) |
|
197 } |