Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Unified Diff: src/log.cc

Issue 115814: Implement a dynamically growing memory log buffer with an upper limit. (Closed)
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/SConscript ('k') | src/log-utils.h » ('j') | src/log-utils.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/log.cc
diff --git a/src/log.cc b/src/log.cc
index 59018a18a0ae947e537986f9218f74874f3ab73f..e149fdb17a89ba80071bf76ee238df3e1159a7fc 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -31,6 +31,7 @@
#include "bootstrapper.h"
#include "log.h"
+#include "log-utils.h"
#include "macro-assembler.h"
#include "platform.h"
#include "serialize.h"
@@ -287,304 +288,6 @@ void Profiler::Run() {
}
-#ifdef ENABLE_LOGGING_AND_PROFILING
-
-// Functions and data for performing output of log messages.
-class Log : public AllStatic {
- public:
- // Opens stdout for logging.
- static void OpenStdout();
-
- // Opens file for logging.
- static void OpenFile(const char* name);
-
- // Opens memory buffer for logging.
- static void OpenMemoryBuffer();
-
- // Frees all resources acquired in Open... functions.
- static void Close();
-
- // See description in include/v8.h.
- static int GetLogLines(int from_pos, char* dest_buf, int max_size);
-
- // Returns whether logging is enabled.
- static bool IsEnabled() {
- return output_handle_ != NULL || output_buffer_ != NULL;
- }
-
- private:
- typedef int (*WritePtr)(const char* msg, int length);
-
- // Initialization function called from Open... functions.
- static void Init();
-
- // Write functions assume that mutex_ is acquired by the caller.
- static WritePtr Write;
-
- // Implementation of writing to a log file.
- static int WriteToFile(const char* msg, int length) {
- ASSERT(output_handle_ != NULL);
- int rv = fwrite(msg, 1, length, output_handle_);
- ASSERT(length == rv);
- return rv;
- }
-
- // Implementation of writing to a memory buffer.
- static int WriteToMemory(const char* msg, int length) {
- ASSERT(output_buffer_ != NULL);
- ASSERT(output_buffer_write_pos_ >= output_buffer_);
- if (output_buffer_write_pos_ + length
- <= output_buffer_ + kOutputBufferSize) {
- memcpy(output_buffer_write_pos_, msg, length);
- output_buffer_write_pos_ += length;
- return length;
- } else {
- // Memory buffer is full, ignore write.
- return 0;
- }
- }
-
- // When logging is active, either output_handle_ or output_buffer_ is used
- // to store a pointer to log destination. If logging was opened via OpenStdout
- // or OpenFile, then output_handle_ is used. If logging was opened
- // via OpenMemoryBuffer, then output_buffer_ is used.
- // mutex_ should be acquired before using output_handle_ or output_buffer_.
- static FILE* output_handle_;
-
- static char* output_buffer_;
-
- // mutex_ is a Mutex used for enforcing exclusive
- // access to the formatting buffer and the log file or log memory buffer.
- static Mutex* mutex_;
-
- // Size of buffer used for memory logging.
- static const int kOutputBufferSize = 2 * 1024 * 1024;
-
- // Writing position in a memory buffer.
- static char* output_buffer_write_pos_;
-
- // Size of buffer used for formatting log messages.
- static const int kMessageBufferSize = 2048;
-
- // Buffer used for formatting log messages. This is a singleton buffer and
- // mutex_ should be acquired before using it.
- static char* message_buffer_;
-
- friend class LogMessageBuilder;
-};
-
-
-Log::WritePtr Log::Write = NULL;
-FILE* Log::output_handle_ = NULL;
-char* Log::output_buffer_ = NULL;
-Mutex* Log::mutex_ = NULL;
-char* Log::output_buffer_write_pos_ = NULL;
-char* Log::message_buffer_ = NULL;
-
-
-void Log::Init() {
- mutex_ = OS::CreateMutex();
- message_buffer_ = NewArray<char>(kMessageBufferSize);
-}
-
-
-void Log::OpenStdout() {
- ASSERT(!IsEnabled());
- output_handle_ = stdout;
- Write = WriteToFile;
- Init();
-}
-
-
-void Log::OpenFile(const char* name) {
- ASSERT(!IsEnabled());
- output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
- Write = WriteToFile;
- Init();
-}
-
-
-void Log::OpenMemoryBuffer() {
- ASSERT(!IsEnabled());
- output_buffer_ = NewArray<char>(kOutputBufferSize);
- output_buffer_write_pos_ = output_buffer_;
- Write = WriteToMemory;
- Init();
-}
-
-
-void Log::Close() {
- if (Write == WriteToFile) {
- fclose(output_handle_);
- output_handle_ = NULL;
- } else if (Write == WriteToMemory) {
- DeleteArray(output_buffer_);
- output_buffer_ = NULL;
- } else {
- ASSERT(Write == NULL);
- }
- Write = NULL;
-
- delete mutex_;
- mutex_ = NULL;
-
- DeleteArray(message_buffer_);
- message_buffer_ = NULL;
-}
-
-
-int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
- if (Write != WriteToMemory) return 0;
- ASSERT(output_buffer_ != NULL);
- ASSERT(output_buffer_write_pos_ >= output_buffer_);
- ASSERT(from_pos >= 0);
- ASSERT(max_size >= 0);
- int actual_size = max_size;
- char* buffer_read_pos = output_buffer_ + from_pos;
- ScopedLock sl(mutex_);
- if (actual_size == 0
- || output_buffer_write_pos_ == output_buffer_
- || buffer_read_pos >= output_buffer_write_pos_) {
- // No data requested or can be returned.
- return 0;
- }
- if (buffer_read_pos + actual_size > output_buffer_write_pos_) {
- // Requested size overlaps with current writing position and
- // needs to be truncated.
- actual_size = output_buffer_write_pos_ - buffer_read_pos;
- ASSERT(actual_size == 0 || buffer_read_pos[actual_size - 1] == '\n');
- } else {
- // Find previous log line boundary.
- char* end_pos = buffer_read_pos + actual_size - 1;
- while (end_pos >= buffer_read_pos && *end_pos != '\n') --end_pos;
- actual_size = end_pos - buffer_read_pos + 1;
- }
- ASSERT(actual_size <= max_size);
- if (actual_size > 0) {
- memcpy(dest_buf, buffer_read_pos, actual_size);
- }
- return actual_size;
-}
-
-
-// Utility class for formatting log messages. It fills the message into the
-// static buffer in Log.
-class LogMessageBuilder BASE_EMBEDDED {
- public:
- explicit LogMessageBuilder();
- ~LogMessageBuilder() { }
-
- void Append(const char* format, ...);
- void Append(const char* format, va_list args);
- void Append(const char c);
- void Append(String* str);
- void AppendDetailed(String* str, bool show_impl_info);
-
- void WriteToLogFile();
- void WriteCStringToLogFile(const char* str);
-
- private:
- ScopedLock sl;
- int pos_;
-};
-
-
-// Create a message builder starting from position 0. This acquires the mutex
-// in the logger as well.
-LogMessageBuilder::LogMessageBuilder(): sl(Log::mutex_), pos_(0) {
- ASSERT(Log::message_buffer_ != NULL);
-}
-
-
-// Append string data to the log message.
-void LogMessageBuilder::Append(const char* format, ...) {
- Vector<char> buf(Log::message_buffer_ + pos_,
- Log::kMessageBufferSize - pos_);
- va_list args;
- va_start(args, format);
- Append(format, args);
- va_end(args);
- ASSERT(pos_ <= Log::kMessageBufferSize);
-}
-
-
-// Append string data to the log message.
-void LogMessageBuilder::Append(const char* format, va_list args) {
- Vector<char> buf(Log::message_buffer_ + pos_,
- Log::kMessageBufferSize - pos_);
- int result = v8::internal::OS::VSNPrintF(buf, format, args);
-
- // Result is -1 if output was truncated.
- if (result >= 0) {
- pos_ += result;
- } else {
- pos_ = Log::kMessageBufferSize;
- }
- ASSERT(pos_ <= Log::kMessageBufferSize);
-}
-
-
-// Append a character to the log message.
-void LogMessageBuilder::Append(const char c) {
- if (pos_ < Log::kMessageBufferSize) {
- Log::message_buffer_[pos_++] = c;
- }
- ASSERT(pos_ <= Log::kMessageBufferSize);
-}
-
-
-// Append a heap string.
-void LogMessageBuilder::Append(String* str) {
- AssertNoAllocation no_heap_allocation; // Ensure string stay valid.
- int length = str->length();
- for (int i = 0; i < length; i++) {
- Append(static_cast<char>(str->Get(i)));
- }
-}
-
-void LogMessageBuilder::AppendDetailed(String* str, bool show_impl_info) {
- AssertNoAllocation no_heap_allocation; // Ensure string stay valid.
- int len = str->length();
- if (len > 0x1000)
- len = 0x1000;
- if (show_impl_info) {
- Append(str->IsAsciiRepresentation() ? 'a' : '2');
- if (StringShape(str).IsExternal())
- Append('e');
- if (StringShape(str).IsSymbol())
- Append('#');
- Append(":%i:", str->length());
- }
- for (int i = 0; i < len; i++) {
- uc32 c = str->Get(i);
- if (c > 0xff) {
- Append("\\u%04x", c);
- } else if (c < 32 || c > 126) {
- Append("\\x%02x", c);
- } else if (c == ',') {
- Append("\\,");
- } else if (c == '\\') {
- Append("\\\\");
- } else {
- Append("%lc", c);
- }
- }
-}
-
-// Write the log message to the log file currently opened.
-void LogMessageBuilder::WriteToLogFile() {
- ASSERT(pos_ <= Log::kMessageBufferSize);
- Log::Write(Log::message_buffer_, pos_);
-}
-
-// Write a null-terminated string to to the log file currently opened.
-void LogMessageBuilder::WriteCStringToLogFile(const char* str) {
- int len = strlen(str);
- Log::Write(str, len);
-}
-#endif
-
-
//
// Logger class implementation.
//
« no previous file with comments | « src/SConscript ('k') | src/log-utils.h » ('j') | src/log-utils.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698