Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JVM class format: Why is `constant_pool_count` one larger than it "should" be?

Tags:

java

jvm

The JVM class file format uses constant_pool_count to specify the size of a class's constant pool:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

Where constant_pool_count is defined as

The value of the constant_pool_count item is equal to the number of entries in the constant_pool table plus one.

Why the is the count specified in this "plus one" way instead of just being equal to the number of constants? Meanwhile, interfaces_count, fields_count, methods_count, and attributes_count don't seem to follow this pattern.

Some guesses:

  • It could have something to do with achieving optimal byte alignment
  • Perhaps it's an artifact of a particular design decision elsewhere in the JVM

Update: This section on Wikipedia doesn't do much to clarify:

Due to historic choices made during the file format development, the number of constants in the constant pool table is not actually the same as the constant pool count which precedes the table. First, the table is indexed starting at 1 (rather than 0), but the count should actually be interpreted as the maximum index plus one.[3] Additionally, two types of constants (longs and doubles) take up two consecutive slots in the table, although the second such slot is a phantom index that is never directly used.

The second part explains why the count doesn't necessarily equal the number of constants if any of them happen to be long or double, however it still isn't clear why the "plus one" has anything to do with 1-based indexing if they subtract it off the array length anyway.

like image 366
Greg Haskins Avatar asked Oct 31 '22 23:10

Greg Haskins


1 Answers

because constant_pool_count itself is contained in the constaint_pool(the first constant). that is logically constaint_pool[0] == constant_pool_count.

but constant_pool_count is a field in the ClassFile structure, constant_pool array does not necessary to contain it any more.

so remove constant_pool_count from constant_pool array, the constant_pool array's length will be constant_pool_count - 1.

deleted:

BTW: as you can notice, the constant_pool_count is u2, the constant_pool entries are cp_info(u1+u1=u2), u2 and cp_info are equivelant structure in length.

consider u2 as {u1; u1[1]}, it is similar to cp_info{u1; u1[]}.

like image 143
Xing Fei Avatar answered Nov 09 '22 12:11

Xing Fei