Clarification on hot_throw optimisation

Chris Newland cnewland at
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:

Issue where I've tried to note my findings:

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);



    public char getChar(char[] chars, int index)
            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();

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

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"/>

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:

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,



More information about the hotspot-compiler-dev mailing list