Bug 147747

Summary: max stack for clinit of enum overestimated
Product: [Eclipse Project] JDT Reporter: Art Dyer <art.dyer>
Component: CoreAssignee: Olivier Thomann <Olivier_Thomann>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: 3.1.2   
Target Milestone: 3.2.1   
Hardware: PC   
OS: Windows 2000   
Whiteboard:
Attachments:
Description Flags
Proposed fix none

Description Art Dyer CLA 2006-06-19 12:27:59 EDT
Discovered in 3.1.2; still present in 3.2RC7.

The compiler-generated <clinit> for an enum has a max stack depth that appears to be (2N + 4) where N is the number of constants in the enum.  But the truemaximum depth is a constant.  For an enum with a large number of constants, this error becomes significant.

enum Foo { A, B, C }

Here is an edited excert from "javap -verbose Foo".  I have added (in the first column) what I think the stack depth is after each instruction.  There are two main steps (constructing the constants and putting them in the array), and each step consists of N repetitions of the same template of instructions.  Each of the templates leaves the stack depth the same as it found it.  The deepest it gets is 4, but the class file says 10.  With 1000 constants, the class file says 2004.

static {};
  Code:
   Stack=10, Locals=0, Args_size=0

1  0:   new #1; //class Foo
2  3:   dup
3  4:   ldc #14; //String A
4  6:   iconst_0
1  7:   invokespecial #15; //Method "<init>":(Ljava/lang/String;I)V
0  10:  putstatic #19; //Field A:LFoo;

1  13:  new #1; //class Foo
2  16:  dup
3  17:  ldc #21; //String B
4  19:  iconst_1
1  20:  invokespecial #15; //Method "<init>":(Ljava/lang/String;I)V
0  23:  putstatic #22; //Field B:LFoo;

1  26:  new #1; //class Foo
2  29:  dup
3  30:  ldc #24; //String C
4  32:  iconst_2
1  33:  invokespecial #15; //Method "<init>":(Ljava/lang/String;I)V
0  36:  putstatic #25; //Field C:LFoo;

1  39:  iconst_3
1  40:  anewarray #1; //class Foo

2  43:  dup
3  44:  iconst_0
4  45:  getstatic #19; //Field A:LFoo;
1  48:  aastore

2  49:  dup
3  50:  iconst_1
4  51:  getstatic #22; //Field B:LFoo;
1  54:  aastore

2  55:  dup
3  56:  iconst_2
4  57:  getstatic #25; //Field C:LFoo;
1  60:  aastore

0  61:  putstatic #27; //Field ENUM$VALUES:[LFoo;
   64:  return
Comment 1 Olivier Thomann CLA 2006-06-20 10:56:24 EDT
Created attachment 44919 [details]
Proposed fix

We indeed miss to remove the arguments from the stack depth inside the invokespecial call.
Comment 2 Olivier Thomann CLA 2006-06-20 12:02:58 EDT
Fix released for 3.3 M1 in HEAD and released for 3.2.1 in TARGET_321 branch.
Regression test added in org.eclipse.jdt.core.tests.compiler.regression.EnumTest.test133.
Comment 3 Frederic Fusier CLA 2006-08-08 04:18:30 EDT
Verified for 3.3 M1 using build I20060807-2000.
Comment 4 David Audel CLA 2006-09-12 05:07:06 EDT
Verified for 3.2.1 using build M20060908-1655