Remove the assert in Integer.valueOf()
Rémi Forax
forax at univ-mlv.fr
Mon Apr 23 17:35:41 UTC 2012
Hi guys,
I've found a case where assert is harmful because it doesn't
play well with Hotspot inlining heuristic.
I'm currently playing with a lambda modified implementation of java.util and
as you see below Integer.valueOf is considered as too big by Hotspot
to be inlined.
79 2 b lambda.perf.Iterables::filterMapReduce
(72 bytes)
@ 4 java.util.AbstractList::iterator (10
bytes) inline (hot)
@ 6 java.util.AbstractList$Itr::<init>
(6 bytes) unloaded signature classes
@ 61 java.util.AbstractList$Itr::hasNext
(20 bytes) inline (hot)
@ 8 java.util.Arrays$ArrayList::size (6
bytes) inline (hot)
! @ 16 java.util.AbstractList$Itr::next (45
bytes) inline (hot)
@ 1
java.util.AbstractList$Itr::checkForComodification (23 bytes) inline (hot)
@ 14 java.util.Arrays$ArrayList::get (7
bytes) inline (hot)
@ 29 lambda.perf.Test$1::accept (9
bytes) inline (hot)
@ 5 lambda.perf.Test$1::accept (13
bytes) inline (hot)
@ 1 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 45 lambda.perf.Test$2::map (9 bytes)
inline (hot)
@ 5 lambda.perf.Test$2::map (2 bytes)
inline (hot)
@ 52 lambda.perf.Test$3::apply (13
bytes) inline (hot)
@ 9 lambda.perf.Test$3::apply (13
bytes) inline (hot)
@ 1 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 5 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 9 java.lang.Integer::valueOf (54
bytes) too big
@ 61 java.util.AbstractList$Itr::hasNext
(20 bytes) inline (hot)
@ 8 java.util.Arrays$ArrayList::size (6
bytes) inline (hot)
but the code of Integer.valueOf doesn't seem too big:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
The issue is that Hotspot also count the bytecodes related to assert
in its inlining heuristic.
If the assert is commented, the inlining tree is good.
88 2 b lambda.perf.Iterables::filterMapReduce (72 bytes)
@ 4 java.util.AbstractList::iterator (10
bytes) inline (hot)
@ 6 java.util.AbstractList$Itr::<init>
(6 bytes) unloaded signature classes
@ 61 java.util.AbstractList$Itr::hasNext
(20 bytes) inline (hot)
@ 8 java.util.Arrays$ArrayList::size (6
bytes) inline (hot)
! @ 16 java.util.AbstractList$Itr::next (45
bytes) inline (hot)
@ 1
java.util.AbstractList$Itr::checkForComodification (23 bytes) inline (hot)
@ 14 java.util.Arrays$ArrayList::get (7
bytes) inline (hot)
@ 29 lambda.perf.Test$1::accept (9
bytes) inline (hot)
@ 5 lambda.perf.Test$1::accept (13
bytes) inline (hot)
@ 1 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 45 lambda.perf.Test$2::map (9 bytes)
inline (hot)
@ 5 lambda.perf.Test$2::map (2 bytes)
inline (hot)
@ 52 lambda.perf.Test$3::apply (13
bytes) inline (hot)
@ 9 lambda.perf.Test$3::apply (13
bytes) inline (hot)
@ 1 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 5 java.lang.Integer::intValue (5
bytes) inline (hot)
@ 9 java.lang.Integer::valueOf (32
bytes) inline (hot)
@ 28 java.lang.Integer::<init> (10
bytes) call site not reached
@ 61 java.util.AbstractList$Itr::hasNext
(20 bytes) inline (hot)
@ 8 java.util.Arrays$ArrayList::size (6
bytes) inline (hot)
Given that Integer.valueOf() is a method used very often and that if the
inlining fails,
the escape analysis will not remove the allocation,
I think it's a good idea to comment this assert.
cheers,
Rémi
More information about the core-libs-dev
mailing list