United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6910461 Register allocator may insert spill code at wrong insertion index
JDK-6910461 : Register allocator may insert spill code at wrong insertion index

Details
Type:
Bug
Submit Date:
2009-12-15
Status:
Closed
Updated Date:
2013-07-18
Project Name:
JDK
Resolved Date:
2012-03-07
Component:
hotspot
OS:
solaris_10
Sub-Component:
compiler
CPU:
sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
6u15
Fixed Versions:
hs24 (b02)

Related Reports
Backport:
Backport:
Backport:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-90, mixed mode)

FULL OS VERSION :
All platforms.

A DESCRIPTION OF THE PROBLEM :
When resolving exception edges after register allocation, the C1 register allocator may insert spill code at the wrong insertion position due to an off-by-one error.


THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

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

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the file
src/share/vm/c1/c1_LinearScan.cpp @ 1840:

  if (move_resolver.has_mappings()) {
    // insert moves after first instruction
    move_resolver.set_insert_position(block->lir(), 1);
    move_resolver.resolve_and_append_moves();
  }

The constant 1 here is incorrect, since moves are inserted _after_ the specified index. Index 0 is always a label and the last index is always a branch. Usually the exception handler block has some instructions, but if it is empty the moves will be inserted after the branch (index 1) and cause an assertion failure later (in the move optimizer).



EXPECTED VERSUS ACTUAL BEHAVIOR :
The register allocator should insert moves at the correct position, but it does not. This may produce an assertion error later in the compiler, or may produce incorrect code that fails when catching the exception.
REPRODUCIBILITY :
This bug can be reproduced rarely.

---------- BEGIN SOURCE ----------
/*
 * @Harness: java
 * @Runs: 0 = 0; 1 = 2
 */
package jtt.except;

public class Except_Synchronized05 {

    Object field;

    public static int test(int arg) {
        Except_Synchronized05 obj = new Except_Synchronized05();
        int a = obj.bar(arg) != null ? 1 : 0;
        int b = obj.baz(arg) != null ? 1 : 0;
        return a + b;
    }

    public synchronized Object bar(int arg) {
        try {
            String f = foo1(arg);
            if (f == null) {
                field = new Object();
            }
        } catch (NullPointerException e) {
            // do nothing
        }
        return field;
    }

    public Object baz(int arg) {
        synchronized (this) {
            try {
                String f = foo1(arg);
                if (f == null) {
                    field = new Object();
                }
            } catch (NullPointerException e) {
                // do nothing
            }
            return field;
        }
    }

    private String foo1(int arg) {
        if (arg == 0) {
            throw null;
        }
        return null;
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
  Fix: change the constant 1 to constant 0 in the above mentioned code (repeated here):

src/share/vm/c1/c1_LinearScan.cpp @ 1840:

  if (move_resolver.has_mappings()) {
    // insert moves after first instruction
    move_resolver.set_insert_position(block->lir(), 0);
    move_resolver.resolve_and_append_moves();
  }

                                    

Comments
EVALUATION

see description.
                                     
2012-02-27
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/b279f99d7143
                                     
2012-02-29
EVALUATION

http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/b279f99d7143
                                     
2012-03-22



Hardware and Software, Engineered to Work Together