# HG changeset patch # User KUBOTA Yuji # Date 1496933387 -32400 # Node ID 7e8c6ccee74dcd91edf4c3688c9fa8c7a7c588b2 # Parent b6ea4d40d35f63e738b7c9453ecc44f6bb9e2dfc Bug 3399: Fix potential error when conflict between class loading and GC Reviewed-by: yasuenag https://github.com/HeapStats/heapstats/pull/99 diff -r b6ea4d40d35f -r 7e8c6ccee74d agent/ChangeLog --- a/agent/ChangeLog Fri Mar 10 13:40:42 2017 +0900 +++ b/agent/ChangeLog Thu Jun 08 23:49:47 2017 +0900 @@ -1,3 +1,7 @@ +2017-06-08 KUBOTA Yuji + + * Bug 3399: Fix potential error when conflict between class loading and GC + 2017-03-10 KUBOTA Yuji * Bump to 1.0.7 diff -r b6ea4d40d35f -r 7e8c6ccee74d agent/src/oopUtil.hpp --- a/agent/src/oopUtil.hpp Fri Mar 10 13:40:42 2017 +0900 +++ b/agent/src/oopUtil.hpp Thu Jun 08 23:49:47 2017 +0900 @@ -1,7 +1,7 @@ /*! * \file oopUtil.hpp * \brief This file is used to getting information inner JVM.
- * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * 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 @@ -203,6 +203,13 @@ */ extern "C" int *safePointState; +/*! + * \brief Numbering which shows safepoint state as enumeration. + */ +#define SAFEPOINT_STATE_NORMAL_EXECUTION 0 +#define SAFEPOINT_STATE_SYNCHRONIZING 1 +#define SAFEPOINT_STATE_SYNCHRONIZED 2 + /* Define CMS GC pointer variable for calling from external. */ /* Define function pointer variable for calling from external. */ @@ -533,7 +540,15 @@ * \return Is synchronizing or working at safepoint now. */ inline bool isAtSafepoint(void) { - return (*safePointState == 2); + return (*safePointState == SAFEPOINT_STATE_SYNCHRONIZED); +} + +/*! + * \brief Get safepoint state. + * \return Is not at safepoint now. + */ +inline bool isAtNormalExecution(void) { + return (*safePointState == SAFEPOINT_STATE_NORMAL_EXECUTION); } /*! diff -r b6ea4d40d35f -r 7e8c6ccee74d agent/src/snapShotMain.cpp --- a/agent/src/snapShotMain.cpp Fri Mar 10 13:40:42 2017 +0900 +++ b/agent/src/snapShotMain.cpp Thu Jun 08 23:49:47 2017 +0900 @@ -1,7 +1,7 @@ /*! * \file snapShotMain.cpp * \brief This file is used to take snapshot. - * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * 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 @@ -27,6 +27,7 @@ #include #include +#include #include "snapShotMain.hpp" #include "libmain.hpp" @@ -132,6 +133,14 @@ 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 = asKlassOop(mirror); @@ -153,6 +162,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 = asKlassOop(mirror);