RFR: 8282773: Refactor parsing of integer VM options [v2]

Ioi Lam iklam at openjdk.java.net
Thu Mar 10 03:37:57 UTC 2022


On Thu, 10 Mar 2022 01:43:22 GMT, David Holmes <dholmes at openjdk.org> wrote:

>> Ioi Lam has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains ten additional commits since the last revision:
>> 
>>  - Merge branch 'master' into new-interger-argument-parser
>>  - fixed handling of errno
>>  - add #include <limits> for std::numeric_limits<T>
>>  - avoid UB in multiply_by_1k(); more clean-up
>>  - avoid UB operations in k/m/g/t muplication
>>  - refactored test cases
>>  - step3
>>  - step2
>>  - tmp1
>
> src/hotspot/share/runtime/arguments.cpp line 751:
> 
>> 749: static bool parse_integer_impl(const char *s, char **endptr, int base, T* result) {
>> 750:   // Can't use strtol because it doesn't detect (at least on Linux/gcc) overflowing
>> 751:   // input such as "0x123456789" or "-0x800000001"
> 
> This doesn't seem to be true in general. The Linux manpage indicates overflow and underflow are detected. And a simple test program confirms:
> 
> 
>  > ./conversion
> Overflow detected okay for 0x123456789 (val = 2147483647)
> Overflow detected okay for -0x800000001 (val = -2147483648)

I tried changing the code to this. It doesn't work. "0x123456789" is incorrectly parsed to 591751049 for the `int` flag `AVX3Threshold` without setting `errno`:


template <typename T, ENABLE_IF(std::is_signed<T>::value), ENABLE_IF(sizeof(T) == 4)> // signed 32-bit
static bool parse_integer_impl(const char *s, char **endptr, int base, T* result) {
  errno = 0; // errno is thread safe
  *result = strtol(s, endptr, base);
  return errno == 0;
}

$ java -XX:AVX3Threshold=0 --version
java 19-internal 2022-09-20
Java(TM) SE Runtime Environment (slowdebug build 19-internal-adhoc.iklam.ken)
Java HotSpot(TM) 64-Bit Server VM (slowdebug build 19-internal-adhoc.iklam.ken, mixed mode, sharing)
$ java -XX:AVX3Threshold=0x123456789 --version
AVX3Threshold ( 591751049 ) must be 0 or a power of two value between 0 and MAX_INT
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ gcc --version
gcc (GCC) 10.3.0
$ uname -a
Linux host 5.13.0-28-generic #31-Ubuntu SMP Thu Jan 13 17:41:06 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux


My stand-alone test case:


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char** argv) {
  if (argc >= 2) {
    char* endptr;

    errno = 0;    
    int n = strtol(argv[1], &endptr, 16);
    printf("errno = %d, strtol() returns %d == 0x%x\n", errno, n, n);
  }
}

$ gcc -g strtol.cpp -o strtol
$ ./strtol 0x12345678
errno = 0, strtol() returns 305419896 == 0x12345678
$ ./strtol 0x123456789
errno = 0, strtol() returns 591751049 == 0x23456789

> src/hotspot/share/runtime/arguments.cpp line 945:
> 
>> 943:   } else if (flag->is_double()) {
>> 944:     jlong v;
>> 945:     if (parse_integer(value, &v)) {
> 
> I don't see how this can parse floating-point values ???

Floating point strings with a decimal point character are parsed elsewhere in `set_fp_numeric_flag()`. I'll add a comment to clarify this.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7763


More information about the hotspot-runtime-dev mailing list