1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2009 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_LOG_UTILS_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_LOG_UTILS_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Logger; 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Functions and data for performing output of log messages. 3944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Log { 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Performs process-wide initialization. 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Initialize(); 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Disables logging, but preserves acquired resources. 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block void stop() { is_stopped_ = true; } 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Frees all resources acquired in Initialize and Open... functions. 483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // When a temporary file is used for the log, returns its stream descriptor, 493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // leaving the file open. 503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FILE* Close(); 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns whether logging is enabled. 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsEnabled() { 543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return !is_stopped_ && output_handle_ != NULL; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Size of buffer used for formatting log messages. 583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kMessageBufferSize = 2048; 593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // This mode is only used in tests, as temporary files are automatically 613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // deleted on close and thus can't be accessed afterwards. 6269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static const char* const kLogToTemporaryFile; 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit Log(Logger* logger); 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opens stdout for logging. 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block void OpenStdout(); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opens file for logging. 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block void OpenFile(const char* name); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Opens a temporary file for logging. 743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void OpenTemporaryFile(); 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Implementation of writing to a log file. 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int WriteToFile(const char* msg, int length) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(output_handle_ != NULL); 79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block size_t rv = fwrite(msg, 1, length, output_handle_); 80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(static_cast<size_t>(length) == rv); 81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block USE(rv); 82f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch fflush(output_handle_); 83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return length; 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Whether logging is stopped (e.g. due to insufficient resources). 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool is_stopped_; 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // When logging is active output_handle_ is used to store a pointer to log 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // destination. mutex_ should be acquired before using output_handle_. 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block FILE* output_handle_; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Used when low-level profiling is active. 94257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FILE* ll_output_handle_; 95f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mutex_ is a Mutex used for enforcing exclusive 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // access to the formatting buffer and the log file or log memory buffer. 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Mutex* mutex_; 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Buffer used for formatting log messages. This is a singleton buffer and 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mutex_ should be acquired before using it. 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* message_buffer_; 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Logger* logger_; 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch friend class Logger; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class LogMessageBuilder; 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utility class for formatting log messages. It fills the message into the 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// static buffer in Log. 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LogMessageBuilder BASE_EMBEDDED { 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a message builder starting from position 0. This acquires the mutex 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in the log as well. 11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit LogMessageBuilder(Logger* logger); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~LogMessageBuilder() { } 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append string data to the log message. 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Append(const char* format, ...); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append string data to the log message. 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AppendVA(const char* format, va_list args); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append a character to the log message. 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Append(const char c); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append a heap string. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Append(String* str); 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Appends an address. 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AppendAddress(Address addr); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AppendDetailed(String* str, bool show_impl_info); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Append a portion of a string. 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void AppendStringPart(const char* str, int len); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Write the log message to the log file currently opened. 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void WriteToLogFile(); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Log* log_; 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScopedLock sl; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int pos_; 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_LOG_UTILS_H_ 152