Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move argument memory size parsing to j9argscan #10445

Merged
merged 1 commit into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 26 additions & 71 deletions runtime/gc_modron_startup/mmparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "j9cfg.h"
#include "j9protos.h"
#include "j9consts.h"
#include "j9argscan.h"
#include "jni.h"
#include "jvminit.h"
#include "j9port.h"
Expand Down Expand Up @@ -1355,95 +1356,49 @@ scan_hex_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argNa
}

/**
* Wrapper for scan_udata_helper, that provides parsing for memory sizes.
* User should be able to specify the size in GiBs, MiBs, or KiBs (with G,g,M,m,K,k suffixes) or
* in bytes (no suffix)
* Wrapper for scan_udata_memory_size, that provides readable error messages.
* @param cursor address of the pointer to the string to parse for the udata.
* @param value address of the storage for the udata to be read.
* @param argName string containing the argument name to be used in error reporting.
* @return true if parsing was successful, false otherwise.
*/
bool
scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName)
scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, uintptr_t *value, const char *argName)
{
PORT_ACCESS_FROM_JAVAVM(javaVM);
uintptr_t result = scan_udata_memory_size(cursor, value);

if(!scan_udata_helper(javaVM, cursor, value, argName)) {
return false;
}

if(try_scan(cursor, "T") || try_scan(cursor, "t")) {
if (0 != *value) {
#if defined(J9VM_ENV_DATA64)
if (*value <= (((UDATA)-1) >> 40)) {
*value <<= 40;
} else
#endif /* defined(J9VM_ENV_DATA64) */
{
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
}
} else if(try_scan(cursor, "G") || try_scan(cursor, "g")) {
if (*value <= (((UDATA)-1) >> 30)) {
*value <<= 30;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
} else if(try_scan(cursor, "M") || try_scan(cursor, "m")) {
if (*value <= (((UDATA)-1) >> 20)) {
*value <<= 20;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
} else if(try_scan(cursor, "K") || try_scan(cursor, "k")) {
if (*value <= (((UDATA)-1) >> 10)) {
*value <<= 10;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
/* Report Errors */
if (1 == result) {
AlenBadel marked this conversation as resolved.
Show resolved Hide resolved
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
} else if (2 == result) {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
}
return true;

return 0 == result;
}

/**
* Wrapper for scan_u64_helper, that provides parsing for memory sizes.
* User should be able to specify the size in GiBs, MiBs, or KiBs (with G,g,M,m,K,k suffixes) or
* in bytes (no suffix)
* Wrapper for scan_u64_helper, that provides readable error messages.
* @param cursor address of the pointer to the string to parse for the udata.
* @param value address of the storage for the udata to be read.
* @param argName string containing the argument name to be used in error reporting.
* @return true if parsing was successful, false otherwise.
*/
bool
scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, U_64 *value, const char *argName)
scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, uint64_t *value, const char *argName)
{
PORT_ACCESS_FROM_JAVAVM(javaVM);
uintptr_t result = scan_u64_memory_size(cursor, value);

if(!scan_u64_helper(javaVM, cursor, value, argName)) {
return false;
/* Report Errors */
if (1 == result) {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_MUST_BE_NUMBER, argName);
} else if (2 == result) {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
}

if(try_scan(cursor, "G") || try_scan(cursor, "g")) {
if (*value <= (((U_64)-1) >> 30)) {
*value <<= 30;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
} else if(try_scan(cursor, "M") || try_scan(cursor, "m")) {
if (*value <= (((U_64)-1) >> 20)) {
*value <<= 20;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
} else if(try_scan(cursor, "K") || try_scan(cursor, "k")) {
if (*value <= (((U_64)-1) >> 10)) {
*value <<= 10;
} else {
j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_GC_OPTIONS_VALUE_OVERFLOWED, argName);
return false;
}
}
return true;
return 0 == result;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions runtime/gc_modron_startup/mmparse.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/*******************************************************************************
* Copyright (c) 1991, 2019 IBM Corp. and others
* Copyright (c) 1991, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -90,8 +90,8 @@ jint gcParseXXgcArguments(J9JavaVM *vm, char *optArg);
bool scan_udata_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName);
bool scan_u32_helper(J9JavaVM *javaVM, char **cursor, U_32 *value, const char *argName);
bool scan_u64_helper(J9JavaVM *javaVM, char **cursor, U_64 *value, const char *argName);
bool scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName);
bool scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, U_64 *value, const char *argName);
bool scan_udata_memory_size_helper(J9JavaVM *javaVM, char **cursor, uintptr_t *value, const char *argName);
bool scan_u64_memory_size_helper(J9JavaVM *javaVM, char **cursor, uint64_t *value, const char *argName);
bool scan_hex_helper(J9JavaVM *javaVM, char **cursor, UDATA *value, const char *argName);
void gcParseXgcpolicy(MM_GCExtensions *extensions);

Expand Down
18 changes: 17 additions & 1 deletion runtime/oti/j9argscan.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2018 IBM Corp. and others
* Copyright (c) 2001, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -158,6 +158,22 @@ uintptr_t scan_u64(char **scan_start, uint64_t* result);
*/
uintptr_t scan_u32(char **scan_start, uint32_t* result);

/**
* @brief
* @param **scan_start
* @param result
* @return uintptr_t
*/
uintptr_t scan_u64_memory_size(char **scan_start, uint64_t* result);

/**
* @brief
* @param **scan_start
* @param result
* @return uintptr_t
*/
uintptr_t scan_udata_memory_size(char **scan_start, uintptr_t* result);

#ifdef __cplusplus
} /* extern "C" */
#endif
Expand Down
92 changes: 91 additions & 1 deletion runtime/util_core/j9argscan.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2018 IBM Corp. and others
* Copyright (c) 1991, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -385,6 +385,96 @@ scan_hex_caseflag_u64(char **scan_start, BOOLEAN uppercaseAllowed, uint64_t* res
return bits;
}

/**
* Scan the next unsigned number off of the argument string, and parses for memory sizes.
* Specify the size in TiBs, GiBs, MiBs, or KiBs (with T,t,G,g,M,m,K,k suffixes) or in bytes (no suffix).
* @param[in] scan_start The string to be scanned
* @param[out] result The result
* @return returns 0 on success, 1 if the argument string is not a number, or 2 if overflow occurs.
*/
uintptr_t
scan_u64_memory_size(char **scan_start, uint64_t* result)
{
uintptr_t rc = scan_u64(scan_start, result);

if (0 == rc) {
if (try_scan(scan_start, "T") || try_scan(scan_start, "t")) {
if (*result <= (((U_64)-1) >> 40)) {
AlenBadel marked this conversation as resolved.
Show resolved Hide resolved
*result <<= 40;
} else {
rc = 2;
}
} else if (try_scan(scan_start, "G") || try_scan(scan_start, "g")) {
if (*result <= (((U_64)-1) >> 30)) {
*result <<= 30;
} else {
rc = 2;
}
} else if (try_scan(scan_start, "M") || try_scan(scan_start, "m")) {
if (*result <= (((U_64)-1) >> 20)) {
*result <<= 20;
} else {
rc = 2;
}
} else if (try_scan(scan_start, "K") || try_scan(scan_start, "k")) {
if (*result <= (((U_64)-1) >> 10)) {
*result <<= 10;
} else {
rc = 2;
}
}
}
return rc;
}

/**
* Scan the next unsigned number off of the argument string, and parses for memory sizes.
* Specify the size in TiBs, GiBs, MiBs, or KiBs (with T,t,G,g,M,m,K,k suffixes) or in bytes (no suffix).
* @param[in] scan_start The string to be scanned
* @param[out] result The result
* @return returns 0 on success, 1 if the argument string is not a number, or 2 if overflow occurs.
*/
uintptr_t
scan_udata_memory_size(char **scan_start, uintptr_t* result)
{
uintptr_t rc = scan_udata(scan_start, result);

if (0 == rc) {
/* Scan Memory String, and check for overflow */
if (try_scan(scan_start, "T") || try_scan(scan_start, "t")) {
if (0 != *result) {
#if defined(J9VM_ENV_DATA64)
if (*result <= (((UDATA)-1) >> 40)) {
*result <<= 40;
} else
#endif /* defined(J9VM_ENV_DATA64) */
{
rc = 2;
}
}
} else if (try_scan(scan_start, "G") || try_scan(scan_start, "g")) {
if (*result <= (((UDATA)-1) >> 30)) {
*result <<= 30;
} else {
rc = 2;
}
} else if (try_scan(scan_start, "M") || try_scan(scan_start, "m")) {
if (*result <= (((UDATA)-1) >> 20)) {
*result <<= 20;
} else {
rc = 2;
}
} else if (try_scan(scan_start, "K") || try_scan(scan_start, "k")) {
if (*result <= (((UDATA)-1) >> 10)) {
*result <<= 10;
} else {
rc = 2;
}
}
}

return rc;
}

/*
* Print an error message indicating that an option was not recognized
Expand Down