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