openj9
openj9 copied to clipboard
JITServer shared fanin cache
Fanin data is used by the Inliner to determine from how many different places a callee is invoked. Fanin data is collected by the interpreter profiler and is kept per j9method caller. For each caller we have a linked list of up to 20 entries of <caller, pcIndex, numSamples> (the searching key is <caller, pcIndex>). Currently, the fanin data is serialized and sent to server every time the server creates a j9ResolvedMethod (this happens very often).
This PR proposes to store fanin data at the server in a shared repository (JITServerSharedProfileCache hashtable) that can be accessed by different clients. The 'key' to search for the fanin data of a particular method is a AOTCacheMethodRecord. The 'value' is a ProfiledMethodEntry which includes a FaninProfile. For simplicity, the FaninProfile of a method will include only 3 fields:
class FaninProfile
{
uint64_t _numSamples; // Total number of fanin samples for this callee
uint64_t _numSamplesOtherBucket; // Number of samples falling in the 'otherBucket'
uint32_t _numCallers; // Number of different callers (max is MAX_IPMETHOD_CALLERS+1)
};
This simplified view is enough for the Inliner to take appropriate inlining decisions. In a future PR we may eliminate the list of callers that are sent by the client to the server because their identity is not important for performance.
Flow if information:
- The server creates a TR_ResolvedJ9JITServerMethod. As part of that process the server sends a message to the client to create a resolved method mirror and the client embeds the fanin info in the reply (serialized info).
- The server stores fanin info into the resolved method (with "heap" memory) by using
TR_ResolvedJ9JITServerMethod::unpackMethodInfo()which callsiProfiler->cacheFaninDataForMethod() - The server may have two different sources of fanin info: (1) the data sent by the client and (2) the data stored in the shared profile cache The server compares the quality of the data of both sources using
JITServerSharedProfileCache::compareFaninProfiles()and picks the source of higher quality. At this point the quality is judged solely based on the total number of samples. - If the shared profile repository has better fanin quality, the server will load that using
clientSession->loadFaninDataFromSharedProfileCache(); - If the client has better fanin quality, the server deserializes the data from the client with
deserializeFaninMethodEntry(), but also stores this information into the shared profile repository:clientSession->storeFaninDataInSharedProfileCache() - If the two fanin sources are about the same in tems of quality, then the server picks the data sent by the client because it is fresher.
- At a later point, the Inliner reads the fanin info stored in the J9ResolvedMethod.
Storing the fanin data into the shared profile repository: ClientSessionData::storeFaninDataInSharedProfileCache(TR_OpaqueMethodBlock *method, const TR_ContiguousIPMethodHashTableEntry *serialEntry)
- The server converts the incoming j9method into a
AOTCacheMethodRecord. To do so, first the server uses the j9method as a key into the_J9MethodMapto find the correspondingJ9MethodInfoand from there it returns_aotCacheMethodRecord. If theaotCacheMethodRecorddoes not yet exist, it will be created by usinggetClassRecord()andgetMethodRecord() - The obtained methodRecord is used as a key into the
JITServerSharedProfileCachehashtable to retrieve aProfiledMethodEntry - If the desired
ProfiledMethodEntryexists, the server writes (or overwrites) the fanin data. - If the desired
ProfiledMethodEntrydoes not exist, the server creates a new one and writes the fanin data.
Loading the fanin data from the shared profile repository: ClientSessionData::loadFaninDataFromSharedProfileCache(TR_OpaqueMethodBlock *method, TR_Memory *trMemory)
- The server converts the incoming j9method into a
AOTCacheMethodRecord(see details in the storing procedure) - The obtained methodRecord is used as a key into the
JITServerSharedProfileCachehashtable to retrieve aProfiledMethodEntry - If the cached fanin exists, the server use "heap" memory to allocate a
TR_FaninSummaryInfostructure which be returned to the caller to be stored in the J9ResolvedMethod. If the cached fanin does not exist, the server returns a NULL pointer.