Clarification on hot_throw optimisation

Chris Newland cnewland at chrisnewland.com
Fri Sep 9 06:48:05 UTC 2016


Hi all,

I'm adding support for highlighting the hot_throw HotSpot optimisation in
JITWatch (a LogCompilation visualiser) [1] and would like to ask if I've
understood it correctly please.

Example code:
https://github.com/AdoptOpenJDK/jitwatch/blob/master/core/src/main/resources/examples/HotThrow.java

Issue where I've tried to note my findings:
https://github.com/AdoptOpenJDK/jitwatch/issues/223

======================================
import java.util.Random;

public class HotThrow
{
    private Random random = new Random();

    public HotThrow()
    {
        StringBuilder builder = new StringBuilder();

        String string = "The quick brown fox jumps over the lazy dog";

        char[] chars = string.toCharArray();

        for (int i = 0 ; i < 1_000_000; i++)
        {
            int index = random.nextInt(100);

            char c = getChar(chars, index);

            builder.append(c);
        }

        System.out.println(builder.toString());
    }

    public char getChar(char[] chars, int index)
    {
        try
        {
            return chars[index];
        }
        catch(ArrayIndexOutOfBoundsException e)
        {
            return '*';
        }
    }

    public static void main(String[] args)
    {
        new HotThrow();
    }
}
======================================

I believe that the range check on the array index was eliminated in C2 but
hit a trap when index was out of range.

HotSpot then detected this as a hot throw in vm/opto/graphKit.cpp

case Deoptimization::Reason_range_check:
      ex_obj = env()->ArrayIndexOutOfBoundsException_instance();
      break;

and because there was a local exception handler it uses a pre-allocated
AIOOBE (without a stack trace?) and didn't deoptimise or drop back to the
interpreter.

JITWatch looks for LogCompilation like:

    <parse method="832" stamp="0.187" uses="10000">
      <observe total="-1" count="-1" trap="range_check"/>
      <observe that="has_exception_handlers"/>
      <bc code="52" bci="2"/>
      <uncommon_trap reason="null_check" bci="2" action="maybe_recompile"/>
      <observe count="-1" trap="range_check"/>
      <hot_throw reason="range_check" preallocated="1"/>
      <parse_done nodes="75" memory="31744" stamp="0.187" live="72"/>
    </parse>

and I then use bci reference and the method bytecode Exception table to
look up the exception type and highlight it in the JITWatch UI:
https://www.chrisnewland.com/images/jitwatch/release1.1/hotthrow.png

Is this correct?

I didn't quite understand the comment in graphKit

  // Note:   If the deopt count has blown up, the uncommon trap
  // runtime is going to flush this nmethod, not matter what.

Will the hot_throw optimisation stop working after a certain count? I've
not observed that yet.

Many thanks,

Chris
@chriswhocodes

[1] https://github.com/AdoptOpenJDK/jitwatch





More information about the hotspot-compiler-dev mailing list