view agent/src/oopUtil.hpp @ 30:57fd757ef0e2

Bug 1644: Can't hook FullGC when G1 Evacuation Failure occurs. reviewed-by: ykubota
author Yasumasa Suenaga <suenaga.yasumasa@lab.ntt.co.jp>
date Wed, 15 Jan 2014 10:10:31 +0900
parents 0a4a349799b0
children a4b4008e4ec0
line wrap: on
line source

/*!
 * \file oopUtil.hpp
 * \brief This file is used to getting information inner JVM.<br>
 * Copyright (C) 2011-2013 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 _OOP_UTIL_H
#define _OOP_UTIL_H

#include <jni.h>
#include <jvmti.h>

#include <stdint.h>
#include <sys/types.h>

#include "symbolFinder.hpp"
#include "vmStructScanner.hpp"
#include "jvmInfo.hpp"
#include "bitMapMarker.hpp"

/* Typedef. */

/* Inner function type. */

/*!
 * \brief This function is C++ heap class member.<br>
 *        So 1st arg must be set instance.
 * \param thisptr [in] SharedHeap/ParallelScavengeHeap object instance.
 * \param oop     [in] Java object.
 * \return Java object is existing in perm gen.
 */
typedef bool (*THeap_IsInPermanent)(void *thisptr, void *oop);

/*!
 * \brief This function is C++ JvmtiEnv class member.<br>
 *        So 1st arg must be set instance.<br>
 *        jvmtiError JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr)
 * \param thisptr  [in]  JvmtiEnv object instance.
 * \param object   [in]  Java object.
 * \param size_ptr [out] Pointer of java object's size.
 * \return Java object's size.
 */
typedef int (*TJvmtiEnv_GetObjectSize)(void *thisptr,
                                             jobject object, jlong *size_ptr);

/*!
 * \brief This function is java_lang_Class class member.<br>
 *        void *java_lang_Class::as_klassOop(void *mirror);
 * \param mirror [in] Java object mirror.
 * \return KlassOop of java object mirror.
 */
typedef void *(*TJavaLangClass_AsKlassOop)(void *mirror);

/* Callback function type. */

/*!
 * \brief This function is for heap object callback.
 * \param klassOop [in] Pointer of java class object(KlassOopDesc).
 * \param size     [in] Size of object instance.
 */
typedef void (*THeapObjectCallback)(void *klassOop, jlong size);

/*!
 * \brief This function is for class oop adjust callback by GC.
 * \param oldOop [in] Old pointer of java class object(KlassOopDesc).
 * \param newOop [in] New pointer of java class object(KlassOopDesc).
 */
typedef void (*TKlassAdjustCallback)(void *oldOop, void *newOop);

/*!
 * \brief This function type is for common callback.
 */
typedef void (*TCommonCallback)(void);

/* Other type. */

/*!
 * \brief Override function information structure.
 * This structure should be aligned 16 bytes.
 * (This structure will be accessed with XMM register through SSE instructions.)
 */
typedef struct {
  const char *vtableSymbol; /*!< Symbol string of target class.           */
  void **vtable;            /*!< Pointer of C++ vtable.                   */
  const char *funcSymbol;   /*!< Symbol string of target function.        */
  void *overrideFunc;       /*!< Pointer of override function.            */
  void *originalFunc;       /*!< Pointer of callback target.              */
  void *afterFunc;          /*!< Pointer of callback after invoke target. */
  bool isVTableWritable;    /*!< Is vtable already writable? */
}
#ifdef __LP64__
__attribute__((aligned(16)))
#endif
THookFunctionInfo;

/*!
 * \brief This structure is expressing garbage collector state.
 */
typedef enum{
  gcStart  = 1, /*!< Garbage collector is start.                    */
  gcFinish = 2, /*!< Garbage collector is finished.                 */
  gcLast   = 3, /*!< Garbage collector is tarminating on JVM death. */
} TGCState;


/* Variable for CMS collector state. */

/*!
 * \brief CMS collector is idling.
 */
