summaryrefslogtreecommitdiffstats
path: root/V8Binding/v8/src/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'V8Binding/v8/src/log.cc')
-rw-r--r--V8Binding/v8/src/log.cc326
1 files changed, 186 insertions, 140 deletions
diff --git a/V8Binding/v8/src/log.cc b/V8Binding/v8/src/log.cc
index c1edf4d..0dba08d 100644
--- a/V8Binding/v8/src/log.cc
+++ b/V8Binding/v8/src/log.cc
@@ -31,9 +31,7 @@
#include "bootstrapper.h"
#include "log.h"
-#include "log-utils.h"
#include "macro-assembler.h"
-#include "platform.h"
#include "serialize.h"
#include "string-stream.h"
@@ -262,6 +260,7 @@ void Profiler::Engage() {
Logger::ticker_->SetProfiler(this);
Logger::ProfilerBeginEvent();
+ Logger::LogAliases();
}
@@ -301,17 +300,41 @@ Profiler* Logger::profiler_ = NULL;
VMState* Logger::current_state_ = NULL;
VMState Logger::bottom_state_(EXTERNAL);
SlidingStateWindow* Logger::sliding_state_window_ = NULL;
+const char** Logger::log_events_ = NULL;
+CompressionHelper* Logger::compression_helper_ = NULL;
+bool Logger::is_logging_ = false;
+#define DECLARE_LONG_EVENT(ignore1, long_name, ignore2) long_name,
+const char* kLongLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
+ LOG_EVENTS_AND_TAGS_LIST(DECLARE_LONG_EVENT)
+};
+#undef DECLARE_LONG_EVENT
-bool Logger::IsEnabled() {
- return Log::IsEnabled();
-}
+#define DECLARE_SHORT_EVENT(ignore1, ignore2, short_name) short_name,
+const char* kCompressedLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
+ LOG_EVENTS_AND_TAGS_LIST(DECLARE_SHORT_EVENT)
+};
+#undef DECLARE_SHORT_EVENT
void Logger::ProfilerBeginEvent() {
if (!Log::IsEnabled()) return;
LogMessageBuilder msg;
msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs);
+ if (FLAG_compress_log) {
+ msg.Append("profiler,\"compression\",%d\n", kCompressionWindowSize);
+ }
+ msg.WriteToLogFile();
+}
+
+
+void Logger::LogAliases() {
+ if (!Log::IsEnabled() || !FLAG_compress_log) return;
+ LogMessageBuilder msg;
+ for (int i = 0; i < NUMBER_OF_LOG_EVENTS; ++i) {
+ msg.Append("alias,%s,%s\n",
+ kCompressedLogEventsNames[i], kLongLogEventsNames[i]);
+ }
msg.WriteToLogFile();
}
@@ -373,7 +396,7 @@ void Logger::ApiEvent(const char* format, ...) {
LogMessageBuilder msg;
va_list ap;
va_start(ap, format);
- msg.Append(format, ap);
+ msg.AppendVA(format, ap);
va_end(ap);
msg.WriteToLogFile();
}
@@ -397,26 +420,30 @@ void Logger::ApiNamedSecurityCheck(Object* key) {
void Logger::SharedLibraryEvent(const char* library_path,
- unsigned start,
- unsigned end) {
+ uintptr_t start,
+ uintptr_t end) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_prof) return;
LogMessageBuilder msg;
- msg.Append("shared-library,\"%s\",0x%08x,0x%08x\n", library_path,
- start, end);
+ msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
+ library_path,
+ start,
+ end);
msg.WriteToLogFile();
#endif
}
void Logger::SharedLibraryEvent(const wchar_t* library_path,
- unsigned start,
- unsigned end) {
+ uintptr_t start,
+ uintptr_t end) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_prof) return;
LogMessageBuilder msg;
- msg.Append("shared-library,\"%ls\",0x%08x,0x%08x\n", library_path,
- start, end);
+ msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
+ library_path,
+ start,
+ end);
msg.WriteToLogFile();
#endif
}
@@ -594,12 +621,51 @@ void Logger::DeleteEvent(const char* name, void* object) {
}
-void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+
+// A class that contains all common code dealing with record compression.
+class CompressionHelper {
+ public:
+ explicit CompressionHelper(int window_size)
+ : compressor_(window_size), repeat_count_(0) { }
+
+ // Handles storing message in compressor, retrieving the previous one and
+ // prefixing it with repeat count, if needed.
+ // Returns true if message needs to be written to log.
+ bool HandleMessage(LogMessageBuilder* msg) {
+ if (!msg->StoreInCompressor(&compressor_)) {
+ // Current message repeats the previous one, don't write it.
+ ++repeat_count_;
+ return false;
+ }
+ if (repeat_count_ == 0) {
+ return msg->RetrieveCompressedPrevious(&compressor_);
+ }
+ OS::SNPrintF(prefix_, "%s,%d,",
+ Logger::log_events_[Logger::REPEAT_META_EVENT],
+ repeat_count_ + 1);
+ repeat_count_ = 0;
+ return msg->RetrieveCompressedPrevious(&compressor_, prefix_.start());
+ }
+
+ private:
+ LogRecordCompressor compressor_;
+ int repeat_count_;
+ EmbeddedVector<char, 20> prefix_;
+};
+
+#endif // ENABLE_LOGGING_AND_PROFILING
+
+
+void Logger::CodeCreateEvent(LogEventsAndTags tag,
+ Code* code,
+ const char* comment) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
- msg.Append("code-creation,%s,0x%" V8PRIxPTR ",%d,\"", tag, code->address(),
- code->ExecutableSize());
+ msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
+ msg.AppendAddress(code->address());
+ msg.Append(",%d,\"", code->ExecutableSize());
for (const char* p = comment; *p != '\0'; p++) {
if (*p == '"') {
msg.Append('\\');
@@ -607,26 +673,37 @@ void Logger::CodeCreateEvent(const char* tag, Code* code, const char* comment) {
msg.Append(*p);
}
msg.Append('"');
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
msg.Append('\n');
msg.WriteToLogFile();
#endif
}
-void Logger::CodeCreateEvent(const char* tag, Code* code, String* name) {
+void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
SmartPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append("code-creation,%s,0x%" V8PRIxPTR ",%d,\"%s\"\n",
- tag, code->address(), code->ExecutableSize(), *str);
+ msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
+ msg.AppendAddress(code->address());
+ msg.Append(",%d,\"%s\"", code->ExecutableSize(), *str);
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
-void Logger::CodeCreateEvent(const char* tag, Code* code, String* name,
+void Logger::CodeCreateEvent(LogEventsAndTags tag,
+ Code* code, String* name,
String* source, int line) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
@@ -635,23 +712,32 @@ void Logger::CodeCreateEvent(const char* tag, Code* code, String* name,
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
SmartPointer<char> sourcestr =
source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append("code-creation,%s,0x%" V8PRIxPTR ",%d,\"%s %s:%d\"\n",
- tag, code->address(),
- code->ExecutableSize(),
- *str, *sourcestr, line);
+ msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
+ msg.AppendAddress(code->address());
+ msg.Append(",%d,\"%s %s:%d\"",
+ code->ExecutableSize(), *str, *sourcestr, line);
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
-void Logger::CodeCreateEvent(const char* tag, Code* code, int args_count) {
+void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
- msg.Append("code-creation,%s,0x%" V8PRIxPTR ",%d,\"args_count: %d\"\n", tag,
- code->address(),
- code->ExecutableSize(),
- args_count);
+ msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
+ msg.AppendAddress(code->address());
+ msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
@@ -661,23 +747,17 @@ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
- msg.Append("code-creation,%s,0x%" V8PRIxPTR ",%d,\"", "RegExp",
- code->address(),
- code->ExecutableSize());
+ msg.Append("%s,%s,",
+ log_events_[CODE_CREATION_EVENT], log_events_[REG_EXP_TAG]);
+ msg.AppendAddress(code->address());
+ msg.Append(",%d,\"", code->ExecutableSize());
msg.AppendDetailed(source, false);
- msg.Append("\"\n");
- msg.WriteToLogFile();
-#endif
-}
-
-
-void Logger::CodeAllocateEvent(Code* code, Assembler* assem) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
- if (!Log::IsEnabled() || !FLAG_log_code) return;
- LogMessageBuilder msg;
- msg.Append("code-allocate,0x%" V8PRIxPTR ",0x%" V8PRIxPTR "\n",
- code->address(),
- assem);
+ msg.Append('\"');
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
@@ -685,9 +765,19 @@ void Logger::CodeAllocateEvent(Code* code, Assembler* assem) {
void Logger::CodeMoveEvent(Address from, Address to) {
#ifdef ENABLE_LOGGING_AND_PROFILING
+ static Address prev_to_ = NULL;
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
- msg.Append("code-move,0x%" V8PRIxPTR ",0x%" V8PRIxPTR "\n", from, to);
+ msg.Append("%s,", log_events_[CODE_MOVE_EVENT]);
+ msg.AppendAddress(from);
+ msg.Append(',');
+ msg.AppendAddress(to, prev_to_);
+ prev_to_ = to;
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
@@ -697,7 +787,13 @@ void Logger::CodeDeleteEvent(Address from) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (!Log::IsEnabled() || !FLAG_log_code) return;
LogMessageBuilder msg;
- msg.Append("code-delete,0x%" V8PRIxPTR "\n", from);
+ msg.Append("%s,", log_events_[CODE_DELETE_EVENT]);
+ msg.AppendAddress(from);
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
+ }
+ msg.Append('\n');
msg.WriteToLogFile();
#endif
}
@@ -802,14 +898,26 @@ void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
#ifdef ENABLE_LOGGING_AND_PROFILING
void Logger::TickEvent(TickSample* sample, bool overflow) {
if (!Log::IsEnabled() || !FLAG_prof) return;
+ static Address prev_sp = NULL;
LogMessageBuilder msg;
- msg.Append("tick,0x%" V8PRIxPTR ",0x%" V8PRIxPTR ",%d",
- sample->pc, sample->sp, static_cast<int>(sample->state));
+ msg.Append("%s,", log_events_[TICK_EVENT]);
+ Address prev_addr = reinterpret_cast<Address>(sample->pc);
+ msg.AppendAddress(prev_addr);
+ msg.Append(',');
+ msg.AppendAddress(reinterpret_cast<Address>(sample->sp), prev_sp);
+ prev_sp = reinterpret_cast<Address>(sample->sp);
+ msg.Append(",%d", static_cast<int>(sample->state));
if (overflow) {
msg.Append(",overflow");
}
for (int i = 0; i < sample->frames_count; ++i) {
- msg.Append(",0x%" V8PRIxPTR, sample->stack[i]);
+ msg.Append(',');
+ msg.AppendAddress(sample->stack[i], prev_addr);
+ prev_addr = sample->stack[i];
+ }
+ if (FLAG_compress_log) {
+ ASSERT(compression_helper_ != NULL);
+ if (!compression_helper_->HandleMessage(&msg)) return;
}
msg.Append('\n');
msg.WriteToLogFile();
@@ -832,6 +940,7 @@ void Logger::PauseProfiler() {
// Must be the same message as Log::kDynamicBufferSeal.
LOG(UncheckedStringEvent("profiler", "pause"));
}
+ is_logging_ = false;
}
@@ -839,6 +948,7 @@ void Logger::ResumeProfiler() {
if (!profiler_->paused() || !Log::IsEnabled()) {
return;
}
+ is_logging_ = true;
if (FLAG_prof_lazy) {
LOG(UncheckedStringEvent("profiler", "resume"));
FLAG_log_code = true;
@@ -912,18 +1022,19 @@ void Logger::LogCompiledFunctions() {
Handle<String> script_name(String::cast(script->name()));
int line_num = GetScriptLineNumber(script, shared->start_position());
if (line_num > 0) {
- line_num += script->line_offset()->value() + 1;
- LOG(CodeCreateEvent("LazyCompile", shared->code(), *func_name,
- *script_name, line_num));
+ LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG,
+ shared->code(), *func_name,
+ *script_name, line_num + 1));
} else {
// Can't distinguish enum and script here, so always use Script.
- LOG(CodeCreateEvent("Script", shared->code(), *script_name));
+ LOG(CodeCreateEvent(Logger::SCRIPT_TAG,
+ shared->code(), *script_name));
}
continue;
}
}
// If no script or script has no name.
- LOG(CodeCreateEvent("LazyCompile", shared->code(), *func_name));
+ LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, shared->code(), *func_name));
}
DeleteArray(sfis);
@@ -954,9 +1065,11 @@ bool Logger::Setup() {
FLAG_prof_auto = false;
}
- bool open_log_file = FLAG_log || FLAG_log_runtime || FLAG_log_api
+ 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 || FLAG_prof_lazy;
+ || 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) {
@@ -1013,10 +1126,21 @@ bool Logger::Setup() {
sliding_state_window_ = new SlidingStateWindow();
}
+ log_events_ = FLAG_compress_log ?
+ kCompressedLogEventsNames : kLongLogEventsNames;
+ if (FLAG_compress_log) {
+ compression_helper_ = new CompressionHelper(kCompressionWindowSize);
+ }
+
+ is_logging_ = start_logging;
+
if (FLAG_prof) {
profiler_ = new Profiler();
- if (!FLAG_prof_auto)
+ if (!FLAG_prof_auto) {
profiler_->pause();
+ } else {
+ is_logging_ = true;
+ }
profiler_->Engage();
}
@@ -1041,6 +1165,9 @@ void Logger::TearDown() {
profiler_ = NULL;
}
+ delete compression_helper_;
+ compression_helper_ = NULL;
+
delete sliding_state_window_;
sliding_state_window_ = NULL;
@@ -1071,85 +1198,4 @@ void Logger::EnableSlidingStateWindow() {
}
-//
-// VMState class implementation. A simple stack of VM states held by the
-// logger and partially threaded through the call stack. States are pushed by
-// VMState construction and popped by destruction.
-//
-#ifdef ENABLE_LOGGING_AND_PROFILING
-static const char* StateToString(StateTag state) {
- switch (state) {
- case JS:
- return "JS";
- case GC:
- return "GC";
- case COMPILER:
- return "COMPILER";
- case OTHER:
- return "OTHER";
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-VMState::VMState(StateTag state) {
-#if !defined(ENABLE_HEAP_PROTECTION)
- // When not protecting the heap, there is no difference between
- // EXTERNAL and OTHER. As an optimization in that case, we will not
- // perform EXTERNAL->OTHER transitions through the API. We thus
- // compress the two states into one.
- if (state == EXTERNAL) state = OTHER;
-#endif
- state_ = state;
- previous_ = Logger::current_state_;
- Logger::current_state_ = this;
-
- if (FLAG_log_state_changes) {
- LOG(UncheckedStringEvent("Entering", StateToString(state_)));
- if (previous_ != NULL) {
- LOG(UncheckedStringEvent("From", StateToString(previous_->state_)));
- }
- }
-
-#ifdef ENABLE_HEAP_PROTECTION
- if (FLAG_protect_heap && previous_ != NULL) {
- if (state_ == EXTERNAL) {
- // We are leaving V8.
- ASSERT(previous_->state_ != EXTERNAL);
- Heap::Protect();
- } else if (previous_->state_ == EXTERNAL) {
- // We are entering V8.
- Heap::Unprotect();
- }
- }
-#endif
-}
-
-
-VMState::~VMState() {
- Logger::current_state_ = previous_;
-
- if (FLAG_log_state_changes) {
- LOG(UncheckedStringEvent("Leaving", StateToString(state_)));
- if (previous_ != NULL) {
- LOG(UncheckedStringEvent("To", StateToString(previous_->state_)));
- }
- }
-
-#ifdef ENABLE_HEAP_PROTECTION
- if (FLAG_protect_heap && previous_ != NULL) {
- if (state_ == EXTERNAL) {
- // We are reentering V8.
- ASSERT(previous_->state_ != EXTERNAL);
- Heap::Unprotect();
- } else if (previous_->state_ == EXTERNAL) {
- // We are leaving V8.
- Heap::Protect();
- }
- }
-#endif
-}
-#endif
-
} } // namespace v8::internal