summaryrefslogtreecommitdiff
path: root/deps/v8/src/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/log.cc')
-rw-r--r--deps/v8/src/log.cc487
1 files changed, 241 insertions, 246 deletions
diff --git a/deps/v8/src/log.cc b/deps/v8/src/log.cc
index da38d3e7f3..fc7fcb9ced 100644
--- a/deps/v8/src/log.cc
+++ b/deps/v8/src/log.cc
@@ -5,49 +5,38 @@
#include "src/log.h"
#include <cstdarg>
+#include <memory>
#include <sstream>
#include "src/bailout-reason.h"
#include "src/base/platform/platform.h"
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
+#include "src/counters.h"
#include "src/deoptimizer.h"
#include "src/global-handles.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter.h"
+#include "src/libsampler/sampler.h"
#include "src/log-inl.h"
#include "src/log-utils.h"
#include "src/macro-assembler.h"
#include "src/perf-jit.h"
-#include "src/profiler/cpu-profiler.h"
+#include "src/profiler/profiler-listener.h"
+#include "src/profiler/tick-sample.h"
#include "src/runtime-profiler.h"
+#include "src/source-position-table.h"
#include "src/string-stream.h"
#include "src/vm-state-inl.h"
namespace v8 {
namespace internal {
-
#define DECLARE_EVENT(ignore1, name) name,
-static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
- LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
-};
+static const char* kLogEventsNames[CodeEventListener::NUMBER_OF_LOG_EVENTS] = {
+ LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)};
#undef DECLARE_EVENT
-
-#define CALL_LISTENERS(Call) \
-for (int i = 0; i < listeners_.length(); ++i) { \
- listeners_[i]->Call; \
-}
-
-#define PROFILER_LOG(Call) \
- do { \
- CpuProfiler* cpu_profiler = isolate_->cpu_profiler(); \
- if (cpu_profiler->is_profiling()) { \
- cpu_profiler->Call; \
- } \
- } while (false);
-
static const char* ComputeMarker(SharedFunctionInfo* shared,
AbstractCode* code) {
switch (code->kind()) {
@@ -70,7 +59,7 @@ class CodeEventLogger::NameBuffer {
utf8_pos_ = 0;
}
- void Init(Logger::LogEventsAndTags tag) {
+ void Init(CodeEventListener::LogEventsAndTags tag) {
Reset();
AppendBytes(kLogEventsNames[tag]);
AppendByte(':');
@@ -82,7 +71,7 @@ class CodeEventLogger::NameBuffer {
} else {
Symbol* symbol = Symbol::cast(name);
AppendBytes("symbol(");
- if (!symbol->name()->IsUndefined()) {
+ if (!symbol->name()->IsUndefined(symbol->GetIsolate())) {
AppendBytes("\"");
AppendString(String::cast(symbol->name()));
AppendBytes("\" ");
@@ -164,34 +153,32 @@ CodeEventLogger::CodeEventLogger() : name_buffer_(new NameBuffer) { }
CodeEventLogger::~CodeEventLogger() { delete name_buffer_; }
-void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
+void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, const char* comment) {
name_buffer_->Init(tag);
name_buffer_->AppendBytes(comment);
LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
}
-void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
+void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, Name* name) {
name_buffer_->Init(tag);
name_buffer_->AppendName(name);
LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
}
-void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
+void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code,
- SharedFunctionInfo* shared,
- CompilationInfo* info, Name* name) {
+ SharedFunctionInfo* shared, Name* name) {
name_buffer_->Init(tag);
name_buffer_->AppendBytes(ComputeMarker(shared, code));
name_buffer_->AppendName(name);
LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
}
-void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
+void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code,
- SharedFunctionInfo* shared,
- CompilationInfo* info, Name* source,
+ SharedFunctionInfo* shared, Name* source,
int line, int column) {
name_buffer_->Init(tag);
name_buffer_->AppendBytes(ComputeMarker(shared, code));
@@ -209,7 +196,7 @@ void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
}
-void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
+void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
AbstractCode* code, int args_count) {
name_buffer_->Init(tag);
name_buffer_->AppendInt(args_count);
@@ -218,7 +205,7 @@ void CodeEventLogger::CodeCreateEvent(Logger::LogEventsAndTags tag,
void CodeEventLogger::RegExpCodeCreateEvent(AbstractCode* code,
String* source) {
- name_buffer_->Init(Logger::REG_EXP_TAG);
+ name_buffer_->Init(CodeEventListener::REG_EXP_TAG);
name_buffer_->AppendString(source);
LogRecordedBuffer(code, NULL, name_buffer_->get(), name_buffer_->size());
}
@@ -280,12 +267,17 @@ void PerfBasicLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*,
return;
}
- base::OS::FPrint(perf_output_handle_, "%llx %x %.*s\n",
- reinterpret_cast<uint64_t>(code->instruction_start()),
+ // Linux perf expects hex literals without a leading 0x, while some
+ // implementations of printf might prepend one when using the %p format
+ // for pointers, leading to wrongly formatted JIT symbols maps.
+ //
+ // Instead, we use V8PRIxPTR format string and cast pointer to uintpr_t,
+ // so that we have control over the exact output format.
+ base::OS::FPrint(perf_output_handle_, "%" V8PRIxPTR " %x %.*s\n",
+ reinterpret_cast<uintptr_t>(code->instruction_start()),
code->instruction_size(), length, name);
}
-
// Low-level logging support.
#define LL_LOG(Call) if (ll_logger_) ll_logger_->Call;
@@ -424,10 +416,6 @@ void LowLevelLogger::CodeMovingGCEvent() {
LogWriteBytes(&tag, sizeof(tag));
}
-
-#define JIT_LOG(Call) if (jit_logger_) jit_logger_->Call;
-
-
class JitLogger : public CodeEventLogger {
public:
explicit JitLogger(JitCodeEventHandler code_event_handler);
@@ -528,6 +516,31 @@ void JitLogger::EndCodePosInfoEvent(AbstractCode* code,
}
+// TODO(lpy): Keeping sampling thread inside V8 is a workaround currently,
+// the reason is to reduce code duplication during migration to sampler library,
+// sampling thread, as well as the sampler, will be moved to D8 eventually.
+class SamplingThread : public base::Thread {
+ public:
+ static const int kSamplingThreadStackSize = 64 * KB;
+
+ SamplingThread(sampler::Sampler* sampler, int interval)
+ : base::Thread(base::Thread::Options("SamplingThread",
+ kSamplingThreadStackSize)),
+ sampler_(sampler),
+ interval_(interval) {}
+ void Run() override {
+ while (sampler_->IsProfiling()) {
+ sampler_->DoSample();
+ base::OS::Sleep(base::TimeDelta::FromMilliseconds(interval_));
+ }
+ }
+
+ private:
+ sampler::Sampler* sampler_;
+ const int interval_;
+};
+
+
// The Profiler samples pc and sp values for the main thread.
// Each sample is appended to a circular buffer.
// An independent thread removes data and writes it to the log.
@@ -540,7 +553,7 @@ class Profiler: public base::Thread {
void Disengage();
// Inserts collected profiling data into buffer.
- void Insert(TickSample* sample) {
+ void Insert(v8::TickSample* sample) {
if (paused_)
return;
@@ -561,7 +574,7 @@ class Profiler: public base::Thread {
private:
// Waits for a signal and removes profiling data.
- bool Remove(TickSample* sample) {
+ bool Remove(v8::TickSample* sample) {
buffer_semaphore_.Wait(); // Wait for an element.
*sample = buffer_[base::NoBarrier_Load(&tail_)];
bool result = overflow_;
@@ -578,7 +591,7 @@ class Profiler: public base::Thread {
// Cyclic buffer for communicating profiling samples
// between the signal handler and the worker thread.
static const int kBufferSize = 128;
- TickSample buffer_[kBufferSize]; // Buffer storage.
+ v8::TickSample buffer_[kBufferSize]; // Buffer storage.
int head_; // Index to the buffer head.
base::Atomic32 tail_; // Index to the buffer tail.
bool overflow_; // Tell whether a buffer overflow has occurred.
@@ -600,33 +613,44 @@ class Profiler: public base::Thread {
// Ticker used to provide ticks to the profiler and the sliding state
// window.
//
-class Ticker: public Sampler {
+class Ticker: public sampler::Sampler {
public:
- Ticker(Isolate* isolate, int interval):
- Sampler(isolate, interval),
- profiler_(NULL) {}
-
- ~Ticker() { if (IsActive()) Stop(); }
+ Ticker(Isolate* isolate, int interval)
+ : sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)),
+ profiler_(nullptr),
+ sampling_thread_(new SamplingThread(this, interval)) {}
- virtual void Tick(TickSample* sample) {
- if (profiler_) profiler_->Insert(sample);
+ ~Ticker() {
+ if (IsActive()) Stop();
+ delete sampling_thread_;
}
void SetProfiler(Profiler* profiler) {
- DCHECK(profiler_ == NULL);
+ DCHECK(profiler_ == nullptr);
profiler_ = profiler;
IncreaseProfilingDepth();
if (!IsActive()) Start();
+ sampling_thread_->StartSynchronously();
}
void ClearProfiler() {
- profiler_ = NULL;
+ profiler_ = nullptr;
if (IsActive()) Stop();
DecreaseProfilingDepth();
+ sampling_thread_->Join();
+ }
+
+ void SampleStack(const v8::RegisterState& state) override {
+ if (!profiler_) return;
+ Isolate* isolate = reinterpret_cast<Isolate*>(this->isolate());
+ TickSample sample;
+ sample.Init(isolate, state, TickSample::kIncludeCEntryFrame, true);
+ profiler_->Insert(&sample);
}
private:
Profiler* profiler_;
+ SamplingThread* sampling_thread_;
};
@@ -653,8 +677,9 @@ void Profiler::Engage() {
std::vector<base::OS::SharedLibraryAddress> addresses =
base::OS::GetSharedLibraryAddresses();
for (size_t i = 0; i < addresses.size(); ++i) {
- LOG(isolate_, SharedLibraryEvent(
- addresses[i].library_path, addresses[i].start, addresses[i].end));
+ LOG(isolate_,
+ SharedLibraryEvent(addresses[i].library_path, addresses[i].start,
+ addresses[i].end, addresses[i].aslr_slide));
}
// Start thread processing the profiler buffer.
@@ -679,7 +704,7 @@ void Profiler::Disengage() {
// inserting a fake element in the queue and then wait for
// the thread to terminate.
base::NoBarrier_Store(&running_, 0);
- TickSample sample;
+ v8::TickSample sample;
// Reset 'paused_' flag, otherwise semaphore may not be signalled.
resume();
Insert(&sample);
@@ -690,7 +715,7 @@ void Profiler::Disengage() {
void Profiler::Run() {
- TickSample sample;
+ v8::TickSample sample;
bool overflow = Remove(&sample);
while (base::NoBarrier_Load(&running_)) {
LOG(isolate_, TickEvent(&sample, overflow));
@@ -721,24 +746,16 @@ Logger::~Logger() {
delete log_;
}
-
void Logger::addCodeEventListener(CodeEventListener* listener) {
- DCHECK(!hasCodeEventListener(listener));
- listeners_.Add(listener);
+ bool result = isolate_->code_event_dispatcher()->AddListener(listener);
+ USE(result);
+ DCHECK(result);
}
-
void Logger::removeCodeEventListener(CodeEventListener* listener) {
- DCHECK(hasCodeEventListener(listener));
- listeners_.RemoveElement(listener);
+ isolate_->code_event_dispatcher()->RemoveListener(listener);
}
-
-bool Logger::hasCodeEventListener(CodeEventListener* listener) {
- return listeners_.Contains(listener);
-}
-
-
void Logger::ProfilerBeginEvent() {
if (!log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
@@ -781,7 +798,7 @@ void Logger::UncheckedIntEvent(const char* name, int value) {
void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
if (!log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
- msg.Append("%s,%" V8_PTR_PREFIX "d", name, value);
+ msg.Append("%s,%" V8PRIdPTR, name, value);
msg.WriteToLogFile();
}
@@ -789,7 +806,7 @@ void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
void Logger::HandleEvent(const char* name, Object** location) {
if (!log_->IsEnabled() || !FLAG_log_handles) return;
Log::MessageBuilder msg(log_);
- msg.Append("%s,0x%" V8PRIxPTR, name, location);
+ msg.Append("%s,%p", name, static_cast<void*>(location));
msg.WriteToLogFile();
}
@@ -813,24 +830,23 @@ void Logger::ApiSecurityCheck() {
ApiEvent("api,check-security");
}
-
void Logger::SharedLibraryEvent(const std::string& library_path,
- uintptr_t start,
- uintptr_t end) {
+ uintptr_t start, uintptr_t end,
+ intptr_t aslr_slide) {
if (!log_->IsEnabled() || !FLAG_prof_cpp) return;
Log::MessageBuilder msg(log_);
- msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR,
- library_path.c_str(), start, end);
+ msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR
+ ",%" V8PRIdPTR,
+ library_path.c_str(), start, end, aslr_slide);
msg.WriteToLogFile();
}
void Logger::CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) {
- PROFILER_LOG(CodeDeoptEvent(code, pc, fp_to_sp_delta));
if (!log_->IsEnabled() || !FLAG_log_internal_timer_events) return;
Log::MessageBuilder msg(log_);
int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
- msg.Append("code-deopt,%ld,%d", since_epoch, code->CodeSize());
+ msg.Append("code-deopt,%d,%d", since_epoch, code->CodeSize());
msg.WriteToLogFile();
}
@@ -840,7 +856,7 @@ void Logger::CurrentTimeEvent() {
DCHECK(FLAG_log_timer_events || FLAG_prof_cpp);
Log::MessageBuilder msg(log_);
int since_epoch = static_cast<int>(timer_.Elapsed().InMicroseconds());
- msg.Append("current-time,%ld", since_epoch);
+ msg.Append("current-time,%d", since_epoch);
msg.WriteToLogFile();
}
@@ -870,14 +886,6 @@ void Logger::LeaveExternal(Isolate* isolate) {
isolate->set_current_vm_state(JS);
}
-
-template <class TimerEvent>
-void TimerEventScope<TimerEvent>::LogTimerEvent(Logger::StartEnd se) {
- Logger::CallEventLogger(isolate_, TimerEvent::name(), se,
- TimerEvent::expose_to_api());
-}
-
-
// Instantiate template methods.
#define V(TimerName, expose) \
template void TimerEventScope<TimerEvent##TimerName>::LogTimerEvent( \
@@ -914,19 +922,19 @@ void LogRegExpSource(Handle<JSRegExp> regexp, Isolate* isolate,
// global flag
Handle<Object> global =
JSReceiver::GetProperty(isolate, regexp, "global").ToHandleChecked();
- if (global->IsTrue()) {
+ if (global->IsTrue(isolate)) {
msg->Append('g');
}
// ignorecase flag
Handle<Object> ignorecase =
JSReceiver::GetProperty(isolate, regexp, "ignoreCase").ToHandleChecked();
- if (ignorecase->IsTrue()) {
+ if (ignorecase->IsTrue(isolate)) {
msg->Append('i');
}
// multiline flag
Handle<Object> multiline =
JSReceiver::GetProperty(isolate, regexp, "multiline").ToHandleChecked();
- if (multiline->IsTrue()) {
+ if (multiline->IsTrue(isolate)) {
msg->Append('m');
}
}
@@ -949,20 +957,20 @@ void Logger::ApiNamedPropertyAccess(const char* tag,
DCHECK(name->IsName());
if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = holder->class_name();
- base::SmartArrayPointer<char> class_name =
+ std::unique_ptr<char[]> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
if (name->IsString()) {
- base::SmartArrayPointer<char> property_name =
+ std::unique_ptr<char[]> property_name =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",\"%s\"", tag, class_name.get(),
property_name.get());
} else {
Symbol* symbol = Symbol::cast(name);
uint32_t hash = symbol->Hash();
- if (symbol->name()->IsUndefined()) {
+ if (symbol->name()->IsUndefined(symbol->GetIsolate())) {
ApiEvent("api,%s,\"%s\",symbol(hash %x)", tag, class_name.get(), hash);
} else {
- base::SmartArrayPointer<char> str =
+ std::unique_ptr<char[]> str =
String::cast(symbol->name())
->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",symbol(\"%s\" hash %x)", tag, class_name.get(),
@@ -976,7 +984,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag,
uint32_t index) {
if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = holder->class_name();
- base::SmartArrayPointer<char> class_name =
+ std::unique_ptr<char[]> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",%u", tag, class_name.get(), index);
}
@@ -985,7 +993,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag,
void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = object->class_name();
- base::SmartArrayPointer<char> class_name =
+ std::unique_ptr<char[]> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\"", tag, class_name.get());
}
@@ -1000,8 +1008,7 @@ void Logger::ApiEntryCall(const char* name) {
void Logger::NewEvent(const char* name, void* object, size_t size) {
if (!log_->IsEnabled() || !FLAG_log) return;
Log::MessageBuilder msg(log_);
- msg.Append("new,%s,0x%" V8PRIxPTR ",%u", name, object,
- static_cast<unsigned int>(size));
+ msg.Append("new,%s,%p,%u", name, object, static_cast<unsigned int>(size));
msg.WriteToLogFile();
}
@@ -1009,7 +1016,7 @@ void Logger::NewEvent(const char* name, void* object, size_t size) {
void Logger::DeleteEvent(const char* name, void* object) {
if (!log_->IsEnabled() || !FLAG_log) return;
Log::MessageBuilder msg(log_);
- msg.Append("delete,%s,0x%" V8PRIxPTR, name, object);
+ msg.Append("delete,%s,%p", name, object);
msg.WriteToLogFile();
}
@@ -1019,22 +1026,22 @@ void Logger::CallbackEventInternal(const char* prefix, Name* name,
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
msg.Append("%s,%s,-2,",
- kLogEventsNames[CODE_CREATION_EVENT],
- kLogEventsNames[CALLBACK_TAG]);
+ kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT],
+ kLogEventsNames[CodeEventListener::CALLBACK_TAG]);
msg.AppendAddress(entry_point);
if (name->IsString()) {
- base::SmartArrayPointer<char> str =
+ std::unique_ptr<char[]> str =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append(",1,\"%s%s\"", prefix, str.get());
} else {
Symbol* symbol = Symbol::cast(name);
- if (symbol->name()->IsUndefined()) {
- msg.Append(",1,symbol(hash %x)", prefix, symbol->Hash());
+ if (symbol->name()->IsUndefined(symbol->GetIsolate())) {
+ msg.Append(",1,symbol(hash %x)", symbol->Hash());
} else {
- base::SmartArrayPointer<char> str =
+ std::unique_ptr<char[]> str =
String::cast(symbol->name())
->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append(",1,symbol(\"%s\" hash %x)", prefix, str.get(),
+ msg.Append(",1,symbol(\"%s%s\" hash %x)", prefix, str.get(),
symbol->Hash());
}
}
@@ -1043,41 +1050,33 @@ void Logger::CallbackEventInternal(const char* prefix, Name* name,
void Logger::CallbackEvent(Name* name, Address entry_point) {
- PROFILER_LOG(CallbackEvent(name, entry_point));
CallbackEventInternal("", name, entry_point);
}
void Logger::GetterCallbackEvent(Name* name, Address entry_point) {
- PROFILER_LOG(GetterCallbackEvent(name, entry_point));
CallbackEventInternal("get ", name, entry_point);
}
void Logger::SetterCallbackEvent(Name* name, Address entry_point) {
- PROFILER_LOG(SetterCallbackEvent(name, entry_point));
CallbackEventInternal("set ", name, entry_point);
}
static void AppendCodeCreateHeader(Log::MessageBuilder* msg,
- Logger::LogEventsAndTags tag,
+ CodeEventListener::LogEventsAndTags tag,
AbstractCode* code) {
DCHECK(msg);
msg->Append("%s,%s,%d,",
- kLogEventsNames[Logger::CODE_CREATION_EVENT],
- kLogEventsNames[tag],
- code->kind());
+ kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT],
+ kLogEventsNames[tag], code->kind());
msg->AppendAddress(code->address());
msg->Append(",%d,", code->ExecutableSize());
}
-void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
- const char* comment) {
- PROFILER_LOG(CodeCreateEvent(tag, code, comment));
-
+void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, const char* comment) {
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeCreateEvent(tag, code, comment));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
AppendCodeCreateHeader(&msg, tag, code);
@@ -1085,13 +1084,9 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
msg.WriteToLogFile();
}
-void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
- Name* name) {
- PROFILER_LOG(CodeCreateEvent(tag, code, name));
-
+void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, Name* name) {
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeCreateEvent(tag, code, name));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
AppendCodeCreateHeader(&msg, tag, code);
@@ -1105,14 +1100,10 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
msg.WriteToLogFile();
}
-void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
- SharedFunctionInfo* shared, CompilationInfo* info,
+void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, SharedFunctionInfo* shared,
Name* name) {
- PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, name));
-
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, name));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
if (code == AbstractCode::cast(
isolate_->builtins()->builtin(Builtins::kCompileLazy))) {
@@ -1122,7 +1113,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
Log::MessageBuilder msg(log_);
AppendCodeCreateHeader(&msg, tag, code);
if (name->IsString()) {
- base::SmartArrayPointer<char> str =
+ std::unique_ptr<char[]> str =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("\"%s\"", str.get());
} else {
@@ -1138,23 +1129,18 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
// Although, it is possible to extract source and line from
// the SharedFunctionInfo object, we left it to caller
// to leave logging functions free from heap allocations.
-void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
- SharedFunctionInfo* shared, CompilationInfo* info,
+void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, SharedFunctionInfo* shared,
Name* source, int line, int column) {
- PROFILER_LOG(CodeCreateEvent(tag, code, shared, info, source, line, column));
-
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeCreateEvent(tag, code, shared, info, source, line,
- column));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
AppendCodeCreateHeader(&msg, tag, code);
- base::SmartArrayPointer<char> name =
+ std::unique_ptr<char[]> name =
shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("\"%s ", name.get());
if (source->IsString()) {
- base::SmartArrayPointer<char> sourcestr = String::cast(source)->ToCString(
+ std::unique_ptr<char[]> sourcestr = String::cast(source)->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("%s", sourcestr.get());
} else {
@@ -1166,13 +1152,9 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
msg.WriteToLogFile();
}
-void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
- int args_count) {
- PROFILER_LOG(CodeCreateEvent(tag, code, args_count));
-
+void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
+ AbstractCode* code, int args_count) {
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeCreateEvent(tag, code, args_count));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
AppendCodeCreateHeader(&msg, tag, code);
@@ -1182,15 +1164,11 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
void Logger::CodeDisableOptEvent(AbstractCode* code,
SharedFunctionInfo* shared) {
- PROFILER_LOG(CodeDisableOptEvent(code, shared));
-
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeDisableOptEvent(code, shared));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
- msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]);
- base::SmartArrayPointer<char> name =
+ msg.Append("%s,", kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT]);
+ std::unique_ptr<char[]> name =
shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("\"%s\",", name.get());
msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason()));
@@ -1199,23 +1177,16 @@ void Logger::CodeDisableOptEvent(AbstractCode* code,
void Logger::CodeMovingGCEvent() {
- PROFILER_LOG(CodeMovingGCEvent());
-
if (!is_logging_code_events()) return;
if (!log_->IsEnabled() || !FLAG_ll_prof) return;
- CALL_LISTENERS(CodeMovingGCEvent());
base::OS::SignalCodeMovingGC();
}
void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
- PROFILER_LOG(RegExpCodeCreateEvent(code, source));
-
if (!is_logging_code_events()) return;
- CALL_LISTENERS(RegExpCodeCreateEvent(code, source));
-
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
- AppendCodeCreateHeader(&msg, REG_EXP_TAG, code);
+ AppendCodeCreateHeader(&msg, CodeEventListener::REG_EXP_TAG, code);
msg.Append('"');
msg.AppendDetailed(source, false);
msg.Append('"');
@@ -1223,48 +1194,34 @@ void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) {
}
void Logger::CodeMoveEvent(AbstractCode* from, Address to) {
- PROFILER_LOG(CodeMoveEvent(from, to));
-
if (!is_logging_code_events()) return;
- CALL_LISTENERS(CodeMoveEvent(from, to));
- MoveEventInternal(CODE_MOVE_EVENT, from->address(), to);
-}
-
-void Logger::CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
- int pc_offset, int position) {
- JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
- pc_offset,
- position,
- JitCodeEvent::POSITION));
+ MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(), to);
}
-
-void Logger::CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data,
- int pc_offset,
- int position) {
- JIT_LOG(AddCodeLinePosInfoEvent(jit_handler_data,
- pc_offset,
- position,
- JitCodeEvent::STATEMENT_POSITION));
-}
-
-
-void Logger::CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder) {
- if (jit_logger_ != NULL) {
- pos_recorder->AttachJITHandlerData(jit_logger_->StartCodePosInfoEvent());
+void Logger::CodeLinePosInfoRecordEvent(AbstractCode* code,
+ ByteArray* source_position_table) {
+ if (jit_logger_) {
+ void* jit_handler_data = jit_logger_->StartCodePosInfoEvent();
+ for (SourcePositionTableIterator iter(source_position_table); !iter.done();
+ iter.Advance()) {
+ if (iter.is_statement()) {
+ jit_logger_->AddCodeLinePosInfoEvent(
+ jit_handler_data, iter.code_offset(), iter.source_position(),
+ JitCodeEvent::STATEMENT_POSITION);
+ }
+ jit_logger_->AddCodeLinePosInfoEvent(jit_handler_data, iter.code_offset(),
+ iter.source_position(),
+ JitCodeEvent::POSITION);
+ }
+ jit_logger_->EndCodePosInfoEvent(code, jit_handler_data);
}
}
-void Logger::CodeEndLinePosInfoRecordEvent(AbstractCode* code,
- void* jit_handler_data) {
- JIT_LOG(EndCodePosInfoEvent(code, jit_handler_data));
-}
-
-
void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
if (code_name == NULL) return; // Not a code object.
Log::MessageBuilder msg(log_);
- msg.Append("%s,%d,", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
+ msg.Append("%s,%d,",
+ kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT], pos);
msg.AppendDoubleQuotedString(code_name);
msg.WriteToLogFile();
}
@@ -1272,13 +1229,11 @@ void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
if (!is_logging_code_events()) return;
- MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
+ MoveEventInternal(CodeEventListener::SHARED_FUNC_MOVE_EVENT, from, to);
}
-
-void Logger::MoveEventInternal(LogEventsAndTags event,
- Address from,
- Address to) {
+void Logger::MoveEventInternal(CodeEventListener::LogEventsAndTags event,
+ Address from, Address to) {
if (!FLAG_log_code || !log_->IsEnabled()) return;
Log::MessageBuilder msg(log_);
msg.Append("%s,", kLogEventsNames[event]);
@@ -1372,19 +1327,34 @@ void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
msg.WriteToLogFile();
}
+void Logger::RuntimeCallTimerEvent() {
+ RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
+ RuntimeCallTimer* timer = stats->current_timer();
+ if (timer == nullptr) return;
+ RuntimeCallCounter* counter = timer->counter();
+ if (counter == nullptr) return;
+ Log::MessageBuilder msg(log_);
+ msg.Append("active-runtime-timer,");
+ msg.AppendDoubleQuotedString(counter->name);
+ msg.WriteToLogFile();
+}
-void Logger::TickEvent(TickSample* sample, bool overflow) {
+void Logger::TickEvent(v8::TickSample* sample, bool overflow) {
if (!log_->IsEnabled() || !FLAG_prof_cpp) return;
+ if (FLAG_runtime_call_stats) {
+ RuntimeCallTimerEvent();
+ }
Log::MessageBuilder msg(log_);
- msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
- msg.AppendAddress(sample->pc);
- msg.Append(",%ld", static_cast<int>(timer_.Elapsed().InMicroseconds()));
+ msg.Append("%s,", kLogEventsNames[CodeEventListener::TICK_EVENT]);
+ msg.AppendAddress(reinterpret_cast<Address>(sample->pc));
+ msg.Append(",%d", static_cast<int>(timer_.Elapsed().InMicroseconds()));
if (sample->has_external_callback) {
msg.Append(",1,");
- msg.AppendAddress(sample->external_callback_entry);
+ msg.AppendAddress(
+ reinterpret_cast<Address>(sample->external_callback_entry));
} else {
msg.Append(",0,");
- msg.AppendAddress(sample->tos);
+ msg.AppendAddress(reinterpret_cast<Address>(sample->tos));
}
msg.Append(",%d", static_cast<int>(sample->state));
if (overflow) {
@@ -1392,7 +1362,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) {
}
for (unsigned i = 0; i < sample->frames_count; ++i) {
msg.Append(',');
- msg.AppendAddress(sample->stack[i]);
+ msg.AppendAddress(reinterpret_cast<Address>(sample->stack[i]));
}
msg.WriteToLogFile();
}
@@ -1403,6 +1373,7 @@ void Logger::StopProfiler() {
if (profiler_ != NULL) {
profiler_->pause();
is_logging_ = false;
+ removeCodeEventListener(this);
}
}
@@ -1484,7 +1455,7 @@ static int EnumerateCompiledFunctions(Heap* heap,
void Logger::LogCodeObject(Object* object) {
AbstractCode* code_object = AbstractCode::cast(object);
- LogEventsAndTags tag = Logger::STUB_TAG;
+ CodeEventListener::LogEventsAndTags tag = CodeEventListener::STUB_TAG;
const char* description = "Unknown code from the snapshot";
switch (code_object->kind()) {
case AbstractCode::FUNCTION:
@@ -1502,53 +1473,59 @@ void Logger::LogCodeObject(Object* object) {
CodeStub::MajorName(CodeStub::GetMajorKey(code_object->GetCode()));
if (description == NULL)
description = "A stub from the snapshot";
- tag = Logger::STUB_TAG;
+ tag = CodeEventListener::STUB_TAG;
break;
case AbstractCode::REGEXP:
description = "Regular expression code";
- tag = Logger::REG_EXP_TAG;
+ tag = CodeEventListener::REG_EXP_TAG;
break;
case AbstractCode::BUILTIN:
description =
isolate_->builtins()->name(code_object->GetCode()->builtin_index());
- tag = Logger::BUILTIN_TAG;
+ tag = CodeEventListener::BUILTIN_TAG;
break;
case AbstractCode::HANDLER:
description = "An IC handler from the snapshot";
- tag = Logger::HANDLER_TAG;
+ tag = CodeEventListener::HANDLER_TAG;
break;
case AbstractCode::KEYED_LOAD_IC:
description = "A keyed load IC from the snapshot";
- tag = Logger::KEYED_LOAD_IC_TAG;
+ tag = CodeEventListener::KEYED_LOAD_IC_TAG;
break;
case AbstractCode::LOAD_IC:
description = "A load IC from the snapshot";
- tag = Logger::LOAD_IC_TAG;
+ tag = CodeEventListener::LOAD_IC_TAG;
+ break;
+ case AbstractCode::LOAD_GLOBAL_IC:
+ description = "A load global IC from the snapshot";
+ tag = Logger::LOAD_GLOBAL_IC_TAG;
break;
case AbstractCode::CALL_IC:
description = "A call IC from the snapshot";
- tag = Logger::CALL_IC_TAG;
+ tag = CodeEventListener::CALL_IC_TAG;
break;
case AbstractCode::STORE_IC:
description = "A store IC from the snapshot";
- tag = Logger::STORE_IC_TAG;
+ tag = CodeEventListener::STORE_IC_TAG;
break;
case AbstractCode::KEYED_STORE_IC:
description = "A keyed store IC from the snapshot";
- tag = Logger::KEYED_STORE_IC_TAG;
+ tag = CodeEventListener::KEYED_STORE_IC_TAG;
break;
case AbstractCode::WASM_FUNCTION:
description = "A Wasm function";
- tag = Logger::STUB_TAG;
+ tag = CodeEventListener::STUB_TAG;
break;
case AbstractCode::JS_TO_WASM_FUNCTION:
description = "A JavaScript to Wasm adapter";
- tag = Logger::STUB_TAG;
+ tag = CodeEventListener::STUB_TAG;
break;
case AbstractCode::WASM_TO_JS_FUNCTION:
description = "A Wasm to JavaScript adapter";
- tag = Logger::STUB_TAG;
+ tag = CodeEventListener::STUB_TAG;
break;
+ case AbstractCode::NUMBER_OF_KINDS:
+ UNIMPLEMENTED();
}
PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
}
@@ -1556,8 +1533,6 @@ void Logger::LogCodeObject(Object* object) {
void Logger::LogCodeObjects() {
Heap* heap = isolate_->heap();
- heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
- "Logger::LogCodeObjects");
HeapIterator iterator(heap);
DisallowHeapAllocation no_gc;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
@@ -1569,20 +1544,24 @@ void Logger::LogCodeObjects() {
void Logger::LogBytecodeHandlers() {
if (!FLAG_ignition) return;
- interpreter::Interpreter* interpreter = isolate_->interpreter();
+ const interpreter::OperandScale kOperandScales[] = {
+#define VALUE(Name, _) interpreter::OperandScale::k##Name,
+ OPERAND_SCALE_LIST(VALUE)
+#undef VALUE
+ };
+
const int last_index = static_cast<int>(interpreter::Bytecode::kLast);
- for (auto operand_scale = interpreter::OperandScale::kSingle;
- operand_scale <= interpreter::OperandScale::kMaxValid;
- operand_scale =
- interpreter::Bytecodes::NextOperandScale(operand_scale)) {
+ interpreter::Interpreter* interpreter = isolate_->interpreter();
+ for (auto operand_scale : kOperandScales) {
for (int index = 0; index <= last_index; ++index) {
interpreter::Bytecode bytecode = interpreter::Bytecodes::FromByte(index);
if (interpreter::Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) {
Code* code = interpreter->GetBytecodeHandler(bytecode, operand_scale);
std::string bytecode_name =
interpreter::Bytecodes::ToString(bytecode, operand_scale);
- CodeCreateEvent(Logger::BYTECODE_HANDLER_TAG, AbstractCode::cast(code),
- bytecode_name.c_str());
+ PROFILE(isolate_, CodeCreateEvent(
+ CodeEventListener::BYTECODE_HANDLER_TAG,
+ AbstractCode::cast(code), bytecode_name.c_str()));
}
}
}
@@ -1601,28 +1580,28 @@ void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
if (line_num > 0) {
PROFILE(isolate_,
CodeCreateEvent(
- Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
- *code, *shared, NULL,
- *script_name, line_num, column_num));
+ Logger::ToNativeByScript(
+ CodeEventListener::LAZY_COMPILE_TAG, *script),
+ *code, *shared, *script_name, line_num, column_num));
} else {
// Can't distinguish eval and script here, so always use Script.
PROFILE(isolate_,
- CodeCreateEvent(
- Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
- *code, *shared, NULL, *script_name));
+ CodeCreateEvent(Logger::ToNativeByScript(
+ CodeEventListener::SCRIPT_TAG, *script),
+ *code, *shared, *script_name));
}
} else {
PROFILE(isolate_,
- CodeCreateEvent(
- Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
- *code, *shared, NULL,
- isolate_->heap()->empty_string(), line_num, column_num));
+ CodeCreateEvent(Logger::ToNativeByScript(
+ CodeEventListener::LAZY_COMPILE_TAG, *script),
+ *code, *shared, isolate_->heap()->empty_string(),
+ line_num, column_num));
}
} else if (shared->IsApiFunction()) {
// API function.
FunctionTemplateInfo* fun_data = shared->get_api_func_data();
Object* raw_call_data = fun_data->call_code();
- if (!raw_call_data->IsUndefined()) {
+ if (!raw_call_data->IsUndefined(isolate_)) {
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
Object* callback_obj = call_data->callback();
Address entry_point = v8::ToCData<Address>(callback_obj);
@@ -1632,17 +1611,14 @@ void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
PROFILE(isolate_, CallbackEvent(*func_name, entry_point));
}
} else {
- PROFILE(isolate_,
- CodeCreateEvent(
- Logger::LAZY_COMPILE_TAG, *code, *shared, NULL, *func_name));
+ PROFILE(isolate_, CodeCreateEvent(CodeEventListener::LAZY_COMPILE_TAG,
+ *code, *shared, *func_name));
}
}
void Logger::LogCompiledFunctions() {
Heap* heap = isolate_->heap();
- heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
- "Logger::LogCompiledFunctions");
HandleScope scope(isolate_);
const int compiled_funcs_count = EnumerateCompiledFunctions(heap, NULL, NULL);
ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
@@ -1661,8 +1637,6 @@ void Logger::LogCompiledFunctions() {
void Logger::LogAccessorCallbacks() {
Heap* heap = isolate_->heap();
- heap->CollectAllGarbage(Heap::kMakeHeapIterableMask,
- "Logger::LogAccessorCallbacks");
HeapIterator iterator(heap);
DisallowHeapAllocation no_gc;
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
@@ -1747,7 +1721,6 @@ bool Logger::SetUp(Isolate* isolate) {
PrepareLogFileName(log_file_name, isolate, FLAG_logfile);
log_->Initialize(log_file_name.str().c_str());
-
if (FLAG_perf_basic_prof) {
perf_basic_logger_ = new PerfBasicLogger();
addCodeEventListener(perf_basic_logger_);
@@ -1777,6 +1750,12 @@ bool Logger::SetUp(Isolate* isolate) {
profiler_->Engage();
}
+ profiler_listener_.reset();
+
+ if (is_logging_) {
+ addCodeEventListener(this);
+ }
+
return true;
}
@@ -1800,8 +1779,20 @@ void Logger::SetCodeEventHandler(uint32_t options,
}
}
+void Logger::SetUpProfilerListener() {
+ if (!is_initialized_) return;
+ if (profiler_listener_.get() == nullptr) {
+ profiler_listener_.reset(new ProfilerListener(isolate_));
+ }
+ addCodeEventListener(profiler_listener_.get());
+}
+
+void Logger::TearDownProfilerListener() {
+ if (profiler_listener_->HasObservers()) return;
+ removeCodeEventListener(profiler_listener_.get());
+}
-Sampler* Logger::sampler() {
+sampler::Sampler* Logger::sampler() {
return ticker_;
}
@@ -1844,6 +1835,10 @@ FILE* Logger::TearDown() {
jit_logger_ = NULL;
}
+ if (profiler_listener_.get() != nullptr) {
+ removeCodeEventListener(profiler_listener_.get());
+ }
+
return log_->Close();
}