Mercurial > hg > heapstats
view agent/src/heapstats-engines/snapShotContainer.hpp @ 258:9a13d070bb77
Bug 3511: Migrate to Intel TBB
Reviewed-by: ykubota
https://github.com/HeapStats/heapstats/pull/128
author | Yasumasa Suenaga <yasuenag@gmail.com> |
---|---|
date | Fri, 19 Jan 2018 14:06:27 +0900 |
parents | aba6d9899517 |
children | 07a69089c840 |
line wrap: on
line source
/*! * \file snapshotContainer.hpp * \brief This file is used to add up using size every class. * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef _SNAPSHOT_CONTAINER_HPP #define _SNAPSHOT_CONTAINER_HPP #include <tbb/concurrent_hash_map.h> #include <tbb/concurrent_queue.h> #include <algorithm> #include "jvmInfo.hpp" #include "oopUtil.hpp" #include "classContainer.hpp" #if PROCESSOR_ARCH == X86 #include "arch/x86/lock.inline.hpp" #elif PROCESSOR_ARCH == ARM #include "arch/arm/lock.inline.hpp" #endif /* Magic number macro. */ /*! * \brief Magic number of snapshot file format.<br /> * 49 ... HeapStats 1.0 format.<br /> * 61 ... HeapStats 1.1 format.<br /> * Extended magic number is represented as logical or. * Meanings of each field are as below: * 0b10000000: This SnapShot is 2.0 format. * It contains snapshot and metaspace data. * 0b00000001: This SnapShot contains reference data. * 0b00000010: This SnapShot contains safepoint time. * Other fields (bit 2 - 6) are reserved. * \warning Don't change output snapshot format, if you change this value. */ #define EXTENDED_SNAPSHOT 0x80 // 0b10000000 #define EXTENDED_REFTREE_SNAPSHOT 0x81 // 0b10000001 #define EXTENDED_SAFEPOINT_TIME 0x82 // 0b10000010 /*! * \brief This structure stored class size and number of class-instance. */ #pragma pack(push, 1) typedef struct { jlong count; /*!< Class instance count. */ jlong total_size; /*!< Class total use size. */ } TObjectCounter; /*! * \brief This structure stored child class size information. */ struct TChildClassCounter { TObjectCounter *counter; /*!< Java inner class object. */ TObjectData *objData; /*!< Class information. */ TChildClassCounter *next; /*!< Pointer of next object. */ }; /*! * \brief This structure stored class and children class size information. */ typedef struct { TObjectCounter *counter; /*!< Java inner class object. */ TChildClassCounter *child; /*!< Child class informations. */ volatile int spinlock; /*!< Spin lock object. */ TOopMapBlock *offsets; /*!< Offset list. */ int offsetCount; /*!< Count of offset list. */ } TClassCounter; /*! * \brief This structure stored snapshot information. */ typedef struct { char magicNumber; /*!< Magic number for format. */ char byteOrderMark; /*!< Express byte order. */ jlong snapShotTime; /*!< Datetime of take snapshot. */ jlong size; /*!< Class entries count. */ jint cause; /*!< Cause of snapshot. */ jlong gcCauseLen; /*!< Length of GC cause. */ char gcCause[80]; /*!< String about GC casue. */ jlong FGCCount; /*!< Full-GC count. */ jlong YGCCount; /*!< Young-GC count. */ jlong gcWorktime; /*!< GC worktime. */ jlong newAreaSize; /*!< New area using size. */ jlong oldAreaSize; /*!< Old area using size. */ jlong totalHeapSize; /*!< Total heap size. */ jlong metaspaceUsage; /*!< Usage of PermGen or Metaspace. */ jlong metaspaceCapacity; /*!< Max capacity of PermGen or Metaspace. */ jlong safepointTime; /*!< Safepoint time in milliseconds. */ } TSnapShotFileHeader; #pragma pack(pop) /*! * \brief This class is stored class object usage on heap. */ class TSnapShotContainer; /*! * \brief Type is for map of storing object counters. */ typedef tbb::concurrent_hash_map<TObjectData *, TClassCounter *, TPointerHasher<TObjectData *> > TSizeMap; /*! * \brief Container of active snapshot list. */ typedef tbb::concurrent_hash_map<TSnapShotContainer *, int> TActiveSnapShots; typedef std::pair<TClassCounter *, PKlassOop> TChildrenMapKey; typedef tbb::concurrent_hash_map <TChildrenMapKey, TChildClassCounter *> TChildrenMap; /*! * \brief Snapshot container instance stock queue. */ typedef tbb::concurrent_queue<TSnapShotContainer *> TSnapShotQueue; /*! * \brief This class is stored class object usage on heap. */ class TSnapShotContainer { public: /*! * \brief Initialize snapshot caontainer class. * \return Is process succeed. * \warning Please call only once from main thread. */ static bool globalInitialize(void); /*! * \brief Finalize snapshot caontainer class. * \warning Please call only once from main thread. */ static void globalFinalize(void); /*! * \brief Get snapshot container instance. * \return Snapshot container instance. * \warning Don't deallocate instance getting by this function.<br> * Please call "releaseInstance" method. */ static TSnapShotContainer *getInstance(void); /*! * \brief Release snapshot container instance.. * \param instance [in] Snapshot container instance. * \warning Don't access instance after called this function. */ static void releaseInstance(TSnapShotContainer *instance); /*! * \brief Get class entries count. * \return Entries count of class information. */ inline size_t getContainerSize(void) { return this->_header.size; } /*! * \brief Set time of take snapshot. * \param t [in] Datetime of take snapshot. */ inline void setSnapShotTime(jlong t) { this->_header.snapShotTime = t; } /*! * \brief Set snapshot cause. * \param cause [in] Cause of snapshot. */ inline void setSnapShotCause(TInvokeCause cause) { this->_header.cause = cause; } /*! * \brief Set total size of Java Heap. * \param size [in] Total size of Java Heap. */ inline void setTotalSize(jlong size) { this->_header.totalHeapSize = size; } /*! * \brief Set JVM performance info to header. * \param info [in] JVM running performance information. */ void setJvmInfo(TJvmInfo *info); /*! * \brief Get snapshot header. * \return Snapshot header. */ inline TSnapShotFileHeader *getHeader(void) { return (TSnapShotFileHeader *)&this->_header; } /*! * \brief Increment instance count and using size atomically. * \param counter [in] Increment target class. * \param size [in] Increment object size. */ void Inc(TObjectCounter *counter, jlong size); /*! * \brief Increment instance count and using size without lock. * \param counter [in] Increment target class. * \param size [in] Increment object size. */ inline void FastInc(TObjectCounter *counter, jlong size) { counter->count++; counter->total_size += size; } /*! * \brief Increment instance count and using size. * \param counter [in] Increment target class. * \param operand [in] Right-hand operand (SRC operand). * This value must be aligned 16bytes. */ void addInc(TObjectCounter *counter, TObjectCounter *operand); /*! * \brief Find class data. * \param objData [in] Class key object. * \return Found class data. * Value is null, if class is not found. */ inline TClassCounter *findClass(TObjectData *objData) { TSizeMap::const_accessor acc; return counterMap.find(acc, objData) ? acc->second : NULL; } /*! * \brief Find child class data. * \param clsCounter [in] Parent class counter object. * \param klassOop [in] Child class key object. * \return Found class data. * Value is null, if class is not found. */ inline TChildClassCounter *findChildClass(TClassCounter *clsCounter, PKlassOop klassOop) { TChildrenMapKey key = std::make_pair(clsCounter, klassOop); TChildrenMap::const_accessor acc; return childrenMap.find(acc, key) ? acc->second : NULL; } /*! * \brief Append new-class to container. * \param objData [in] New-class key object. * \return New-class data. */ virtual TClassCounter *pushNewClass(TObjectData *objData); /*! * \brief Append new-child-class to container. * \param clsCounter [in] Parent class counter object. * \param objData [in] New-child-class key object. * \return New-class data. */ virtual TChildClassCounter *pushNewChildClass(TClassCounter *clsCounter, TObjectData *objData); /*! * \brief Output GC statistics information. */ void printGCInfo(void); /*! * \brief Clear snapshot data. */ void clear(bool isForce); /*! * \brief Set "isCleared" flag. */ inline void setIsCleared(bool flag) { this->isCleared = flag; } /*! * \brief Remove unloaded TObjectData in this snapshot container. * This function should be called at safepoint. * \param unloadedList Set of unloaded TObjectData. */ void removeObjectData(TClassInfoSet &unloadedList); /*! * \brief Remove unloaded TObjectData all active snapshot container. * \param unloadedList Set of unloaded TObjectData. */ static void removeObjectDataFromAllSnapShots(TClassInfoSet &unloadedList); protected: /*! * \brief TSnapshotContainer constructor. */ TSnapShotContainer(void); /*! * \brief TSnapshotContainer destructor. */ virtual ~TSnapShotContainer(void); /*! * \brief Zero clear to TObjectCounter. * \param counter TObjectCounter to clear. */ void clearObjectCounter(TObjectCounter *counter); /*! * \brief Zero clear to TClassCounter. * \param counter TClassCounter to clear. */ void clearClassCounter(TClassCounter *counter); /*! * \brief Zero clear to TClassCounter and its children counter. * \param counter TClassCounter to clear. */ void clearChildClassCounters(TClassCounter *counter); /*! * \brief Snapshot container instance stock queue. */ static TSnapShotQueue *stockQueue; /*! * \brief Max limit count of snapshot container instance. */ const static unsigned int MAX_STOCK_COUNT = 2; /*! * \brief Map for TClassCounter. */ TSizeMap counterMap; /*! * \brief Map for TChildClassCounter. */ TChildrenMap childrenMap; private: /*! * \brief Snapshot header. */ volatile TSnapShotFileHeader _header; /*! * \brief Is this container is cleared ? */ volatile bool isCleared; /*! * \brief Set of active TSnapShotContainer set */ static TActiveSnapShots activeSnapShots; }; /* Include optimized inline functions. */ #if PROCESSOR_ARCH == X86 #include "arch/x86/snapShotContainer.inline.hpp" #elif PROCESSOR_ARCH == ARM #include "arch/arm/snapShotContainer.inline.hpp" #endif #ifdef AVX #include "arch/x86/avx/snapShotContainer.inline.hpp" #elif defined SSE4 #include "arch/x86/sse4/snapShotContainer.inline.hpp" #elif defined SSE2 || defined SSE3 #include "arch/x86/sse2/snapShotContainer.inline.hpp" #elif defined NEON #include "arch/arm/neon/snapShotContainer.inline.hpp" #else /*! * \brief Increment instance count and using size. * \param counter [in] Increment target class. * \param operand [in] Right-hand operand (SRC operand). * This value must be aligned 16bytes. */ inline void TSnapShotContainer::addInc(TObjectCounter *counter, TObjectCounter *operand) { counter->count += operand->count; counter->total_size += operand->total_size; } /*! * \brief Zero clear to TObjectCounter. * \param counter TObjectCounter to clear. */ inline void TSnapShotContainer::clearObjectCounter(TObjectCounter *counter) { counter->count = 0; counter->total_size = 0; } /*! * \brief Zero clear to TClassCounter and its children counter. * \param counter TClassCounter to clear. */ inline void TSnapShotContainer::clearChildClassCounters( TClassCounter *counter) { /* Reset counter of children class. */ TChildClassCounter *child_counter = counter->child; while (child_counter != NULL) { child_counter->counter->count = 0; child_counter->counter->total_size = 0; child_counter = child_counter->next; } /* Reset counter of all class. */ this->clearObjectCounter(counter->counter); } #endif #endif // _SNAPSHOT_CONTAINER_HPP