... normal Java threads and contains events for methods being enqueued for compilation, uncommon traps that invalidate a method and other events. The other part of the log comes from the compiler threads themselves. During the execution the compiler threads write their logs to temporary files with names of the form hs_c#_<pid>.log where # is the number of the thread using by the compiler thread. At VM shutdown the separate logs are appended onto the main hotspot.log to form the final complete log.
The output from the compiler is basically a log of the stages of the compile along with the high level decisions made during the compile such as inlining. The individual log for a compiler thread is wrapped by the compilation_log element which has a single attribute 'thread' which is the id thread in which the compiler runs.
<compilation_log thread=''> .. </compilation_log>
There's a start_compile_thread element which mainly gives a timestamp for the start time.
<start_compile_thread thread='1090857296' process='6053' stamp='1.241'/>
Many elements contain time stamps as the end which can be used to order them relative to events in other threads and the measure elapsed time. The time stamp is in seconds since the start of the VM and the start time of the VM is recorded in the hotspot_log element in the time_ms attribute.
Methods to be compiled are placed into the compile queue and the compiler threads dequeue them and compile them as long as there are elements in the queue. Each individual compile is shown as a 'task' element.
<task compile_id='1' method='java/lang/Thread <init> (Ljava/lang/ThreadGroup;Ljava/lang/String;)V' bytes='49' count='6' iicount='6' blocking='1' stamp='1.242'> ... <task_done success='1' nmsize='1216' count='0' inlined_bytes='111' stamp='1.550'/> </task>
Every compile is assigned a compile id by the system at the point is is enqueued and that's recorded as the compile_id attribute. Some compiles are on stack replacement (OSR) compile where the code is going to be used to replace an already existing activation. These are tagged by the compile_kind attribute as compile_kind='osr'. It can also have the value c2n for compiled native wrappers which are used to call JNI methods.
The 'method' attribute is a string version of the VM name of the method with spaces separating the class, method name signature.
The 'bytes' attribute is number of bytecodes in the method.
'count' is the invocation count as recorded by the method invocation counters. This may not appear in more recent versions of the log output. Note that these counters are mainly used for triggering compiles and are not guaranteed to be an accurate reflection of the number of times a method has actually executed. Multiple threads may be updated these counters and sometimes the VM will reset a counter to a lower value to delay retriggering of compiles.
'iicount' is the interpreter invocation count. This is a separate copy of the invocation count which is maintained by the profiling support. Again it's not guaranteed to be accurate since multiple threads may update it but it's never reset so it's reasonably accurate.
'blocking' indicates whether the thread that requested the compile is waiting for the compile to finish before proceeding. By default threads don't wait but using -XX:-BackgroundCompilation or -Xbatch will cause them to wait.
The task_done element indicates completion of the compile and includes a 'success' element to indicate whether the compile succeeded. If it succeeded there will be an 'nmsize' attribute which indicates the number of bytes of instruction produced by the compile. The main log includes a more detailed element describing the resulting nmethod and that is described elsewhere. 'inlined_bytes' indicates how many bytecodes where inlined from other methods during the compile.
Each phase of the compilation is wrapped by a 'phase' element which records the name of the phase, the maximum number of nodes in the IR at that point and the timestamp.
<phase name='parse' nodes='3' stamp='1.543'> ... <phase_done nodes='403' stamp='1.545'/> </phase>
Phases may nest and may be repeated. Some phases may only run if certain flags are on or if certain conditions are met.
In C2 the rough structure of the phases is this:
* parse * escapeAnalysis * optimizer ** iterGVN ** idealLoop ** ccp ** iterGVN2 ** idealLoop ** macroExpand ** graphReshape * matcher * scheduler * regalloc * output * install_code
The parse phase may be repeated recursively when handling inlining.
<type id='482' name='void'/>
Many of the elements have to reference classes or methods and this is done by emitting elements that describe "id" to "name" mappings for them. "type" elements describe primitive types.
<klass id='575' name='[B' flags='1041'/> <klass id='608' name='sun/misc/URLClassPath$FileLoader' unloaded='1'/>
"klass" elements describe instance and array types. These either have a "flags" attribute which corresponds to the class flags from the class file or an "unloaded" attribute that indicates the class wasn't loaded at that point.
<method id='586' holder='521' name='checkBounds' return='482' arguments='575 480 480' flags='10' bytes='46' iicount='51'/>
"method" elements refers back to previously mentioned type or klass elements.
"holder" is the id of klass that declares the method. "name" is the method name. "arguments" is a list of ids that correspond to the argument types. "flags" is the method access flags encoded as the classfile would. "bytes" is the number of bytecodes. "iicount" is the interpreter invocation count at the point it was emitted into the log.
<bc code='190' bci='28'/>
Many pieces of output are prefixed by "bc" elements which indicate what the current bytecode in the parse is. "code" is the number of the bytecode itself and "bci" is the current bci.
<dependency type='unique_concrete_method' ctxk='586' x='604'/>
A "dependency" element indicates that class hierarchy analysis has indicated some interesting property of the classes that allows the compiler to optimistically assume things like there are no subclasses of a particular class or there is only one implementor of a particular method. The "type" attribute describes what kind of dependence this is. The "ctkx" attribute is a context class for the dependence. The "x" attribute is the method involved in the dependence.
<uncommon_trap method='589' bci='36' reason='unloaded' action='reinterpret' index='46' klass='608'/>
<uncommon_trap bci='28' reason='null_check' action='maybe_recompile'/>
"uncommon_trap" elements correspond to points in the bytecode parsing where the compiler decided to stop parsing the bytecodes and emit an uncommon trap. Uncommon traps are always emitted to handled unloaded classes by dropping out of the compiled code and back into the interpreter. They are also emitted in cases where some particular path or code pattern is considered uncommon and the compiler puts in the uncommon trap so that if that path becomes more common it can detect it so the method can be recompiled.
The uncommon trap element is used in 2 different ways in the output. It describes the emission of the trap during parse and also describes the event when the trap triggers during execution. The attributes in these 2 cases are different. All uncommon traps have "reason" and "action" attributes that drive their behaviour.
These are the reasons:
* array_check * class_check * div0_check * intrinsic * null_assert * null_check * range_check * unhandled * uninitialized * unloaded
And these are the possible actions
* make_not_entrant * maybe_recompile * none * reinterpret
They also have "bci" attributes to indicate where they occur in the current parse. Some have "index" attributes that refer back to the constant pool of containing method and indicate an entry which needs to resolved.
Sometimes "uncommon_trap" elements are used to handle exception paths so they will occur inline with before other elements. In this case they haven't terminated the main parse but only the exception path.
uncommon_trap elements may occur outside of the compilation_log portion of the output and these indicate that the uncommon trap in the generated code was executed. These include a "thread" attribute for the executing thread, the "compile_id", "compiler" and "level" of the nmethod that contained the trap.
<call method='596' count='-1' prof_factor='1'/>
"call" elements are emitted when processing call sites in the bytecodes. "method" refers to a method attribute describing the method to be invoked. "count" is the count of the number of times this site was execute according to the profile data. A "virtual" attribute indicates that we can't bind the method statically. The "inline" attribute indicates that inlining is allowed at this site. If the profile information includes a type profile of the possible receivers this will be included as "receiver", "receiver_count", "receiver2" and "receiver2_count".
The call element may be followed by several different attributes to indicate how it was handled. It may be followed by an "uncommon_trap" which indicates that something about the call was unhandled or it wasn't expected to be needed. If it's followed by "parse" then the method was inlined.
<inline_fail reason='already compiled into a medium method'/> <direct_call bci='115'/>
A "direct_call" following the "call" means that we just emitted a normal call to the method. It may be preceded by an "inline_fall" attribute if we attempted to inlined but decided against it because of the inlining heuristics. It includes a "reason" attribute which is a textual description from the inlining logic.
<intrinsic id='_compareTo' nodes='27'/>
An "intrinsic" is a special internal implementation of a method. The "id" attribute is the internal name of the intrinsic. The actual method it applies to should be the one mentioned in the original "call" element.
Some call sites will be handled by using type profile information to emit type checks for common types and execute inlined versions for those cases. The output for these is somewhat complicated. "call" elements will be emitted for the expected methods followed by "predicted_call" elements.
<predicted_call bci='4' klass='600'/>
This indicates that a check for "klass" was emitted. These may also be followed by "uncommon_trap" elements. The sequence may be terminated by a class_check uncommon_trap with the comment "monomorphic vcall checkcast" to indicate that the predicted types were the only type we saw so any other type should cause an uncommon trap so the method can be recompiled. The whole sequence will then be followed by the code generation for each of the predicted methods which should be a "parse" phase for the inlining. |