Mercurial > hg > release > heapstats-2.0
changeset 202:5c34d6644d7e
Bug 3399: Fix potential error when conflict between class loading and GC
Reviewed-by: yasuenag
https://github.com/HeapStats/heapstats/pull/99
author | KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> |
---|---|
date | Thu, 08 Jun 2017 23:57:00 +0900 |
parents | c9dd616c3992 |
children | 40462ad5632e |
files | ChangeLog agent/src/heapstats-engines/classContainer.cpp agent/src/heapstats-engines/deadlockFinder.cpp agent/src/heapstats-engines/snapShotMain.cpp agent/src/heapstats-engines/vmVariables.hpp |
diffstat | 5 files changed, 48 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Thu Apr 13 12:32:05 2017 +0900 +++ b/ChangeLog Thu Jun 08 23:57:00 2017 +0900 @@ -1,3 +1,7 @@ +2017-06-08 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> + + * Bug 3399: Fix potential error when conflict between class loading and GC + 2017-04-13 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> * Bug 3359: Ignore only auto generated Makefile
--- a/agent/src/heapstats-engines/classContainer.cpp Thu Apr 13 12:32:05 2017 +0900 +++ b/agent/src/heapstats-engines/classContainer.cpp Thu Jun 08 23:57:00 2017 +0900 @@ -906,6 +906,11 @@ */ void JNICALL OnClassUnload(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) { + /* + * This function does not require to check whether at safepoint because + * Class Unloading always executes at safepoint. + */ + /* Get klassOop. */ void *mirror = *(void **)klass; void *klassOop = TVMFunctions::getInstance()->AsKlassOop(mirror);
--- a/agent/src/heapstats-engines/deadlockFinder.cpp Thu Apr 13 12:32:05 2017 +0900 +++ b/agent/src/heapstats-engines/deadlockFinder.cpp Thu Jun 08 23:57:00 2017 +0900 @@ -188,16 +188,6 @@ */ void *TDeadlockFinder::threads_lock = NULL; -/* Common methods. */ - -/*! - * \brief Get safepoint state. - * \return Is synchronizing or working at safepoint now. - */ -inline bool isAtSafepoint(void) { - return (TVMVariables::getInstance()->getSafePointState() == 2); -} - /*! * \brief Event handler of JVMTI MonitorContendedEnter for finding deadlock. * \param jvmti [in] JVMTI environment.
--- a/agent/src/heapstats-engines/snapShotMain.cpp Thu Apr 13 12:32:05 2017 +0900 +++ b/agent/src/heapstats-engines/snapShotMain.cpp Thu Jun 08 23:57:00 2017 +0900 @@ -19,6 +19,8 @@ * */ +#include <sched.h> + #include "globals.hpp" #include "vmFunctions.hpp" #include "elapsedTimer.hpp" @@ -135,6 +137,15 @@ */ void JNICALL OnClassPrepare(jvmtiEnv *jvmti, JNIEnv *env, jthread thread, jclass klass) { + + /* + * Wait if VM is at a safepoint which includes safepoint synchronizing, + * because jclass (oop in JNIHandle) might be relocated. + */ + while (!isAtNormalExecution()) { + sched_yield(); + } + /* Get klassOop. */ void *mirror = *(void **)klass; void *klassOop = TVMFunctions::getInstance()->AsKlassOop(mirror);
--- a/agent/src/heapstats-engines/vmVariables.hpp Thu Apr 13 12:32:05 2017 +0900 +++ b/agent/src/heapstats-engines/vmVariables.hpp Thu Jun 08 23:57:00 2017 +0900 @@ -1,7 +1,7 @@ /*! * \file vmVariables.hpp * \brief This file includes variables in HotSpot VM. - * Copyright (C) 2014-2015 Yasumasa Suenaga + * Copyright (C) 2014-2017 Yasumasa Suenaga * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -36,6 +36,13 @@ */ #define SAFEPOINT_STATE_SYMBOL "_ZN20SafepointSynchronize6_stateE" +/*! + * \brief Numbering which shows safepoint state as enumeration. + */ +#define SAFEPOINT_STATE_NORMAL_EXECUTION 0 +#define SAFEPOINT_STATE_SYNCHRONIZING 1 +#define SAFEPOINT_STATE_SYNCHRONIZED 2 + /* extern variables */ extern "C" void *collectedHeap; @@ -395,4 +402,24 @@ inline void *getG1StartAddr() { return g1StartAddr; }; }; +/* Utility functions for Safepoint */ + +/*! + * \brief Check whether VM is at safepoint or not. + * \return true if VM is at safepoint. + */ +inline bool isAtSafepoint(void) { + return (TVMVariables::getInstance()->getSafePointState() + == SAFEPOINT_STATE_SYNCHRONIZED); +}; + +/*! + * \brief Check whether VM is at normal execution or not. + * \return true if VM is at normal execution. + */ +inline bool isAtNormalExecution(void) { + return (TVMVariables::getInstance()->getSafePointState() + == SAFEPOINT_STATE_NORMAL_EXECUTION); +}; + #endif // VMVARIABLES_H