| Index: src/log-utils.cc
|
| ===================================================================
|
| --- src/log-utils.cc (revision 7267)
|
| +++ src/log-utils.cc (working copy)
|
| @@ -28,6 +28,7 @@
|
| #include "v8.h"
|
|
|
| #include "log-utils.h"
|
| +#include "string-stream.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -118,29 +119,117 @@
|
| return data_size;
|
| }
|
|
|
| -
|
| -bool Log::is_stopped_ = false;
|
| -Log::WritePtr Log::Write = NULL;
|
| -FILE* Log::output_handle_ = NULL;
|
| -FILE* Log::output_code_handle_ = NULL;
|
| -LogDynamicBuffer* Log::output_buffer_ = NULL;
|
| // Must be the same message as in Logger::PauseProfiler.
|
| -const char* Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
|
| -Mutex* Log::mutex_ = NULL;
|
| -char* Log::message_buffer_ = NULL;
|
| +const char* const Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
|
|
|
| +Log::Log(Logger* logger)
|
| + : write_to_file_(false),
|
| + is_stopped_(false),
|
| + output_handle_(NULL),
|
| + output_code_handle_(NULL),
|
| + output_buffer_(NULL),
|
| + mutex_(NULL),
|
| + message_buffer_(NULL),
|
| + logger_(logger) {
|
| +}
|
|
|
| -void Log::Init() {
|
| +
|
| +static void AddIsolateIdIfNeeded(StringStream* stream) {
|
| + Isolate* isolate = Isolate::Current();
|
| + if (isolate->IsDefaultIsolate()) return;
|
| + stream->Add("isolate-%p-", isolate);
|
| +}
|
| +
|
| +
|
| +void Log::Initialize() {
|
| +#ifdef ENABLE_LOGGING_AND_PROFILING
|
| mutex_ = OS::CreateMutex();
|
| message_buffer_ = NewArray<char>(kMessageBufferSize);
|
| +
|
| + // --log-all enables all the log flags.
|
| + if (FLAG_log_all) {
|
| + FLAG_log_runtime = true;
|
| + FLAG_log_api = true;
|
| + FLAG_log_code = true;
|
| + FLAG_log_gc = true;
|
| + FLAG_log_suspect = true;
|
| + FLAG_log_handles = true;
|
| + FLAG_log_regexp = true;
|
| + }
|
| +
|
| + // --prof implies --log-code.
|
| + if (FLAG_prof) FLAG_log_code = true;
|
| +
|
| + // --prof_lazy controls --log-code, implies --noprof_auto.
|
| + if (FLAG_prof_lazy) {
|
| + FLAG_log_code = false;
|
| + FLAG_prof_auto = false;
|
| + }
|
| +
|
| + bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
|
| + || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
|
| + || FLAG_log_regexp || FLAG_log_state_changes;
|
| +
|
| + bool open_log_file = start_logging || FLAG_prof_lazy;
|
| +
|
| + // If we're logging anything, we need to open the log file.
|
| + if (open_log_file) {
|
| + if (strcmp(FLAG_logfile, "-") == 0) {
|
| + OpenStdout();
|
| + } else if (strcmp(FLAG_logfile, "*") == 0) {
|
| + OpenMemoryBuffer();
|
| + } else {
|
| + if (strchr(FLAG_logfile, '%') != NULL ||
|
| + !Isolate::Current()->IsDefaultIsolate()) {
|
| + // If there's a '%' in the log file name we have to expand
|
| + // placeholders.
|
| + HeapStringAllocator allocator;
|
| + StringStream stream(&allocator);
|
| + AddIsolateIdIfNeeded(&stream);
|
| + for (const char* p = FLAG_logfile; *p; p++) {
|
| + if (*p == '%') {
|
| + p++;
|
| + switch (*p) {
|
| + case '\0':
|
| + // If there's a % at the end of the string we back up
|
| + // one character so we can escape the loop properly.
|
| + p--;
|
| + break;
|
| + case 't': {
|
| + // %t expands to the current time in milliseconds.
|
| + double time = OS::TimeCurrentMillis();
|
| + stream.Add("%.0f", FmtElm(time));
|
| + break;
|
| + }
|
| + case '%':
|
| + // %% expands (contracts really) to %.
|
| + stream.Put('%');
|
| + break;
|
| + default:
|
| + // All other %'s expand to themselves.
|
| + stream.Put('%');
|
| + stream.Put(*p);
|
| + break;
|
| + }
|
| + } else {
|
| + stream.Put(*p);
|
| + }
|
| + }
|
| + SmartPointer<const char> expanded = stream.ToCString();
|
| + OpenFile(*expanded);
|
| + } else {
|
| + OpenFile(FLAG_logfile);
|
| + }
|
| + }
|
| + }
|
| +#endif
|
| }
|
|
|
|
|
| void Log::OpenStdout() {
|
| ASSERT(!IsEnabled());
|
| output_handle_ = stdout;
|
| - Write = WriteToFile;
|
| - Init();
|
| + write_to_file_ = true;
|
| }
|
|
|
|
|
| @@ -150,6 +239,7 @@
|
| void Log::OpenFile(const char* name) {
|
| ASSERT(!IsEnabled());
|
| output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
|
| + write_to_file_ = true;
|
| if (FLAG_ll_prof) {
|
| // Open a file for logging the contents of code objects so that
|
| // they can be disassembled later.
|
| @@ -160,8 +250,6 @@
|
| memcpy(code_name.start() + name_len, kCodeLogExt, sizeof(kCodeLogExt));
|
| output_code_handle_ = OS::FOpen(code_name.start(), OS::LogFileOpenMode);
|
| }
|
| - Write = WriteToFile;
|
| - Init();
|
| }
|
|
|
|
|
| @@ -170,24 +258,20 @@
|
| output_buffer_ = new LogDynamicBuffer(
|
| kDynamicBufferBlockSize, kMaxDynamicBufferSize,
|
| kDynamicBufferSeal, StrLength(kDynamicBufferSeal));
|
| - Write = WriteToMemory;
|
| - Init();
|
| + write_to_file_ = false;
|
| }
|
|
|
|
|
| void Log::Close() {
|
| - if (Write == WriteToFile) {
|
| + if (write_to_file_) {
|
| if (output_handle_ != NULL) fclose(output_handle_);
|
| output_handle_ = NULL;
|
| if (output_code_handle_ != NULL) fclose(output_code_handle_);
|
| output_code_handle_ = NULL;
|
| - } else if (Write == WriteToMemory) {
|
| + } else {
|
| delete output_buffer_;
|
| output_buffer_ = NULL;
|
| - } else {
|
| - ASSERT(Write == NULL);
|
| }
|
| - Write = NULL;
|
|
|
| DeleteArray(message_buffer_);
|
| message_buffer_ = NULL;
|
| @@ -200,7 +284,7 @@
|
|
|
|
|
| int Log::GetLogLines(int from_pos, char* dest_buf, int max_size) {
|
| - if (Write != WriteToMemory) return 0;
|
| + if (write_to_file_) return 0;
|
| ASSERT(output_buffer_ != NULL);
|
| ASSERT(from_pos >= 0);
|
| ASSERT(max_size >= 0);
|
| @@ -220,17 +304,16 @@
|
| }
|
|
|
|
|
| -LogMessageBuilder::WriteFailureHandler
|
| - LogMessageBuilder::write_failure_handler = NULL;
|
| -
|
| -
|
| -LogMessageBuilder::LogMessageBuilder(): sl(Log::mutex_), pos_(0) {
|
| - ASSERT(Log::message_buffer_ != NULL);
|
| +LogMessageBuilder::LogMessageBuilder(Logger* logger)
|
| + : log_(logger->log_),
|
| + sl(log_->mutex_),
|
| + pos_(0) {
|
| + ASSERT(log_->message_buffer_ != NULL);
|
| }
|
|
|
|
|
| void LogMessageBuilder::Append(const char* format, ...) {
|
| - Vector<char> buf(Log::message_buffer_ + pos_,
|
| + Vector<char> buf(log_->message_buffer_ + pos_,
|
| Log::kMessageBufferSize - pos_);
|
| va_list args;
|
| va_start(args, format);
|
| @@ -241,7 +324,7 @@
|
|
|
|
|
| void LogMessageBuilder::AppendVA(const char* format, va_list args) {
|
| - Vector<char> buf(Log::message_buffer_ + pos_,
|
| + Vector<char> buf(log_->message_buffer_ + pos_,
|
| Log::kMessageBufferSize - pos_);
|
| int result = v8::internal::OS::VSNPrintF(buf, format, args);
|
|
|
| @@ -257,7 +340,7 @@
|
|
|
| void LogMessageBuilder::Append(const char c) {
|
| if (pos_ < Log::kMessageBufferSize) {
|
| - Log::message_buffer_[pos_++] = c;
|
| + log_->message_buffer_[pos_++] = c;
|
| }
|
| ASSERT(pos_ <= Log::kMessageBufferSize);
|
| }
|
| @@ -315,7 +398,7 @@
|
| ASSERT(len >= 0);
|
| if (len == 0) return;
|
| }
|
| - Vector<char> buf(Log::message_buffer_ + pos_,
|
| + Vector<char> buf(log_->message_buffer_ + pos_,
|
| Log::kMessageBufferSize - pos_);
|
| OS::StrNCpy(buf, str, len);
|
| pos_ += len;
|
| @@ -325,12 +408,16 @@
|
|
|
| void LogMessageBuilder::WriteToLogFile() {
|
| ASSERT(pos_ <= Log::kMessageBufferSize);
|
| - const int written = Log::Write(Log::message_buffer_, pos_);
|
| - if (written != pos_ && write_failure_handler != NULL) {
|
| - write_failure_handler();
|
| + const int written = log_->write_to_file_ ?
|
| + log_->WriteToFile(log_->message_buffer_, pos_) :
|
| + log_->WriteToMemory(log_->message_buffer_, pos_);
|
| + if (written != pos_) {
|
| + log_->stop();
|
| + log_->logger_->LogFailure();
|
| }
|
| }
|
|
|
| +
|
| #endif // ENABLE_LOGGING_AND_PROFILING
|
|
|
| } } // namespace v8::internal
|
|
|