Bug 147747 - max stack for clinit of enum overestimated
Summary: max stack for clinit of enum overestimated
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1.2   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 3.2.1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-19 12:27 EDT by Art Dyer CLA
Modified: 2006-09-12 05:07 EDT (History)
0 users

See Also:


Attachments
Proposed fix (4.36 KB, patch)
2006-06-20 10:56 EDT, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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