Path: blob/master/runtime/gc_glue_java/ConcurrentSafepointCallbackJava.cpp
5990 views
/*******************************************************************************1* Copyright (c) 2015, 2017 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "ConcurrentSafepointCallbackJava.hpp"23#include "ModronAssertions.h"2425MM_ConcurrentSafepointCallbackJava *26MM_ConcurrentSafepointCallbackJava::newInstance(MM_EnvironmentBase *env)27{28MM_ConcurrentSafepointCallbackJava *callback;2930callback = (MM_ConcurrentSafepointCallbackJava *)env->getForge()->allocate(sizeof(MM_ConcurrentSafepointCallbackJava), MM_AllocationCategory::FIXED, J9_GET_CALLSITE());31if (NULL != callback) {32new(callback) MM_ConcurrentSafepointCallbackJava(env);33if (!callback->initialize(env)) {34callback->kill(env);35return NULL;36}37}38return callback;39}4041void42MM_ConcurrentSafepointCallbackJava::kill(MM_EnvironmentBase *env)43{44if (-1 != _asyncEventKey) {45J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();46javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, this->_asyncEventKey);47javaVM->internalVMFunctions->J9UnregisterAsyncEvent(javaVM, this->_asyncEventKey);48}4950#if defined(AIXPPC) || defined(LINUXPPC)51if (_cancelAfterGC) {52J9HookInterface** mmHooks = J9_HOOK_INTERFACE(env->getExtensions()->omrHookInterface);53(*mmHooks)->J9HookUnregister(mmHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, reportGlobalGCComplete, this);54}55#endif /* defined(AIXPPC) || defined(LINUXPPC) */5657env->getForge()->free(this);58}5960bool61MM_ConcurrentSafepointCallbackJava::initialize(MM_EnvironmentBase *env)62{63J9HookInterface** vmHooks = J9_HOOK_INTERFACE(((J9JavaVM*)env->getLanguageVM())->hookInterface);6465if (NULL == env->getOmrVMThread()) {66/* Register on hook for VM initialized. We can't register our async callback hooks here67* as we have no vmThread at this time so register on VM init hook so we can do so later68*/69(*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_INITIALIZED, vmInitialized, OMR_GET_CALLSITE(), this);70(*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_SHUTTING_DOWN, vmTerminating, OMR_GET_CALLSITE(), this);71} else {72registerAsyncEventHandler(env, this);73}7475return true;76}7778/**79* Called when a VM initialization is complete.80*81* @param eventNum id for event82* @param eventData reference to J9VMInitEvent83* @param userData reference to MM_ConcurrentSafepointCallbackJava84*85*/86void87MM_ConcurrentSafepointCallbackJava::vmInitialized(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)88{89J9VMInitEvent* event = (J9VMInitEvent *)eventData;90MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->vmThread->omrVMThread);91registerAsyncEventHandler(env, (MM_ConcurrentSafepointCallbackJava*) userData);92}9394void95MM_ConcurrentSafepointCallbackJava::registerAsyncEventHandler(MM_EnvironmentBase *env, MM_ConcurrentSafepointCallbackJava *callback)96{97J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();9899/* VM initialization complete so we will now have a vmThread under which to register our Async event handler */100callback->_asyncEventKey = javaVM->internalVMFunctions->J9RegisterAsyncEvent(javaVM, asyncEventHandler, callback);101}102103void104MM_ConcurrentSafepointCallbackJava::asyncEventHandler(J9VMThread *vmThread, intptr_t handlerKey, void *userData)105{106MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;107callback->_handler(vmThread->omrVMThread, callback->_userData);108}109110/**111* Called when a VM is about to terminate.112*113* @param eventNum id for event114* @param eventData reference to JJ9VMShutdownEvent115* @param userData reference to MM_ConcurrentSafepointCallbackJava116*117*/118void119MM_ConcurrentSafepointCallbackJava::vmTerminating(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)120{121J9VMShutdownEvent* event = (J9VMShutdownEvent *)eventData;122MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->vmThread->omrVMThread);123J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();124125MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;126javaVM->internalVMFunctions->J9UnregisterAsyncEvent(javaVM, callback->_asyncEventKey);127}128129/**130* Called when a global collect has completed131*132* @param eventNum id for event133* @param eventData reference to MM_GlobalGCEndEvent134* @param userData reference to MM_ConcurrentSafepointCallbackJava135*/136void137MM_ConcurrentSafepointCallbackJava::reportGlobalGCComplete(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)138{139MM_GlobalGCEndEvent *event = (MM_GlobalGCEndEvent *)eventData;140MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->currentThread);141J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();142143MM_ConcurrentSafepointCallbackJava *callback = (MM_ConcurrentSafepointCallbackJava*) userData;144javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, callback->_asyncEventKey);145}146147void148#if defined(AIXPPC) || defined(LINUXPPC)149MM_ConcurrentSafepointCallbackJava::registerCallback(MM_EnvironmentBase *env, SafepointCallbackHandler handler, void *userData, bool cancelAfterGC)150#else151MM_ConcurrentSafepointCallbackJava::registerCallback(MM_EnvironmentBase *env, SafepointCallbackHandler handler, void *userData)152#endif /* defined(AIXPPC) || defined(LINUXPPC) */153{154Assert_MM_true(NULL == _handler);155Assert_MM_true(NULL == _userData);156157_handler = handler;158_userData = userData;159160#if defined(AIXPPC) || defined(LINUXPPC)161_cancelAfterGC = cancelAfterGC;162if (_cancelAfterGC) {163/* Register hook for global GC end. */164J9HookInterface** mmHooks = J9_HOOK_INTERFACE(env->getExtensions()->omrHookInterface);165(*mmHooks)->J9HookRegisterWithCallSite(mmHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, reportGlobalGCComplete, OMR_GET_CALLSITE(), this);166}167#endif /* defined(AIXPPC) || defined(LINUXPPC) */168}169170void171MM_ConcurrentSafepointCallbackJava::requestCallback(MM_EnvironmentBase *env)172{173Assert_MM_false(NULL == _handler);174Assert_MM_false(NULL == _userData);175176J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();177javaVM->internalVMFunctions->J9SignalAsyncEvent(javaVM, (J9VMThread *)env->getLanguageVMThread(), _asyncEventKey);178}179180void181MM_ConcurrentSafepointCallbackJava::cancelCallback(MM_EnvironmentBase *env)182{183J9JavaVM *javaVM = (J9JavaVM*) env->getLanguageVM();184javaVM->internalVMFunctions->J9CancelAsyncEvent(javaVM, NULL, _asyncEventKey);185}186187188