-
Bug
-
Resolution: Fixed
-
P2
-
8, 9
-
b167
-
generic
-
generic
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8179755 | 10 | Igor Veresov | P2 | Resolved | Fixed | b07 |
JDK-8190592 | 8u171 | David Buck | P2 | Resolved | Fixed | b01 |
JDK-8185275 | 8u162 | David Buck | P2 | Closed | Fixed | b01 |
JDK-8198044 | emb-8u171 | David Buck | P2 | Resolved | Fixed | b01 |
FULL PRODUCT VERSION :
$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Server VM (build 25.121-b13, mixed mode)
FULL OS VERSION :
Linux localhost.localdomain 3.10.0-327.36.2.el7.x86_64 #1 SMP Mon Oct 10 23:08:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The attached testcase fails when run in compiled mode on 32 bit Intel Linux.
It does NOT fail in interpreted mode (-Xint) or in compiled mode with a 64 bit VM.
It does NOT fail on 32 bit Intel Windows.
The testcase has taken significant effort to extract. We have a COBOL product (NTT DATA Enterprise COBOL, formerly Dell Enterprise COBOL) that translates COBOL to Java for execution and the problem originates from a customer COBOL program.
The slightly unusual coding patterns reflect our implementation of COBOL "unsigned usage display" numerics, in which a decimal number is represented in memory using ASCII digits, i.e that characters '0', '1', ... (This also necessitates our use of 'Unsafe')
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code:
$ javac Sim.java Chunk.java
Execute 'Sim'
$ java Sim
EXPECTED VERSUS ACTUAL BEHAVIOR :
$ java Sim
Output is as follows:
main() >
[0000000000]
[0000000001]
[0000000002]
[0000000003]
[0000000004]
[0000000005]
[0000000006]
[0000000007]
[0000000008]
[0000000009]
...
[0000110638]
[0000110639]
[0000110640]
[0000110641]
[0000000000]
[0000000000]
[0000000000]
...
[0000000000]
[0000000000]
[0000000000]
main() <
The output should just be an increasing integer, as can be seen by using -Xint:
java -Xint Sim:
main() >
[0000000000]
[0000000001]
[0000000002]
[0000000003]
[0000000004]
[0000000005]
[0000000006]
[0000000007]
[0000000008]
[0000000009]
...
[0000198760]
[0000198761]
[0000198762]
[0000198763]
[0000198764]
main() <
The exact point in the failing case where the error occurs (output turns to zero) seems to vary, and I assume corresponds to when HotSpot compilation occurs
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Sim.java:
public class Sim {
private final Chunk c_A1;
private final Chunk c_A2;
private final Chunk c_R;
public static void main(String[] args) {
System.out.println("main() >");
Sim s = new Sim();
s.go();
System.out.println("main() <");
}
public Sim() {
Chunk r_0 = new Chunk(64);
c_A1 = r_0.slice(0, 11);
c_A2 = r_0.slice(11, 11);
c_R = r_0.slice(22, 19);
}
private void go() {
c_A1.fillSmall(0, 11, (byte)0x30);
for (long i = 0; i < 198765L; i++) {
c_A2.put_Long_DU(0, 11, i );
c_R.fillSmall(9, 10, (byte)0x30);
c_R.put_Long_DU(9, 10, c_R.get_DU_Long(9, 10) + c_A2.get_DU_Long(0, 11));
c_R.put_Long_DU(9, 10, c_R.get_DU_Long(9, 10) + c_A1.get_DU_Long(0, 11));
printR();
}
}
private void printR() {
final byte[] ba = c_R.getAsByteArray(9, 10);
final String s = new String(ba);
System.out.println("[" + s + "]");
}
}
Chunk.java:
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Chunk {
private static final Unsafe UNSAFE;
private final long baseAddress;
private final int length;
static {
Unsafe u = null;
try {
final Class<Unsafe> uc = Unsafe.class;
final Field field = uc.getDeclaredField("theUnsafe");
field.setAccessible(true);
u = (Unsafe) field.get(uc);
} catch (NoSuchFieldException | IllegalAccessException | RuntimeException ex) {
ex.printStackTrace();
}
UNSAFE = u;
}
public Chunk(int length) {
baseAddress = UNSAFE.allocateMemory(length);
this.length = length;
}
public final long getBaseAddress() {
return baseAddress;
}
public final int getLength() {
return length;
}
protected Chunk(Chunk oc, int op, int ol) {
baseAddress = oc.getBaseAddress() + op;
if (oc.getLength() == -1) {
length = -1;
} else {
length = Math.min(ol, oc.getLength() - op);
}
}
public Chunk slice(int p, int l) {
Chunk o = new Chunk(this, p, l);
return o;
}
public final void fillSmall(int tp, int tl, byte b) {
long p = baseAddress + tp;
for (int i = 0; i < tl; i++) {
UNSAFE.putByte(p++, b);
}
}
public void put_Long_DU(int p, int d, long v) {
long a = baseAddress + p;
for (int i = d - 1; i >= 0; i--) {
long b = (v % 10) + 0x30;
UNSAFE.putByte(a + i, (byte) b);
v /= 10;
}
}
public long get_DU_Long(int p, int l) {
long a = baseAddress + p;
long ret = 0;
for (int i = 0; i < l; i++) {
final int b = UNSAFE.getByte(a++);
ret *= 10;
ret += b & 0x0f;
}
return ret;
}
public byte[] getAsByteArray(int p, int l) {
byte[] ret = new byte[l];
long a = baseAddress + p;
for (int i = 0; i < l; i++) {
ret[i] = UNSAFE.getByte(a++);
}
return ret;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
End customer has had to change their original COBOL program to avoid generating the pattern that causes this issue. They have had to do this in multiple programs.
$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Server VM (build 25.121-b13, mixed mode)
FULL OS VERSION :
Linux localhost.localdomain 3.10.0-327.36.2.el7.x86_64 #1 SMP Mon Oct 10 23:08:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The attached testcase fails when run in compiled mode on 32 bit Intel Linux.
It does NOT fail in interpreted mode (-Xint) or in compiled mode with a 64 bit VM.
It does NOT fail on 32 bit Intel Windows.
The testcase has taken significant effort to extract. We have a COBOL product (NTT DATA Enterprise COBOL, formerly Dell Enterprise COBOL) that translates COBOL to Java for execution and the problem originates from a customer COBOL program.
The slightly unusual coding patterns reflect our implementation of COBOL "unsigned usage display" numerics, in which a decimal number is represented in memory using ASCII digits, i.e that characters '0', '1', ... (This also necessitates our use of 'Unsafe')
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code:
$ javac Sim.java Chunk.java
Execute 'Sim'
$ java Sim
EXPECTED VERSUS ACTUAL BEHAVIOR :
$ java Sim
Output is as follows:
main() >
[0000000000]
[0000000001]
[0000000002]
[0000000003]
[0000000004]
[0000000005]
[0000000006]
[0000000007]
[0000000008]
[0000000009]
...
[0000110638]
[0000110639]
[0000110640]
[0000110641]
[0000000000]
[0000000000]
[0000000000]
...
[0000000000]
[0000000000]
[0000000000]
main() <
The output should just be an increasing integer, as can be seen by using -Xint:
java -Xint Sim:
main() >
[0000000000]
[0000000001]
[0000000002]
[0000000003]
[0000000004]
[0000000005]
[0000000006]
[0000000007]
[0000000008]
[0000000009]
...
[0000198760]
[0000198761]
[0000198762]
[0000198763]
[0000198764]
main() <
The exact point in the failing case where the error occurs (output turns to zero) seems to vary, and I assume corresponds to when HotSpot compilation occurs
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Sim.java:
public class Sim {
private final Chunk c_A1;
private final Chunk c_A2;
private final Chunk c_R;
public static void main(String[] args) {
System.out.println("main() >");
Sim s = new Sim();
s.go();
System.out.println("main() <");
}
public Sim() {
Chunk r_0 = new Chunk(64);
c_A1 = r_0.slice(0, 11);
c_A2 = r_0.slice(11, 11);
c_R = r_0.slice(22, 19);
}
private void go() {
c_A1.fillSmall(0, 11, (byte)0x30);
for (long i = 0; i < 198765L; i++) {
c_A2.put_Long_DU(0, 11, i );
c_R.fillSmall(9, 10, (byte)0x30);
c_R.put_Long_DU(9, 10, c_R.get_DU_Long(9, 10) + c_A2.get_DU_Long(0, 11));
c_R.put_Long_DU(9, 10, c_R.get_DU_Long(9, 10) + c_A1.get_DU_Long(0, 11));
printR();
}
}
private void printR() {
final byte[] ba = c_R.getAsByteArray(9, 10);
final String s = new String(ba);
System.out.println("[" + s + "]");
}
}
Chunk.java:
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Chunk {
private static final Unsafe UNSAFE;
private final long baseAddress;
private final int length;
static {
Unsafe u = null;
try {
final Class<Unsafe> uc = Unsafe.class;
final Field field = uc.getDeclaredField("theUnsafe");
field.setAccessible(true);
u = (Unsafe) field.get(uc);
} catch (NoSuchFieldException | IllegalAccessException | RuntimeException ex) {
ex.printStackTrace();
}
UNSAFE = u;
}
public Chunk(int length) {
baseAddress = UNSAFE.allocateMemory(length);
this.length = length;
}
public final long getBaseAddress() {
return baseAddress;
}
public final int getLength() {
return length;
}
protected Chunk(Chunk oc, int op, int ol) {
baseAddress = oc.getBaseAddress() + op;
if (oc.getLength() == -1) {
length = -1;
} else {
length = Math.min(ol, oc.getLength() - op);
}
}
public Chunk slice(int p, int l) {
Chunk o = new Chunk(this, p, l);
return o;
}
public final void fillSmall(int tp, int tl, byte b) {
long p = baseAddress + tp;
for (int i = 0; i < tl; i++) {
UNSAFE.putByte(p++, b);
}
}
public void put_Long_DU(int p, int d, long v) {
long a = baseAddress + p;
for (int i = d - 1; i >= 0; i--) {
long b = (v % 10) + 0x30;
UNSAFE.putByte(a + i, (byte) b);
v /= 10;
}
}
public long get_DU_Long(int p, int l) {
long a = baseAddress + p;
long ret = 0;
for (int i = 0; i < l; i++) {
final int b = UNSAFE.getByte(a++);
ret *= 10;
ret += b & 0x0f;
}
return ret;
}
public byte[] getAsByteArray(int p, int l) {
byte[] ret = new byte[l];
long a = baseAddress + p;
for (int i = 0; i < l; i++) {
ret[i] = UNSAFE.getByte(a++);
}
return ret;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
End customer has had to change their original COBOL program to avoid generating the pattern that causes this issue. They have had to do this in multiple programs.
- backported by
-
JDK-8179755 Aliasing problem with raw memory accesses
-
- Resolved
-
-
JDK-8190592 Aliasing problem with raw memory accesses
-
- Resolved
-
-
JDK-8198044 Aliasing problem with raw memory accesses
-
- Resolved
-
-
JDK-8185275 Aliasing problem with raw memory accesses
-
- Closed
-
- duplicates
-
JDK-8185029 Incorrect result from program when JIT takes effect
-
- Closed
-
-
JDK-8183398 Another occurence of JDK-8178047
-
- Closed
-
(1 duplicates)