JDK-4385404 : incorrect primitive long arithmetic error with Java 1.3.0 Solaris HotSpot
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 1.3.0,1.3.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: x86,sparc
  • Submitted: 2000-11-02
  • Updated: 2000-11-17
  • Resolved: 2000-11-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other
1.3.1 betaFixed 1.4.0Fixed
Related Reports
Duplicate :  
Description

Name: tb29552			Date: 11/02/2000


/*
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)

Simple arithmetic on primitive longs returns an incorrect
value. So far, we have only seen this is a set of loops on
primitive longs running with HotSpot. The bug does not occur
in 1.2.2, previous versions of Java, or in 1.3.0 with the
interpreter.

The class below shows the error when run on the 1.3.0 JVM
with HotSpot on Solaris 6 or Solaris 8. I haven't tried
Solaris 7.

The bug is that the variable "k" gets an incorrect result
for "k++" at one point in the loop. So far as I can tell,
all five loops need to be present for the bug to
occur. Removing the loops that are OUTSIDE or AFTER the loop
on "k" causes the bug to *appear* to vanish, suggesting this
is a peephole optimization error in HotSpot.

The println() statements display the variables starting
shortly before the error occurs. When i==0 and j==166 and
k==135, k++ yields 455572 instead of 136.


-----------------------------------------------------------
*/
public class Crashes130SolarisWithHotSpot  {
    public static void main(String[] argv)
    {
        System.out.println("First Loop");
        for (long i = 0; i < 1; i++)
        {
            for (long j = 1; j < 192 - i; j++)
            {
                Object o = new Object();
                for (long k = i; k < i + j; k++)
                {
                    if (i == 0 && j == 166 && k > 120)
                        System.out.println("i=" + i + ", j=" + j + ", k=" + k);
                    if (k > 192)
                    {
                        System.out.println("BUG!!!");
                        System.exit(-1);
                    }
                }
            }
        }

        System.out.println("Second Loop");
        for (long i = 0; i < 1; i++)
        {
            for (long j = 0; j < 1; j++)
            {
                Object o = new Object();
            }
        }
        System.out.println("Success!!");
    }
}

(Review ID: 111729) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: ladybird FIXED IN: ladybird INTEGRATED IN: ladybird-beta merlin-beta
14-06-2004

WORK AROUND Name: tb29552 Date: 11/02/2000 Stay with 1.2.2. I'm in charge of Java installation on about 2000 production and development computers (Solaris 5.5.1-Solaris 8) at my company. We'll be keeping them at 1.2.2 until this is fixed. ###@###.### 2000-11-02 Use the hotspot server compiler instead of the client compiler: % java -server -showversion Crashes130SolarisWithHotSpot java version "1.3.0" Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0) Java HotSpot(TM) Server VM (build 1.3.0, mixed mode) First Loop i=0, j=166, k=121 i=0, j=166, k=122 i=0, j=166, k=123 i=0, j=166, k=124 i=0, j=166, k=125 i=0, j=166, k=126 i=0, j=166, k=127 i=0, j=166, k=128 i=0, j=166, k=129 i=0, j=166, k=130 i=0, j=166, k=131 i=0, j=166, k=132 i=0, j=166, k=133 i=0, j=166, k=134 i=0, j=166, k=135 i=0, j=166, k=136 i=0, j=166, k=137 i=0, j=166, k=138 i=0, j=166, k=139 i=0, j=166, k=140 i=0, j=166, k=141 i=0, j=166, k=142 i=0, j=166, k=143 i=0, j=166, k=144 i=0, j=166, k=145 i=0, j=166, k=146 i=0, j=166, k=147 i=0, j=166, k=148 i=0, j=166, k=149 i=0, j=166, k=150 i=0, j=166, k=151 i=0, j=166, k=152 i=0, j=166, k=153 i=0, j=166, k=154 i=0, j=166, k=155 i=0, j=166, k=156 i=0, j=166, k=157 i=0, j=166, k=158 i=0, j=166, k=159 i=0, j=166, k=160 i=0, j=166, k=161 i=0, j=166, k=162 i=0, j=166, k=163 i=0, j=166, k=164 i=0, j=166, k=165 Second Loop Success!! ====================================================================== Also you can use -XX:-UseOnStackReplacement to get around the problem.
11-06-2004

SUGGESTED FIX Contextual diffs for c1_ScanBlocks.cpp: *** /tmp/dwlBFH_ Mon Nov 6 15:11:50 2000 --- c1_ScanBlocks.cpp Mon Nov 6 11:35:07 2000 *************** *** 77,84 **** if (!si->is_initialized() || !si->is_loaded()) desc->set_has_class_init(true); } else if (n->as_AccessLocal() != NULL) { AccessLocal* local = n->as_AccessLocal(); int use_count = local->as_StoreLocal() != NULL ? 1 : n->use_count(); ! accumulate_access(local->index(), local->type()->tag(), use_count); if (local->index() == 0 && local->as_StoreLocal() != NULL) desc->set_has_store_0(true); } else if(n->as_StoreIndexed() != NULL) { StoreIndexed* si = n->as_StoreIndexed(); --- 77,86 ---- if (!si->is_initialized() || !si->is_loaded()) desc->set_has_class_init(true); } else if (n->as_AccessLocal() != NULL) { AccessLocal* local = n->as_AccessLocal(); + ValueType* type = local->type(); int use_count = local->as_StoreLocal() != NULL ? 1 : n->use_count(); ! accumulate_access(local->index(), type->tag(), use_count); ! if (type->is_double_word()) accumulate_access(local->index() + 1, type->tag(), use_count); if (local->index() == 0 && local->as_StoreLocal() != NULL) desc->set_has_store_0(true); } else if(n->as_StoreIndexed() != NULL) { StoreIndexed* si = n->as_StoreIndexed();
11-06-2004

EVALUATION Using -XX:-UseOnStackReplacement cures the bug in both 1.3 and 1.3.1(merlin). The bug however, does not occur with 1.4 (merlin) without the use of the flag. Alos, the bug is not reproducible on win32. The problem does not occur in debug mode either on any of the formentioned versions. mohammad.gharahgouzloo@Eng 2000-11-02 This is really a bug in C1's ScanBlocks class, not a bug in OSR. It exhibits itself on SPARC on the included example when an OSR compile occurs during the first set of loops. ScanBlocks::accumulate_access() does not count access to the low words (index+1) of doubleword locals. This causes the local variable "o" in the second loop nest to be globally cached in a register even though its stack slot overlaps the slots for local variable "k" in the first loop nest. Consequently, the OSR entry code initializes a register instead of the second stack word for "k" and the result is unpredictable. david.cox@Eng 2000-11-06
06-11-2000