There is one issue we must be careful about when decompressing an archive. Normally, when we need to create a reference to a constant pool entry in a reconstructed classfile, we can just assign the element referenced to any free slot in the constant pool. However, the bytecode LDC instruction can only encode an index in the range 1-255. These instructions can only reference integer, float and string constants.
The first fix is to assign integer, float and string constant pool entries the smallest available index. Other constant pool entries are assigned in the largest available index; we transmit the total number of constant pool entries required as part of are encoding.
This almost fixes the problem. However, if there are more than 255 integer, float and string constants referenced in a classfile, which ones are assigned small indices? We would like to ensure that the same set of constants is assigned small indices as in the original classfile; otherwise, we would have to change some LDC instructions to LDC_W instructions, which are of different sizes. This would then require patching all jump offsets that traversed the changed instruction.
Instead, if a integer, float or string constant is referenced with a LDC_W instruction, then it is assigned a high constant pool index; if it is referenced with a LDC instruction, it is assigned a low constant pool index. This assumes that a classfile doesn't reference the same constant pool entry with both a LDC and a LDC_W instruction. It would be inefficient to do so, and can be fixed (and made more efficient) when the classfile is encoded if necessary.
This almost fixes the problem, except that a
integer, float or string constant can also be referenced
as a constant value for a field. We use an additional bit
in the access flags for a field
to encode whether a constant value int/float/string
should be assigned a high index.