1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2009 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_LOG_UTILS_H_ 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_LOG_UTILS_H_ 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h" 9257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Logger; 1444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Functions and data for performing output of log messages. 1644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass Log { 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 1844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Performs process-wide initialization. 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Initialize(const char* log_file_name); 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Disables logging, but preserves acquired resources. 2244f0eee88ff00398ff7f715fab053374d808c90dSteve Block void stop() { is_stopped_ = true; } 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool InitLogAtStart() { 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch || FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch || FLAG_ll_prof || FLAG_perf_basic_prof || FLAG_perf_jit_prof 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch || FLAG_log_internal_timer_events; 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Frees all resources acquired in Initialize and Open... functions. 323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // When a temporary file is used for the log, returns its stream descriptor, 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // leaving the file open. 343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch FILE* Close(); 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns whether logging is enabled. 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool IsEnabled() { 383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return !is_stopped_ && output_handle_ != NULL; 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Size of buffer used for formatting log messages. 423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kMessageBufferSize = 2048; 433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // This mode is only used in tests, as temporary files are automatically 453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // deleted on close and thus can't be accessed afterwards. 4669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static const char* const kLogToTemporaryFile; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const char* const kLogToConsole; 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Utility class for formatting log messages. It fills the message into the 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // static buffer in Log. 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class MessageBuilder BASE_EMBEDDED { 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create a message builder starting from position 0. 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This acquires the mutex in the log as well. 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MessageBuilder(Log* log); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~MessageBuilder() { } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append string data to the log message. 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Append(const char* format, ...); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append string data to the log message. 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendVA(const char* format, va_list args); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append a character to the log message. 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Append(const char c); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append double quoted string to the log message. 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendDoubleQuotedString(const char* string); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append a heap string. 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Append(String* str); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Appends an address. 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendAddress(Address addr); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendSymbolName(Symbol* symbol); 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendDetailed(String* str, bool show_impl_info); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Append a portion of a string. 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AppendStringPart(const char* str, int len); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write the log message to the log file currently opened. 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void WriteToLogFile(); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Log* log_; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::LockGuard<base::Mutex> lock_guard_; 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pos_; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit Log(Logger* logger); 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opens stdout for logging. 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void OpenStdout(); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opens file for logging. 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block void OpenFile(const char* name); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Opens a temporary file for logging. 1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void OpenTemporaryFile(); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Implementation of writing to a log file. 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int WriteToFile(const char* msg, int length) { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(output_handle_ != NULL); 107d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block size_t rv = fwrite(msg, 1, length, output_handle_); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<size_t>(length) == rv); 109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block USE(rv); 110f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch fflush(output_handle_); 111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return length; 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Whether logging is stopped (e.g. due to insufficient resources). 11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool is_stopped_; 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // When logging is active output_handle_ is used to store a pointer to log 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // destination. mutex_ should be acquired before using output_handle_. 11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block FILE* output_handle_; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mutex_ is a Mutex used for enforcing exclusive 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // access to the formatting buffer and the log file or log memory buffer. 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Mutex mutex_; 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Buffer used for formatting log messages. This is a singleton buffer and 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mutex_ should be acquired before using it. 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* message_buffer_; 12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Logger* logger_; 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch friend class Logger; 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_LOG_UTILS_H_ 138