# HG changeset patch # User KUBOTA Yuji # Date 1496933332 -32400 # Node ID 79f42583c31c5204c044f0d3a5e121d0f8cba67b # Parent 60be2921a8bfecffa59e0ba576572abfb7df2373 Bug 3399: Fix potential error when conflict between class loading and GC Reviewed-by: yasuenag https://github.com/HeapStats/heapstats/pull/99 diff -r 60be2921a8bf -r 79f42583c31c agent/ChangeLog --- a/agent/ChangeLog Fri Mar 10 13:41:27 2017 +0900 +++ b/agent/ChangeLog Thu Jun 08 23:48:52 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.1.6 diff -r 60be2921a8bf -r 79f42583c31c agent/src/classContainer.cpp --- a/agent/src/classContainer.cpp Fri Mar 10 13:41:27 2017 +0900 +++ b/agent/src/classContainer.cpp Thu Jun 08 23:48:52 2017 +0900 @@ -957,6 +957,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); diff -r 60be2921a8bf -r 79f42583c31c agent/src/oopUtil.hpp --- a/agent/src/oopUtil.hpp Fri Mar 10 13:41:27 2017 +0900 +++ b/agent/src/oopUtil.hpp Thu Jun 08 23:48:52 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 @@ -231,6 +231,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. */ @@ -571,7 +578,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 60be2921a8bf -r 79f42583c31c agent/src/snapShotMain.cpp --- a/agent/src/snapShotMain.cpp Fri Mar 10 13:41:27 2017 +0900 +++ b/agent/src/snapShotMain.cpp Thu Jun 08 23:48:52 2017 +0900 @@ -27,6 +27,7 @@ #include #include +#include #include "snapShotMain.hpp" #include "libmain.hpp" @@ -151,6 +152,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);