Path: blob/master/runtime/gc_verbose_old/VerboseEventStream.cpp
5985 views
1/*******************************************************************************2* Copyright (c) 1991, 2014 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* 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-exception21*******************************************************************************/2223#include "AtomicOperations.hpp"24#include "EnvironmentBase.hpp"25#include "VerboseEvent.hpp"26#include "VerboseEventStream.hpp"27#include "GCExtensions.hpp"28#include "VerboseManagerOld.hpp"2930/**31* Create a new MM_VerboseEventStream instance.32* @return Pointer to the new MM_VerboseEventStream.33*/34MM_VerboseEventStream *35MM_VerboseEventStream::newInstance(MM_EnvironmentBase *env, MM_VerboseManagerOld *manager)36{37MM_VerboseEventStream *eventStream = NULL;38MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());3940eventStream = (MM_VerboseEventStream *)extensions->getForge()->allocate(sizeof(MM_VerboseEventStream), MM_AllocationCategory::DIAGNOSTIC, J9_GET_CALLSITE());41if (eventStream) {42new(eventStream) MM_VerboseEventStream(env, manager);43}44return eventStream;45}4647/**48* Kill the MM_VerboseEventStream instance.49* Tears down the related structures and frees any storage.50*/51void52MM_VerboseEventStream::kill(MM_EnvironmentBase *env)53{54tearDown(env);5556MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());57extensions->getForge()->free(this);58}5960/**61* Tear down the structures managed by the MM_VerboseEventStream.62*/63void64MM_VerboseEventStream::tearDown(MM_EnvironmentBase *env)65{66MM_VerboseEvent *event, *nextEvent;6768event = _eventChain;69_eventChain = NULL;70_eventChainTail = NULL;7172while(NULL != event){73nextEvent = event->getNextEvent();74event->kill(env);75event = nextEvent;76}77}7879/**80* Calls each events consume routine.81*/82void83MM_VerboseEventStream::callConsumeRoutines(MM_EnvironmentBase *env)84{85MM_VerboseEvent *event = _eventChain;8687while(NULL != event) {88event->consumeEvents();89event = event->getNextEvent();90}91}9293/**94* Removes events which don't output form the chain.95*/96void97MM_VerboseEventStream::removeNonOutputEvents(MM_EnvironmentBase *env)98{99MM_VerboseEvent *event, *nextEvent;100101event = _eventChain;102while(NULL != event){103nextEvent = event->getNextEvent();104if(!event->definesOutputRoutine()){105removeEventFromChain(env, event);106}107event = nextEvent;108}109}110111/**112* Remove a specified event from the event chain.113* @param event Pointer to the event to be removed.114*/115void116MM_VerboseEventStream::removeEventFromChain(MM_EnvironmentBase *env, MM_VerboseEvent *event)117{118MM_VerboseEvent *previousEvent = event->getPreviousEvent();119MM_VerboseEvent *nextEvent = event->getNextEvent();120121if(NULL != previousEvent) {122previousEvent->setNextEvent(nextEvent);123} else {124/* We are removing the head of the chain */125_eventChain = nextEvent;126}127128if(NULL != nextEvent) {129nextEvent->setPreviousEvent(previousEvent);130} else {131/* We are removing the tail of the chain */132_eventChainTail = previousEvent;133}134135event->kill(env);136}137138/**139* Add an event to the event chain.140* @param event Pointer to the event to be added.141*/142void143MM_VerboseEventStream::chainEvent(MM_EnvironmentBase *env, MM_VerboseEvent *event)144{145UDATA oldValue, newValue;146147newValue = (UDATA)event;148149do {150oldValue = (UDATA)_eventChainTail;151((MM_VerboseEvent *)newValue)->setPreviousEvent((MM_VerboseEvent *)oldValue);152} while((UDATA)oldValue != MM_AtomicOperations::lockCompareExchange((volatile UDATA *)&_eventChainTail, oldValue, newValue));153154if (oldValue) {155((MM_VerboseEvent *)oldValue)->setNextEvent((MM_VerboseEvent*)newValue);156} else {157_eventChain = event;158}159}160161/**162* Process the event stream.163* Prepares the event stream for output and notifies the verbose manager to pass the stream to the output agents.164*/165void166MM_VerboseEventStream::processStream(MM_EnvironmentBase *env)167{168PORT_ACCESS_FROM_ENVIRONMENT(env);169_manager->incrementOutputCount();170callConsumeRoutines(env);171removeNonOutputEvents(env);172_manager->passStreamToOutputAgents(env, this);173if(isDisposable()) {174kill(env);175} else {176_manager->setLastOutputTime(j9time_hires_clock());177tearDown(env);178}179}180181/**182* Returns an event of a specific type.183* Walks the event stream backwards from the event passed in and returns the first event of the type requested.184* @param eventID the type of event required.185* @param hookInterface interface associated with eventID186* @param event pointer to the current event.187* @return Pointer an event of that type.188*/189MM_VerboseEvent *190MM_VerboseEventStream::returnEvent(UDATA eventid, J9HookInterface** hookInterface, MM_VerboseEvent *event)191{192while(NULL != event) {193if((eventid == event->getEventType()) && (hookInterface == event->getHookInterface())) {194return event;195}196event = event->getPreviousEvent();197}198return NULL;199}200201/**202* Returns an event of a specific type.203* Walks the event stream backwards from the event passed in and returns the first event of the type requested.204* HOWEVER, if an event of type stopEventID is encountered first, NULL is returned.205* @param eventID the type of event required.206* @param hookInterface interface associated with eventID207* @param event pointer to the current event.208* @param stopEventID the type of event to stop at if encountered.209* @param stopHookInterface interface associated with stopEventID210* @return Pointer an event of that type.211*/212MM_VerboseEvent *213MM_VerboseEventStream::returnEvent(UDATA eventid, J9HookInterface** hookInterface, MM_VerboseEvent *event, UDATA stopEventID, J9HookInterface** stopHookInterface)214{215while(NULL != event) {216if((stopEventID == event->getEventType()) && (stopHookInterface == event->getHookInterface())) {217/* we've hit a "stopEventID" first, so return NULL */218return NULL;219}220if((eventid == event->getEventType()) && (hookInterface == event->getHookInterface())) {221return event;222}223event = event->getPreviousEvent();224}225return NULL;226}227228229