Update V8 to r7427: Initial merge by git

As required by WebKit r82507

Change-Id: I7ae83ef3f689356043b4929255b7c1dd31d8c5df
diff --git a/src/log-utils.cc b/src/log-utils.cc
index 9a498ec..a854ade 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -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