Skip to content

Commit

Permalink
Merge pull request #10445 from AlenBadel/memsize_parse
Browse files Browse the repository at this point in the history
Move argument memory size parsing to j9argscan
  • Loading branch information
dmitripivkine committed Aug 27, 2020
2 parents bc88c6e + fd15265 commit 99ef7aa
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 76 deletions.
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 @@ -1368,95 +1369,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) {
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)) {
*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

0 comments on commit 99ef7aa

Please sign in to comment.