Saturday, 18 June 2011

Megamorphic

Finished implementing megamorphic ICs for x86_32. The performance improvement seems to be minimal (performs worse for some benchmarks). Planning to add a stats collector for ICs to see what's going on.

Things to lookout for:-

# of ICed callsites with 1 or 2 calls - Large number implies we are spending too much time on ICing callsites which don't gain anything from IC.

# of callsites with a miss after 1 or 2 hits - Megamorphic callsites. This number should not be too high.

Saturday, 11 June 2011

Design of IC - emission of callsite

See a discussion regarding IC design here

The discussion is one how to implement the inline cached callsite code emission.

Wednesday, 8 June 2011

Three kinds of classes

Primitive
These are classes which correspond to primitive data types like short. Note that these are different from the classes java.lang.Short and such. These classes are preloaded by Jato and used only by Java Standard Library.
Array
These are classes which correspond to types of references like
int [] ia = new int[10];
There cannot be any subclasses for these classes.
Regular
All other "normal" classes fall into this category.

Monday, 6 June 2011

PATCH: Support for multiple entry points for methods

Support for multiple entry points for methods

The existing code assumes that each method has a unique entry point which can be used as the call target. This assumption is no longer valid when inline caching is enabled. Each virtual method will have two entry points an unverified or normal entry point which is the same as current entry point and a verified entry point which assumes that the function was called from a call-site with inline cache.

The entry points are stored in *_entry_point fields in the struct compilation_unit. For Java methods, these fields are set inside emit_machine_code().

cu->entry_point
This is the normal entry point for a method. For native methods, this points to the native code. For Java methods, this points to the unverified entry point.
cu->ic_entry_point
This points to the verified entry point for Java methods. This field is NULL for methods for which inline caching is not applicable.
cu_entry_point() or cu_ic_entry_point() returns addresses that can be used as call targets. These functions should be favoured compared to buffer_ptr(cu->objcode) for obtaining call targets.

buffer_ptr(cu->objcode) returns the address of the first machine instruction generated for the method. This may or may not be a valid entry point. This should not be used for fetching entry points.

Thursday, 2 June 2011

Plan for inline caching on x86_32

HotSpot passes the first two int/reference args in registers. For non-static methods this means this argument is always available in a register for inline cache check. The number of memory accesses is 1.

Jato passes this argument on stack. So obtaining this->class will require 2 memory accesses. We could use this pointer available at call-site in a register.

The call site code generated looks like this

/* edi contains this pointer */
mov %(edi), %ecx /* This works as null check and also passes this->class to #fn */
mov #imm, %eax
call #fn


The #imm and #fn fields depends on the state of the inline cache.

Clean state

#imm = vm_method *
#fn = inline_cache_setup

Monomorphic state

#imm = expected class
#fn = verified entry point of the method

Megamorphic state

#imm = vtable index of the virtual method
#fn = vtable lookup routine

The inline cache check can be

cmp %eax, %ecx
jne inline_cache_miss_handler


inline_cache_setup implements the transition from clean to monomorphic. inline_cache_miss_handler implements the transition from monomorphic to megamorphic.

Both routines along with the vtable lookup routine can use this->class passed in ecx for vtable lookup.