#define CMS_IDLING 2

/*!
 * \brief CMS collector is initial-marking phase.
 */
#define CMS_INITIALMARKING 3

/*!
 * \brief CMS collector is marking phase.
 */
#define CMS_MARKING 4

/*!
 * \brief CMS collector is final-making phase.
 */
#define CMS_FINALMARKING 7

/*!
 * \brief CMS collector is sweep phase.
 */
#define CMS_SWEEPING 8


/* Macro. */

/*!
 * \brief Convert to THookFunctionInfo macro.
 */
#define HOOK_FUNC(clsSym, funcSym, befFunc, aftFunc) \
  {(clsSym), NULL, (funcSym), (befFunc), NULL, (aftFunc), false}

/*!
 * \brief Enf flag for THookFunctionInfo macro.
 */
#define HOOK_FUNC_END \
  {NULL, NULL, NULL, NULL, NULL, NULL, false}

/* Variables. */

/* Define JVM paramter pointer variable for calling from external. */

/*!
 * \brief Pointer to "-XX:UseCompressedOops" or "-XX:UseCompressedKlassPointers".
 */
extern "C" bool *isCOOP;

/*!
 * \brief Pointer to "-XX:UseParallelGC".
 */
extern "C" bool *useParallel;

/*!
 * \brief Pointer to "-XX:UseParallelOldGC".
 */
extern "C" bool *useParOld;

/*!
 * \brief Pointer to "-XX:UseConcMarkSweepGC".
 */
extern "C" bool *useCMS;

/*!
 * \brief Pointer to"-XX:UseG1GC".
 */
extern "C" bool *useG1;

/*!
 * \brief JVM safepoint state pointer.
 */
extern "C" int *safePointState;

/* Define CMS GC pointer variable for calling from external. */

/* Define function pointer variable for calling from external. */

/*!
 * \brief Function pointer for "is_in_permanent".
 */
extern "C" THeap_IsInPermanent is_in_permanent;

/*!
 * \brief Pointer of "_collectedHeap" field in Universe.<br>
 *        Use to calling "is_in_permanent" function.
 */
extern "C" void *collectedHeap;

/*!
 * \brief Function pointer for "JvmtiEnv::GetObjectSize".
 */
extern "C" TJvmtiEnv_GetObjectSize getObjectSize;

/*!
 * \brief Function pointer for "java_lang_Class::as_klassOop".
 */
extern "C" TJavaLangClass_AsKlassOop asKlassOop;

/*!
 * \brief Symbol finder object about "libjvm.so" shared library.
 */
extern TSymbolFinder *symFinder;

/*!
 * \brief JVM inner structure scanner.
 */
extern TVMStructScanner *vmScanner;

/* Variable for function override. */

/*!
 * \brief Pointer of hook information on parallelGC.
 */
extern "C" THookFunctionInfo par_hook[];

/*!
 * \brief Pointer of hook information on parallelGC for after CR6964458.
 */
extern "C" THookFunctionInfo CR6964458_par_hook[];

/*!
 * \brief Pointer of hook information on parallelGC for after CR8000213.
 */
extern "C" THookFunctionInfo CR8000213_par_hook[];

/*!
 * \brief Pointer of hook information on parallelOldGC.
 */
extern "C" THookFunctionInfo parOld_hook[];

/*!
 * \brief Pointer of hook information on parallelOldGC after CR6964458.
 */
extern "C" THookFunctionInfo CR6964458_parOld_hook[];

/*!
 * \brief Pointer of hook information on parallelOldGC after CR8000213.
 */
extern "C" THookFunctionInfo CR8000213_parOld_hook[];

/*!
 * \brief Pointer of hook information on CMSGC.
 */
extern "C" THookFunctionInfo cms_sweep_hook[];

/*!
 * \brief Pointer of hook information on CMSGC.
 */
extern "C" THookFunctionInfo cms_new_hook[];

/*!
 * \brief Pointer of hook information on CMSGC after CR6964458.
 */
extern "C" THookFunctionInfo CR6964458_cms_new_hook[];

/*!
 * \brief Pointer of hook information on CMSGC after CR8000213.
 */
extern "C" THookFunctionInfo CR8000213_cms_new_hook[];

/*!
 * \brief Pointer of hook information on G1GC.
 */
extern "C" THookFunctionInfo g1_hook[];

/*!
 * \brief Pointer of hook information on G1GC after CR6964458.
 */
extern "C" THookFunctionInfo CR6964458_g1_hook[];

/*!
 * \brief Pointer of hook information on G1GC after CR8000213.
 */
extern "C" THookFunctionInfo CR8000213_g1_hook[];

/*!
 * \brief Pointer of hook information on G1GC event.
 */
extern "C" THookFunctionInfo g1Event_hook[];

/*!
 * \brief Pointer of hook change and adjust oop with GC.
 */
extern "C" THookFunctionInfo adj_hook[];

/*!
 * \brief Pointer of hook oop iterate with JVMTI HeapOverIterate.
 */
extern "C" THookFunctionInfo jvmti_hook[];

/*!
 * \brief Pointer of hook inner GC function.
 */
extern "C" THookFunctionInfo innerStart_hook[];


/* Function. */

/* Function for callback. */

/*!
 * \brief Callback function for parallel GC and user's GC.<br>
 *        E.g. System.gc() in java code, JVMTI and etc..
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForParallel(void *oop);

/*!
 * \brief Callback function for parallel Old GC.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForParOld(void *oop);

/*!
 * \brief Callback function for OopClosure::do_oop(oop *).<br>
 *        This function is targeted for G1ParScanAndMarkExtRootClosure.
 *        (initial-mark for G1)
 * \param oop [in] Java heap object(OopDesc format).
 */
extern "C" void callbackForDoOop(void **oop);

/*!
 * \brief Callback function for OopClosure::do_oop(narrowOop *).<br>
 *        This function is targeted for G1ParScanAndMarkExtRootClosure.
 *        (initial-mark for G1)
 * \param oop [in] Java heap object(OopDesc format).
 */
extern "C" void callbackForDoNarrowOop(unsigned int *narrowOop);

/*!
 * \brief Callback function for CMS GC and G1 GC.<br>
 *        This function is targeted for Young Gen only.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 * \sa CMSParRemarkTask::do_young_space_rescan()<br>
 *     ContiguousSpace::par_oop_iterate()
 */
extern "C" void callbackForIterate(void *oop);

/*!
 * \brief Callback function for CMS sweep.<br>
 *        This function is targeted for CMS Gen only.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForSweep(void *oop);

/*!
 * \brief Callback function for oop_adjust_pointers.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForAdjustPtr(void *oop);

/*!
 * \brief Callback function for do_addr.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForDoAddr(void *oop);

/*!
 * \brief Callback function for oop_update_pointers.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForUpdatePtr(void *oop);

/*!
 * \brief Callback function for snapshot with data dump or interval.
 * \param oop [in] Java heap object(OopDesc format).
 * \warning Param "oop" isn't usable for JVMTI and JNI.
 */
extern "C" void callbackForJvmtiIterate(void *oop);

/*!
 * \brief Callback function for before G1 GC cleanup.
 */
extern "C" void callbackForG1Cleanup(void);

/*!
 * \brief Callback function for before System.gc() on using G1GC.
 * \param isFull [in] Is this event FullGC?
 */
extern "C" void callbackForG1Full(bool isFull);

/*!
 * \brief Callback function for after System.gc() on using G1GC.
 * \param isFull [in] Is this event FullGC?
 */
extern "C" void callbackForG1FullReturn(bool isFull);

/*!
 * \brief Callback function for WatcherThread.
 */
extern "C" void callbackForWatcherThreadRun(void);

/* Function for init/final. */

/*!
 * \brief Initialization of this util.
 * \param jvmti [in] JVMTI environment object.
 * \return Process result.
 */
bool oopUtilInitialize(jvmtiEnv *jvmti);

