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

FloatBuffer returns incorrect results when used with the Java 6 HotSpot ServerVM

    XMLWordPrintable

Details

    • Enhancement
    • Resolution: Duplicate
    • P5
    • None
    • 6
    • hotspot
    • x86
    • windows_xp

    Description

      FULL PRODUCT VERSION :
      Linux
      java version "1.6.0_02"
      Java(TM) SE Runtime Environment (build 1.6.0_02-b05)
      Java HotSpot(TM) Server VM (build 1.6.0_02-b05, mixed mode)

      WIndows XP (32-bit)
      java version "1.6.0_02"
      Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
      Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)

      FULL OS VERSION :
      WindowsXP (SP2+patches)
      Linux 2.6.9-22.ELsmp x86_64
      Linux 2.6.9-22.ELsmp i686 i386

      A DESCRIPTION OF THE PROBLEM :
      NOTE: Same bug as reported in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6550579
        Bug 6550579 shows a status of closed, fixed, but as of the latest Java6 updated, the bug is still present. Request to have this fix backported to 6.0.

      When using a java.nio.FloatBuffer in a loop, the values placed into the FloatBuffer via the put( float[], int, int) method are not always equal to the values of the source float[] data when the program is executed using the Hotspot Server VM (-server option).

      Note that the problem appears to only be present when the jvm is executed with the -server option. If -client is used, the FloatBuffer values are correct.

      Note that sometimes the data in the FloatBuffer is correct. It's the use of a FloatBuffer in a loop that appears to be part of the problem (at least as discovered and tested).

      This problem appears to be new to Java 6 and is not present in the Java 1.4 or Java 5 vms that I tested.

      THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Did not try

      THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a loop that executes more than 1 time
      2. Copy an array for floats into a java.nio.FloatBuffer using the put(float[], int, int) method. Ref http://java.sun.com/javase/6/docs/api/java/nio/FloatBuffer.html#put(float[],%20int,%20int)
      3. Compare values of the source float array to those values in the FloatBuffer
      4. Execute with the '-server' jvm option (e.g. java -server FloatBufferTest)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      When tested in prior jvms and in the Java 6 jvm using the '-client' option, the source float array and the values copied into the FloatBuffer are the same (as they should be). When tested in the Java 6 jvm using the '-server' option, the source float array and the values copied into the FloatBuffer are not always the same when the FloatBuffer is being used inside of a loop.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      java FloatBufferTest
      0 loops experienced errors. Total FloatBuffer loops executed 1000
      0 loops experienced errors. Total DoubleBuffer loops executed 1000
      0 IntBuffer loops experienced errors. Total IntBuffer loops executed 1000
      Java version 1.6.0_02-b06
      Java name Java HotSpot(TM) Client VM

      java -server FloatBufferTest
      Error count for the current loop in comparing FloatBuffer to float src array 24668
      Error count for the current loop in comparing FloatBuffer to float src array 24386
      2 loops experienced errors. Total FloatBuffer loops executed 1000
      First FloatBuffer loop to error: 1
      0 loops experienced errors. Total DoubleBuffer loops executed 1000
      0 IntBuffer loops experienced errors. Total IntBuffer loops executed 1000
      Java version 1.6.0_02-b06
      Java name Java HotSpot(TM) Server VM


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.nio.ByteBuffer;
      import java.nio.DoubleBuffer;
      import java.nio.FloatBuffer;
      import java.nio.IntBuffer;
      import java.util.Random;

      /**
       * The FloatBufferTest demonstrates an error in the FloatBuffer when executed
       * with the Java 6 jvm with the jvm arg '-server'. If the Java 6 jvm is executed
       * in client mode, then there is no error.
       *
       * Also worth noting is that the Java 1.4 and Java 5 jvms execute the code
       * without any errors for both jvm args '-server' and '-client'.
       *
       * To see the errors execute the code below using the Java 6 jvm with '-server'
       * specified.
       *
       * example: java -server FloatBufferTest
       *
       * Execute the same code using the same Java 6 jvm without the '-server' option
       * and no errors are produced.
       *
       * example: java FloatBufferTest or java -client FloatBufferTest
       *
       * Java version: Java version 1.6.0_01-b06
       *
       * Misc: The IntBuffer and DoubleBuffer are also tested in the same manner that
       * the FloatBuffer is tested and no errors have been seen using the same scenario.
       * Perhaps execution order of the methods may affect the outcome (not tested).
       */
      public class FloatBufferTest {


      private static int NUM_LOOPS = 1000;

      //change to true to dump error values to console
      //note that doing so may affect results
      private static boolean DUMP_ERROR_VALUES = false;

      public static void main(String[] args) {
      long seed = 8675309;
      int dlength = 50000; // 50000 entries

      FloatBufferTest.testFloatBuffer(seed, dlength);
      //test DoubleBuffer in the same manner
      FloatBufferTest.testDoubleBuffer(seed, dlength);
      //test IntBuffer in the same manner
      FloatBufferTest.testIntBuffer(seed, dlength);

      //dump some jvm info
      String jvmversion = System.getProperty("java.vm.version");
      String jvmname = System.getProperty("java.vm.name");
      System.err.println("Java version " + jvmversion);
      System.err.println("Java name " + jvmname);

      }

      /**
      * Test the FloatBuffer
      * @param pSeed the seed value
      * @param pLength the number of data values
      */
      protected static void testFloatBuffer(long pSeed, int pLength) {

      int blength = 4; // 4 btyes
      float[] floats = new float[pLength];

      Random r = new Random(pSeed);
      //populate src float array
      for (int i = 0; i < pLength; i++) {
      floats[i] = r.nextFloat();
      }


      int loopErrorCount = 0;
      int firstLoopToErr = -1;





      for (int ii = 0; ii <= NUM_LOOPS; ii++) {

      ByteBuffer destbb = ByteBuffer.allocate(pLength * blength);
      FloatBuffer fb = destbb.asFloatBuffer();
      fb.put(floats, 0, pLength);

      int errorCount = 0;
      //compare source float values to those copied into the FloatBuffer
      for (int i = 0; i < floats.length; i++) {
      float fbfvalue = fb.get(i);
      float srcvalue = floats[i];
      //check for mismatching values
      if (fbfvalue != srcvalue) {
      errorCount++;

      if (DUMP_ERROR_VALUES) {
      System.err.println("*** Data values not equal error");
      System.err.println(i + " (array index) Expected " + srcvalue
      + ", got " + fbfvalue);
      }

      }
      } //end i

      //check if there where any errors in loop execution
      if (errorCount > 0) {
      //track the first loop to error
      if (firstLoopToErr == -1) {
      firstLoopToErr = ii;
      }
      loopErrorCount++;
      System.err
      .println("Error count for the current loop in comparing FloatBuffer to float src array "
      + errorCount);
      }


      }// end ii

      System.err.println(loopErrorCount + " loops experienced errors. Total FloatBuffer loops executed " + NUM_LOOPS);
      if (loopErrorCount > 0) {
      System.err.println("First FloatBuffer loop to error: " + firstLoopToErr);
      }

      }

      /**
      * Test the DoubleBuffer
      * @param pSeed the seed value
      * @param pLength the number of data values
      */
      protected static void testDoubleBuffer(long pSeed, int pLength) {

      int blength = 8; // 8 btyes
      double[] src = new double[pLength];

      Random r = new Random(pSeed);
      //populate src array
      for (int i = 0; i < pLength; i++) {
      src[i] = r.nextDouble();
      }


      int loopErrorCount = 0;
      int firstLoopToErr = -1;





      for (int ii = 0; ii <= NUM_LOOPS; ii++) {

      ByteBuffer destbb = ByteBuffer.allocate(pLength * blength);
      DoubleBuffer fb = destbb.asDoubleBuffer();
      fb.put(src, 0, pLength);

      int errorCount = 0;
      //compare source float values to those copied into the DoubleBuffer
      for (int i = 0; i < src.length; i++) {
      double fbfvalue = fb.get(i);
      double srcvalue = src[i];
      //check for mismatching values
      if (fbfvalue != srcvalue) {
      errorCount++;

      if (DUMP_ERROR_VALUES) {
      System.err.println("*** Data values not equal error");
      System.err.println(i + " (array index) Expected " + srcvalue
      + ", got " + fbfvalue);
      }

      }
      } //end i

      //check if there where any errors in loop execution
      if (errorCount > 0) {
      //track the first loop to error
      if (firstLoopToErr == -1) {
      firstLoopToErr = ii;
      }
      loopErrorCount++;
      System.err
      .println("Error count for the current loop in comparing DoubleBuffer to double src array "
      + errorCount);
      }


      }// end ii

      System.err.println(loopErrorCount + " loops experienced errors. Total DoubleBuffer loops executed " + NUM_LOOPS);
      if (loopErrorCount > 0) {
      System.err.println("First DoubleBuffer loop to error: " + firstLoopToErr);
      }

      }

      /**
      * Test the IntBuffer
      * @param pSeed the seed value
      * @param pLength the number of data values
      */
      protected static void testIntBuffer(long pSeed, int pLength) {

      int blength = 4; // 4 btyes
      int[] src = new int[pLength];

      Random r = new Random(pSeed);
      //populate src array
      for (int i = 0; i < pLength; i++) {
      src[i] = r.nextInt();
      }


      int loopErrorCount = 0;
      int firstLoopToErr = -1;





      for (int ii = 0; ii <= NUM_LOOPS; ii++) {

      ByteBuffer destbb = ByteBuffer.allocate(pLength * blength);
      IntBuffer fb = destbb.asIntBuffer();
      fb.put(src, 0, pLength);

      int errorCount = 0;
      //compare source float values to those copied into the IntBuffer
      for (int i = 0; i < src.length; i++) {
      int fbfvalue = fb.get(i);
      int srcvalue = src[i];
      //check for mismatching values
      if (fbfvalue != srcvalue) {
      errorCount++;

      if (DUMP_ERROR_VALUES) {
      System.err.println("*** Data values not equal error");
      System.err.println(i + " (array index) Expected " + srcvalue
      + ", got " + fbfvalue);
      }

      }
      } //end i

      //check if there where any errors in loop execution
      if (errorCount > 0) {
      //track the first loop to error
      if (firstLoopToErr == -1) {
      firstLoopToErr = ii;
      }
      loopErrorCount++;
      System.err
      .println("Error count for the current loop in comparing IntBuffer to double src array "
      + errorCount);
      }


      }// end ii

      System.err.println(loopErrorCount + " IntBuffer loops experienced errors. Total IntBuffer loops executed " + NUM_LOOPS);
      if (loopErrorCount > 0) {
      System.err.println("First IntBuffer loop to error: " + firstLoopToErr);
      }

      }


      }
      ---------- END SOURCE ----------

      Attachments

        Issue Links

          Activity

            People

              kvn Vladimir Kozlov
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: