Version 3.2.4.
Added isolates which allows several V8 instances in the same process. This is controlled through the new Isolate class in the API.
Implemented more of EcmaScript 5 strict mode.
Reduced the time it takes to make detailed heap snapshot.
Added a number of commands to the ARM simulator and enhanced the ARM disassembler.
git-svn-id: http://v8.googlecode.com/svn/trunk@7322 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
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