/*!
 * \brief Finailization of this util.
 */
void oopUtilFinalize(void);

/*!
 * \brief Setup hooking.
 * \warning Please this function call at after Agent_OnLoad.
 * \param funcOnGC     [in] Pointer of GC callback function.
 * \param funcOnJVMTI  [in] Pointer of JVMTI callback function.
 * \param funcOnCMS    [in] Pointer of CMSGC callback function.
 * \param funcOnAdjust [in] Pointer of adjust class callback function.
 * \param funcOnG1GC   [in] Pointer of event callback on G1GC finished.
 * \param maxMemSize   [in] Allocatable maximum memory size of JVM.
 * \return Process result.
 */
bool setupHook(THeapObjectCallback funcOnGC, THeapObjectCallback funcOnCMS,
          THeapObjectCallback funcOnJVMTI, TKlassAdjustCallback funcOnAdjust,
                                  TCommonCallback funcOnG1GC, size_t maxMemSize);

/* Function for oop util. */

/*!
 * \brief Getting oop's class information(It's "Klass", not "KlassOop").
 * \param klassOop [in] Java heap object(Inner "KlassOop" class).
 * \return Class information object(Inner "Klass" class).
 */
void *getKlassFromKlassOop(void *klassOop);

/*!
 * \brief Getting oop's class information(It's "Klass", not "KlassOop").
 * \param oop [in] Java heap object(Inner class format).
 * \return Class information object.
 * \sa oopDesc::klass()<br>
 *     at hotspot/src/share/vm/oops/oop.inline.hpp in JDK.
 */
void *getKlassOopFromOop(void *oop);

/*!
 * \brief Getting class's name form java inner class.
 * \param klass [in] Java class object(Inner class format).
 * \return String of object class name.<br>
 *         Don't forget deallocate if value isn't null.
 */
char *getClassName(void *klass);

/* Function for other. */

/*!
 * \brief Setting GC hooking enable.
 * \param enable [in] Is GC hook enable.
 * \return Process result.
 */
bool setGCHookState(bool enable);

/*!
 * \brief Setting JVMTI hooking enable.
 * \param enable [in] Is JVMTI hook enable.
 * \return Process result.
 */
bool setJvmtiHookState(bool enable);

/*!
 * \brief Check CMS garbage collector state.
 * \param state        [in]  State of CMS garbage collector.
 * \param needSnapShot [out] Is need snapshot now.
 * \return CMS collector state.
 * \warning Please don't forget call on JVM death.
 */
int checkCMSState(TGCState state, bool *needSnapShot);

/*!
 * \brief Setup hooking for inner GC event.
 * \warning Please this function call at after Agent_OnLoad.
 * \param enableHook     [in] Flag of enable hooking to function.
 * \param interruptEvent [in] Event callback on many times GC interupt.
 * \return Process result.
 */
bool setupHookForInnerGCEvent(bool enableHook, TCommonCallback interruptEvent);

/*!
 * \brief Get safepoint state.
 * \return Is synchronizing or working at safepoint now.
 */
inline bool isInWorkSafepoint(void) {
  return (*safePointState != 0);
}

/*!
 * \brief Get safepoint state.
 * \return Is working at safepoint now.
 */
inline bool isAtSafepoint(void) {
  return (*safePointState == 2);
}

/*!
 * \brief "is_in_permanent" for after CR6964458.
 *        This function always return false because this CR means PermGen Removal.
 * \param thisptr [in] G1CollectedHeap/GenCollectedHeap/ParallelScavengeHeap
 *                     class instance.
 * \param oop     [in] (C++) Java object.
 * \return always false.
 */
bool is_in_permanent_AfterCR6964458(void *thisptr, void *oop);

/*!
 * \brief Bitmap object for G1 GC.
 */
extern TBitMapMarker *checkObjectMap;

/*!
 * \brief VTable list which should be hooked.
 */
extern void *VTableForTypeArrayOopClosure[];


#endif // _OOP_UTIL_H