Closed
Description
We found the implementation of layout encoding and decoding is asymmetric:
// encoding
public static int forArray(boolean isObject, int arrayBaseOffset, int arrayIndexShift) {
int tag = isObject ? ARRAY_TAG_OBJECT_VALUE : ARRAY_TAG_PRIMITIVE_VALUE;
int encoding = (tag << ARRAY_TAG_SHIFT) | (arrayBaseOffset << ARRAY_BASE_SHIFT) | (arrayIndexShift << ARRAY_INDEX_SHIFT_SHIFT);
// assertions
assert !isInstance(encoding) && isArray(encoding);
assert isObjectArray(encoding) == isObject;
assert isPrimitiveArray(encoding) != isObject;
assert getArrayBaseOffset(encoding).equal(WordFactory.unsigned(arrayBaseOffset));
^^^^^^^^^^^^^^^^^^^^^^^^^^ throw AssertionError
assert getArrayIndexShift(encoding) == arrayIndexShift;
return encoding;
}
// decoding
public static UnsignedWord getArrayBaseOffset(int encoding) {
return WordFactory.unsigned((encoding >> ARRAY_BASE_SHIFT) & ARRAY_BASE_MASK);
^^^^^^^^^^^^^^^^
}
In encoding method, arrayBaseOffset
has 22 bits which range from 8th to 29th inclusively, but in decoding method, arrayBaseOffset
only contains 8 bits because of array base mask (255), this
would cause a potential problem if array base offset excesses 255, we can reproduce this scenario by the following case:
import sys
TMPL = "public class C{} implements I{}, I{}, I{} {{}}"
TMPL2 = "public interface I{} {{}}"
if __name__ == "__main__":
N = 1000
for i in range(0,N):
with open('C{}.java'.format(i), 'w') as f:
f.write(TMPL.format(i,i,((i + 3) % N), ((i+5) % N)))
with open('I{}.java'.format(i), 'w') as f:
f.write(TMPL2.format(i))
with open('Main.java', 'w') as f:
f.write("public class Main {")
f.write("public static void main(String[] args) {")
f.write("int hash = 0;");
for i in range(0,N):
f.write("C{} c{} = new C{}();".format(i, i, i));
f.write("hash ^= c{}.hashCode();".format(i));
f.write("System.exit(hash);}}")
Commands:
python gen.py
javac Main.java
native-image -J-ea Main
This script will generate many interfaces and classes, and lead to big interface-bits.
native-image will throw an AssertError due to the previous problem. Is this a bug or an intentional design of native-image?
Can we change the ARRAY_BASE_MASK from 255 to (1 << (Integer.SIZE - ARRAY_TAG_BITS - ARRAY_BASE_SHIFT)) - 1 ?
Metadata
Metadata
Assignees
Labels
No labels