Mercurial > hg > heapstats
changeset 166:6872a12a8688
Bug 2977: [REFACTORING][JDK 9] Add marking bitmap for ParNew GC at CMS Final Remark
author | Yasumasa Suenaga <yasuenag@gmail.com> |
---|---|
date | Thu, 02 Jun 2016 22:23:26 +0900 |
parents | a51e5042a3d1 |
children | 365f5563c84b |
files | agent/src/heapstats-engines/overrider.cpp agent/src/heapstats-engines/vmFunctions.cpp agent/src/heapstats-engines/vmFunctions.hpp agent/src/heapstats-engines/vmVariables.cpp agent/src/heapstats-engines/vmVariables.hpp |
diffstat | 5 files changed, 109 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/src/heapstats-engines/overrider.cpp Thu Jun 02 22:23:18 2016 +0900 +++ b/agent/src/heapstats-engines/overrider.cpp Thu Jun 02 22:23:26 2016 +0900 @@ -107,7 +107,7 @@ DEFINE_OVERRIDE_FUNC_1(watcherThread); /*! - * \brief Bitmap object for G1 GC. + * \brief Bitmap object for CMS and G1 GC. */ TBitMapMarker *checkObjectMap = NULL; @@ -893,7 +893,8 @@ */ void cleanupOverrider(void) { /* Cleanup. */ - if (TVMVariables::getInstance()->getUseG1()) { + TVMVariables *vmVal = TVMVariables::getInstance(); + if (vmVal->getUseCMS() || vmVal->getUseG1()) { delete checkObjectMap; checkObjectMap = NULL; } @@ -939,6 +940,8 @@ *needSnapShot = needSnapShotByCMSPhase; needSnapShotByCMSPhase = false; } else if (vmVal->getCMS_collectorState() == CMS_FINALMARKING) { + checkObjectMap->clear(); + /* switch hooking for CMS new generation. */ switchOverrideFunction(cms_new_hook, true); } @@ -1169,6 +1172,27 @@ bool setupForCMS(void) { SELECT_HOOK_FUNCS(cms_new); + TVMVariables *vmVal = TVMVariables::getInstance(); + const void *startAddr = vmVal->getYoungGenStartAddr(); + const size_t youngSize = vmVal->getYoungGenSize(); + +/* Create bitmap to check object collected flag. */ +#ifdef AVX + checkObjectMap = new TAVXBitMapMarker(startAddr, youngSize); +#elif(defined SSE2) || (defined SSE3) || (defined SSE4) + checkObjectMap = new TSSE2BitMapMarker(startAddr, youngSize); +#elif PROCESSOR_ARCH == X86 + checkObjectMap = new TX86BitMapMarker(startAddr, youngSize); +#elif PROCESSOR_ARCH == ARM + +#ifdef NEON + checkObjectMap = new TNeonBitMapMarker(startAddr, youngSize); +#else + checkObjectMap = new TARMBitMapMarker(startAddr, youngSize); +#endif + +#endif + if (unlikely(!setupOverrideFunction(cms_new_hook))) { logger->printCritMsg("Cannot setup to override CMS_new (ParNew GC)."); return false; @@ -1269,6 +1293,7 @@ /* Switch CMS hooking at new generation. */ switchOverrideFunction(cms_new_hook, enable); list = cms_sweep_hook; + checkObjectMap->clear(); } else if (vmVal->getUseG1()) { /* If users select G1, we prepare TSnapShotContainer NOW! */ snapshotByGC = TSnapShotContainer::getInstance(); @@ -1507,6 +1532,11 @@ return; } + if (checkObjectMap->checkAndMark(oop)) { + /* Object is in young gen and already marked. */ + return; + } + /* Invoke callback by CMS GC. */ cmsCallbackFunc(oop, NULL); } else if (vmVal->getUseG1()) {
--- a/agent/src/heapstats-engines/vmFunctions.cpp Thu Jun 02 22:23:18 2016 +0900 +++ b/agent/src/heapstats-engines/vmFunctions.cpp Thu Jun 02 22:23:26 2016 +0900 @@ -33,7 +33,7 @@ /*! * \brief Function pointer for "is_in_permanent". */ -THeap_IsInPermanent is_in_permanent = NULL; +THeap_IsIn is_in_permanent = NULL; /* Internal function */ @@ -83,12 +83,12 @@ /* Search "is_in_permanent" function symbol. */ if (jvmInfo->isAfterCR6964458()) { /* Perm gen does not exist. */ - is_in_permanent = (THeap_IsInPermanent)&dummyIsInPermanent; + is_in_permanent = (THeap_IsIn)&dummyIsInPermanent; } else if (vmVal->getUseParallel() || vmVal->getUseParOld()) { - is_in_permanent = (THeap_IsInPermanent) this->symFinder->findSymbol( + is_in_permanent = (THeap_IsIn) this->symFinder->findSymbol( IS_IN_PERM_ON_PARALLEL_GC_SYMBOL); } else { - is_in_permanent = (THeap_IsInPermanent) this->symFinder->findSymbol( + is_in_permanent = (THeap_IsIn) this->symFinder->findSymbol( IS_IN_PERM_ON_OTHER_GC_SYMBOL); } @@ -97,6 +97,15 @@ return false; } + /* Search "is_in" function symbol for ParNew GC when CMS GC is worked. */ + if (vmVal->getUseCMS()) { + is_in = (THeap_IsIn) this->symFinder->findSymbol(IS_IN_SYMBOL); + if (unlikely(is_in == NULL)) { + logger->printCritMsg("is_in() not found."); + return false; + } + } + /* Search "GetObjectSize" function symbol. */ getObjectSize = (TJvmtiEnv_GetObjectSize) this->symFinder->findSymbol( SYMBOL_GETOBJCTSIZE);
--- a/agent/src/heapstats-engines/vmFunctions.hpp Thu Jun 02 22:23:18 2016 +0900 +++ b/agent/src/heapstats-engines/vmFunctions.hpp Thu Jun 02 22:23:26 2016 +0900 @@ -40,6 +40,11 @@ #define IS_IN_PERM_ON_OTHER_GC_SYMBOL "_ZNK10SharedHeap15is_in_permanentEPKv" /*! + * \brief Symbol of Generation::is_in() + */ +#define IS_IN_SYMBOL "_ZNK10Generation5is_inEPKv" + +/*! * \brief Symbol of "JvmtiEnv::GetObjectSize" macro. */ #ifdef __x86_64__ @@ -157,11 +162,11 @@ /*! * \brief This function is C++ heap class member.<br> * So 1st arg must be set instance. - * \param thisptr [in] SharedHeap/ParallelScavengeHeap object instance. + * \param thisptr [in] Instance of Java memory region. * \param oop [in] Java object. - * \return Java object is existing in perm gen. + * \return true if oop is in this region. */ -typedef bool (*THeap_IsInPermanent)(void *thisptr, void *oop); +typedef bool (*THeap_IsIn)(const void *thisptr, const void *oop); /*! * \brief This function is C++ JvmtiEnv class member.<br> @@ -284,7 +289,7 @@ /* extern variables */ extern "C" void *VTableForTypeArrayOopClosure[2]; -extern "C" THeap_IsInPermanent is_in_permanent; +extern "C" THeap_IsIn is_in_permanent; /*! * \brief This class gathers/provides functions in HotSpot VM. @@ -297,6 +302,11 @@ TJvmtiEnv_GetObjectSize getObjectSize; /*! + * \brief Function pointer for "Generation::is_in". + */ + THeap_IsIn is_in; + + /*! * \brief Function pointer for "java_lang_Class::as_klassOop". */ TJavaLangClass_AsKlassOop asKlassOop; @@ -418,6 +428,10 @@ return getObjectSize(thisptr, object, size_ptr); } + inline bool IsInYoung(const void *oop) { + return is_in(TVMVariables::getInstance()->getYoungGen(), oop); + } + inline void *AsKlassOop(void *mirror) { return asKlassOop(mirror); } inline void *GetClassLoaderForInstanceKlass(void *klassOop) {
--- a/agent/src/heapstats-engines/vmVariables.cpp Thu Jun 02 22:23:18 2016 +0900 +++ b/agent/src/heapstats-engines/vmVariables.cpp Thu Jun 02 22:23:26 2016 +0900 @@ -82,6 +82,9 @@ ofsOSThreadThreadId = -1; ofsObjectMonitorObject = -1; threads_lock = NULL; + youngGen = NULL; + youngGenStartAddr = NULL; + youngGenSize = 0; #ifdef __LP64__ HeapWordSize = 8; @@ -366,6 +369,11 @@ off_t offsetCmsShifter = -1; off_t offsetCmsMapAtCollector = -1; off_t offsetCmsVirtualSpace = -1; + off_t offsetGens = -1; + off_t offsetYoungGen = -1; + off_t offsetYoungGenReserved = -1; + off_t offsetMemRegionStart = -1; + off_t offsetMemRegionWordSize = -1; TOffsetNameMap ofsMap[] = { {"CMSBitMap", "_virtual_space", &offsetCmsVirtualSpace, NULL}, {"CMSBitMap", "_bmStartWord", &offsetCmsStartWord, NULL}, @@ -373,6 +381,11 @@ {"CMSCollector", "_markBitMap", &offsetCmsMapAtCollector, NULL}, {"ConcurrentMarkSweepThread", "_collector", NULL, &cmsCollector}, {"VirtualSpace", "_low", &offsetLowAtVirtualSpace, NULL}, + {"GenCollectedHeap", "_gens", &offsetGens, NULL}, + {"GenCollectedHeap", "_young_gen", &offsetYoungGen, NULL}, + {"Generation", "_reserved", &offsetYoungGenReserved, NULL}, + {"MemRegion", "_start", &offsetMemRegionStart, NULL}, + {"MemRegion", "_word_size", &offsetMemRegionWordSize, NULL}, /* End marker. */ {NULL, NULL, NULL, NULL}}; @@ -401,6 +414,9 @@ if (unlikely(offsetCmsVirtualSpace == -1 || offsetCmsStartWord == -1 || offsetCmsShifter == -1 || offsetCmsMapAtCollector == -1 || cmsCollector == NULL || offsetLowAtVirtualSpace == -1 || + (offsetGens == -1 && offsetYoungGen == -1) || + offsetYoungGenReserved == -1 || offsetMemRegionStart == -1 || + offsetMemRegionWordSize == -1 || *(void **)cmsCollector == NULL)) { logger->printCritMsg("Cannot get CMS values from VMStructs."); return false; @@ -415,8 +431,19 @@ ptrdiff_t virtSpace = cmsBitmapPtr + offsetCmsVirtualSpace; cmsBitMap_startAddr = *(size_t **)(virtSpace + offsetLowAtVirtualSpace); + youngGen = (offsetGens == -1) // JDK-8061802 + ? *(void **)incAddress(collectedHeap, offsetYoungGen) + : *(void **)incAddress(collectedHeap, offsetGens); + void *youngGenReserved = incAddress(youngGen, offsetYoungGenReserved); + youngGenStartAddr = + *(void **)incAddress(youngGenReserved, offsetMemRegionStart); + size_t youngGenWordSize = + *(size_t *)incAddress(youngGenReserved, offsetMemRegionWordSize); + youngGenSize = youngGenWordSize * HeapWordSize; + if (unlikely((cmsBitMap_startWord == NULL) || - (cmsBitMap_startAddr == NULL))) { + (cmsBitMap_startAddr == NULL) || + (youngGen == NULL) || (youngGenStartAddr == NULL))) { logger->printCritMsg("Cannot calculate CMS values."); return false; }
--- a/agent/src/heapstats-engines/vmVariables.hpp Thu Jun 02 22:23:18 2016 +0900 +++ b/agent/src/heapstats-engines/vmVariables.hpp Thu Jun 02 22:23:26 2016 +0900 @@ -312,6 +312,21 @@ */ void *threads_lock; + /*! + * \brief Pointer of YoungGen in GenCollectedHeap. + */ + void *youngGen; + + /*! + * \brief Start address of YoungGen. + */ + void *youngGenStartAddr; + + /*! + * \brief sizeof YoungGen. + */ + size_t youngGenSize; + /* Class of HeapStats for scanning variables in HotSpot VM */ TSymbolFinder *symFinder; TVMStructScanner *vmScanner; @@ -447,6 +462,9 @@ inline off_t getOfsOSThreadThreadId() { return ofsOSThreadThreadId; }; inline off_t getOfsObjectMonitorObject() { return ofsObjectMonitorObject; }; inline void *getThreadsLock() { return threads_lock; }; + inline void *getYoungGen() const { return youngGen; }; + inline void *getYoungGenStartAddr() const { return youngGenStartAddr; }; + inline size_t getYoungGenSize() const { return youngGenSize; }; }; #endif // VMVARIABLES_H