Index: vmcore/include/jit_export.h =================================================================== --- vmcore/include/jit_export.h (revision 489062) +++ vmcore/include/jit_export.h (working copy) @@ -176,6 +176,11 @@ */ Boolean exe_restore_context_after_unwind : 1; + /** + * Sent CompileMethodLoad event when a method is compiled and loaded into memory + */ + Boolean exe_notify_compile_method_load : 1; + } OpenMethodExecutionParams; Index: jitrino/src/vm/drl/DrlVMInterface.cpp =================================================================== --- jitrino/src/vm/drl/DrlVMInterface.cpp (revision 489062) +++ jitrino/src/vm/drl/DrlVMInterface.cpp (working copy) @@ -984,17 +984,14 @@ return mayInline == TRUE; } -void DrlVMCompilationInterface::sendCompiledMethodLoadEvent(MethodDesc * methodDesc, +void DrlVMCompilationInterface::sendCompiledMethodLoadEvent(MethodDesc* methodDesc, MethodDesc* outerDesc, uint32 codeSize, void* codeAddr, uint32 mapLength, AddrLocation* addrLocationMap, void* compileInfo) { - // VM-JIT interface function should be called here instead of logging - if (Log::isEnabled()) { - Log::out() << " ** Inlined method: " - << methodDesc->getName() << std::endl; - Log::out() << " ** Number of locations:" << mapLength - << std::endl; - } - + + Method_Handle method = (Method_Handle)getRuntimeMethodHandle(methodDesc); + Method_Handle outer = (Method_Handle)getRuntimeMethodHandle(outerDesc); + + compile_method_load(method, codeSize, codeAddr, mapLength, addrLocationMap, compileInfo, outer); } bool DrlVMDataInterface::areReferencesCompressed() { Index: jitrino/src/vm/drl/DrlJITInterface.cpp =================================================================== --- jitrino/src/vm/drl/DrlJITInterface.cpp (revision 489062) +++ jitrino/src/vm/drl/DrlJITInterface.cpp (working copy) @@ -323,6 +323,9 @@ false, // exe_do_code_mapping false, // exe_do_local_var_mapping false, // exe_insert_write_barriers + false, // exe_provide_access_to_this + false, // exe_restore_context_after_unwind + false, // exe_notify_compile_method_load }; return compilation_capabilities; } Index: jitrino/src/vm/drl/DrlVMInterface.h =================================================================== --- jitrino/src/vm/drl/DrlVMInterface.h (revision 489062) +++ jitrino/src/vm/drl/DrlVMInterface.h (working copy) @@ -549,11 +549,10 @@ } bool isCompileLoadEventRequired() { - // additional compilation param is needed to handle this event - return false; + return compilation_params.exe_notify_compile_method_load; } - virtual void sendCompiledMethodLoadEvent(MethodDesc * methodDesc, + virtual void sendCompiledMethodLoadEvent(MethodDesc* methodDesc, MethodDesc* outerDesc, uint32 codeSize, void* codeAddr, uint32 mapLength, AddrLocation* addrLocationMap, void* compileInfo); Index: jitrino/src/vm/VMInterface.h =================================================================== --- jitrino/src/vm/VMInterface.h (revision 489062) +++ jitrino/src/vm/VMInterface.h (working copy) @@ -31,6 +31,7 @@ #include "open/types.h" #include "jit_export.h" +#include "jit_intf.h" #include #include #include "PlatformDependant.h" @@ -49,7 +50,6 @@ class PersistentInstructionId; class MemoryManager; class CompilationContext; -struct AddrLocation; /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// @@ -508,7 +508,7 @@ virtual bool isCompileLoadEventRequired() = 0; // send compile - virtual void sendCompiledMethodLoadEvent(MethodDesc * methodDesc, + virtual void sendCompiledMethodLoadEvent(MethodDesc* methodDesc, MethodDesc* outerDesc, uint32 codeSize, void* codeAddr, uint32 mapLength, AddrLocation* addrLocationMap, void* compileInfo) = 0; @@ -566,12 +566,6 @@ CompilationContext* compilationContext; }; -// AddrLocation data structure should be put in VM-JIT interface -struct AddrLocation { - void* start_addr; - uint16 location; -}; - class DataInterface { public: virtual ~DataInterface() {} Index: jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp =================================================================== --- jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (revision 489062) +++ jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (working copy) @@ -46,7 +46,7 @@ :memoryManager(0x1000, "CodeEmitter"), exceptionHandlerInfos(memoryManager), constantAreaLayout(memoryManager), traversalInfo(memoryManager), methodLocationMap(memoryManager), - entryExitMap(memoryManager) + entryExitMap(memoryManager), instSizeMap(memoryManager) { } @@ -72,6 +72,7 @@ void orderNodesAndMarkInlinees(StlList& container, Node * node, bool isForward); void reportCompiledInlinees(); + void reportInlinedMethod(CompiledMethodInfo* methInfo, MethodMarkerPseudoInst* methEntryInst); //------------------------------------------------------------------------------------ class ConstantAreaLayout @@ -131,22 +132,48 @@ StlVector traversalInfo; StlMap methodLocationMap; StlMap entryExitMap; + StlMap instSizeMap; }; + +typedef StlMap LocationMap; + class CompiledMethodInfo { public: - CompiledMethodInfo(MemoryManager& mm): locationList(mm) {} + CompiledMethodInfo(MemoryManager& mm, POINTER_SIZE_INT addr, MethodMarkerPseudoInst* outerEntry, uint32 idpth): + memoryManager(mm), + locationMap(memoryManager), + codeSize(0), + codeAddr(addr), + outerMethodEntry(outerEntry), + inlineDepth(idpth) + {} uint32 getCodeSize() { return codeSize; } - void* getCodeAddr() { return codeAddr; } + uint32 getInlineDepth() { return inlineDepth; } + POINTER_SIZE_INT getCodeAddr() { return codeAddr; } + MethodMarkerPseudoInst* getOuterMethodEntry() { return outerMethodEntry; } protected: friend class CodeEmitter; - StlList* > locationList; + MemoryManager& memoryManager; + LocationMap locationMap; uint32 codeSize; - void* codeAddr; - void setCodeSize(uint32 size) { codeSize = size; } - void setCodeAddr(void* addr) { codeAddr = addr; } - void addLocation(std::pair* entry) { - locationList.push_back(entry); + POINTER_SIZE_INT codeAddr; + MethodMarkerPseudoInst* outerMethodEntry; + // inlineDepth == 1 means that CompiledMethod is inlined into irManager->getMethodDesc() + uint32 inlineDepth; + + void addCodeSize(uint32 size) { codeSize += size; } + + void includeInst(Inst* inst, uint64 bcOffset) { + if( inst->hasKind(Inst::Kind_PseudoInst)) { + return; + } else { + addCodeSize(inst->getCodeSize()); + } + + POINTER_SIZE_INT instStartAddr = (POINTER_SIZE_INT) inst->getCodeStartAddr(); + assert(!locationMap.has(instStartAddr)); + locationMap[instStartAddr] = (uint16)bcOffset; } private: @@ -348,7 +375,12 @@ uint8 * blockStartIp = ip; bb->setCodeOffset( blockStartIp-codeStreamStart ); for (Inst* inst = (Inst*)bb->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) { - if( inst->hasKind(Inst::Kind_PseudoInst)) continue; + if( inst->hasKind(Inst::Kind_PseudoInst)) { + + uint8 * instStartIp = ip; + inst->setCodeOffset( instStartIp-blockStartIp ); + continue; + } #ifdef _EM64T_ if (inst->hasKind(Inst::Kind_ControlTransferInst) && @@ -679,32 +711,40 @@ for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) { if (inst->getKind() == Inst::Kind_MethodEntryPseudoInst) { + // keep old method entry + MethodMarkerPseudoInst* oldMethodEntryInst = methMarkerInst; + assert(!oldMethodEntryInst || oldMethodEntryInst->getKind() == Inst::Kind_MethodEntryPseudoInst); + // set new methMarkerInst methMarkerInst = (MethodMarkerPseudoInst*)inst; - inlineStack.push_back(methMarkerInst); - methInfo = new(memoryManager) CompiledMethodInfo(memoryManager); - methInfo->setCodeAddr(methMarkerInst->getCodeStartAddr()); + inlineStack.push_back(methMarkerInst); + // construct new inlined method info + methInfo = new(memoryManager) CompiledMethodInfo(memoryManager, + (POINTER_SIZE_INT)methMarkerInst->getCodeStartAddr(), + oldMethodEntryInst, + inlineStack.size()); + methodLocationMap[methMarkerInst] = methInfo; } else if (inst->getKind() == Inst::Kind_MethodEndPseudoInst) { methMarkerInst = (MethodMarkerPseudoInst*)inst; assert(((MethodMarkerPseudoInst*)inlineStack.back())->getMethodDesc() == methMarkerInst->getMethodDesc()); entryExitMap[methMarkerInst] = inlineStack.back(); - if (methInfo != NULL) { - Inst* entryInst = inlineStack.back(); - POINTER_SIZE_INT codeSize = (POINTER_SIZE_INT)entryInst->getCodeStartAddr() - - (POINTER_SIZE_INT)methMarkerInst->getCodeStartAddr(); - methInfo->setCodeSize((uint32)codeSize); - } inlineStack.pop_back(); methMarkerInst = NULL; } else { //handle usual instructions if (methMarkerInst != NULL) { // inlined locations for methMarkerInst assert(methInfo == methodLocationMap[methMarkerInst]); + if( ! inst->hasKind(Inst::Kind_PseudoInst)) { + instSizeMap[(POINTER_SIZE_INT) inst->getCodeStartAddr()] = inst->getCodeSize(); + } uint64 instID = inst->getId(); uint64 bcOffset = bc2LIRMapHandler->getVectorEntry(instID); - - if (bcOffset != ILLEGAL_VALUE) { - POINTER_SIZE_INT instStartAddr = (POINTER_SIZE_INT) inst->getCodeStartAddr(); - methInfo->addLocation(new(memoryManager) std::pair(instStartAddr, (uint16)bcOffset)); + methInfo->includeInst(inst,bcOffset); + // addLocation with ILLEGAL_VALUE for all outers + MethodMarkerPseudoInst* outerEntry = methInfo->getOuterMethodEntry(); + while (outerEntry) { + CompiledMethodInfo* outerInfo = methodLocationMap[outerEntry]; + outerInfo->includeInst(inst, ILLEGAL_VALUE); + outerEntry = outerInfo->getOuterMethodEntry(); } } } @@ -743,6 +783,70 @@ } +void CodeEmitter::reportInlinedMethod(CompiledMethodInfo* methInfo, MethodMarkerPseudoInst* methEntryInst) { + AddrLocation* addrLocationMap = new(memoryManager) AddrLocation[methInfo->locationMap.size()]; + + MethodDesc* method = methEntryInst->getMethodDesc(); + MethodMarkerPseudoInst* outerEntry = methInfo->getOuterMethodEntry(); + MethodDesc* outer = (outerEntry != NULL) ? outerEntry->getMethodDesc() : &irManager->getMethodDesc(); + + LocationMap::const_iterator lit, + litStart = methInfo->locationMap.begin(), + litEnd = methInfo->locationMap.end(); + + POINTER_SIZE_INT methodStartAddr = methInfo->getCodeAddr(); + POINTER_SIZE_INT prevAddr = 0; + uint32 methodSize = 0; + uint32 locationMapSize = 0; + + for (lit = litStart; lit != litEnd; lit++) { + + POINTER_SIZE_INT addr = (*lit).first; + uint16 bcOffset = (*lit).second; + assert( addr > prevAddr); // locationMap content must be ordered + + if (addr != prevAddr + instSizeMap[prevAddr] && methodSize > 0) { + // gap in layout + assert(instSizeMap.has(prevAddr)); + assert(addr > prevAddr + instSizeMap[prevAddr]); + + // report already gathered + irManager->getCompilationInterface().sendCompiledMethodLoadEvent(method, outer, methodSize, + (void*)methodStartAddr, locationMapSize, addrLocationMap, NULL); + if (Log::isEnabled()) { + Log::out() << "Reporting Inlinee (part) " << method->getParentType()->getName() << "." + << method->getName() << " "; + Log::out() << "Outer = " << outer->getParentType()->getName() << "." << outer->getName(); + Log::out() << " start=" << methodStartAddr << " size=" << methodSize << ::std::endl; + } + + // reset values + methodStartAddr = addr; + addrLocationMap += locationMapSize; // shift pointer + locationMapSize = 0; + methodSize = 0; + + } + + // process current location + addrLocationMap[locationMapSize].start_addr = (void*)addr; + addrLocationMap[locationMapSize].location = bcOffset; + locationMapSize++; + methodSize += instSizeMap[addr]; + prevAddr = addr; + } + // report final + irManager->getCompilationInterface().sendCompiledMethodLoadEvent(method, outer, methodSize, + (void*)methodStartAddr, locationMapSize, addrLocationMap, NULL); + if (Log::isEnabled()) { + Log::out() << "Reporting Inlinee (final) " << method->getParentType()->getName() << "." + << method->getName() << " "; + Log::out() << "Outer = " << outer->getParentType()->getName() << "." << outer->getName(); + Log::out() << " start=" << methodStartAddr << " size=" << methodSize << ::std::endl; + } + +} + void CodeEmitter::reportCompiledInlinees() { StlList inlineList(memoryManager); traversalInfo.resize(irManager->getFlowGraph()->getMaxNodeId() + 1, 0); @@ -751,23 +855,23 @@ StlMap::const_iterator i, itEnd = methodLocationMap.end(); - //std::cout << " * Method: " << irManager.getMethodDesc().getName() << std::endl; - for (i = methodLocationMap.begin(); i != itEnd; i++) { - MethodMarkerPseudoInst* metEntryInst = (MethodMarkerPseudoInst*)i->first; - CompiledMethodInfo* methInfo = (CompiledMethodInfo*)i->second; - AddrLocation* addrLocationMap = new(memoryManager) AddrLocation[methInfo->locationList.size()]; - StlList* >::const_iterator lit, - litEnd = methInfo->locationList.end(); - int j = 0; - for (lit = methInfo->locationList.begin(); lit != litEnd; lit++) { - addrLocationMap[j].start_addr = (void*)(*lit)->first; - addrLocationMap[j].location = (*lit)->second; + // send events according to inlining depth + // depth == 1 - the first level inlinees + bool found = false; + uint32 depth = 1; + do { + found = false; + for (i = methodLocationMap.begin(); i != itEnd; i++) { + MethodMarkerPseudoInst* methEntryInst = (MethodMarkerPseudoInst*)i->first; + CompiledMethodInfo* methInfo = (CompiledMethodInfo*)i->second; + if (depth == methInfo->getInlineDepth()) { + found = true; + reportInlinedMethod(methInfo, methEntryInst); + } } - irManager->getCompilationInterface().sendCompiledMethodLoadEvent(metEntryInst->getMethodDesc(), - methInfo->codeSize, methInfo->codeAddr, (uint32)methInfo->locationList.size(), - addrLocationMap, NULL); - } + depth++; + } while (found); }