Path: blob/master/runtime/gc_modron_startup/mmparse.cpp
5985 views
/*******************************************************************************1* Copyright (c) 1991, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122/**23* @file24* @ingroup GC_Modron_Startup25*/2627#include "j9.h"28#include "j9cfg.h"29#include "j9protos.h"30#include "j9consts.h"31#include "j9argscan.h"32#include "jni.h"33#include "jvminit.h"34#include "j9port.h"35#include "modronnls.h"36#include "gcutils.h"37#include "ModronAssertions.h"3839#include "mmparse.h"4041#include "Configuration.hpp"42#include "GCExtensions.hpp"43#if defined(J9VM_GC_MODRON_TRACE)44#include "Tgc.hpp"45#endif /* defined(J9VM_GC_MODRON_TRACE) */4647/**48* @name GC command line options49* Memory parameter command line options.50* @note The order of parsing is important, as substrings occur in some parameters.51* \anchor gcOptions52* @{53*/54#define OPT_XGC_COLON "-Xgc:"55#define OPT_XXGC_COLON "-XXgc:"56#define OPT_XTGC_COLON "-Xtgc:"57#define OPT_XMX "-Xmx"58#define OPT_XMCA "-Xmca"59#define OPT_XMCO "-Xmco"60#define OPT_XMCRS "-Xmcrs"61#define OPT_XMN "-Xmn"62#define OPT_XMNS "-Xmns"63#define OPT_XMNX "-Xmnx"64#define OPT_XMOI "-Xmoi"65#define OPT_XMO "-Xmo"66#define OPT_XMOS "-Xmos"67#define OPT_XMOX "-Xmox"68#define OPT_XMS "-Xms"69#define OPT_XMRX "-Xmrx"70#define OPT_XMR "-Xmr"71#define OPT_SOFTMX "-Xsoftmx"72#define OPT_NUMA_NONE "-Xnuma:none"73#define OPT_XXMAXRAMPERCENT "-XX:MaxRAMPercentage="74#define OPT_XXINITIALRAMPERCENT "-XX:InitialRAMPercentage="7576/**77* @}78*/7980static char OPTION_SET_GROUP_UNUSED[] = "";8182#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)83/**84* @name Class unloading argument group85* Command line option group indexes for class unloading options.86* @note The ordering of the enums must match the char array.87*88* @{89*/90enum {91optionGroupClassGC_index_noclassgc = 0,92optionGroupClassGC_index_classgc,93optionGroupClassGC_index_alwaysclassgc94};9596static const char *optionGroupClassGC[] = {97"-Xnoclassgc",98"-Xclassgc",99"-Xalwaysclassgc",100NULL101};102/**103* @}104*/105#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */106107#if defined(J9VM_GC_LARGE_OBJECT_AREA)108/**109* @name Concurrent metering argument group110* Command line option group indexes for concurrent metering options.111* @note The ordering of the enums must match the char array.112*113* @{114*/115enum {116optionGroupConMeter_index_soa = 0,117optionGroupConMeter_index_loa,118optionGroupConMeter_index_dynamic119};120121static const char *optionGroupConMeter[] = {122"-Xconmeter:soa",123"-Xconmeter:loa",124"-Xconmeter:dynamic",125NULL126};127/**128* @}129*/130#endif /* J9VM_GC_LARGE_OBJECT_AREA) */131132/**133* @name Xlp error state group.134*135* @{136*/137struct XlpError {138const char *xlpOptionErrorString;139size_t xlpOptionErrorStringSize;140const char *xlpMissingOptionString;141bool extraCommaWarning;142};143144typedef enum {145XLP_NO_ERROR = 0,146XLP_OPTION_NOT_SUPPORTED,147XLP_MEM_NAN,148XLP_MEM_OVERFLOW,149XLP_PAGE_SIZE_INCORRECT,150XLP_INCOMPLETE_OPTION,151XLP_LARGE_PAGE_NOT_SUPPORTED,152XLP_PARAMETER_NOT_RECOGNIZED153} XlpErrorState;154155typedef enum {156PARSING_FIRST_OPTION = 1,157PARSING_OPTION,158PARSING_COMMA,159PARSING_ERROR160} parsingStates;161/**162* @}163*/164165/**166* Find, consume and record an option from the argument list.167* Given an option string and the match type, find the argument in the to be consumed list.168* If found, consume it.169*170* @return -1 if the argument was not consumed properly, otherwise the index position of the argument (>=0)171*/172static IDATA173option_set(J9JavaVM* vm, const char* option, IDATA match)174{175return FIND_AND_CONSUME_ARG2(match, option, NULL);176}177178/**179* Find, consume and record an option from the argument list.180* Given an option string and the match type, find the argument in the to be consumed list.181* If found, consume it, verify the memory value.182*183* @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.184* @note value stored at address is invalid if failure returned185* @note optionIndex contains position of argument on command line if success returned, else -1186*/187static IDATA188option_set_to_opt(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)189{190IDATA element;191IDATA returnCode = OPTION_OK;192UDATA value;193194element = FIND_AND_CONSUME_ARG2(match, option, NULL);195*optionIndex = element;196197if (element >= 0) {198returnCode = GET_MEMORY_VALUE(element, option, value);199if (OPTION_OK == returnCode){200*address = value;201}202}203return returnCode;204}205206/**207* Find, consume and record an option from the argument list.208* Given an option string and the match type, find the argument in the to be consumed list.209* If found, consume it, verify the memory value.210*211* @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.212* @note value stored at address is invalid if failure returned213* @note optionIndex contains position of argument on command line if success returned, else -1214*/215static IDATA216option_set_to_opt_percent(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)217{218IDATA element;219IDATA returnCode = OPTION_OK;220UDATA value;221222element = FIND_AND_CONSUME_ARG2(match, option, NULL);223*optionIndex = element;224225if (element >= 0) {226returnCode = GET_PERCENT_VALUE(element, option, value);227if (OPTION_OK == returnCode) {228*address = value;229}230}231return returnCode;232}233234/**235* Find, consume and record an option from the argument list.236* Given an option string and the match type, find the argument in the to be consumed list.237* If not found, return success.238* If found, consume it, verify the memory value.239*240* @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.241* @note value stored at address is invalid if failure returned242* @note optionIndex contains position of argument on command line if success returned, else -1243*/244static IDATA245option_set_to_opt_integer(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, UDATA* address)246{247IDATA element;248IDATA returnCode = OPTION_OK;249IDATA value;250251element = FIND_AND_CONSUME_ARG2(match, option, NULL);252*optionIndex = element;253254if (element >= 0) {255returnCode = GET_INTEGER_VALUE(element, option, value);256if (OPTION_OK == returnCode) {257*address = value;258}259}260return returnCode;261}262263/**264* Find, consume and record an option from the argument list.265* Given an option string and the match type, find the argument in the to be consumed list.266* If not found, return success.267* If found, consume it, verify the memory value.268*269* @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.270* @note value stored at address is invalid if failure returned271* @note optionIndex contains position of argument on command line if success returned, else -1272*/273static IDATA274option_set_to_opt_double(J9JavaVM* vm, const char* option, IDATA* optionIndex, IDATA match, double* address)275{276IDATA element = -1;277IDATA returnCode = OPTION_OK;278double value = 0.0;279280element = FIND_AND_CONSUME_ARG2(match, option, NULL);281*optionIndex = element;282283if (element >= 0) {284returnCode = GET_DOUBLE_VALUE(element, option, value);285if (OPTION_OK == returnCode) {286*address = value;287}288}289return returnCode;290}291292/**293* Find, consume and record a pair of options from the argument list.294* Consumes the options option1 and option2 and return which option was rightmost.295*296* @return -1 if the arguments were not consumed properly, otherwise the index position of the rightmost argument (>=0)297* @note if successful consumed optionIndex contains 0 if the rightmost argument is option1, 1 if the rightmost argument is option2, else -1298*/299static IDATA300option_set_pair(J9JavaVM *vm, const char *option1, const char *option2, IDATA *optionPairIndex) {301IDATA index1, index2;302index1 = option_set(vm, option1, EXACT_MATCH);303index2 = option_set(vm, option2, EXACT_MATCH);304305if (index1 > index2) {306*optionPairIndex = 0;307return index1;308}309310if (-1 != index2) {311*optionPairIndex = 1;312return index2;313}314315*optionPairIndex = -1;316return -1;317}318319/**320* Find, consume and record a group of options from the argument list.321* Consumes the options optionGroup and return which option was rightmost.322*323* @return -1 if the arguments were not consumed properly, otherwise the index position of the rightmost argument (>=0)324* @note if successful consumed optionIndex contains the index into optionGroup of the rightmost argument, else -1325*/326static IDATA327option_set_group(J9JavaVM *vm, const char **optionGroup, IDATA *optionGroupIndex) {328IDATA rightMostIndex, currentIndex, currentOption;329330/* default return values */331*optionGroupIndex = -1;332rightMostIndex = -1;333334currentOption = 0;335while(NULL != *optionGroup) {336/* ensure that we skip over entries in the table which aren't supported on this configuration (but preserved for shape consistency) */337if (OPTION_SET_GROUP_UNUSED != *optionGroup) {338if (-1 != (currentIndex = option_set(vm, *optionGroup, EXACT_MATCH))) {339if (currentIndex > rightMostIndex) {340rightMostIndex = currentIndex;341*optionGroupIndex = currentOption;342}343}344}345currentOption += 1;346optionGroup++;347}348349return rightMostIndex;350}351352/**353* Parse sub options for -Xlp:xxxxx:354*/355static XlpErrorState356xlpSubOptionsParser(J9JavaVM *vm, IDATA xlpIndex, XlpError *xlpError, UDATA *requestedPageSize, UDATA *requestedPageFlags, bool *strict, bool *warn)357{358/* -Xlp:objectheap: found and it is most right option, so it is not overwritten by -Xlp<size> */359char *optionsString = NULL;360char *scan_limit = NULL;361362/* start parsing with option */363parsingStates parsingState = PARSING_FIRST_OPTION;364UDATA optionNumber = 1;365char *previousOption = NULL;366char *errorString = NULL;367368UDATA pageSizeHowMany = 0;369#if defined(J9ZOS390)370UDATA pageableHowMany = 0;371UDATA pageableOptionNumber = 0;372UDATA nonPageableHowMany = 0;373UDATA nonPageableOptionNumber = 0;374#endif /* defined(J9ZOS390) */375376/* Reset error state from parsing of previous -Xlp<size> option */377XlpErrorState xlpErrorState = XLP_NO_ERROR;378379xlpError->xlpOptionErrorString = NULL;380xlpError->xlpOptionErrorStringSize = 0;381xlpError->xlpMissingOptionString = NULL;382xlpError->extraCommaWarning = false;383384/* Get pointer to entire option */385GET_OPTION_OPTION(xlpIndex, ':', ':', &optionsString);386387/* optionsString can not be NULL here, though it may point to null ('\0') character */388scan_limit = optionsString + strlen(optionsString);389390/*391* parsing -Xlp:objectheap: for options392*393* reporting general parsing problems (bad formed and unknown options)394* recognize cases where extra commas are entered to print warning after if necessary395*/396397while (optionsString < scan_limit) {398if (try_scan(&optionsString, ",")) {399/* Comma separator is discovered */400switch (parsingState) {401case PARSING_FIRST_OPTION:402/* leading comma - ignored but warning required */403xlpError->extraCommaWarning = true;404parsingState = PARSING_OPTION;405break;406case PARSING_OPTION:407/* more then one comma - ignored but warning required */408xlpError->extraCommaWarning = true;409break;410case PARSING_COMMA:411/* expecting for comma here, next should be an option*/412parsingState = PARSING_OPTION;413/* next option number */414optionNumber += 1;415break;416case PARSING_ERROR:417default:418/* must be unreachable states */419Assert_MM_unreachable();420break;421}422} else {423/* Comma separator has not been found. so */424switch (parsingState) {425case PARSING_FIRST_OPTION:426/* still looking for parsing of first option - nothing to do */427parsingState = PARSING_OPTION;428break;429case PARSING_OPTION:430/* Can not recognize an option case */431Assert_MM_true(previousOption == optionsString);432errorString = optionsString;433parsingState = PARSING_ERROR;434break;435case PARSING_COMMA:436/* can not find comma after option - so this is something unrecognizable at the end of known option */437errorString = previousOption;438parsingState = PARSING_ERROR;439break;440case PARSING_ERROR:441default:442/* must be unreachable states */443Assert_MM_unreachable();444break;445}446}447448if (PARSING_ERROR == parsingState) {449Assert_MM_true(NULL != errorString);450451xlpErrorState = XLP_PARAMETER_NOT_RECOGNIZED;452xlpError->xlpOptionErrorString = errorString;453454/* try to find comma to isolate unrecognized option */455char *commaLocation = strchr(errorString, ',');456if (NULL != commaLocation) {457/* comma found */458xlpError->xlpOptionErrorStringSize = (size_t)(commaLocation - errorString);459} else {460/* comma not found - print to the end of the string */461xlpError->xlpOptionErrorStringSize = strlen(errorString);462}463464return xlpErrorState;465}466467/* check that something was parsed or previousOption still NULL, otherwise we are in dead loop */468Assert_MM_true((NULL == previousOption) || (previousOption != optionsString));469470previousOption = optionsString;471472if (try_scan(&optionsString, "pagesize=")) {473/* try to get memory value */474if (!scan_udata_memory_size_helper(vm, &optionsString, requestedPageSize, "pagesize=")) {475/* size is not formed properly */476xlpErrorState = XLP_PAGE_SIZE_INCORRECT;477return xlpErrorState;478}479480pageSizeHowMany += 1;481482parsingState = PARSING_COMMA;483} else if (try_scan(&optionsString, "pageable")) {484#if defined(J9ZOS390)485pageableHowMany += 1;486pageableOptionNumber = optionNumber;487#endif /* defined(J9ZOS390) */488parsingState = PARSING_COMMA;489} else if (try_scan(&optionsString, "nonpageable")) {490#if defined(J9ZOS390)491nonPageableHowMany += 1;492nonPageableOptionNumber = optionNumber;493#endif /* defined(J9ZOS390) */494parsingState = PARSING_COMMA;495} else if ((NULL != strict) && try_scan(&optionsString, "strict")) {496*strict = true;497parsingState = PARSING_COMMA;498} else if ((NULL != warn) && try_scan(&optionsString, "warn")) {499*warn = true;500parsingState = PARSING_COMMA;501}502}503504/*505* post-parse check for trailing comma(s)506*/507switch (parsingState) {508/* if loop ended in one of these two states extra comma warning required */509case PARSING_FIRST_OPTION:510case PARSING_OPTION:511/* trailing comma(s) or comma(s) alone */512xlpError->extraCommaWarning = true;513break;514case PARSING_COMMA:515/* loop ended at comma search state - do nothing */516break;517case PARSING_ERROR:518default:519/* must be unreachable states */520Assert_MM_unreachable();521break;522}523524/* --- analyze correctness of entered options --- */525/*526* pagesize = <size>527* - this options must be specified for all platforms528*/529if (0 == pageSizeHowMany) {530/* error: pagesize= must be specified */531xlpErrorState = XLP_INCOMPLETE_OPTION;532xlpError->xlpOptionErrorString = "-Xlp:objectheap:";533xlpError->xlpMissingOptionString = "pagesize=";534return xlpErrorState;535}536537#if defined(J9ZOS390)538/*539* [non]pageable540* - this option must be specified for Z platforms541*/542if ((0 == pageableHowMany) && (0 == nonPageableHowMany)) {543/* error: [non]pageable not found */544xlpErrorState = XLP_INCOMPLETE_OPTION;545xlpError->xlpOptionErrorString = "-Xlp:objectheap:";546xlpError->xlpMissingOptionString = "[non]pageable";547return xlpErrorState;548}549550if (pageableOptionNumber > nonPageableOptionNumber) {551/* pageable is most right */552*requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_PAGEABLE;553} else {554/* nonpageable is most right */555*requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_FIXED;556}557#endif /* defined(J9ZOS390) */558559return xlpErrorState;560}561562/**563* Find and consume -Xlp option(s) from the argument list.564*565* @param vm pointer to Java VM structure566*567* @return false if the option(s) are not consumed properly, true on success.568*/569static bool570gcParseXlpOption(J9JavaVM *vm)571{572MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);573bool rc = false;574XlpErrorState xlpErrorState = XLP_NO_ERROR;575XlpError xlpError = {NULL, /* xlpOptionErrorString */5760, /* xlpOptionErrorStringSize */577NULL, /* xlpMissingOptionString */578false}; /* extraCommaWarning */579IDATA xlpIndex = -1;580IDATA xlpMemIndex = -1;581IDATA xlpObjectHeapIndex = -1;582IDATA xlpGCIndex = -1;583UDATA requestedPageSize = 0;584UDATA requestedPageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;585PORT_ACCESS_FROM_JAVAVM(vm);586587/* Parse -Xlp option.588* -Xlp option enables large pages with the default large page size, but will not589* override any -Xlp<size> or -Xlp:objectheap:pagesize=<size> option.590*/591xlpIndex = option_set(vm, "-Xlp", EXACT_MATCH);592if (-1 != xlpIndex) {593UDATA defaultLargePageSize = 0;594UDATA defaultLargePageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;595j9vmem_default_large_page_size_ex(0, &defaultLargePageSize, &defaultLargePageFlags);596if (0 != defaultLargePageSize) {597extensions->requestedPageSize = defaultLargePageSize;598extensions->requestedPageFlags = defaultLargePageFlags;599} else {600xlpErrorState = XLP_OPTION_NOT_SUPPORTED;601xlpError.xlpOptionErrorString = "-Xlp";602/* Cannot report error message here,603* as we may find a valid "-Xlp:objectheap" that overwrites this option604*/605}606}607608/* Parse -Xlp<size> option. It overrides -Xlp option. */609xlpMemIndex = FIND_AND_CONSUME_ARG(EXACT_MEMORY_MATCH, "-Xlp", NULL);610if (-1 != xlpMemIndex) {611/* Reset error state from parsing of previous -Xlp option */612xlpErrorState = XLP_NO_ERROR;613614/* No need to set requestedPageFlags explicitly. We use the default value J9PORT_VMEM_PAGE_FLAG_NOT_USED */615616/* If the machine does not support large pages, we may fail.617* Page flags for default large page size is not required, just pass NULL.618*/619j9vmem_default_large_page_size_ex(0, &requestedPageSize, NULL);620if (0 != requestedPageSize) {621IDATA result = option_set_to_opt(vm, "-Xlp", &xlpMemIndex, EXACT_MEMORY_MATCH, &requestedPageSize);622if (OPTION_OK != result) {623/* this -Xlp option must be formed properly even it might be overwritten by "-Xlp:objectheap" */624if (OPTION_MALFORMED == result) {625xlpErrorState = XLP_MEM_NAN;626} else {627xlpErrorState = XLP_MEM_OVERFLOW;628}629goto _reportXlpError;630}631} else {632xlpErrorState = XLP_OPTION_NOT_SUPPORTED;633xlpError.xlpOptionErrorString = "-Xlp";634/* Cannot report error message here, as we may find a valid "-Xlp:objectheap" that overwrites this option */635}636}637638/* Parse -Xlp:objectheap:pagesize=<size> option.639* It overrides -Xlp option.640* It also overrides -Xlp<size> option if it appears to the right of -Xlp<size>641*642* The proper formed -Xlp:objectheap: option must be (in strict order):643* For all non-Z platforms:644* -Xlp:objectheap:pagesize=<size> or645* -Xlp:objectheap:pagesize=<size>,pageable or646* -Xlp:objectheap:pagesize=<size>,nonpageable647*648* For Z platforms649* -Xlp:objectheap:pagesize=<size>,pageable or650* -Xlp:objectheap:pagesize=<size>,nonpageable651*/652xlpObjectHeapIndex = FIND_AND_CONSUME_ARG(STARTSWITH_MATCH, "-Xlp:objectheap:", NULL);653654/* so if -Xlp:objectheap: is specified */655if ((-1 != xlpObjectHeapIndex) && (xlpObjectHeapIndex > xlpMemIndex)) {656/*657* Parse sub options for -Xlp:objectheap:658*/659xlpErrorState = xlpSubOptionsParser(vm, xlpObjectHeapIndex, &xlpError, &requestedPageSize, &requestedPageFlags, &extensions->largePageFailOnError, &extensions->largePageWarnOnError);660661if (xlpError.extraCommaWarning) {662/* print extra comma ignored warning */663j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_EXTRA_COMMA);664}665}666667/* If there is a pending error state, report it now */668if (XLP_NO_ERROR != xlpErrorState) {669goto _reportXlpError;670}671672/* If a valid -Xlp<size> or -Xlp:objectheap:pagesize=<size> is present, check if the requested page size is supported */673/* We don't need to check error state here - we did goto for all errors */674if ((-1 != xlpMemIndex) || (-1 != xlpObjectHeapIndex)) {675UDATA pageSize = requestedPageSize;676UDATA pageFlags = requestedPageFlags;677BOOLEAN isRequestedSizeSupported = FALSE;678679IDATA result = j9vmem_find_valid_page_size(0, &pageSize, &pageFlags, &isRequestedSizeSupported);680681/*682* j9vmem_find_valid_page_size happened to be changed to always return 0683* However formally the function type still be IDATA so assert if it returns anything else684*/685Assert_MM_true(0 == result);686687extensions->requestedPageSize = pageSize;688extensions->requestedPageFlags = pageFlags;689690if (!isRequestedSizeSupported) {691/* Print a message indicating requested page size is not supported and a different page size will be used */692const char *oldQualifier, *newQualifier;693const char *oldPageType = NULL;694const char *newPageType = NULL;695UDATA oldSize = requestedPageSize;696UDATA newSize = pageSize;697qualifiedSize(&oldSize, &oldQualifier);698qualifiedSize(&newSize, &newQualifier);699if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & requestedPageFlags)) {700oldPageType = getPageTypeString(requestedPageFlags);701}702if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & pageFlags)) {703newPageType = getPageTypeString(pageFlags);704}705if (NULL == oldPageType) {706if (NULL == newPageType) {707j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED, oldSize, oldQualifier, newSize, newQualifier);708} else {709j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_NEW_PAGETYPE, oldSize, oldQualifier, newSize, newQualifier, newPageType);710}711} else {712if (NULL == newPageType) {713j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_REQUESTED_PAGETYPE, oldSize, oldQualifier, oldPageType, newSize, newQualifier);714} else {715j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_LARGE_PAGE_SIZE_NOT_SUPPORTED_WITH_PAGETYPE, oldSize, oldQualifier, oldPageType, newSize, newQualifier, newPageType);716}717}718}719}720721/*722* Check for -Xlp:gc: and handle it if necessary723*/724xlpGCIndex = FIND_AND_CONSUME_ARG(STARTSWITH_MATCH, "-Xlp:gcmetadata:", NULL);725726if (-1 != xlpGCIndex) {727UDATA gcmetadataPageSize = 0;728UDATA gcmetadataPageFlags = J9PORT_VMEM_PAGE_FLAG_NOT_USED;729UDATA *pageSizes;730UDATA *pageFlags;731bool found = false;732/*733* Parse sub options for -Xlp:gc:734*/735xlpErrorState = xlpSubOptionsParser(vm, xlpGCIndex, &xlpError, &gcmetadataPageSize, &gcmetadataPageFlags, NULL, NULL);736737if (XLP_NO_ERROR != xlpErrorState) {738goto _reportXlpError;739}740741if (xlpError.extraCommaWarning) {742/* print extra comma ignored warning */743j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_EXTRA_COMMA);744}745746/*747* Update values in case of exact match only748*/749pageSizes = j9vmem_supported_page_sizes();750pageFlags = j9vmem_supported_page_flags();751752for (UDATA pageIndex = 0; 0 != pageSizes[pageIndex]; ++pageIndex) {753if ((pageSizes[pageIndex] == gcmetadataPageSize) && (pageFlags[pageIndex] == gcmetadataPageFlags)) {754found = true;755extensions->gcmetadataPageSize = gcmetadataPageSize;756extensions->gcmetadataPageFlags = gcmetadataPageFlags;757break;758}759}760761if (!found) {762const char *oldQualifier, *newQualifier;763UDATA oldSize = gcmetadataPageSize;764UDATA newSize = extensions->gcmetadataPageSize;765const char *oldPageType = getPageTypeStringWithLeadingSpace(oldSize);766const char *newPageType = getPageTypeStringWithLeadingSpace(newSize);767qualifiedSize(&oldSize, &oldQualifier);768qualifiedSize(&newSize, &newQualifier);769770j9nls_printf(PORTLIB, J9NLS_INFO, J9NLS_GC_OPTIONS_XLP_PAGE_NOT_SUPPORTED, "gcmetadata", oldSize, oldQualifier, oldPageType, newSize, newQualifier, newPageType);771}772}773774_reportXlpError:775/* If error occurred during parsing of -Xlp options, report it here. */776if (XLP_NO_ERROR != xlpErrorState) {777/* parsing failed, return false */778rc = false;779780switch(xlpErrorState) {781case XLP_OPTION_NOT_SUPPORTED:782j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_SYSTEM_CONFIG_OPTION_NOT_SUPPORTED, xlpError.xlpOptionErrorString);783break;784case XLP_MEM_NAN:785j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xlp");786break;787case XLP_MEM_OVERFLOW:788j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xlp");789break;790case XLP_PAGE_SIZE_INCORRECT:791j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_INCORRECT_MEMORY_SIZE, "-Xlp:objectheap:pagesize=<size>");792break;793case XLP_INCOMPLETE_OPTION:794j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_INCOMPLETE_OPTION, xlpError.xlpOptionErrorString, xlpError.xlpMissingOptionString);795break;796case XLP_LARGE_PAGE_NOT_SUPPORTED:797{798const char *qualifier = NULL;799const char *pageType = NULL;800UDATA pageSize = requestedPageSize;801qualifiedSize(&pageSize, &qualifier);802if (0 == (J9PORT_VMEM_PAGE_FLAG_NOT_USED & requestedPageFlags)) {803pageType = getPageTypeString(requestedPageFlags);804}805if (NULL == pageType) {806j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_LARGE_PAGE_NOT_SUPPORTED, pageSize, qualifier);807} else {808j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_LARGE_PAGE_NOT_SUPPORTED_WITH_PAGETYPE, pageSize, qualifier, pageType);809}810811break;812}813case XLP_PARAMETER_NOT_RECOGNIZED:814j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_UNRECOGNIZED_OPTION, xlpError.xlpOptionErrorStringSize, xlpError.xlpOptionErrorString);815break;816default:817j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_XLP_PARSING_ERROR);818break;819}820} else {821rc = true;822}823824return rc;825}826/**827* Consume Sovereign arguments.828*829* @return 1 if parsing was successful, 0 otherwise.830*/831static UDATA832gcParseSovereignArguments(J9JavaVM *vm)833{834MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);835IDATA result = 0;836UDATA inputValue = 0;837#if defined(J9VM_GC_LARGE_OBJECT_AREA)838IDATA groupIndex = 0;839IDATA indexMeter = 0;840#endif /* J9VM_GC_LARGE_OBJECT_AREA */841const char *optionFound = NULL;842IDATA index = -1;843PORT_ACCESS_FROM_JAVAVM(vm);844845if (!gcParseXlpOption(vm)) {846goto _error;847}848849/* Check for explicit specification of GC policy */850gcParseXgcpolicy(extensions);851852if (-1 != option_set_pair(vm, "-Xenableexplicitgc", "-Xdisableexplicitgc", &index)) {853extensions->disableExplicitGC = (index != 0);854}855856#if defined(J9VM_GC_MODRON_COMPACTION)857/* These arguments aren't done as mutual exclusive pairs because their effects are not opposites */858if (-1 != option_set(vm, "-Xnocompactexplicitgc", EXACT_MATCH)) {859extensions->nocompactOnSystemGC = 1;860extensions->compactOnSystemGC = 0;861}862863if (-1 != option_set(vm, "-Xcompactexplicitgc", EXACT_MATCH)) {864extensions->compactOnSystemGC = 1;865}866867/* These arguments aren't done as mutual exclusive pairs because their effects are not opposites */868if (-1 != option_set(vm, "-Xcompactgc", EXACT_MATCH)) {869extensions->compactOnGlobalGC = 1;870extensions->compactOnSystemGC = 1;871}872873if (-1 != option_set(vm, "-Xnocompactgc", EXACT_MATCH)) {874extensions->noCompactOnGlobalGC = 1;875}876877if (-1 != option_set_pair(vm, "-Xnopartialcompactgc", "-Xpartialcompactgc", &index)) {878/* Incremental compaction is no longer supported.879* Options are supported but deprecated.880*/881}882#endif /* J9VM_GC_MODRON_COMPACTION */883884result = option_set_to_opt_percent(vm, "-Xminf", &index, EXACT_MEMORY_MATCH, &extensions->heapFreeMinimumRatioMultiplier);885if (OPTION_OK != result) {886if (OPTION_MALFORMED == result) {887j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xminf");888} else {889j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xminf", 0.0, 1.0);890}891goto _error;892}893result = option_set_to_opt_percent(vm, "-Xmaxf", &index, EXACT_MEMORY_MATCH, &extensions->heapFreeMaximumRatioMultiplier);894if (OPTION_OK != result) {895if (OPTION_MALFORMED == result) {896j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxf");897} else {898j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmaxf", 0.0, 1.0);899}900goto _error;901}902result = option_set_to_opt(vm, "-Xmine", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionMinimumSize);903if (OPTION_OK != result) {904if (OPTION_MALFORMED == result) {905j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmine");906} else {907j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xmine");908}909goto _error;910}911result = option_set_to_opt(vm, "-Xmaxe", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionMaximumSize);912if (OPTION_OK != result) {913if (OPTION_MALFORMED == result) {914j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxe");915} else {916j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xmaxe");917}918goto _error;919}920921922923result = option_set_to_opt_percent(vm, "-Xmaxt", &index, EXACT_MEMORY_MATCH, &extensions->heapExpansionGCRatioThreshold._valueSpecified);924if (OPTION_OK != result) {925if (OPTION_MALFORMED == result) {926j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmaxt");927} else {928j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmaxt", 0.0, 1.0);929}930goto _error;931} else if (-1 != index) {932extensions->heapExpansionGCRatioThreshold._wasSpecified = true;933}934935936937result = option_set_to_opt_percent(vm, "-Xmint", &index, EXACT_MEMORY_MATCH, &extensions->heapContractionGCRatioThreshold._valueSpecified);938if (OPTION_OK != result) {939if (OPTION_MALFORMED == result) {940j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xmint");941} else {942j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xmint", 0.0, 1.0);943}944goto _error;945} else if (-1 != index) {946extensions->heapContractionGCRatioThreshold._wasSpecified = true;947}948949950if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, VMOPT_XGCTHREADS, NULL)) {951result = option_set_to_opt_integer(vm, VMOPT_XGCTHREADS, &index, EXACT_MEMORY_MATCH, &extensions->gcThreadCount);952if (OPTION_OK != result) {953if (OPTION_MALFORMED == result) {954j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XGCTHREADS);955} else {956j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XGCTHREADS);957}958goto _error;959}960961if(0 == extensions->gcThreadCount) {962j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, VMOPT_XGCTHREADS, (UDATA)0);963goto _error;964}965966extensions->gcThreadCountForced = true;967}968969/* Handling VMOPT_XGCMAXTHREADS is equivalent to VMOPT_XGCTHREADS (above), except it sets gcThreadCountForced to false rather than true. */970if (-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, VMOPT_XGCMAXTHREADS, NULL)) {971result = option_set_to_opt_integer(vm, VMOPT_XGCMAXTHREADS, &index, EXACT_MEMORY_MATCH, &extensions->gcThreadCount);972if (OPTION_OK != result) {973if (OPTION_MALFORMED == result) {974j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XGCMAXTHREADS);975} else {976j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XGCMAXTHREADS);977}978goto _error;979}980981if (0 == extensions->gcThreadCount) {982j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, VMOPT_XGCMAXTHREADS, (UDATA)0);983goto _error;984}985986extensions->gcThreadCountForced = false;987}988989if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xgcworkpackets", NULL)) {990result = option_set_to_opt_integer(vm, "-Xgcworkpackets", &index, EXACT_MEMORY_MATCH, &extensions->workpacketCount);991if (OPTION_OK != result) {992if (OPTION_MALFORMED == result) {993j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xgcworkpackets");994} else {995j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xgcworkpackets");996}997goto _error;998}999if(0 == extensions->workpacketCount) {1000j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, "-Xgcworkpackets", (UDATA)0);1001goto _error;1002}1003}10041005#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)1006if (-1 != option_set_group(vm, optionGroupClassGC, &index)) {1007switch (index) {1008case optionGroupClassGC_index_noclassgc:1009extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_NEVER;1010break;10111012case optionGroupClassGC_index_classgc:1013extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_ON_CLASS_LOADER_CHANGES;1014break;10151016case optionGroupClassGC_index_alwaysclassgc:1017extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_ALWAYS;1018break;1019}1020extensions->dynamicClassUnloadingSet = true;1021}1022#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */1023if (-1 != option_set_pair(vm, "-Xdisablestringconstantgc", "-Xenablestringconstantgc", &index)) {1024extensions->collectStringConstants = (0 != index);1025}10261027#if defined(OMR_GC_MODRON_CONCURRENT_MARK)1028result = option_set_to_opt_integer(vm, VMOPT_XCONCURRENTBACKGROUND, &index, EXACT_MEMORY_MATCH, &extensions->concurrentBackground);1029if (OPTION_OK != result) {1030if (OPTION_MALFORMED == result) {1031j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, VMOPT_XCONCURRENTBACKGROUND);1032} else {1033j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, VMOPT_XCONCURRENTBACKGROUND);1034}1035goto _error;1036}10371038result = option_set_to_opt_integer(vm, "-Xconcurrentlevel", &index, EXACT_MEMORY_MATCH, &extensions->concurrentLevel);1039if (OPTION_OK != result) {1040if (OPTION_MALFORMED == result) {1041j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconcurrentlevel");1042} else {1043j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xconcurrentlevel");1044}1045goto _error;1046}10471048if (0 == extensions->concurrentLevel) {1049/* LIR 1396: -Xconcurrentlevel0 should mean -Xgc:noConcurrentMark. */1050extensions->configurationOptions._forceOptionConcurrentMark = true;1051extensions->concurrentMark = false;1052}10531054result = option_set_to_opt(vm, "-Xconcurrentslack", &index, EXACT_MEMORY_MATCH, &extensions->concurrentSlack);1055if (OPTION_OK != result) {1056if (OPTION_MALFORMED == result) {1057j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconcurrentslack");1058} else {1059j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-Xconcurrentslack");1060}1061goto _error;1062}10631064#endif /* OMR_GC_MODRON_CONCURRENT_MARK */10651066#if defined(J9VM_GC_LARGE_OBJECT_AREA)1067/* parse this before -Xloamaximum, as -Xloamaximum0 will turn loa off */1068if (-1 != option_set_pair(vm, "-Xnoloa", "-Xloa", &index)) {1069extensions->configurationOptions._forceOptionLargeObjectArea = true;1070extensions->largeObjectArea = (1 == index);1071}10721073if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloainitial", NULL)) {1074result = option_set_to_opt_percent(vm, "-Xloainitial", &index, EXACT_MEMORY_MATCH, &inputValue);1075if (OPTION_OK != result) {1076if (OPTION_MALFORMED == result) {1077j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloainitial");1078} else {1079j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloainitial", 0.0, 0.95);1080}1081goto _error;1082}1083if (inputValue > 95) {1084j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloainitial", 0.0, 0.95);1085goto _error;1086}1087extensions->largeObjectAreaInitialRatio = (double)inputValue / (double)100;1088}10891090if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloamaximum", NULL)) {1091result = option_set_to_opt_percent(vm, "-Xloamaximum", &index, EXACT_MEMORY_MATCH, &inputValue);1092if (OPTION_OK != result) {1093if (OPTION_MALFORMED == result) {1094j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloamaximum");1095} else {1096j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloamaximum", 0.0, 0.95);1097}1098goto _error;1099}1100if (inputValue > 95) {1101j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloamaximum", 0.0, 0.95);1102goto _error;1103}1104extensions->largeObjectAreaMaximumRatio = (double)inputValue / (double)100;1105if(0 == extensions->largeObjectAreaMaximumRatio) {1106/* Implies -Xnoloa */1107extensions->configurationOptions._forceOptionLargeObjectArea = true;1108extensions->largeObjectArea = false;1109}1110}11111112if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloaminimum", NULL)) {1113result = option_set_to_opt_percent(vm, "-Xloaminimum", &index, EXACT_MEMORY_MATCH, &inputValue);1114if (OPTION_OK != result) {1115if (OPTION_MALFORMED == result) {1116j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xloaminimum");1117} else {1118j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloaminimum", 0.0, 0.95);1119}1120goto _error;1121}1122if (inputValue > 95) {1123j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-Xloaminimum", 0.0, 0.95);1124goto _error;1125}1126extensions->largeObjectAreaMinimumRatio = (double)inputValue / (double)100;1127if(-1 == FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xloainitial", NULL)) {1128/* -Xloainitial wasn't specified, so we need to override it to match the -Xloaminimum we've just set */1129extensions->largeObjectAreaInitialRatio = extensions->largeObjectAreaMinimumRatio;1130}1131}11321133indexMeter = option_set_group(vm, optionGroupConMeter, &groupIndex);1134if (-1 != indexMeter) {1135switch(groupIndex) {1136case optionGroupConMeter_index_soa:1137extensions->concurrentMetering = MM_GCExtensions::METER_BY_SOA;1138break;11391140case optionGroupConMeter_index_loa:1141extensions->concurrentMetering = MM_GCExtensions::METER_BY_LOA;1142break;11431144case optionGroupConMeter_index_dynamic:1145extensions->concurrentMetering = MM_GCExtensions::METER_DYNAMIC;1146break;1147}1148}11491150/* Try to match SOV alternative syntax of -Xconmeter(0|1|2) */1151if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xconmeter", NULL)) {1152result = option_set_to_opt_integer(vm, "-Xconmeter", &index, EXACT_MEMORY_MATCH, &inputValue);1153if (OPTION_OK != result) {1154j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-Xconmeter");1155goto _error;1156}11571158switch(inputValue) {1159case 0:1160extensions->concurrentMetering = MM_GCExtensions::METER_BY_SOA;1161break;1162case 1:1163extensions->concurrentMetering = MM_GCExtensions::METER_BY_LOA;1164break;1165case 2:1166extensions->concurrentMetering = MM_GCExtensions::METER_DYNAMIC;1167break;1168default:1169j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_INTEGER_OUT_OF_RANGE, "-Xconmeter", (UDATA)0, (UDATA)2);1170goto _error;1171break;1172}1173}11741175#endif /* J9VM_GC_LARGE_OBJECT_AREA) */11761177/* If user has specified any of the following SOV options then we just silently ignore them1178*1179* -Xparroot1180* -XloratioN1181* -XloincrN1182* -XlorsrvN1183* All these options (except -Xparoot) take a float value between 0 and 1.0.1184*1185*/1186option_set(vm, "-Xparroot", EXACT_MATCH);1187option_set_to_opt_percent(vm, "-Xloratio", &index, EXACT_MEMORY_MATCH, &inputValue);1188option_set_to_opt_percent(vm, "-Xloincr", &index, EXACT_MEMORY_MATCH, &inputValue);1189option_set_to_opt_percent(vm, "-Xlorsrv", &index, EXACT_MEMORY_MATCH, &inputValue);11901191/* options to enable/disable excessivegc */1192if (-1 != option_set_pair(vm, "-Xdisableexcessivegc", "-Xenableexcessivegc", &index)) {1193extensions->excessiveGCEnabled._wasSpecified = true;1194extensions->excessiveGCEnabled._valueSpecified = (1 == index) ? true : false;1195}11961197if((-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-XSoftRefThreshold", NULL))) {1198optionFound = "-XSoftRefThreshold";1199} else {1200if((-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-Xsoftrefthreshold", NULL))) {1201optionFound = "-Xsoftrefthreshold";1202}1203}12041205if (NULL != optionFound) {1206result = option_set_to_opt_integer(vm, optionFound, &index, EXACT_MEMORY_MATCH, &extensions->maxSoftReferenceAge);1207if (OPTION_OK != result) {1208if (OPTION_MALFORMED == result) {1209j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, optionFound);1210} else {1211j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, optionFound);1212}1213goto _error;1214}12151216if ((IDATA)extensions->maxSoftReferenceAge < 0) {1217j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, optionFound);1218goto _error;1219}1220}12211222if(-1 != FIND_ARG_IN_VMARGS(EXACT_MEMORY_MATCH, "-XX:stringTableListToTreeThreshold=", NULL)) {1223UDATA threshold = 0;1224result = option_set_to_opt_integer(vm, "-XX:stringTableListToTreeThreshold=", &index, EXACT_MEMORY_MATCH, &threshold);1225if (OPTION_OK != result) {1226if (OPTION_MALFORMED == result) {1227j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, "-XX:stringTableListToTreeThreshold=");1228} else {1229j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, "-XX:stringTableListToTreeThreshold=");1230}1231goto _error;1232}12331234if (threshold <= U_32_MAX) {1235extensions->_stringTableListToTreeThreshold = (U_32)threshold;1236} else {1237extensions->_stringTableListToTreeThreshold = U_32_MAX;1238}1239}12401241return 1;12421243_error:1244return 0;12451246}12471248static UDATA1249gcParseXXArguments(J9JavaVM *vm)1250{1251MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);12521253{1254IDATA heapManagementMXBeanCompatibilityIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+HeapManagementMXBeanCompatibility", NULL);1255IDATA noHheapManagementMXBeanCompatibilityIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-HeapManagementMXBeanCompatibility", NULL);1256if (heapManagementMXBeanCompatibilityIndex != noHheapManagementMXBeanCompatibilityIndex) {1257/* At least one option is set. Find the right most one. */1258if (heapManagementMXBeanCompatibilityIndex > noHheapManagementMXBeanCompatibilityIndex) {1259extensions->_HeapManagementMXBeanBackCompatibilityEnabled = true;1260} else {1261extensions->_HeapManagementMXBeanBackCompatibilityEnabled = false;1262}1263}1264}12651266{1267IDATA useGCStartupHintsIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+UseGCStartupHints", NULL);1268IDATA noUseGCStartupHintsIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-UseGCStartupHints", NULL);1269if (useGCStartupHintsIndex != noUseGCStartupHintsIndex) {1270/* At least one option is set. Find the right most one. */1271if (useGCStartupHintsIndex > noUseGCStartupHintsIndex) {1272extensions->useGCStartupHints = true;1273} else {1274extensions->useGCStartupHints = false;1275}1276}1277}12781279{1280IDATA alwaysPreTouchIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+AlwaysPreTouch", NULL);1281IDATA notAlwaysPreTouchIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-AlwaysPreTouch", NULL);1282if (alwaysPreTouchIndex != notAlwaysPreTouchIndex) {1283/* At least one option is set. Find the right most one. */1284if (alwaysPreTouchIndex > notAlwaysPreTouchIndex) {1285extensions->pretouchHeapOnExpand = true;1286} else {1287extensions->pretouchHeapOnExpand = false;1288}1289}1290}12911292{1293IDATA adaptiveGCThreadingIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:+AdaptiveGCThreading", NULL);1294IDATA noAdaptiveGCThreadingIndex = FIND_ARG_IN_VMARGS(EXACT_MATCH, "-XX:-AdaptiveGCThreading", NULL);1295if (adaptiveGCThreadingIndex != noAdaptiveGCThreadingIndex) {1296/* At least one option is set. Find the right most one. */1297if (adaptiveGCThreadingIndex > noAdaptiveGCThreadingIndex) {1298extensions->adaptiveGCThreading = true;1299} else {1300extensions->adaptiveGCThreading = false;1301}1302}1303}13041305return 1;1306}13071308/**1309* Wrapper for scan_udata, that provides readable error messages.1310* @param cursor address of the pointer to the string to parse for the udata1311* @param value address of the storage for the udata to be read1312* @param argName string containing the argument name to be used in error reporting1313* @return true if parsing was successful, false otherwise.1314*/1315bool1316scan_udata_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName)1317{1318UDATA result;1319PORT_ACCESS_FROM_JAVAVM(javaVM);13201321if (0 != (result = scan_udata(cursor, value))) {1322if (1 == result) {1323j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1324} else {1325j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1326}1327return false;1328}13291330// TODO: should we add a delimiter check here?1331return true;1332}13331334/**1335* Wrapper for scan_udata, that provides readable error messages.1336* @param cursor address of the pointer to the string to parse for the udata1337* @param value address of the storage for the udata to be read1338* @param argName string containing the argument name to be used in error reporting1339* @return true if parsing was successful, false otherwise.1340*/1341bool1342scan_u32_helper(J9JavaVM *javaVM, char **cursor, U_32 *value, const char *argName)1343{1344UDATA result;1345PORT_ACCESS_FROM_JAVAVM(javaVM);13461347if (0 != (result = scan_u32(cursor, value))) {1348if (1 == result) {1349j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1350} else {1351j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1352}1353return false;1354}13551356// TODO: should we add a delimiter check here?1357return true;1358}13591360/**1361* Wrapper for scan_long, that provides readable error messages.1362* @param cursor address of the pointer to the string to parse for the u_641363* @param value address of the storage for the U_64 to be read1364* @param argName string containing the argument name to be used in error reporting1365* @return true if parsing was successful, false otherwise.1366*/1367bool1368scan_u64_helper(J9JavaVM *javaVM, char **cursor, U_64 *value, const char *argName)1369{1370U_64 result;1371PORT_ACCESS_FROM_JAVAVM(javaVM);13721373if (0 != (result = scan_u64(cursor, value))) {1374if (1 == result) {1375j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1376} else {1377j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1378}1379return false;1380}13811382// TODO: should we add a delimiter check here?1383return true;1384}13851386/**1387* Wrapper for scan_hex, that provides readable error messages.1388* @param cursor address of the pointer to the string to parse for the hex value1389* @param value address of the storage for the hex value to be read1390* @param argName string containing the argument name to be used in error reporting1391* @return true if parsing was successful, false otherwise.1392*/1393bool1394scan_hex_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName)1395{1396UDATA result;1397PORT_ACCESS_FROM_JAVAVM(javaVM);13981399if (0 != (result = scan_hex(cursor, value))) {1400if (1 == result) {1401j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1402} else {1403j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1404}1405return false;1406}14071408// TODO: should we add a delimiter check here?1409return true;1410}14111412/**1413* Wrapper for scan_udata_memory_size, that provides readable error messages.1414* @param cursor address of the pointer to the string to parse for the udata.1415* @param value address of the storage for the udata to be read.1416* @param argName string containing the argument name to be used in error reporting.1417* @return true if parsing was successful, false otherwise.1418*/1419bool1420scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, uintptr_t *value, const char *argName)1421{1422PORT_ACCESS_FROM_JAVAVM(javaVM);1423uintptr_t result = scan_udata_memory_size(cursor, value);14241425/* Report Errors */1426if (1 == result) {1427j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1428} else if (2 == result) {1429j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1430}14311432return 0 == result;1433}14341435/**1436* Wrapper for scan_u64_helper, that provides readable error messages.1437* @param cursor address of the pointer to the string to parse for the udata.1438* @param value address of the storage for the udata to be read.1439* @param argName string containing the argument name to be used in error reporting.1440* @return true if parsing was successful, false otherwise.1441*/1442bool1443scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, uint64_t *value, const char *argName)1444{1445PORT_ACCESS_FROM_JAVAVM(javaVM);1446uintptr_t result = scan_u64_memory_size(cursor, value);14471448/* Report Errors */1449if (1 == result) {1450j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);1451} else if (2 == result) {1452j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);1453}14541455return 0 == result;1456}14571458/**1459* Initialize GC fields with values provided by user.1460* Record the parameter in the appropriate structure and record which1461* parameters were specified by the user.1462* @param memoryParameters pointer to the array of parameters to be set1463*/1464jint1465gcParseCommandLineAndInitializeWithValues(J9JavaVM *vm, IDATA *memoryParameters)1466{1467MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);1468UDATA optionValue = 0;1469IDATA index = 0;1470IDATA result = 0;1471UDATA userNewSpaceSize = 0;1472UDATA userOldSpaceSize = 0;1473char *xGCOptions = NULL;1474char *xxGCOptions = NULL;1475IDATA xGCColonIndex = 0;1476IDATA xxGCColonIndex = 0;1477J9VMInitArgs *vmArgs = vm->vmArgsArray;14781479PORT_ACCESS_FROM_JAVAVM(vm);14801481/* Parse the command line1482* Order is important for parameters that match as substrings (-Xmrx/-Xmr)1483*/1484{1485bool enableOriginalJDK8HeapSizeCompatibilityOption = false;1486/* only parse VMOPT_XXENABLEORIGINALJDK8HEAPSIZECOMPATIBILITY option for Java 8 and below */1487if (J2SE_18 >= J2SE_VERSION(vm)) {14881489IDATA enabled = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXENABLEORIGINALJDK8HEAPSIZECOMPATIBILITY, NULL);1490IDATA disabled = FIND_AND_CONSUME_ARG(EXACT_MATCH, VMOPT_XXDISABLEORIGINALJDK8HEAPSIZECOMPATIBILITY, NULL);1491if (enabled > disabled) {1492enableOriginalJDK8HeapSizeCompatibilityOption = true;1493}1494}1495/* set default max heap for Java */1496extensions->computeDefaultMaxHeapForJava(enableOriginalJDK8HeapSizeCompatibilityOption);1497}1498result = option_set_to_opt(vm, OPT_XMCA, &index, EXACT_MEMORY_MATCH, &vm->ramClassAllocationIncrement);1499if (OPTION_OK != result) {1500goto _error;1501}1502memoryParameters[opt_Xmca] = index;15031504result = option_set_to_opt(vm, OPT_XMCO, &index, EXACT_MEMORY_MATCH, &vm->romClassAllocationIncrement);1505if (OPTION_OK != result) {1506goto _error;1507}1508memoryParameters[opt_Xmco] = index;15091510result = option_set_to_opt(vm, OPT_XMCRS, &index, EXACT_MEMORY_MATCH, &optionValue);1511if (OPTION_OK != result) {1512goto _error;1513}15141515#if defined(OMR_GC_COMPRESSED_POINTERS)1516if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {1517if (-1 != index) {1518extensions->suballocatorInitialSize = optionValue;1519}1520if(0 == extensions->suballocatorInitialSize) {1521j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_MUST_BE_ABOVE, OPT_XMCRS, (UDATA)0);1522return JNI_EINVAL;1523}1524#define FOUR_GB ((UDATA)4 * 1024 * 1024 * 1024)1525if(extensions->suballocatorInitialSize >= FOUR_GB) {1526j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, OPT_XMCRS);1527return JNI_EINVAL;1528}1529}1530#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */15311532memoryParameters[opt_Xmcrs] = index;15331534result = option_set_to_opt(vm, OPT_XMX, &index, EXACT_MEMORY_MATCH, &extensions->memoryMax);1535if (OPTION_OK != result) {1536goto _error;1537}1538memoryParameters[opt_Xmx] = index;15391540result = option_set_to_opt(vm, OPT_SOFTMX, &index, EXACT_MEMORY_MATCH, &extensions->softMx);1541if (OPTION_OK != result) {1542goto _error;1543}1544memoryParameters[opt_Xsoftmx] = index;15451546/* -Xmns sets both newSpaceSize and minNewSpaceSize */1547result = option_set_to_opt(vm, OPT_XMNS, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmns._valueSpecified);1548if (OPTION_OK != result) {1549goto _error;1550}1551memoryParameters[opt_Xmns] = index;1552if (-1 != memoryParameters[opt_Xmns]) {1553extensions->userSpecifiedParameters._Xmns._wasSpecified = true;1554extensions->newSpaceSize = extensions->userSpecifiedParameters._Xmns._valueSpecified;1555extensions->minNewSpaceSize = extensions->newSpaceSize;1556}15571558result = option_set_to_opt(vm, OPT_XMNX, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmnx._valueSpecified);1559if (OPTION_OK != result) {1560goto _error;1561}1562memoryParameters[opt_Xmnx] = index;1563if (-1 != memoryParameters[opt_Xmnx]) {1564extensions->userSpecifiedParameters._Xmnx._wasSpecified = true;1565extensions->maxNewSpaceSize = extensions->userSpecifiedParameters._Xmnx._valueSpecified;1566}15671568result = option_set_to_opt(vm, OPT_XMOI, &index, EXACT_MEMORY_MATCH, &extensions->allocationIncrement);1569if (OPTION_OK != result) {1570goto _error;1571}1572memoryParameters[opt_Xmoi] = index;1573extensions->allocationIncrementSetByUser = (index != -1);15741575/* -Xmos sets both oldSpaceSize and minOldSpaceSize */1576result = option_set_to_opt(vm, OPT_XMOS, &index, EXACT_MEMORY_MATCH, &extensions->oldSpaceSize);1577if (OPTION_OK != result) {1578goto _error;1579}1580memoryParameters[opt_Xmos] = index;1581if (-1 != memoryParameters[opt_Xmos]) {1582extensions->minOldSpaceSize = extensions->oldSpaceSize;1583}15841585result = option_set_to_opt(vm, OPT_XMOX, &index, EXACT_MEMORY_MATCH, &extensions->maxOldSpaceSize);1586if (OPTION_OK != result) {1587goto _error;1588}1589memoryParameters[opt_Xmox] = index;15901591result = option_set_to_opt(vm, OPT_XMS, &index, EXACT_MEMORY_MATCH, &extensions->initialMemorySize);1592if (OPTION_OK != result) {1593goto _error;1594}1595memoryParameters[opt_Xms] = index;15961597#if defined(J9VM_GC_MODRON_SCAVENGER)1598result = option_set_to_opt(vm, OPT_XMRX, &index, EXACT_MEMORY_MATCH, &optionValue);1599if (OPTION_OK != result) {1600goto _error;1601}1602memoryParameters[opt_Xmrx] = index;1603if(memoryParameters[opt_Xmrx] != -1) {1604extensions->rememberedSet.setMaxSize(optionValue);1605}16061607result = option_set_to_opt(vm, OPT_XMR, &index, EXACT_MEMORY_MATCH, &optionValue);1608if (OPTION_OK != result) {1609goto _error;1610}1611memoryParameters[opt_Xmr] = index;1612if (memoryParameters[opt_Xmr] != -1) {1613extensions->rememberedSet.setGrowSize(optionValue);1614}1615#endif /* J9VM_GC_MODRON_SCAVENGER */16161617result = option_set_to_opt(vm, OPT_XMN, &index, EXACT_MEMORY_MATCH, &extensions->userSpecifiedParameters._Xmn._valueSpecified);1618if (OPTION_OK != result) {1619goto _error;1620}1621memoryParameters[opt_Xmn] = index;1622if (memoryParameters[opt_Xmn] != -1) {1623extensions->userSpecifiedParameters._Xmn._wasSpecified = true;1624userNewSpaceSize = extensions->userSpecifiedParameters._Xmn._valueSpecified;1625/* check that -Xmns/-Xmnx AND -Xmn weren't specified */1626if (memoryParameters[opt_Xmns] != -1) {1627j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMN, OPT_XMNS);1628return JNI_EINVAL;1629}1630if (memoryParameters[opt_Xmnx] != -1) {1631j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMN, OPT_XMNX);1632return JNI_EINVAL;1633}16341635extensions->minNewSpaceSize = userNewSpaceSize;1636extensions->newSpaceSize = userNewSpaceSize;1637extensions->maxNewSpaceSize = userNewSpaceSize;16381639/* Hack table to appear that -Xmns and -Xmnx _were_ specified */1640memoryParameters[opt_Xmns] = memoryParameters[opt_Xmn];1641memoryParameters[opt_Xmnx] = memoryParameters[opt_Xmn];1642}16431644result = option_set_to_opt(vm, OPT_XMO, &index, EXACT_MEMORY_MATCH, &userOldSpaceSize);1645if (OPTION_OK != result) {1646goto _error;1647}1648memoryParameters[opt_Xmo] = index;1649if (memoryParameters[opt_Xmo] != -1) {1650/* check that -Xmos/-Xmox AND -Xmo weren't specified */1651if(memoryParameters[opt_Xmox] != -1) {1652j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMO, OPT_XMOX);1653return JNI_EINVAL;1654}1655if(memoryParameters[opt_Xmos] != -1) {1656j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_EXCLUSIVE, OPT_XMO, OPT_XMOS);1657return JNI_EINVAL;1658}16591660extensions->minOldSpaceSize = userOldSpaceSize;1661extensions->oldSpaceSize = userOldSpaceSize;1662extensions->maxOldSpaceSize = userOldSpaceSize;16631664/* Hack table to appear that -Xmos and -Xmox _were_ specified */1665memoryParameters[opt_Xmos] = memoryParameters[opt_Xmo];1666memoryParameters[opt_Xmox] = memoryParameters[opt_Xmo];1667}16681669result = option_set_to_opt_double(vm, OPT_XXMAXRAMPERCENT, &index, EXACT_MEMORY_MATCH, &extensions->maxRAMPercent);1670if (OPTION_OK != result) {1671goto _error;1672}1673memoryParameters[opt_maxRAMPercent] = index;1674if (memoryParameters[opt_maxRAMPercent] != -1) {1675if ((extensions->maxRAMPercent < 0.0) || (extensions->maxRAMPercent > 100.0)) {1676j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-XX:MaxRAMPercentage", 0.0, 100.0);1677return JNI_EINVAL;1678}1679}16801681result = option_set_to_opt_double(vm, OPT_XXINITIALRAMPERCENT, &index, EXACT_MEMORY_MATCH, &extensions->initialRAMPercent);1682if (OPTION_OK != result) {1683goto _error;1684}1685memoryParameters[opt_initialRAMPercent] = index;1686if (memoryParameters[opt_initialRAMPercent] != -1) {1687if ((extensions->initialRAMPercent < 0.0) || (extensions->initialRAMPercent > 100.0)) {1688j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_PERCENT_OUT_OF_RANGE, "-XX:InitialRAMPercentage", 0.0, 100.0);1689return JNI_EINVAL;1690}1691}16921693/* Parse the option to disable NUMA-awareness. This is parsed on all platforms but only Balanced currently does anything1694* with the result.1695* Note that this option does NOT disable heap interleaving since that is considered a harmless and "passive" optimization.1696*/1697index = option_set(vm, OPT_NUMA_NONE, EXACT_MATCH);1698if (-1 != index) {1699#if defined(J9VM_GC_VLHGC) || defined(J9VM_GC_GENERATIONAL)1700/* this is currently the same behaviour as our internal -Xgc:nonuma option */1701extensions->_numaManager.shouldEnablePhysicalNUMA(false);1702extensions->numaForced = true;1703#endif /* defined(J9VM_GC_VLHGC) || defined(J9VM_GC_GENERATIONAL) */1704}1705/* Since the user is not specifying a value, ensure that -Xmdx is set to the same value1706* as -Xmx. It does not matter whether -Xmx was specified or not.1707*/1708extensions->maxSizeDefaultMemorySpace = extensions->memoryMax;17091710/* Parse for recognized Sovereign command line options. Any duplication with an Xgc option1711* will be overwritten. This currently must be done after check for resource management so we can1712* easily disallow -Xgcpolicy options.1713*/1714if (0 == gcParseSovereignArguments(vm)) {1715return JNI_EINVAL;1716}17171718/* parse -XX: option that logicially belong to GC */1719if (0 == gcParseXXArguments(vm)) {1720return JNI_EINVAL;1721}17221723/* Parse XXgc options */1724xxGCColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XXGC_COLON, NULL );1725while (xxGCColonIndex >= 0) {1726CONSUME_ARG(vmArgs, xxGCColonIndex);1727GET_OPTION_VALUE( xxGCColonIndex, ':', &xxGCOptions);17281729/* Parse xxGCOptions arguments (if any) */1730if (NULL != xxGCOptions) {1731jint retCode;1732if (JNI_OK != (retCode = gcParseXXgcArguments(vm, xxGCOptions))) {1733return retCode;1734}1735}1736xxGCColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XXGC_COLON, NULL, xxGCColonIndex);1737}17381739xGCColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XGC_COLON, NULL );1740while (xGCColonIndex >= 0) {1741CONSUME_ARG(vmArgs, xGCColonIndex);1742GET_OPTION_VALUE( xGCColonIndex, ':', &xGCOptions);17431744/* Parse xGCOptions arguments (if any) */1745if (xGCOptions != NULL) {1746jint retCode;1747if (JNI_OK != (retCode = gcParseXgcArguments(vm, xGCOptions))) {1748return retCode;1749}1750} else {1751return JNI_OK;1752}17531754xGCColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD(STARTSWITH_MATCH, OPT_XGC_COLON, NULL, xGCColonIndex);1755}17561757#if defined(J9VM_GC_GENERATIONAL)1758/*1759* If Split Heap is requested, -Xms, -Xmns and -Xmos will be overwritten1760* so ignore them even specified1761*/1762if (extensions->enableSplitHeap) {1763memoryParameters[opt_Xms] = -1;1764memoryParameters[opt_Xmns] = -1;1765memoryParameters[opt_Xmos] = -1;1766}1767#endif /* defined(J9VM_GC_GENERATIONAL) */17681769return JNI_OK;17701771_error:1772char *errorString = VMARGS_OPTION(index);17731774/* show something meaningful about why parsing failed */1775switch(result) {1776case OPTION_MALFORMED:1777j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_MALFORMED, errorString);1778break;1779case OPTION_OVERFLOW:1780j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_OVERFLOW, errorString);1781break;1782case OPTION_ERROR:1783j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_ERROR, errorString);1784break;1785case OPTION_BUFFER_OVERFLOW:1786j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTION_OVERFLOW, errorString);1787break;1788default:1789scan_failed(PORTLIB, "GC", errorString);1790break;1791}17921793return JNI_EINVAL;1794}17951796bool1797gcParseTGCCommandLine(J9JavaVM *vm)1798{1799bool parseSuccess = true;1800MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);18011802/* note that realtime currently doesn't support TGC so only standard and VLHGC should try to consume TGC arguments */1803if (extensions->isStandardGC() || extensions->isVLHGC() || extensions->isSegregatedHeap()) {1804#if defined(J9VM_GC_MODRON_TRACE)1805J9VMInitArgs *vmArgs = vm->vmArgsArray;1806/* Parse Xtgc options */1807IDATA xTgcColonIndex = FIND_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XTGC_COLON, NULL );1808while (parseSuccess && (xTgcColonIndex >= 0)) {1809char* xTgcOptions = NULL;1810CONSUME_ARG(vmArgs, xTgcColonIndex);1811GET_OPTION_VALUE( xTgcColonIndex, ':', &xTgcOptions);18121813/* Parse xTgcOptions arguments (if any) */1814if (NULL != xTgcOptions) {1815if (!tgcParseArgs(vm, xTgcOptions) || !tgcInitializeRequestedOptions(vm)) {1816parseSuccess = false;1817}1818}1819xTgcColonIndex = FIND_NEXT_ARG_IN_VMARGS_FORWARD( STARTSWITH_MATCH, OPT_XTGC_COLON, NULL, xTgcColonIndex);1820}1821#endif /* defined(J9VM_GC_MODRON_TRACE) */1822}18231824return parseSuccess;1825}182618271828