Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8319310

putstatic/putfield: specify truncation of byte/short/char values

    XMLWordPrintable

Details

    • vm
    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      macOS version:

      Software:
          System Software Overview:
            System Version: macOS 13.2 (22D49)
            Kernel Version: Darwin 22.3.0
            Boot Volume: Macintosh HD
            Boot Mode: Normal
            Computer Name: MacBook Pro
            User Name: MacBook
            Secure Virtual Memory: Enabled
            System Integrity Protection: Enabled
            Time since boot: 1 day, 2 hours, 19 minutes

      Hardware:
          Hardware Overview:

            Model Name: MacBook Pro
            Model Identifier: MacBookPro18,1
            Model Number: MK193CH/A
            Chip: Apple M1 Pro
            Total Number of Cores: 10 (8 performance and 2 efficiency)
            Memory: 16 GB
            System Firmware Version: 8419.80.7
            OS Loader Version: 8419.80.7
            Activation Lock Status: Disabled

      OpenJDK version:
      openjdk version "11.0.20.1" 2023-08-24
      OpenJDK Runtime Environment Temurin-11.0.20.1+1 (build 11.0.20.1+1)
      OpenJDK 64-Bit Server VM Temurin-11.0.20.1+1 (build 11.0.20.1+1, mixed mode)

      openjdk version "1.8.0_382"
      OpenJDK Runtime Environment (Temurin)(build 1.8.0_382-b05)
      OpenJDK 64-Bit Server VM (Temurin)(build 25.382-b05, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      A few months ago, we submitted a bug report to highlight the inconsistency in output between OpenJDK and OpenJ9. The details can be found at: https://bugs.openjdk.org/browse/JDK-8300025.

      While the test case is interesting and the explanation is convincing, it appears that the sophisticated and funny source code overshadows the actual issue: the implementation of "putstatic" seems to deviate from the JVM spec.

      Recently, we found a new test program that effectively exposes the actual issue. The test program can be found at: https://drive.google.com/file/d/168faW6o1CqM4j5LLI_IuNkCm3GyON_Ie/view?usp=drive_link.

      Java code:
      0: bipush -88
      2: istore_1
      3: iload_1
      4: i2c
      5: putstatic #2 // Field field_1:C

      Jasm code:
      0: bipush -88
      2: istore_1
      3: iload_1
      4: putstatic #3 // Field field_1:C

      The biggest difference between these two test program is summarized below:
      The Java code includes an "i2c" instruction before putstatic, which converts the int value loaded by "iload_1" to a char. However, the Jasm code does not explicitly perform this int-to-char conversion.

      When executing the Java code, both HotSpot and OpenJ9 output the correct result: 65448. However, when running the Jasm code, HotSpot outputs 65448, while OpenJ9 outputs -88. The OpenJ9 developer assumes that the difference may be due to HotSpot not applying any narrowing during the get/putstatic operations (https://github.com/eclipse-openj9/openj9/issues/16498). However, this test program seems reveal the opposite truth.

      According to the Java Virtual Machine Specification (https://docs.oracle.com/javase/specs/jvms/se11/jvms11.pdf) on page 583, there seems to be confusion regarding the behavior of the putstatic instruction. The specification states that: "The type of a value stored by a putstatic instruction must be compatible with the descriptor of the referenced field (§4.3.2). If the field descriptor type is boolean, byte, char, short, or int, then the value must be an int. "

      The specification states that the type of the value operated on by the putstatic instruction should be compatible with the descriptor of the referenced field. However, it seems that there is a contradiction in the second sentence regarding the behavior when the field descriptor type is char. It states that the value must be an int, which is confusing.

      Following the first sentence, the putstatic instruction should narrow the int value (-88 in this case) to char before assigning it to filed_1. This aligns with the behavior of the HotSpot. However, following the second sentence, the putstatic instruction should not narrow the int value and directly assign -88 to filed_1, which is the behavior observed in OpenJ9 JVM.

      The observed discrepancy between the behavior of the putstatic instruction in HotSpot and OpenJ9, as well as the confusion it causes, suggests that there might be inconsistency between the actual implementation of putstatic in these JVMs and the specification provided by the JVM spec. It is possible that either the implementation of the JVMs deviates from the specification, or the specification itself has a flaw in the definition of the putstatic instruction.


      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              dlsmith Dan Smith
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: