1755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Copyright 2006-2009 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
5755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#ifndef V8_LOG_UTILS_H_
6755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#define V8_LOG_UTILS_H_
7755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
91c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
10755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgnamespace v8 {
11755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgnamespace internal {
12755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
13ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Logger;
14ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
15755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Functions and data for performing output of log messages.
16ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass Log {
17755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org public:
18ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Performs process-wide initialization.
1910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  void Initialize(const char* log_file_name);
20755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
21755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Disables logging, but preserves acquired resources.
22ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void stop() { is_stopped_ = true; }
23755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
24ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  static bool InitLogAtStart() {
2529699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org    return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc
2629699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org        || FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp
2729699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org        || FLAG_ll_prof || FLAG_perf_basic_prof || FLAG_perf_jit_prof
2829699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org        || FLAG_log_internal_timer_events;
29ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
30ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
31ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Frees all resources acquired in Initialize and Open... functions.
32030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // When a temporary file is used for the log, returns its stream descriptor,
33030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // leaving the file open.
34030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  FILE* Close();
35755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
36755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Returns whether logging is enabled.
37ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool IsEnabled() {
38030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org    return !is_stopped_ && output_handle_ != NULL;
39755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  }
40755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
412bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com  // Size of buffer used for formatting log messages.
42030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  static const int kMessageBufferSize = 2048;
43030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org
44030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // This mode is only used in tests, as temporary files are automatically
45030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // deleted on close and thus can't be accessed afterwards.
467c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  static const char* const kLogToTemporaryFile;
4710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org  static const char* const kLogToConsole;
482bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com
49ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // Utility class for formatting log messages. It fills the message into the
50ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // static buffer in Log.
51ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  class MessageBuilder BASE_EMBEDDED {
52ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org   public:
53ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Create a message builder starting from position 0.
54ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // This acquires the mutex in the log as well.
55ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    explicit MessageBuilder(Log* log);
56ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ~MessageBuilder() { }
57ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
58ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append string data to the log message.
59ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void Append(const char* format, ...);
60ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
61ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append string data to the log message.
62ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendVA(const char* format, va_list args);
63ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
64ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append a character to the log message.
65ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void Append(const char c);
66ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
67ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append double quoted string to the log message.
68ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendDoubleQuotedString(const char* string);
69ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
70ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append a heap string.
71ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void Append(String* str);
72ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
73ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Appends an address.
74ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendAddress(Address addr);
75ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
76ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendSymbolName(Symbol* symbol);
77ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
78ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendDetailed(String* str, bool show_impl_info);
79ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
80ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Append a portion of a string.
81ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void AppendStringPart(const char* str, int len);
82ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
83ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    // Write the log message to the log file currently opened.
84ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    void WriteToLogFile();
85ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
86ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org   private:
87ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Log* log_;
885de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    base::LockGuard<base::Mutex> lock_guard_;
89ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    int pos_;
90ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  };
91ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
92755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org private:
93ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit Log(Logger* logger);
94ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Opens stdout for logging.
96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void OpenStdout();
97755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Opens file for logging.
99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void OpenFile(const char* name);
100755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
101030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // Opens a temporary file for logging.
102030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  void OpenTemporaryFile();
103755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
104755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Implementation of writing to a log file.
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int WriteToFile(const char* msg, int length) {
106e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(output_handle_ != NULL);
107c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    size_t rv = fwrite(msg, 1, length, output_handle_);
108e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(static_cast<size_t>(length) == rv);
109c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    USE(rv);
110eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org    fflush(output_handle_);
111c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    return length;
112755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  }
113755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
114755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Whether logging is stopped (e.g. due to insufficient resources).
115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool is_stopped_;
116755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
117030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // When logging is active output_handle_ is used to store a pointer to log
118030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // destination.  mutex_ should be acquired before using output_handle_.
119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  FILE* output_handle_;
120755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
121755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // mutex_ is a Mutex used for enforcing exclusive
122755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // access to the formatting buffer and the log file or log memory buffer.
1235de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  base::Mutex mutex_;
124755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
125755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // Buffer used for formatting log messages. This is a singleton buffer and
126755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org  // mutex_ should be acquired before using it.
127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  char* message_buffer_;
128ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
129ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Logger* logger_;
130755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
1314a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  friend class Logger;
132755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org};
133755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
134755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
135755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} }  // namespace v8::internal
136755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
137755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#endif  // V8_LOG_UTILS_H_
138