1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_LOG_UTILS_H_
6 #define V8_LOG_UTILS_H_
7 
8 #include <stdio.h>
9 
10 #include <cstdarg>
11 
12 #include "src/allocation.h"
13 #include "src/base/platform/mutex.h"
14 #include "src/flags.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class Logger;
20 
21 // Functions and data for performing output of log messages.
22 class Log {
23  public:
24   // Performs process-wide initialization.
25   void Initialize(const char* log_file_name);
26 
27   // Disables logging, but preserves acquired resources.
stop()28   void stop() { is_stopped_ = true; }
29 
InitLogAtStart()30   static bool InitLogAtStart() {
31     return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc ||
32            FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp ||
33            FLAG_ll_prof || FLAG_perf_basic_prof ||
34            FLAG_log_internal_timer_events || FLAG_prof_cpp;
35   }
36 
37   // Frees all resources acquired in Initialize and Open... functions.
38   // When a temporary file is used for the log, returns its stream descriptor,
39   // leaving the file open.
40   FILE* Close();
41 
42   // Returns whether logging is enabled.
IsEnabled()43   bool IsEnabled() {
44     return !is_stopped_ && output_handle_ != NULL;
45   }
46 
47   // Size of buffer used for formatting log messages.
48   static const int kMessageBufferSize = 2048;
49 
50   // This mode is only used in tests, as temporary files are automatically
51   // deleted on close and thus can't be accessed afterwards.
52   static const char* const kLogToTemporaryFile;
53   static const char* const kLogToConsole;
54 
55   // Utility class for formatting log messages. It fills the message into the
56   // static buffer in Log.
57   class MessageBuilder BASE_EMBEDDED {
58    public:
59     // Create a message builder starting from position 0.
60     // This acquires the mutex in the log as well.
61     explicit MessageBuilder(Log* log);
~MessageBuilder()62     ~MessageBuilder() { }
63 
64     // Append string data to the log message.
65     void Append(const char* format, ...);
66 
67     // Append string data to the log message.
68     void AppendVA(const char* format, va_list args);
69 
70     // Append a character to the log message.
71     void Append(const char c);
72 
73     // Append double quoted string to the log message.
74     void AppendDoubleQuotedString(const char* string);
75 
76     // Append a heap string.
77     void Append(String* str);
78 
79     // Appends an address.
80     void AppendAddress(Address addr);
81 
82     void AppendSymbolName(Symbol* symbol);
83 
84     void AppendDetailed(String* str, bool show_impl_info);
85 
86     // Append a portion of a string.
87     void AppendStringPart(const char* str, int len);
88 
89     // Write the log message to the log file currently opened.
90     void WriteToLogFile();
91 
92    private:
93     Log* log_;
94     base::LockGuard<base::Mutex> lock_guard_;
95     int pos_;
96   };
97 
98  private:
99   explicit Log(Logger* logger);
100 
101   // Opens stdout for logging.
102   void OpenStdout();
103 
104   // Opens file for logging.
105   void OpenFile(const char* name);
106 
107   // Opens a temporary file for logging.
108   void OpenTemporaryFile();
109 
110   // Implementation of writing to a log file.
WriteToFile(const char * msg,int length)111   int WriteToFile(const char* msg, int length) {
112     DCHECK(output_handle_ != NULL);
113     size_t rv = fwrite(msg, 1, length, output_handle_);
114     DCHECK(static_cast<size_t>(length) == rv);
115     USE(rv);
116     fflush(output_handle_);
117     return length;
118   }
119 
120   // Whether logging is stopped (e.g. due to insufficient resources).
121   bool is_stopped_;
122 
123   // When logging is active output_handle_ is used to store a pointer to log
124   // destination.  mutex_ should be acquired before using output_handle_.
125   FILE* output_handle_;
126 
127   // mutex_ is a Mutex used for enforcing exclusive
128   // access to the formatting buffer and the log file or log memory buffer.
129   base::Mutex mutex_;
130 
131   // Buffer used for formatting log messages. This is a singleton buffer and
132   // mutex_ should be acquired before using it.
133   char* message_buffer_;
134 
135   Logger* logger_;
136 
137   friend class Logger;
138 };
139 
140 
141 }  // namespace internal
142 }  // namespace v8
143 
144 #endif  // V8_LOG_UTILS_H_
145