Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_modron_startup/mmparse.cpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
/**
24
* @file
25
* @ingroup GC_Modron_Startup
26
*/
27
28
#include "j9.h"
29
#include "j9cfg.h"
30
#include "j9protos.h"
31
#include "j9consts.h"
32
#include "j9argscan.h"
33
#include "jni.h"
34
#include "jvminit.h"
35
#include "j9port.h"
36
#include "modronnls.h"
37
#include "gcutils.h"
38
#include "ModronAssertions.h"
39
40
#include "mmparse.h"
41
42
#include "Configuration.hpp"
43
#include "GCExtensions.hpp"
44
#if defined(J9VM_GC_MODRON_TRACE)
45
#include "Tgc.hpp"
46
#endif /* defined(J9VM_GC_MODRON_TRACE) */
47
48
/**
49
* @name GC command line options
50
* Memory parameter command line options.
51
* @note The order of parsing is important, as substrings occur in some parameters.
52
* \anchor gcOptions
53
* @{
54
*/
55
#define OPT_XGC_COLON "-Xgc:"
56
#define OPT_XXGC_COLON "-XXgc:"
57
#define OPT_XTGC_COLON "-Xtgc:"
58
#define OPT_XMX "-Xmx"
59
#define OPT_XMCA "-Xmca"
60
#define OPT_XMCO "-Xmco"
61
#define OPT_XMCRS "-Xmcrs"
62
#define OPT_XMN "-Xmn"
63
#define OPT_XMNS "-Xmns"
64
#define OPT_XMNX "-Xmnx"
65
#define OPT_XMOI "-Xmoi"
66
#define OPT_XMO "-Xmo"
67
#define OPT_XMOS "-Xmos"
68
#define OPT_XMOX "-Xmox"
69
#define OPT_XMS "-Xms"
70
#define OPT_XMRX "-Xmrx"
71
#define OPT_XMR "-Xmr"
72
#define OPT_SOFTMX "-Xsoftmx"
73
#define OPT_NUMA_NONE "-Xnuma:none"
74
#define OPT_XXMAXRAMPERCENT "-XX:MaxRAMPercentage="
75
#define OPT_XXINITIALRAMPERCENT "-XX:InitialRAMPercentage="
76
77
/**
78
* @}
79
*/
80
81
static char OPTION_SET_GROUP_UNUSED[] = "";
82
83
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
84
/**
85
* @name Class unloading argument group
86
* Command line option group indexes for class unloading options.
87
* @note The ordering of the enums must match the char array.
88
*
89
* @{
90
*/
91
enum {
92
optionGroupClassGC_index_noclassgc = 0,
93
optionGroupClassGC_index_classgc,
94
optionGroupClassGC_index_alwaysclassgc
95
};
96
97
static const char *optionGroupClassGC[] = {
98
"-Xnoclassgc",
99
"-Xclassgc",
100
"-Xalwaysclassgc",
101
NULL
102
};
103
/**
104
* @}
105
*/
106
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
107
108
#if defined(J9VM_GC_LARGE_OBJECT_AREA)
109
/**
110
* @name Concurrent metering argument group
111
* Command line option group indexes for concurrent metering options.
112
* @note The ordering of the enums must match the char array.
113
*
114
* @{
115
*/
116
enum {
117
optionGroupConMeter_index_soa = 0,
118
optionGroupConMeter_index_loa,
119
optionGroupConMeter_index_dynamic
120
};
121
122
static const char *optionGroupConMeter[] = {
123
"-Xconmeter:soa",
124
"-Xconmeter:loa",
125
"-Xconmeter:dynamic",
126
NULL
127
};
128
/**
129
* @}
130
*/
131
#endif /* J9VM_GC_LARGE_OBJECT_AREA) */
132
133
/**
134
* @name Xlp error state group.
135
*
136
* @{
137
*/
138
struct XlpError {
139
const char *xlpOptionErrorString;
140
size_t xlpOptionErrorStringSize;
141
const char *xlpMissingOptionString;
142
bool extraCommaWarning;
143
};
144
145
typedef enum {
146
XLP_NO_ERROR = 0,
147
XLP_OPTION_NOT_SUPPORTED,
148
XLP_MEM_NAN,
149
XLP_MEM_OVERFLOW,
150
XLP_PAGE_SIZE_INCORRECT,
151
XLP_INCOMPLETE_OPTION,
152
XLP_LARGE_PAGE_NOT_SUPPORTED,
153
XLP_PARAMETER_NOT_RECOGNIZED
154
} XlpErrorState;
155
156
typedef enum {
157
PARSING_FIRST_OPTION = 1,
158
PARSING_OPTION,
159
PARSING_COMMA,
160
PARSING_ERROR
161
} parsingStates;
162
/**
163
* @}
164
*/
165
166
/**
167
* Find, consume and record an option from the argument list.
168
* Given an option string and the match type, find the argument in the to be consumed list.
169
* If found, consume it.
170
*
171
* @return -1 if the argument was not consumed properly, otherwise the index position of the argument (>=0)
172
*/
173
static IDATA
174
option_set(J9JavaVM* vm, const char* option, IDATA match)
175
{
176
return FIND_AND_CONSUME_ARG2(match, option, NULL);
177
}
178
179
/**
180
* Find, consume and record an option from the argument list.
181
* Given an option string and the match type, find the argument in the to be consumed list.
182
* If found, consume it, verify the memory value.
183
*
184
* @return OPTION_OK if option is found and consumed or option not present, OPTION_MALFORMED if the option was malformed, OPTION_OVERFLOW if the option overflowed.
185
* @note value stored at address is invalid if failure returned
186
* @note optionIndex contains position of argument on command line if success returned, else -1
187
*/
188
static IDATA
189
option_set_to_opt(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)
190
{
191
IDATA element;
192
IDATA returnCode = OPTION_OK;
193
UDATA value;
194
195
element = FIND_AND_CONSUME_ARG2(match, option, NULL);
196
*optionIndex = element;
197
198
if (element >= 0) {
199
returnCode = GET_MEMORY_VALUE(element, option, value);
200
if (OPTION_OK == returnCode){
201
*address = value;
202
}
203
}
204
return returnCode;
205
}
206
207
/**
208
* Find, consume and record an option from the argument list.
209
* Given an option string and the match type, find the argument in the to be consumed list.
210
* If found, consume it, verify the memory value.
211
*
212
* @return OPTION_OK if option is found and consumed or option not present, OPTION_MALFORMED if the option was malformed, OPTION_OVERFLOW if the option overflowed.
213
* @note value stored at address is invalid if failure returned
214
* @note optionIndex contains position of argument on command line if success returned, else -1
215
*/
216
static IDATA
217
option_set_to_opt_percent(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)
218
{
219
IDATA element;
220
IDATA returnCode = OPTION_OK;
221
UDATA value;
222
223
element = FIND_AND_CONSUME_ARG2(match, option, NULL);
224
*optionIndex = element;
225
226
if (element >= 0) {
227
returnCode = GET_PERCENT_VALUE(element, option, value);
228
if (OPTION_OK == returnCode) {
229
*address = value;
230
}
231
}
232
return returnCode;
233
}
234
235
/**
236
* Find, consume and record an option from the argument list.
237
* Given an option string and the match type, find the argument in the to be consumed list.
238
* If not found, return success.
239
* If found, consume it, verify the memory value.
240
*
241
* @return OPTION_OK if option is found and consumed or option not present, OPTION_MALFORMED if the option was malformed, OPTION_OVERFLOW if the option overflowed.
242
* @note value stored at address is invalid if failure returned
243
* @note optionIndex contains position of argument on command line if success returned, else -1
244
*/
245
static IDATA
246
option_set_to_opt_integer(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)
247
{
248
IDATA element;
249
IDATA returnCode = OPTION_OK;
250
IDATA value;
251
252
element = FIND_AND_CONSUME_ARG2(match, option, NULL);
253
*optionIndex = element;
254
255
if (element >= 0) {
256
returnCode = GET_INTEGER_VALUE(element, option, value);
257
if (OPTION_OK == returnCode) {
258
*address = value;
259
}
260
}
261
return returnCode;
262
}
263
264
/**
265
* Find, consume and record an option from the argument list.
266
* Given an option string and the match type, find the argument in the to be consumed list.
267
* If not found, return success.
268
* If found, consume it, verify the memory value.
269
*
270
* @return OPTION_OK if option is found and consumed or option not present, OPTION_MALFORMED if the option was malformed, OPTION_OVERFLOW if the option overflowed.
271
* @note value stored at address is invalid if failure returned
272
* @note optionIndex contains position of argument on command line if success returned, else -1
273
*/
274
static IDATA
275
option_set_to_opt_double(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, double* address)
276
{
277
IDATA element = -1;
278
IDATA returnCode = OPTION_OK;
279
double value = 0.0;
280
281
element = FIND_AND_CONSUME_ARG2(match, option, NULL);
282
*optionIndex = element;
283
284
if (element >= 0) {
285
returnCode = GET_DOUBLE_VALUE(element, option, value);
286
if (OPTION_OK == returnCode) {
287
*address = value;
288
}
289
}
290
return returnCode;
291
}
292
293
/**
294
* Find, consume and record a pair of options from the argument list.
295
* Consumes the options option1 and option2 and return which option was rightmost.
296
*
297
* @return -1 if the arguments were not consumed properly, otherwise the index position of the rightmost argument (>=0)
298
* @note if successful consumed optionIndex contains 0 if the rightmost argument is option1, 1 if the rightmost argument is option2, else -1
299
*/
300
static IDATA
301
option_set_pair(J9JavaVM *vm, const char *option1, const char *option2, IDATA *optionPairIndex) {
302
IDATA index1, index2;
303
index1 = option_set(vm, option1, EXACT_MATCH);
304
index2 = option_set(vm, option2, EXACT_MATCH);
305
306
if (index1 > index2) {
307
*optionPairIndex = 0;
308
return index1;
309
}
310
311
if (-1 != index2) {
312
*optionPairIndex = 1;
313
return index2;
314
}
315
316
*optionPairIndex = -1;
317
return -1;
318
}
319
320
/**
321
* Find, consume and record a group of options from the argument list.
322
* Consumes the options optionGroup and return which option was rightmost.
323
*
324
* @return -1 if the arguments were not consumed properly, otherwise the index position of the rightmost argument (>=0)
325
* @note if successful consumed optionIndex contains the index into optionGroup of the rightmost argument, else -1
326
*/
327
static IDATA
328
option_set_group(J9JavaVM *vm, const char **optionGroup, IDATA *optionGroupIndex) {
329
IDATA rightMostIndex, currentIndex, currentOption;
330
331
/* default return values */
332
*optionGroupIndex = -1;
333
rightMostIndex = -1;
334
335
currentOption = 0;
336
while(NULL != *optionGroup) {
337
/* ensure that we skip over entries in the table which aren't supported on this configuration (but preserved for shape consistency) */
338
if (OPTION_SET_GROUP_UNUSED != *optionGroup) {
339
if (-1 != (currentIndex = option_set(vm, *optionGroup, EXACT_MATCH))) {
340
if (currentIndex > rightMostIndex) {
341
rightMostIndex = currentIndex;
342
*optionGroupIndex = currentOption;
343
}
344
}
345
}
346
currentOption += 1;
347
optionGroup++;
348
}
349
350
return rightMostIndex;
351
}
352
353
/**
354
* Parse sub options for -Xlp:xxxxx:
355
*/
356
static XlpErrorState
357
xlpSubOptionsParser(J9JavaVM *vm, IDATA xlpIndex, XlpError *xlpError, UDATA *requestedPageSize, UDATA *requestedPageFlags, bool *strict, bool *warn)
358
{
359
/* -Xlp:objectheap: found and it is most right option, so it is not overwritten by -Xlp<size> */
360
char *optionsString = NULL;
361
char *scan_limit = NULL;
362
363
/* start parsing with option */
364
parsingStates parsingState = PARSING_FIRST_OPTION;
365
UDATA optionNumber = 1;
366
char *previousOption = NULL;
367
char *errorString = NULL;
368
369
UDATA pageSizeHowMany = 0;
370
#if defined(J9ZOS390)
371
UDATA pageableHowMany = 0;
372
UDATA pageableOptionNumber = 0;
373
UDATA nonPageableHowMany = 0;
374
UDATA nonPageableOptionNumber = 0;
375
#endif /* defined(J9ZOS390) */
376
377
/* Reset error state from parsing of previous -Xlp<size> option */
378
XlpErrorState xlpErrorState = XLP_NO_ERROR;
379
380
xlpError->xlpOptionErrorString = NULL;
381
xlpError->xlpOptionErrorStringSize = 0;
382
xlpError->xlpMissingOptionString = NULL;
383
xlpError->extraCommaWarning = false;
384
385
/* Get pointer to entire option */
386
GET_OPTION_OPTION(xlpIndex, ':', ':', &optionsString);
387
388
/* optionsString can not be NULL here, though it may point to null ('\0') character */
389
scan_limit = optionsString + strlen(optionsString);
390
391
/*
392
* parsing -Xlp:objectheap: for options
393
*
394
* reporting general parsing problems (bad formed and unknown options)
395
* recognize cases where extra commas are entered to print warning after if necessary
396
*/
397
398
while (optionsString < scan_limit) {
399
if (try_scan(&optionsString, ",")) {
400
/* Comma separator is discovered */
401
switch (parsingState) {
402
case PARSING_FIRST_OPTION:
403
/* leading comma - ignored but warning required */
404
xlpError->extraCommaWarning = true;
405
parsingState = PARSING_OPTION;
406
break;
407
case PARSING_OPTION:
408
/* more then one comma - ignored but warning required */
409
xlpError->extraCommaWarning = true;
410
break;
411
case PARSING_COMMA:
412
/* expecting for comma here, next should be an option*/
413
parsingState = PARSING_OPTION;
414
/* next option number */
415
optionNumber += 1;
416
break;
417
case PARSING_ERROR:
418
default:
419
/* must be unreachable states */
420
Assert_MM_unreachable();
421
break;
422
}
423
} else {
424
/* Comma separator has not been found. so */
425
switch (parsingState) {
426
case PARSING_FIRST_OPTION:
427
/* still looking for parsing of first option - nothing to do */
428
parsingState = PARSING_OPTION;
429
break;
430
case PARSING_OPTION:
431
/* Can not recognize an option case */
432
Assert_MM_true(previousOption == optionsString);
433
errorString = optionsString;
434
parsingState = PARSING_ERROR;
435
break;
436
case PARSING_COMMA:
437
/* can not find comma after option - so this is something unrecognizable at the end of known option */
438
errorString = previousOption;
439
parsingState = PARSING_ERROR;
440
break;
441
case PARSING_ERROR:
442
default:
443
/* must be unreachable states */
444
Assert_MM_unreachable();
445
break;
446
}
447
}
448
449
if (PARSING_ERROR == parsingState) {
450
Assert_MM_true(NULL != errorString);
451
452
xlpErrorState = XLP_PARAMETER_NOT_RECOGNIZED;
453
xlpError->xlpOptionErrorString = errorString;
454
455
/* try to find comma to isolate unrecognized option */
456
char *commaLocation = strchr(errorString, ',');
457
if (NULL != commaLocation) {
458
/* comma found */
459
xlpError->xlpOptionErrorStringSize = (size_t)(commaLocation - errorString);
460
} else {
461
/* comma not found - print to the end of the string */
462
xlpError->xlpOptionErrorStringSize = strlen(errorString);
463
}
464
465
return xlpErrorState;
466
}
467
468
/* check that something was parsed or previousOption still NULL, otherwise we are in dead loop */
469
Assert_MM_true((NULL == previousOption) || (previousOption != optionsString));
470
471
previousOption = optionsString;
472
473
if (try_scan(&optionsString, "pagesize=")) {
474
/* try to get memory value */
475
if (!scan_udata_memory_size_helper(vm, &optionsString, requestedPageSize, "pagesize=")) {
476
/* size is not formed properly */
477
xlpErrorState = XLP_PAGE_SIZE_INCORRECT;
478
return xlpErrorState;
479
}
480
481
pageSizeHowMany += 1;
482
483
parsingState = PARSING_COMMA;
484
} else if (try_scan(&optionsString, "pageable")) {
485
#if defined(J9ZOS390)
486
pageableHowMany += 1;
487
pageableOptionNumber = optionNumber;
488
#endif /* defined(J9ZOS390) */
489
parsingState = PARSING_COMMA;
490
} else if (try_scan(&optionsString, "nonpageable")) {
491
#if defined(J9ZOS390)
492
nonPageableHowMany += 1;
493
nonPageableOptionNumber = optionNumber;
494
#endif /* defined(J9ZOS390) */
495
parsingState = PARSING_COMMA;
496
} else if ((NULL != strict) && try_scan(&optionsString, "strict")) {
497
*strict = true;
498
parsingState = PARSING_COMMA;
499
} else if ((NULL != warn) && try_scan(&optionsString, "warn")) {
500
*warn = true;
501
parsingState = PARSING_COMMA;
502
}
503
}
504
505
/*
506
* post-parse check for trailing comma(s)
507
*/
508
switch (parsingState) {
509
/* if loop ended in one of these two states extra comma warning required */
510
case PARSING_FIRST_OPTION:
511
case PARSING_OPTION:
512
/* trailing comma(s) or comma(s) alone */
513
xlpError->extraCommaWarning = true;
514
break;
515
case PARSING_COMMA:
516
/* loop ended at comma search state - do nothing */
517
break;
518
case PARSING_ERROR:
519
default:
520
/* must be unreachable states */
521
Assert_MM_unreachable();
522
break;
523
}
524
525
/* --- analyze correctness of entered options --- */
526
/*
527
* pagesize = <size>
528
* - this options must be specified for all platforms
529
*/
530
if (0 == pageSizeHowMany) {
531
/* error: pagesize= must be specified */
532
xlpErrorState = XLP_INCOMPLETE_OPTION;
533
xlpError->xlpOptionErrorString = "-Xlp:objectheap:";
534
xlpError->xlpMissingOptionString = "pagesize=";
535
return xlpErrorState;
536
}
537
538
#if defined(J9ZOS390)
539
/*
540
* [non]pageable
541
* - this option must be specified for Z platforms
542
*/
543
if ((0 == pageableHowMany) && (0 == nonPageableHowMany)) {
544
/* error: [non]pageable not found */
545
xlpErrorState = XLP_INCOMPLETE_OPTION;
546
xlpError->xlpOptionErrorString = "-Xlp:objectheap:";
547
xlpError->xlpMissingOptionString = "[non]pageable";
548
return xlpErrorState;
549
}
550
551
if (pageableOptionNumber > nonPageableOptionNumber) {
552
/* pageable is most right */
553
*requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_PAGEABLE;
554
} else {
555
/* nonpageable is most right */
556
*requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_FIXED;
557
}
558
#endif /* defined(J9ZOS390) */
559
560
return xlpErrorState;
561
}
562
563
/**
564
* Find and consume -Xlp option(s) from the argument list.
565
*
566
* @param vm pointer to Java VM structure
567
*
568
* @return false if the option(s) are not consumed properly, true on success.
569
*/
570
static bool
571
gcParseXlpOption(J9JavaVM *vm)
572
{
573
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
574
bool rc = false;
575
XlpErrorState xlpErrorState = XLP_NO_ERROR;
576
XlpError xlpError = {NULL, /* xlpOptionErrorString */
577
0, /* xlpOptionErrorStringSize */
578
NULL, /* xlpMissingOptionString */
579
false}; /* extraCommaWarning */
580
IDATA xlpIndex = -1;
581
IDATA xlpMemIndex = -1;
582
IDATA xlpObjectHeapIndex = -1;
583
IDATA xlpGCIndex = -1;
584
UDATA requestedPageSize = 0;
585
UDATA requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;
586
PORT_ACCESS_FROM_JAVAVM(vm);
587
588
/* Parse -Xlp option.
589
* -Xlp option enables large pages with the default large page size, but will not
590
* override any -Xlp<size> or -Xlp:objectheap:pagesize=<size> option.
591
*/
592
xlpIndex = option_set(vm, "-Xlp", EXACT_MATCH);
593
if (-1 != xlpIndex) {
594
UDATA defaultLargePageSize = 0;
595
UDATA defaultLargePageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;
596
j9vmem_default_large_page_size_ex(0, &defaultLargePageSize, &defaultLargePageFlags);
597
if (0 != defaultLargePageSize) {
598
extensions->requestedPageSize = defaultLargePageSize;
599
extensions->requestedPageFlags = defaultLargePageFlags;
600
} else {
601
xlpErrorState = XLP_OPTION_NOT_SUPPORTED;
602
xlpError.xlpOptionErrorString = "-Xlp";
603
/* Cannot report error message here,
604
* as we may find a valid "-Xlp:objectheap" that overwrites this option
605
*/
606
}
607
}
608
609
/* Parse -Xlp<size> option. It overrides -Xlp option. */
610
xlpMemIndex = FIND_AND_CONSUME_ARG(EXACT_MEMORY_MATCH, "-Xlp", NULL);
611
if (-1 != xlpMemIndex) {
612
/* Reset error state from parsing of previous -Xlp option */
613
xlpErrorState = XLP_NO_ERROR;
614
615
/* No need to set requestedPageFlags explicitly. We use the default value J9PORT_VMEM_PAGE_FLAG_NOT_USED */
616
617
/* If the machine does not support large pages, we may fail.
618
* Page flags for default large page size is not required, just pass NULL.
619
*/
620
j9vmem_default_large_page_size_ex(0, &requestedPageSize, NULL);
621
if (0 != requestedPageSize) {
622
IDATA result = option_set_to_opt(vm, "-Xlp", &xlpMemIndex, EXACT_MEMORY_MATCH, &requestedPageSize);
623
if (OPTION_OK != result) {
624
/* this -Xlp option must be formed properly even it might be overwritten by "-Xlp:objectheap" */
625
if (OPTION_MALFORMED == result) {
626
xlpErrorState = XLP_MEM_NAN;
627
} else {
628
xlpErrorState = XLP_MEM_OVERFLOW;
629
}
630
goto _reportXlpError;
631
}
632
} else {
633
xlpErrorState = XLP_OPTION_NOT_SUPPORTED;
634
xlpError.xlpOptionErrorString = "-Xlp";
635
/* Cannot report error message here, as we may find a valid "-Xlp:objectheap" that overwrites this option */
636
}
637
}
638
639
/* Parse -Xlp:objectheap:pagesize=<size> option.
640
* It overrides -Xlp option.
641
* It also overrides -Xlp<size> option if it appears to the right of -Xlp<size>
642
*
643
* The proper formed -Xlp:objectheap: option must be (in strict order):
644
* For all non-Z platforms:
645
* -Xlp:objectheap:pagesize=<size> or
646
* -Xlp:objectheap:pagesize=<size>,pageable or
647
* -Xlp:objectheap:pagesize=<size>,nonpageable
648
*
649
* For Z platforms
650
* -Xlp:objectheap:pagesize=<size>,pageable or
651
* -Xlp:objectheap:pagesize=<size>,nonpageable
652
*/
653
xlpObjectHeapIndex = FIND_AND_CONSUME_ARG(STARTSWITH_MATCH, "-Xlp:objectheap:", NULL);
654
655
/* so if -Xlp:objectheap: is specified */
656
if ((-1 != xlpObjectHeapIndex) && (xlpObjectHeapIndex > xlpMemIndex)) {
657
/*
658
* Parse sub options for -Xlp:objectheap:
659
*/
660
xlpErrorState = xlpSubOptionsParser(vm, xlpObjectHeapIndex, &xlpError, &requestedPageSize, &requestedPageFlags, &extensions->largePageFailOnError, &extensions->largePageWarnOnError);
661
662
if (xlpError.extraCommaWarning) {
663
/* print extra comma ignored warning */
664
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_EXTRA_COMMA);
665
}
666
}
667
668
/* If there is a pending error state, report it now */
669
if (XLP_NO_ERROR != xlpErrorState) {
670
goto _reportXlpError;
671
}
672
673
/* If a valid -Xlp<size> or -Xlp:objectheap:pagesize=<size> is present, check if the requested page size is supported */
674
/* We don't need to check error state here - we did goto for all errors */
675
if ((-1 != xlpMemIndex) || (-1 != xlpObjectHeapIndex)) {
676
UDATA pageSize = requestedPageSize;
677
UDATA pageFlags = requestedPageFlags;
678
BOOLEAN isRequestedSizeSupported = FALSE;
679
680
IDATA result = j9vmem_find_valid_page_size(0, &pageSize, &pageFlags, &isRequestedSizeSupported);
681
682
/*
683
* j9vmem_find_valid_page_size happened to be changed to always return 0
684
* However formally the function type still be IDATA so assert if it returns anything else
685
*/
686
Assert_MM_true(0 == result);
687
688
extensions->requestedPageSize = pageSize;
689
extensions->requestedPageFlags = pageFlags;
690
691
if (!isRequestedSizeSupported) {
692
/* Print a message indicating requested page size is not supported and a different page size will be used */
693
const char *oldQualifier, *newQualifier;
694
const char *oldPageType = NULL;
695
const char *newPageType = NULL;
696
UDATA oldSize = requestedPageSize;
697
UDATA newSize = pageSize;
698
qualifiedSize(&oldSize, &oldQualifier);
699
qualifiedSize(&newSize, &newQualifier);
700
if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & requestedPageFlags)) {
701
oldPageType = getPageTypeString(requestedPageFlags);
702
}
703
if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & pageFlags)) {
704
newPageType = getPageTypeString(pageFlags);
705
}
706
if (NULL == oldPageType) {
707
if (NULL == newPageType) {
708
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED, oldSize, oldQualifier, newSize, newQualifier);
709
} else {
710
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_NEW_PAGETYPE, oldSize, oldQualifier, newSize, newQualifier, newPageType);
711
}
712
} else {
713
if (NULL == newPageType) {
714
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_REQUESTED_PAGETYPE, oldSize, oldQualifier, oldPageType, newSize, newQualifier);
715
} else {
716
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_PAGETYPE, oldSize, oldQualifier, oldPageType, newSize, newQualifier, newPageType);
717
}
718
}
719
}
720
}
721
722
/*
723
* Check for -Xlp:gc: and handle it if necessary
724
*/
725
xlpGCIndex = FIND_AND_CONSUME_ARG(STARTSWITH_MATCH, "-Xlp:gcmetadata:", NULL);
726
727
if (-1 != xlpGCIndex) {
728
UDATA gcmetadataPageSize = 0;
729
UDATA gcmetadataPageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;
730
UDATA *pageSizes;
731
UDATA *pageFlags;
732
bool found = false;
733
/*
734
* Parse sub options for -Xlp:gc:
735
*/
736
xlpErrorState = xlpSubOptionsParser(vm, xlpGCIndex, &xlpError, &gcmetadataPageSize, &gcmetadataPageFlags, NULL, NULL);
737
738
if (XLP_NO_ERROR != xlpErrorState) {
739
goto _reportXlpError;
740
}
741
742
if (xlpError.extraCommaWarning) {
743
/* print extra comma ignored warning */
744
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_EXTRA_COMMA);
745
}
746
747
/*
748
* Update values in case of exact match only
749
*/
750
pageSizes = j9vmem_supported_page_sizes();
751
pageFlags = j9vmem_supported_page_flags();
752
753
for (UDATA pageIndex = 0; 0 != pageSizes[pageIndex]; ++pageIndex) {
754
if ((pageSizes[pageIndex] == gcmetadataPageSize) && (pageFlags[pageIndex] == gcmetadataPageFlags)) {
755
found = true;
756
extensions->gcmetadataPageSize = gcmetadataPageSize;
757
extensions->gcmetadataPageFlags = gcmetadataPageFlags;
758
break;
759
}
760
}
761
762
if (!found) {
763
const char *oldQualifier, *newQualifier;
764
UDATA oldSize = gcmetadataPageSize;
765
UDATA newSize = extensions->gcmetadataPageSize;
766
const char *oldPageType = getPageTypeStringWithLeadingSpace(oldSize);
767
const char *newPageType = getPageTypeStringWithLeadingSpace(newSize);
768
qualifiedSize(&oldSize, &oldQualifier);
769
qualifiedSize(&newSize, &newQualifier);
770
771
j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_PAGE_NOT_SUPPORTED, "gcmetadata", oldSize, oldQualifier, oldPageType, newSize, newQualifier, newPageType);
772
}
773
}
774
775
_reportXlpError:
776
/* If error occurred during parsing of -Xlp options, report it here. */
777
if (XLP_NO_ERROR != xlpErrorState) {
778
/* parsing failed, return false */
779
rc = false;
780
781
switch(xlpErrorState) {
782
case XLP_OPTION_NOT_SUPPORTED:
783
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_SYSTEM_CONFIG_OPTION_NOT_SUPPORTED, xlpError.xlpOptionErrorString);
784
break;
785
case XLP_MEM_NAN:
786
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xlp");
787
break;
788
case XLP_MEM_OVERFLOW:
789
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xlp");
790
break;
791
case XLP_PAGE_SIZE_INCORRECT:
792
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_INCORRECT_MEMORY_SIZE, "-Xlp:objectheap:pagesize=<size>");
793
break;
794
case XLP_INCOMPLETE_OPTION:
795
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_INCOMPLETE_OPTION, xlpError.xlpOptionErrorString, xlpError.xlpMissingOptionString);
796
break;
797
case XLP_LARGE_PAGE_NOT_SUPPORTED:
798
{
799
const char *qualifier = NULL;
800
const char *pageType = NULL;
801
UDATA pageSize = requestedPageSize;
802
qualifiedSize(&pageSize, &qualifier);
803
if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & requestedPageFlags)) {
804
pageType = getPageTypeString(requestedPageFlags);
805
}
806
if (NULL == pageType) {
807
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_LARGE_PAGE_NOT_SUPPORTED, pageSize, qualifier);
808
} else {
809
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_LARGE_PAGE_NOT_SUPPORTED_WITH_PAGETYPE, pageSize, qualifier, pageType);
810
}
811
812
break;
813
}
814
case XLP_PARAMETER_NOT_RECOGNIZED:
815
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_UNRECOGNIZED_OPTION, xlpError.xlpOptionErrorStringSize, xlpError.xlpOptionErrorString);
816
break;
817
default:
818
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_PARSING_ERROR);
819
break;
820
}
821
} else {
822
rc = true;
823
}
824
825
return rc;
826
}
827
/**
828
* Consume Sovereign arguments.
829
*
830
* @return 1 if parsing was successful, 0 otherwise.
831
*/
832
static UDATA
833
gcParseSovereignArguments(J9JavaVM *vm)
834
{
835
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
836
IDATA result = 0;
837
UDATA inputValue = 0;
838
#if defined(J9VM_GC_LARGE_OBJECT_AREA)
839
IDATA groupIndex = 0;
840
IDATA indexMeter = 0;
841
#endif /* J9VM_GC_LARGE_OBJECT_AREA */
842
const char *optionFound = NULL;
843
IDATA index = -1;
844
PORT_ACCESS_FROM_JAVAVM(vm);
845
846
if (!gcParseXlpOption(vm)) {
847
goto _error;
848
}
849
850
/* Check for explicit specification of GC policy */
851
gcParseXgcpolicy(extensions);
852
853
if (-1 != option_set_pair(vm, "-Xenableexplicitgc", "-Xdisableexplicitgc", &index)) {
854
extensions->disableExplicitGC = (index != 0);
855
}
856
857
#if defined(J9VM_GC_MODRON_COMPACTION)
858
/* These arguments aren't done as mutual exclusive pairs because their effects are not opposites */
859
if (-1 != option_set(vm, "-Xnocompactexplicitgc", EXACT_MATCH)) {
860
extensions->nocompactOnSystemGC = 1;
861
extensions->compactOnSystemGC = 0;
862
}
863
864
if (-1 != option_set(vm, "-Xcompactexplicitgc", EXACT_MATCH)) {
865
extensions->compactOnSystemGC = 1;
866
}
867
868
/* These arguments aren't done as mutual exclusive pairs because their effects are not opposites */
869
if (-1 != option_set(vm, "-Xcompactgc", EXACT_MATCH)) {
870
extensions->compactOnGlobalGC = 1;
871
extensions->compactOnSystemGC = 1;
872
}
873
874
if (-1 != option_set(vm, "-Xnocompactgc", EXACT_MATCH)) {
875
extensions->noCompactOnGlobalGC = 1;
876
}
877
878
if (-1 != option_set_pair(vm, "-Xnopartialcompactgc", "-Xpartialcompactgc", &index)) {
879
/* Incremental compaction is no longer supported.
880
* Options are supported but deprecated.
881
*/
882
}
883
#endif /* J9VM_GC_MODRON_COMPACTION */
884
885
result = option_set_to_opt_percent(vm, "-Xminf", &index, EXACT_MEMORY_MATCH, &extensions->heapFreeMinimumRatioMultiplier);
886
if (OPTION_OK != result) {
887
if (OPTION_MALFORMED == result) {
888
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xminf");
889
} else {
890
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xminf", 0.0, 1.0);
891
}
892
goto _error;
893
}
894
result = option_set_to_opt_percent(vm, "-Xmaxf", &index, EXACT_MEMORY_MATCH, &extensions->heapFreeMaximumRatioMultiplier);
895
if (OPTION_OK != result) {
896
if (OPTION_MALFORMED == result) {
897
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxf");
898
} else {
899
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmaxf", 0.0, 1.0);
900
}
901
goto _error;
902
}
903
result = option_set_to_opt(vm, "-Xmine", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionMinimumSize);
904
if (OPTION_OK != result) {
905
if (OPTION_MALFORMED == result) {
906
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmine");
907
} else {
908
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xmine");
909
}
910
goto _error;
911
}
912
result = option_set_to_opt(vm, "-Xmaxe", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionMaximumSize);
913
if (OPTION_OK != result) {
914
if (OPTION_MALFORMED == result) {
915
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxe");
916
} else {
917
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xmaxe");
918
}
919
goto _error;
920
}
921
922
923
924
result = option_set_to_opt_percent(vm, "-Xmaxt", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionGCRatioThreshold._valueSpecified);
925
if (OPTION_OK != result) {
926
if (OPTION_MALFORMED == result) {
927
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxt");
928
} else {
929
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmaxt", 0.0, 1.0);
930
}
931
goto _error;
932
} else if (-1 != index) {
933
extensions->heapExpansionGCRatioThreshold._wasSpecified = true;
934
}
935
936
937
938
result = option_set_to_opt_percent(vm, "-Xmint", &index, EXACT_MEMORY_MATCH, &extensions->heapContractionGCRatioThreshold._valueSpecified);
939
if (OPTION_OK != result) {
940
if (OPTION_MALFORMED == result) {
941
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmint");
942
} else {
943
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmint", 0.0, 1.0);
944
}
945
goto _error;
946
} else if (-1 != index) {
947
extensions->heapContractionGCRatioThreshold._wasSpecified = true;
948
}
949
950
951
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, VMOPT_XGCTHREADS, NULL)) {
952
result = option_set_to_opt_integer(vm, VMOPT_XGCTHREADS, &index, EXACT_MEMORY_MATCH, &extensions->gcThreadCount);
953
if (OPTION_OK != result) {
954
if (OPTION_MALFORMED == result) {
955
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XGCTHREADS);
956
} else {
957
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XGCTHREADS);
958
}
959
goto _error;
960
}
961
962
if(0 == extensions->gcThreadCount) {
963
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, VMOPT_XGCTHREADS, (UDATA)0);
964
goto _error;
965
}
966
967
extensions->gcThreadCountForced = true;
968
}
969
970
/* Handling VMOPT_XGCMAXTHREADS is equivalent to VMOPT_XGCTHREADS (above), except it sets gcThreadCountForced to false rather than true. */
971
if (-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, VMOPT_XGCMAXTHREADS, NULL)) {
972
result = option_set_to_opt_integer(vm, VMOPT_XGCMAXTHREADS, &index, EXACT_MEMORY_MATCH, &extensions->gcThreadCount);
973
if (OPTION_OK != result) {
974
if (OPTION_MALFORMED == result) {
975
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XGCMAXTHREADS);
976
} else {
977
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XGCMAXTHREADS);
978
}
979
goto _error;
980
}
981
982
if (0 == extensions->gcThreadCount) {
983
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, VMOPT_XGCMAXTHREADS, (UDATA)0);
984
goto _error;
985
}
986
987
extensions->gcThreadCountForced = false;
988
}
989
990
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xgcworkpackets", NULL)) {
991
result = option_set_to_opt_integer(vm, "-Xgcworkpackets", &index, EXACT_MEMORY_MATCH, &extensions->workpacketCount);
992
if (OPTION_OK != result) {
993
if (OPTION_MALFORMED == result) {
994
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xgcworkpackets");
995
} else {
996
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xgcworkpackets");
997
}
998
goto _error;
999
}
1000
if(0 == extensions->workpacketCount) {
1001
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, "-Xgcworkpackets", (UDATA)0);
1002
goto _error;
1003
}
1004
}
1005
1006
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
1007
if (-1 != option_set_group(vm, optionGroupClassGC, &index)) {
1008
switch (index) {
1009
case optionGroupClassGC_index_noclassgc:
1010
extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_NEVER;
1011
break;
1012
1013
case optionGroupClassGC_index_classgc:
1014
extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_ON_CLASS_LOADER_CHANGES;
1015
break;
1016
1017
case optionGroupClassGC_index_alwaysclassgc:
1018
extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_ALWAYS;
1019
break;
1020
}
1021
extensions->dynamicClassUnloadingSet = true;
1022
}
1023
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
1024
if (-1 != option_set_pair(vm, "-Xdisablestringconstantgc", "-Xenablestringconstantgc", &index)) {
1025
extensions->collectStringConstants = (0 != index);
1026
}
1027
1028
#if defined(OMR_GC_MODRON_CONCURRENT_MARK)
1029
result = option_set_to_opt_integer(vm, VMOPT_XCONCURRENTBACKGROUND, &index, EXACT_MEMORY_MATCH, &extensions->concurrentBackground);
1030
if (OPTION_OK != result) {
1031
if (OPTION_MALFORMED == result) {
1032
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XCONCURRENTBACKGROUND);
1033
} else {
1034
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XCONCURRENTBACKGROUND);
1035
}
1036
goto _error;
1037
}
1038
1039
result = option_set_to_opt_integer(vm, "-Xconcurrentlevel", &index, EXACT_MEMORY_MATCH, &extensions->concurrentLevel);
1040
if (OPTION_OK != result) {
1041
if (OPTION_MALFORMED == result) {
1042
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconcurrentlevel");
1043
} else {
1044
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xconcurrentlevel");
1045
}
1046
goto _error;
1047
}
1048
1049
if (0 == extensions->concurrentLevel) {
1050
/* LIR 1396: -Xconcurrentlevel0 should mean -Xgc:noConcurrentMark. */
1051
extensions->configurationOptions._forceOptionConcurrentMark = true;
1052
extensions->concurrentMark = false;
1053
}
1054
1055
result = option_set_to_opt(vm, "-Xconcurrentslack", &index, EXACT_MEMORY_MATCH, &extensions->concurrentSlack);
1056
if (OPTION_OK != result) {
1057
if (OPTION_MALFORMED == result) {
1058
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconcurrentslack");
1059
} else {
1060
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xconcurrentslack");
1061
}
1062
goto _error;
1063
}
1064
1065
#endif /* OMR_GC_MODRON_CONCURRENT_MARK */
1066
1067
#if defined(J9VM_GC_LARGE_OBJECT_AREA)
1068
/* parse this before -Xloamaximum, as -Xloamaximum0 will turn loa off */
1069
if (-1 != option_set_pair(vm, "-Xnoloa", "-Xloa", &index)) {
1070
extensions->configurationOptions._forceOptionLargeObjectArea = true;
1071
extensions->largeObjectArea = (1 == index);
1072
}
1073
1074
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloainitial", NULL)) {
1075
result = option_set_to_opt_percent(vm, "-Xloainitial", &index, EXACT_MEMORY_MATCH, &inputValue);
1076
if (OPTION_OK != result) {
1077
if (OPTION_MALFORMED == result) {
1078
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloainitial");
1079
} else {
1080
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloainitial", 0.0, 0.95);
1081
}
1082
goto _error;
1083
}
1084
if (inputValue > 95) {
1085
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloainitial", 0.0, 0.95);
1086
goto _error;
1087
}
1088
extensions->largeObjectAreaInitialRatio = (double)inputValue / (double)100;
1089
}
1090
1091
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloamaximum", NULL)) {
1092
result = option_set_to_opt_percent(vm, "-Xloamaximum", &index, EXACT_MEMORY_MATCH, &inputValue);
1093
if (OPTION_OK != result) {
1094
if (OPTION_MALFORMED == result) {
1095
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloamaximum");
1096
} else {
1097
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloamaximum", 0.0, 0.95);
1098
}
1099
goto _error;
1100
}
1101
if (inputValue > 95) {
1102
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloamaximum", 0.0, 0.95);
1103
goto _error;
1104
}
1105
extensions->largeObjectAreaMaximumRatio = (double)inputValue / (double)100;
1106
if(0 == extensions->largeObjectAreaMaximumRatio) {
1107
/* Implies -Xnoloa */
1108
extensions->configurationOptions._forceOptionLargeObjectArea = true;
1109
extensions->largeObjectArea = false;
1110
}
1111
}
1112
1113
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloaminimum", NULL)) {
1114
result = option_set_to_opt_percent(vm, "-Xloaminimum", &index, EXACT_MEMORY_MATCH, &inputValue);
1115
if (OPTION_OK != result) {
1116
if (OPTION_MALFORMED == result) {
1117
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloaminimum");
1118
} else {
1119
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloaminimum", 0.0, 0.95);
1120
}
1121
goto _error;
1122
}
1123
if (inputValue > 95) {
1124
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloaminimum", 0.0, 0.95);
1125
goto _error;
1126
}
1127
extensions->largeObjectAreaMinimumRatio = (double)inputValue / (double)100;
1128
if(-1 == FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloainitial", NULL)) {
1129
/* -Xloainitial wasn't specified, so we need to override it to match the -Xloaminimum we've just set */
1130
extensions->largeObjectAreaInitialRatio = extensions->largeObjectAreaMinimumRatio;
1131
}
1132
}
1133
1134
indexMeter = option_set_group(vm, optionGroupConMeter, &groupIndex);
1135
if (-1 != indexMeter) {
1136
switch(groupIndex) {
1137
case optionGroupConMeter_index_soa:
1138
extensions->concurrentMetering = MM_GCExtensions::METER_BY_SOA;
1139
break;
1140
1141
case optionGroupConMeter_index_loa:
1142
extensions->concurrentMetering = MM_GCExtensions::METER_BY_LOA;
1143
break;
1144
1145
case optionGroupConMeter_index_dynamic:
1146
extensions->concurrentMetering = MM_GCExtensions::METER_DYNAMIC;
1147
break;
1148
}
1149
}
1150
1151
/* Try to match SOV alternative syntax of -Xconmeter(0|1|2) */
1152
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xconmeter", NULL)) {
1153
result = option_set_to_opt_integer(vm, "-Xconmeter", &index, EXACT_MEMORY_MATCH, &inputValue);
1154
if (OPTION_OK != result) {
1155
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconmeter");
1156
goto _error;
1157
}
1158
1159
switch(inputValue) {
1160
case 0:
1161
extensions->concurrentMetering = MM_GCExtensions::METER_BY_SOA;
1162
break;
1163
case 1:
1164
extensions->concurrentMetering = MM_GCExtensions::METER_BY_LOA;
1165
break;
1166
case 2:
1167
extensions->concurrentMetering = MM_GCExtensions::METER_DYNAMIC;
1168
break;
1169
default:
1170
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_INTEGER_OUT_OF_RANGE, "-Xconmeter", (UDATA)0, (UDATA)2);
1171
goto _error;
1172
break;
1173
}
1174
}
1175
1176
#endif /* J9VM_GC_LARGE_OBJECT_AREA) */
1177
1178
/* If user has specified any of the following SOV options then we just silently ignore them
1179
*
1180
* -Xparroot
1181
* -XloratioN
1182
* -XloincrN
1183
* -XlorsrvN
1184
* All these options (except -Xparoot) take a float value between 0 and 1.0.
1185
*
1186
*/
1187
option_set(vm, "-Xparroot", EXACT_MATCH);
1188
option_set_to_opt_percent(vm, "-Xloratio", &index, EXACT_MEMORY_MATCH, &inputValue);
1189
option_set_to_opt_percent(vm, "-Xloincr", &index, EXACT_MEMORY_MATCH, &inputValue);
1190
option_set_to_opt_percent(vm, "-Xlorsrv", &index, EXACT_MEMORY_MATCH, &inputValue);
1191
1192
/* options to enable/disable excessivegc */
1193
if (-1 != option_set_pair(vm, "-Xdisableexcessivegc", "-Xenableexcessivegc", &index)) {
1194
extensions->excessiveGCEnabled._wasSpecified = true;
1195
extensions->excessiveGCEnabled._valueSpecified = (1 == index) ? true : false;
1196
}
1197
1198
if((-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-XSoftRefThreshold", NULL))) {
1199
optionFound = "-XSoftRefThreshold";
1200
} else {
1201
if((-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xsoftrefthreshold", NULL))) {
1202
optionFound = "-Xsoftrefthreshold";
1203
}
1204
}
1205
1206
if (NULL != optionFound) {
1207
result = option_set_to_opt_integer(vm, optionFound, &index, EXACT_MEMORY_MATCH, &extensions->maxSoftReferenceAge);
1208
if (OPTION_OK != result) {
1209
if (OPTION_MALFORMED == result) {
1210
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, optionFound);
1211
} else {
1212
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, optionFound);
1213
}
1214
goto _error;
1215
}
1216
1217
if ((IDATA)extensions->maxSoftReferenceAge < 0) {
1218
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, optionFound);
1219
goto _error;
1220
}
1221
}
1222
1223
if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-XX:stringTableListToTreeThreshold=", NULL)) {
1224
UDATA threshold = 0;
1225
result = option_set_to_opt_integer(vm, "-XX:stringTableListToTreeThreshold=", &index, EXACT_MEMORY_MATCH, &threshold);
1226
if (OPTION_OK != result) {
1227
if (OPTION_MALFORMED == result) {
1228
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-XX:stringTableListToTreeThreshold=");
1229
} else {
1230
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-XX:stringTableListToTreeThreshold=");
1231
}
1232
goto _error;
1233
}
1234
1235
if (threshold <= U_32_MAX) {
1236
extensions->_stringTableListToTreeThreshold = (U_32)threshold;
1237
} else {
1238
extensions->_stringTableListToTreeThreshold = U_32_MAX;
1239
}
1240
}
1241
1242
return 1;
1243
1244
_error:
1245
return 0;
1246
1247
}
1248
1249
static UDATA
1250
gcParseXXArguments(J9JavaVM *vm)
1251
{
1252
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
1253
1254
{
1255
IDATA heapManagementMXBeanCompatibilityIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+HeapManagementMXBeanCompatibility", NULL);
1256
IDATA noHheapManagementMXBeanCompatibilityIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-HeapManagementMXBeanCompatibility", NULL);
1257
if (heapManagementMXBeanCompatibilityIndex != noHheapManagementMXBeanCompatibilityIndex) {
1258
/* At least one option is set. Find the right most one. */
1259
if (heapManagementMXBeanCompatibilityIndex > noHheapManagementMXBeanCompatibilityIndex) {
1260
extensions->_HeapManagementMXBeanBackCompatibilityEnabled = true;
1261
} else {
1262
extensions->_HeapManagementMXBeanBackCompatibilityEnabled = false;
1263
}
1264
}
1265
}
1266
1267
{
1268
IDATA useGCStartupHintsIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+UseGCStartupHints", NULL);
1269
IDATA noUseGCStartupHintsIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-UseGCStartupHints", NULL);
1270
if (useGCStartupHintsIndex != noUseGCStartupHintsIndex) {
1271
/* At least one option is set. Find the right most one. */
1272
if (useGCStartupHintsIndex > noUseGCStartupHintsIndex) {
1273
extensions->useGCStartupHints = true;
1274
} else {
1275
extensions->useGCStartupHints = false;
1276
}
1277
}
1278
}
1279
1280
{
1281
IDATA alwaysPreTouchIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+AlwaysPreTouch", NULL);
1282
IDATA notAlwaysPreTouchIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-AlwaysPreTouch", NULL);
1283
if (alwaysPreTouchIndex != notAlwaysPreTouchIndex) {
1284
/* At least one option is set. Find the right most one. */
1285
if (alwaysPreTouchIndex > notAlwaysPreTouchIndex) {
1286
extensions->pretouchHeapOnExpand = true;
1287
} else {
1288
extensions->pretouchHeapOnExpand = false;
1289
}
1290
}
1291
}
1292
1293
{
1294
IDATA adaptiveGCThreadingIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+AdaptiveGCThreading", NULL);
1295
IDATA noAdaptiveGCThreadingIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-AdaptiveGCThreading", NULL);
1296
if (adaptiveGCThreadingIndex != noAdaptiveGCThreadingIndex) {
1297
/* At least one option is set. Find the right most one. */
1298
if (adaptiveGCThreadingIndex > noAdaptiveGCThreadingIndex) {
1299
extensions->adaptiveGCThreading = true;
1300
} else {
1301
extensions->adaptiveGCThreading = false;
1302
}
1303
}
1304
}
1305
1306
return 1;
1307
}
1308
1309
/**
1310
* Wrapper for scan_udata, that provides readable error messages.
1311
* @param cursor address of the pointer to the string to parse for the udata
1312
* @param value address of the storage for the udata to be read
1313
* @param argName string containing the argument name to be used in error reporting
1314
* @return true if parsing was successful, false otherwise.
1315
*/
1316
bool
1317
scan_udata_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName)
1318
{
1319
UDATA result;
1320
PORT_ACCESS_FROM_JAVAVM(javaVM);
1321
1322
if (0 != (result = scan_udata(cursor, value))) {
1323
if (1 == result) {
1324
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1325
} else {
1326
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1327
}
1328
return false;
1329
}
1330
1331
// TODO: should we add a delimiter check here?
1332
return true;
1333
}
1334
1335
/**
1336
* Wrapper for scan_udata, that provides readable error messages.
1337
* @param cursor address of the pointer to the string to parse for the udata
1338
* @param value address of the storage for the udata to be read
1339
* @param argName string containing the argument name to be used in error reporting
1340
* @return true if parsing was successful, false otherwise.
1341
*/
1342
bool
1343
scan_u32_helper(J9JavaVM *javaVM, char **cursor, U_32 *value, const char *argName)
1344
{
1345
UDATA result;
1346
PORT_ACCESS_FROM_JAVAVM(javaVM);
1347
1348
if (0 != (result = scan_u32(cursor, value))) {
1349
if (1 == result) {
1350
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1351
} else {
1352
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1353
}
1354
return false;
1355
}
1356
1357
// TODO: should we add a delimiter check here?
1358
return true;
1359
}
1360
1361
/**
1362
* Wrapper for scan_long, that provides readable error messages.
1363
* @param cursor address of the pointer to the string to parse for the u_64
1364
* @param value address of the storage for the U_64 to be read
1365
* @param argName string containing the argument name to be used in error reporting
1366
* @return true if parsing was successful, false otherwise.
1367
*/
1368
bool
1369
scan_u64_helper(J9JavaVM *javaVM, char **cursor, U_64 *value, const char *argName)
1370
{
1371
U_64 result;
1372
PORT_ACCESS_FROM_JAVAVM(javaVM);
1373
1374
if (0 != (result = scan_u64(cursor, value))) {
1375
if (1 == result) {
1376
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1377
} else {
1378
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1379
}
1380
return false;
1381
}
1382
1383
// TODO: should we add a delimiter check here?
1384
return true;
1385
}
1386
1387
/**
1388
* Wrapper for scan_hex, that provides readable error messages.
1389
* @param cursor address of the pointer to the string to parse for the hex value
1390
* @param value address of the storage for the hex value to be read
1391
* @param argName string containing the argument name to be used in error reporting
1392
* @return true if parsing was successful, false otherwise.
1393
*/
1394
bool
1395
scan_hex_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName)
1396
{
1397
UDATA result;
1398
PORT_ACCESS_FROM_JAVAVM(javaVM);
1399
1400
if (0 != (result = scan_hex(cursor, value))) {
1401
if (1 == result) {
1402
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1403
} else {
1404
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1405
}
1406
return false;
1407
}
1408
1409
// TODO: should we add a delimiter check here?
1410
return true;
1411
}
1412
1413
/**
1414
* Wrapper for scan_udata_memory_size, that provides readable error messages.
1415
* @param cursor address of the pointer to the string to parse for the udata.
1416
* @param value address of the storage for the udata to be read.
1417
* @param argName string containing the argument name to be used in error reporting.
1418
* @return true if parsing was successful, false otherwise.
1419
*/
1420
bool
1421
scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, uintptr_t *value, const char *argName)
1422
{
1423
PORT_ACCESS_FROM_JAVAVM(javaVM);
1424
uintptr_t result = scan_udata_memory_size(cursor, value);
1425
1426
/* Report Errors */
1427
if (1 == result) {
1428
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1429
} else if (2 == result) {
1430
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1431
}
1432
1433
return 0 == result;
1434
}
1435
1436
/**
1437
* Wrapper for scan_u64_helper, that provides readable error messages.
1438
* @param cursor address of the pointer to the string to parse for the udata.
1439
* @param value address of the storage for the udata to be read.
1440
* @param argName string containing the argument name to be used in error reporting.
1441
* @return true if parsing was successful, false otherwise.
1442
*/
1443
bool
1444
scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, uint64_t *value, const char *argName)
1445
{
1446
PORT_ACCESS_FROM_JAVAVM(javaVM);
1447
uintptr_t result = scan_u64_memory_size(cursor, value);
1448
1449
/* Report Errors */
1450
if (1 == result) {
1451
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
1452
} else if (2 == result) {
1453
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
1454
}
1455
1456
return 0 == result;
1457
}
1458
1459
/**
1460
* Initialize GC fields with values provided by user.
1461
* Record the parameter in the appropriate structure and record which
1462
* parameters were specified by the user.
1463
* @param memoryParameters pointer to the array of parameters to be set
1464
*/
1465
jint
1466
gcParseCommandLineAndInitializeWithValues(J9JavaVM *vm, IDATA *memoryParameters)
1467
{
1468
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
1469
UDATA optionValue = 0;
1470
IDATA index = 0;
1471
IDATA result = 0;
1472
UDATA userNewSpaceSize = 0;
1473
UDATA userOldSpaceSize = 0;
1474
char *xGCOptions = NULL;
1475
char *xxGCOptions = NULL;
1476
IDATA xGCColonIndex = 0;
1477
IDATA xxGCColonIndex = 0;
1478
J9VMInitArgs *vmArgs = vm->vmArgsArray;
1479
1480
PORT_ACCESS_FROM_JAVAVM(vm);
1481
1482
/* Parse the command line
1483
* Order is important for parameters that match as substrings (-Xmrx/-Xmr)
1484
*/
1485
{
1486
bool enableOriginalJDK8HeapSizeCompatibilityOption = false;
1487
/* only parse VMOPT_XXENABLEORIGINALJDK8HEAPSIZECOMPATIBILITY option for Java 8 and below */
1488
if (J2SE_18 >= J2SE_VERSION(vm)) {
1489
1490
IDATA enabled = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXENABLEORIGINALJDK8HEAPSIZECOMPATIBILITY, NULL);
1491
IDATA disabled = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXDISABLEORIGINALJDK8HEAPSIZECOMPATIBILITY, NULL);
1492
if (enabled > disabled) {
1493
enableOriginalJDK8HeapSizeCompatibilityOption = true;
1494
}
1495
}
1496
/* set default max heap for Java */
1497
extensions->computeDefaultMaxHeapForJava(enableOriginalJDK8HeapSizeCompatibilityOption);
1498
}
1499
result = option_set_to_opt(vm, OPT_XMCA, &index, EXACT_MEMORY_MATCH, &vm->ramClassAllocationIncrement);
1500
if (OPTION_OK != result) {
1501
goto _error;
1502
}
1503
memoryParameters[opt_Xmca] = index;
1504
1505
result = option_set_to_opt(vm, OPT_XMCO, &index, EXACT_MEMORY_MATCH, &vm->romClassAllocationIncrement);
1506
if (OPTION_OK != result) {
1507
goto _error;
1508
}
1509
memoryParameters[opt_Xmco] = index;
1510
1511
result = option_set_to_opt(vm, OPT_XMCRS, &index, EXACT_MEMORY_MATCH, &optionValue);
1512
if (OPTION_OK != result) {
1513
goto _error;
1514
}
1515
1516
#if defined(OMR_GC_COMPRESSED_POINTERS)
1517
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {
1518
if (-1 != index) {
1519
extensions->suballocatorInitialSize = optionValue;
1520
}
1521
if(0 == extensions->suballocatorInitialSize) {
1522
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, OPT_XMCRS, (UDATA)0);
1523
return JNI_EINVAL;
1524
}
1525
#define FOUR_GB ((UDATA)4 * 1024 * 1024 * 1024)
1526
if(extensions->suballocatorInitialSize >= FOUR_GB) {
1527
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, OPT_XMCRS);
1528
return JNI_EINVAL;
1529
}
1530
}
1531
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */
1532
1533
memoryParameters[opt_Xmcrs] = index;
1534
1535
result = option_set_to_opt(vm, OPT_XMX, &index, EXACT_MEMORY_MATCH, &extensions->memoryMax);
1536
if (OPTION_OK != result) {
1537
goto _error;
1538
}
1539
memoryParameters[opt_Xmx] = index;
1540
1541
result = option_set_to_opt(vm, OPT_SOFTMX, &index, EXACT_MEMORY_MATCH, &extensions->softMx);
1542
if (OPTION_OK != result) {
1543
goto _error;
1544
}
1545
memoryParameters[opt_Xsoftmx] = index;
1546
1547
/* -Xmns sets both newSpaceSize and minNewSpaceSize */
1548
result = option_set_to_opt(vm, OPT_XMNS, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmns._valueSpecified);
1549
if (OPTION_OK != result) {
1550
goto _error;
1551
}
1552
memoryParameters[opt_Xmns] = index;
1553
if (-1 != memoryParameters[opt_Xmns]) {
1554
extensions->userSpecifiedParameters._Xmns._wasSpecified = true;
1555
extensions->newSpaceSize = extensions->userSpecifiedParameters._Xmns._valueSpecified;
1556
extensions->minNewSpaceSize = extensions->newSpaceSize;
1557
}
1558
1559
result = option_set_to_opt(vm, OPT_XMNX, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmnx._valueSpecified);
1560
if (OPTION_OK != result) {
1561
goto _error;
1562
}
1563
memoryParameters[opt_Xmnx] = index;
1564
if (-1 != memoryParameters[opt_Xmnx]) {
1565
extensions->userSpecifiedParameters._Xmnx._wasSpecified = true;
1566
extensions->maxNewSpaceSize = extensions->userSpecifiedParameters._Xmnx._valueSpecified;
1567
}
1568
1569
result = option_set_to_opt(vm, OPT_XMOI, &index, EXACT_MEMORY_MATCH, &extensions->allocationIncrement);
1570
if (OPTION_OK != result) {
1571
goto _error;
1572
}
1573
memoryParameters[opt_Xmoi] = index;
1574
extensions->allocationIncrementSetByUser = (index != -1);
1575
1576
/* -Xmos sets both oldSpaceSize and minOldSpaceSize */
1577
result = option_set_to_opt(vm, OPT_XMOS, &index, EXACT_MEMORY_MATCH, &extensions->oldSpaceSize);
1578
if (OPTION_OK != result) {
1579
goto _error;
1580
}
1581
memoryParameters[opt_Xmos] = index;
1582
if (-1 != memoryParameters[opt_Xmos]) {
1583
extensions->minOldSpaceSize = extensions->oldSpaceSize;
1584
}
1585
1586
result = option_set_to_opt(vm, OPT_XMOX, &index, EXACT_MEMORY_MATCH, &extensions->maxOldSpaceSize);
1587
if (OPTION_OK != result) {
1588
goto _error;
1589
}
1590
memoryParameters[opt_Xmox] = index;
1591
1592
result = option_set_to_opt(vm, OPT_XMS, &index, EXACT_MEMORY_MATCH, &extensions->initialMemorySize);
1593
if (OPTION_OK != result) {
1594
goto _error;
1595
}
1596
memoryParameters[opt_Xms] = index;
1597
1598
#if defined(J9VM_GC_MODRON_SCAVENGER)
1599
result = option_set_to_opt(vm, OPT_XMRX, &index, EXACT_MEMORY_MATCH, &optionValue);
1600
if (OPTION_OK != result) {
1601
goto _error;
1602
}
1603
memoryParameters[opt_Xmrx] = index;
1604
if(memoryParameters[opt_Xmrx] != -1) {
1605
extensions->rememberedSet.setMaxSize(optionValue);
1606
}
1607
1608
result = option_set_to_opt(vm, OPT_XMR, &index, EXACT_MEMORY_MATCH, &optionValue);
1609
if (OPTION_OK != result) {
1610
goto _error;
1611
}
1612
memoryParameters[opt_Xmr] = index;
1613
if (memoryParameters[opt_Xmr] != -1) {
1614
extensions->rememberedSet.setGrowSize(optionValue);
1615
}
1616
#endif /* J9VM_GC_MODRON_SCAVENGER */
1617
1618
result = option_set_to_opt(vm, OPT_XMN, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmn._valueSpecified);
1619
if (OPTION_OK != result) {
1620
goto _error;
1621
}
1622
memoryParameters[opt_Xmn] = index;
1623
if (memoryParameters[opt_Xmn] != -1) {
1624
extensions->userSpecifiedParameters._Xmn._wasSpecified = true;
1625
userNewSpaceSize = extensions->userSpecifiedParameters._Xmn._valueSpecified;
1626
/* check that -Xmns/-Xmnx AND -Xmn weren't specified */
1627
if (memoryParameters[opt_Xmns] != -1) {
1628
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMN, OPT_XMNS);
1629
return JNI_EINVAL;
1630
}
1631
if (memoryParameters[opt_Xmnx] != -1) {
1632
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMN, OPT_XMNX);
1633
return JNI_EINVAL;
1634
}
1635
1636
extensions->minNewSpaceSize = userNewSpaceSize;
1637
extensions->newSpaceSize = userNewSpaceSize;
1638
extensions->maxNewSpaceSize = userNewSpaceSize;
1639
1640
/* Hack table to appear that -Xmns and -Xmnx _were_ specified */
1641
memoryParameters[opt_Xmns] = memoryParameters[opt_Xmn];
1642
memoryParameters[opt_Xmnx] = memoryParameters[opt_Xmn];
1643
}
1644
1645
result = option_set_to_opt(vm, OPT_XMO, &index, EXACT_MEMORY_MATCH, &userOldSpaceSize);
1646
if (OPTION_OK != result) {
1647
goto _error;
1648
}
1649
memoryParameters[opt_Xmo] = index;
1650
if (memoryParameters[opt_Xmo] != -1) {
1651
/* check that -Xmos/-Xmox AND -Xmo weren't specified */
1652
if(memoryParameters[opt_Xmox] != -1) {
1653
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMO, OPT_XMOX);
1654
return JNI_EINVAL;
1655
}
1656
if(memoryParameters[opt_Xmos] != -1) {
1657
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMO, OPT_XMOS);
1658
return JNI_EINVAL;
1659
}
1660
1661
extensions->minOldSpaceSize = userOldSpaceSize;
1662
extensions->oldSpaceSize = userOldSpaceSize;
1663
extensions->maxOldSpaceSize = userOldSpaceSize;
1664
1665
/* Hack table to appear that -Xmos and -Xmox _were_ specified */
1666
memoryParameters[opt_Xmos] = memoryParameters[opt_Xmo];
1667
memoryParameters[opt_Xmox] = memoryParameters[opt_Xmo];
1668
}
1669
1670
result = option_set_to_opt_double(vm, OPT_XXMAXRAMPERCENT, &index, EXACT_MEMORY_MATCH, &extensions->maxRAMPercent);
1671
if (OPTION_OK != result) {
1672
goto _error;
1673
}
1674
memoryParameters[opt_maxRAMPercent] = index;
1675
if (memoryParameters[opt_maxRAMPercent] != -1) {
1676
if ((extensions->maxRAMPercent < 0.0) || (extensions->maxRAMPercent > 100.0)) {
1677
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-XX:MaxRAMPercentage", 0.0, 100.0);
1678
return JNI_EINVAL;
1679
}
1680
}
1681
1682
result = option_set_to_opt_double(vm, OPT_XXINITIALRAMPERCENT, &index, EXACT_MEMORY_MATCH, &extensions->initialRAMPercent);
1683
if (OPTION_OK != result) {
1684
goto _error;
1685
}
1686
memoryParameters[opt_initialRAMPercent] = index;
1687
if (memoryParameters[opt_initialRAMPercent] != -1) {
1688
if ((extensions->initialRAMPercent < 0.0) || (extensions->initialRAMPercent > 100.0)) {
1689
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-XX:InitialRAMPercentage", 0.0, 100.0);
1690
return JNI_EINVAL;
1691
}
1692
}
1693
1694
/* Parse the option to disable NUMA-awareness. This is parsed on all platforms but only Balanced currently does anything
1695
* with the result.
1696
* Note that this option does NOT disable heap interleaving since that is considered a harmless and "passive" optimization.
1697
*/
1698
index = option_set(vm, OPT_NUMA_NONE, EXACT_MATCH);
1699
if (-1 != index) {
1700
#if defined(J9VM_GC_VLHGC) || defined(J9VM_GC_GENERATIONAL)
1701
/* this is currently the same behaviour as our internal -Xgc:nonuma option */
1702
extensions->_numaManager.shouldEnablePhysicalNUMA(false);
1703
extensions->numaForced = true;
1704
#endif /* defined(J9VM_GC_VLHGC) || defined(J9VM_GC_GENERATIONAL) */
1705
}
1706
/* Since the user is not specifying a value, ensure that -Xmdx is set to the same value
1707
* as -Xmx. It does not matter whether -Xmx was specified or not.
1708
*/
1709
extensions->maxSizeDefaultMemorySpace = extensions->memoryMax;
1710
1711
/* Parse for recognized Sovereign command line options. Any duplication with an Xgc option
1712
* will be overwritten. This currently must be done after check for resource management so we can
1713
* easily disallow -Xgcpolicy options.
1714
*/
1715
if (0 == gcParseSovereignArguments(vm)) {
1716
return JNI_EINVAL;
1717
}
1718
1719
/* parse -XX: option that logicially belong to GC */
1720
if (0 == gcParseXXArguments(vm)) {
1721
return JNI_EINVAL;
1722
}
1723
1724
/* Parse XXgc options */
1725
xxGCColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XXGC_COLON, NULL );
1726
while (xxGCColonIndex >= 0) {
1727
CONSUME_ARG(vmArgs, xxGCColonIndex);
1728
GET_OPTION_VALUE( xxGCColonIndex, ':', &xxGCOptions);
1729
1730
/* Parse xxGCOptions arguments (if any) */
1731
if (NULL != xxGCOptions) {
1732
jint retCode;
1733
if (JNI_OK != (retCode = gcParseXXgcArguments(vm, xxGCOptions))) {
1734
return retCode;
1735
}
1736
}
1737
xxGCColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XXGC_COLON, NULL, xxGCColonIndex);
1738
}
1739
1740
xGCColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XGC_COLON, NULL );
1741
while (xGCColonIndex >= 0) {
1742
CONSUME_ARG(vmArgs, xGCColonIndex);
1743
GET_OPTION_VALUE( xGCColonIndex, ':', &xGCOptions);
1744
1745
/* Parse xGCOptions arguments (if any) */
1746
if (xGCOptions != NULL) {
1747
jint retCode;
1748
if (JNI_OK != (retCode = gcParseXgcArguments(vm, xGCOptions))) {
1749
return retCode;
1750
}
1751
} else {
1752
return JNI_OK;
1753
}
1754
1755
xGCColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD(STARTSWITH_MATCH, OPT_XGC_COLON, NULL, xGCColonIndex);
1756
}
1757
1758
#if defined(J9VM_GC_GENERATIONAL)
1759
/*
1760
* If Split Heap is requested, -Xms, -Xmns and -Xmos will be overwritten
1761
* so ignore them even specified
1762
*/
1763
if (extensions->enableSplitHeap) {
1764
memoryParameters[opt_Xms] = -1;
1765
memoryParameters[opt_Xmns] = -1;
1766
memoryParameters[opt_Xmos] = -1;
1767
}
1768
#endif /* defined(J9VM_GC_GENERATIONAL) */
1769
1770
return JNI_OK;
1771
1772
_error:
1773
char *errorString = VMARGS_OPTION(index);
1774
1775
/* show something meaningful about why parsing failed */
1776
switch(result) {
1777
case OPTION_MALFORMED:
1778
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_MALFORMED, errorString);
1779
break;
1780
case OPTION_OVERFLOW:
1781
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_OVERFLOW, errorString);
1782
break;
1783
case OPTION_ERROR:
1784
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_ERROR, errorString);
1785
break;
1786
case OPTION_BUFFER_OVERFLOW:
1787
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_OVERFLOW, errorString);
1788
break;
1789
default:
1790
scan_failed(PORTLIB, "GC", errorString);
1791
break;
1792
}
1793
1794
return JNI_EINVAL;
1795
}
1796
1797
bool
1798
gcParseTGCCommandLine(J9JavaVM *vm)
1799
{
1800
bool parseSuccess = true;
1801
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
1802
1803
/* note that realtime currently doesn't support TGC so only standard and VLHGC should try to consume TGC arguments */
1804
if (extensions->isStandardGC() || extensions->isVLHGC() || extensions->isSegregatedHeap()) {
1805
#if defined(J9VM_GC_MODRON_TRACE)
1806
J9VMInitArgs *vmArgs = vm->vmArgsArray;
1807
/* Parse Xtgc options */
1808
IDATA xTgcColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XTGC_COLON, NULL );
1809
while (parseSuccess && (xTgcColonIndex >= 0)) {
1810
char* xTgcOptions = NULL;
1811
CONSUME_ARG(vmArgs, xTgcColonIndex);
1812
GET_OPTION_VALUE( xTgcColonIndex, ':', &xTgcOptions);
1813
1814
/* Parse xTgcOptions arguments (if any) */
1815
if (NULL != xTgcOptions) {
1816
if (!tgcParseArgs(vm, xTgcOptions) || !tgcInitializeRequestedOptions(vm)) {
1817
parseSuccess = false;
1818
}
1819
}
1820
xTgcColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XTGC_COLON, NULL, xTgcColonIndex);
1821
}
1822
#endif /* defined(J9VM_GC_MODRON_TRACE) */
1823
}
1824
1825
return parseSuccess;
1826
}
1827
1828