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