RFR: 8343019: Primitive caches must use boxed instances from the archive [v4]
Jiangli Zhou
jiangli at openjdk.org
Wed Oct 30 19:10:18 UTC 2024
On Tue, 29 Oct 2024 13:04:18 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:
>> src/java.base/share/classes/java/lang/Integer.java line 964:
>>
>>> 962: Integer[] c = new Integer[size];
>>> 963: int j = low;
>>> 964: // Use all cached values from the archive to avoid breaking
>>
>> Alternatively, you could use a separate array to store **only** the runtime created cached instances, without copying the references from the archived cache. Both the archived cache and runtime added cache are used. That has slightly less memory and efficiency overhead, but almost unnoticeable.
>
> I don't think I understand. The whole point is to make sure the runtime cache instances are the same as archive cache instances, right? Using both archived and runtime caches leads to identity inconsistencies: if we `==` compare the archived `Integer` box and the runtime `Integer` box of the same value in [-128; 127], they should equal each other. So we have to make sure we use the parts we have already committed to use (from the archive), and add whatever cache elements are missing at runtime. I don't see how it works otherwise.
The runtime cache would only store the additional boxed Integers not in the archived cache, without affecting the archived boxed Integers. Something like the following would work (I didn't test all corner cases):
static final int archivedSize;
...
archivedSize = archivedCache == null ? 0 : archivedCache.length;
if (archivedCache == null || size > archivedCache.length) {
int runtimeCacheSize = size - archivedSize;
Integer[] c = new Integer[runtimeCacheSize];
int j = low + archivedSize;
for(int i = 0; i < runtimeCacheSize; i++) {
c[i] = new Integer(j++);
}
cache = c;
if (archivedCache == null) {
archivedCache = c;
}
} else {
cache = null;
}
`Integer.valueOf()` would retrieve the cached boxed Integer either from the archived cache or the runtime created cache, if the value is within the runtime [low, high].
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) {
int index = i + (-IntegerCache.low);
if (IntegerCache.archivedSize != 0 && IntegerCache.archivedSize >= index) {
return IntegerCache.archivedCache[index];
} else {
return IntegerCache.cache[index - IntegerCache.archivedSize];
}
}
return new Integer(i);
}
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/21737#discussion_r1823234380
More information about the core-libs-dev
mailing list