Bug 21557 - VM bug prevents valid Java code to be executed on VM < 1.3.1
Summary: VM bug prevents valid Java code to be executed on VM < 1.3.1
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 2.0.1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-07-12 14:45 EDT by Olivier Thomann CLA
Modified: 2002-09-20 09:23 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Thomann CLA 2002-07-12 14:45:34 EDT
Test case:
public class X {
	
	public static final int CONST = 0x7fffffff;
    public static void main(String[] args) {

        int i = CONST;

        switch (i) {

            case CONST:
                System.out.println("SUCCESS");

                break;
        }
    }
}

This code compiles fine on Eclipse 2.0, but the resulting .class file executiuon
leads to VerifyError on a 1.3.1 VM.
java.lang.VerifyError: (class: X, method: main signature:
([Ljava/lang/String;)V) Illegal instruction found at offset 4
Exception in thread "main".

On a 1.4 VM the problem has been fixed. Looking at the Sun bug database, we
found the problem:
See Re: http://developer.java.sun.com/developer/bugParade/bugs/4411025.html for
further details.

The bytecodes generated by Eclipse are:
Method void main(java.lang.String[])
   0 ldc #16 <Integer 2147483647>
   2 istore_1
   3 iload_1
   4 tableswitch 2147483647 to 2147483647: default=32
	2147483647: 24
  24 getstatic #22 <Field java.io.PrintStream out>
  27 ldc #24 <String "SUCCESS">
  29 invokevirtual #30 <Method void println(java.lang.String)>
  32 return

The bytecodes generated by Sun 1.3.1 or 1.4 are:
Method void main(java.lang.String[])
   0 ldc #2 <Integer 2147483647>
   2 istore_1
   3 iload_1
   4 lookupswitch 1: default=32
	2147483647: 24
  24 getstatic #3 <Field java.io.PrintStream out>
  27 ldc #4 <String "SUCCESS">
  29 invokevirtual #5 <Method void println(java.lang.String)>
  32 return

The difference is the lookupswitch instead of a tableswitch. We might want to
generate a workaround to generate a lookupswitch if target < 1.4.
Comment 1 Philipe Mulet CLA 2002-07-12 17:45:14 EDT
Yes, I think we want to work-around the VM bug for such targets.
Comment 2 Philipe Mulet CLA 2002-07-15 06:21:42 EDT
Proposed fix from Olivier:

		if (needSwitch) {
			int max = localKeysCopy[caseCount - 1];
			int min = localKeysCopy[0];
			if ((long) (caseCount * 2.5) > ((long) max - (long) 
min)) {
				if (max > 0x7FFF0000 && currentScope.environment
().options.complianceLevel < CompilerOptions.JDK1_4) {
					// we need a special case
					// see 
http://dev.eclipse.org/bugs/show_bug.cgi?id=21557
					codeStream.lookupswitch(defaultLabel, 
constants, sortedIndexes, caseLabels);
				} else {
					codeStream.tableswitch(
						defaultLabel,
						min,
						max,
						constants,
						sortedIndexes,
						caseLabels);
				}
			} else {
				codeStream.lookupswitch(defaultLabel, 
constants, sortedIndexes, caseLabels);
			}
			codeStream.updateLastRecordedEndPC(codeStream.position);
		}
Comment 3 Philipe Mulet CLA 2002-07-15 06:21:58 EDT
Integrated, fixed.
Comment 4 David Audel CLA 2002-08-19 11:50:11 EDT
Verified.
Comment 5 Jerome Lanneluc CLA 2002-08-19 12:22:38 EDT
Verified
Comment 6 David Audel CLA 2002-09-20 09:23:16 EDT
Verified in 2.1 M1