Path: blob/master/runtime/gc_verbose_old/VerboseStandardStreamOutput.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 "VerboseStandardStreamOutput.hpp"24#include "VerboseEvent.hpp"25#include "VerboseBuffer.hpp"26#include "EnvironmentBase.hpp"27#include "GCExtensions.hpp"28#include <string.h>2930#define INPUT_STRING_SIZE 23631#define INDENT_SPACER " "3233/**34* Formats and output data.35* Called by events, formats the data passed into verbose form and outputs it.36* @param indent The current level of indentation.37* @param format String to format the data into.38*/39void40MM_VerboseStandardStreamOutput::formatAndOutput(J9VMThread *vmThread, UDATA indent, const char *format, ...)41{42char inputString[INPUT_STRING_SIZE];43char localBuf[256];44UDATA length;45va_list args;46MM_EnvironmentBase* env = MM_EnvironmentBase::getEnvironment((OMR_VMThread *)vmThread->omrVMThread);47PORT_ACCESS_FROM_ENVIRONMENT(env);4849localBuf[0] = '\0';50for(UDATA i=0; i < indent; i++) {51strcat(localBuf, INDENT_SPACER);52}5354va_start(args, format);55j9str_vprintf(inputString, INPUT_STRING_SIZE, format, args);56va_end(args);5758strcat(localBuf, inputString);59strcat(localBuf, "\n");60length = strlen(localBuf);6162if(NULL != _buffer) {63if(_buffer->add(env, localBuf)) {64/* Added successfully - return */65return;66}67}6869/* If there's a problem with the buffering, we just write straight to the tty */70if(STDERR == _currentStream){71j9file_write_text(J9PORT_TTY_ERR, localBuf, length);72} else {73j9file_write_text(J9PORT_TTY_OUT, localBuf, length);74}75}7677/**78* Create a new MM_VerboseStandardStreamOutput instance.79*/80MM_VerboseStandardStreamOutput *81MM_VerboseStandardStreamOutput::newInstance(MM_EnvironmentBase *env, const char *filename)82{83MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());8485MM_VerboseStandardStreamOutput *agent = (MM_VerboseStandardStreamOutput *)extensions->getForge()->allocate(sizeof(MM_VerboseStandardStreamOutput), MM_AllocationCategory::DIAGNOSTIC, J9_GET_CALLSITE());86if(agent) {87new(agent) MM_VerboseStandardStreamOutput(env);88if(!agent->initialize(env, filename)) {89agent->kill(env);90agent = NULL;91}92}93return agent;94}9596/**97* Initializes the MM_VerboseStandardStreamOutput instance.98*/99bool100MM_VerboseStandardStreamOutput::initialize(MM_EnvironmentBase *env, const char *filename)101{102J9JavaVM* javaVM = (J9JavaVM *)env->getOmrVM()->_language_vm;103PORT_ACCESS_FROM_JAVAVM(javaVM);104const char* version = javaVM->memoryManagerFunctions->omrgc_get_version(env->getOmrVM());105106setStream(getStreamID(env, filename));107108if(STDERR == _currentStream){109j9file_printf(PORTLIB, J9PORT_TTY_ERR, "\n" VERBOSEGC_HEADER_TEXT_ALL, version);110} else {111j9file_printf(PORTLIB, J9PORT_TTY_OUT, "\n" VERBOSEGC_HEADER_TEXT_ALL, version);112}113114if(NULL == (_buffer = MM_VerboseBuffer::newInstance(env, INITIAL_BUFFER_SIZE))) {115return false;116}117118return true;119}120121/**122* Closes the agent's output stream.123*/124void125MM_VerboseStandardStreamOutput::closeStream(MM_EnvironmentBase *env)126{127UDATA length = strlen(VERBOSEGC_FOOTER_TEXT);128PORT_ACCESS_FROM_ENVIRONMENT(env);129130if(STDERR == _currentStream){131j9file_write_text(J9PORT_TTY_ERR, VERBOSEGC_FOOTER_TEXT "\n", length + 1);132} else {133j9file_write_text(J9PORT_TTY_OUT, VERBOSEGC_FOOTER_TEXT "\n", length + 1);134}135}136137/**138* Tear down the structures managed by the MM_VerboseStandardStreamOutput.139* Tears down the verbose buffer.140*/141void142MM_VerboseStandardStreamOutput::tearDown(MM_EnvironmentBase *env)143{144if(NULL != _buffer) {145_buffer->kill(env);146}147}148149/**150* Flushes the verbose buffer to the output stream.151*/152void153MM_VerboseStandardStreamOutput::endOfCycle(J9VMThread *vmThread)154{155PORT_ACCESS_FROM_VMC(vmThread);156157if(NULL != _buffer){158if(STDERR == _currentStream){159j9file_write_text(J9PORT_TTY_ERR, _buffer->contents(), _buffer->currentSize());160j9file_write_text(J9PORT_TTY_ERR, "\n", 1);161} else {162j9file_write_text(J9PORT_TTY_OUT, _buffer->contents(), _buffer->currentSize());163j9file_write_text(J9PORT_TTY_OUT, "\n", 1);164}165_buffer->reset();166}167}168169bool170MM_VerboseStandardStreamOutput::reconfigure(MM_EnvironmentBase *env, const char *filename, UDATA fileCount, UDATA iterations)171{172setStream(getStreamID(env, filename));173return true;174}175176MM_VerboseStandardStreamOutput::StreamID177MM_VerboseStandardStreamOutput::getStreamID(MM_EnvironmentBase *env, const char *string)178{179if(NULL == string) {180return STDERR;181}182183if(!strcmp(string, "stdout")) {184return STDOUT;185}186187return STDERR;188}189190191