| Index: src/log.cc
|
| ===================================================================
|
| --- src/log.cc (revision 7267)
|
| +++ src/log.cc (working copy)
|
| @@ -64,12 +64,12 @@
|
|
|
|
|
| void IncrementStateCounter(StateTag state) {
|
| - Counters::state_counters[state].Increment();
|
| + COUNTERS->state_counters(state)->Increment();
|
| }
|
|
|
|
|
| void DecrementStateCounter(StateTag state) {
|
| - Counters::state_counters[state].Decrement();
|
| + COUNTERS->state_counters(state)->Decrement();
|
| }
|
| };
|
|
|
| @@ -82,7 +82,7 @@
|
| //
|
| class Profiler: public Thread {
|
| public:
|
| - Profiler();
|
| + explicit Profiler(Isolate* isolate);
|
| void Engage();
|
| void Disengage();
|
|
|
| @@ -113,9 +113,9 @@
|
| void Run();
|
|
|
| // Pause and Resume TickSample data collection.
|
| - static bool paused() { return paused_; }
|
| - static void pause() { paused_ = true; }
|
| - static void resume() { paused_ = false; }
|
| + bool paused() const { return paused_; }
|
| + void pause() { paused_ = true; }
|
| + void resume() { paused_ = false; }
|
|
|
| private:
|
| // Returns the next index in the cyclic buffer.
|
| @@ -137,23 +137,24 @@
|
| bool running_;
|
|
|
| // Tells whether we are currently recording tick samples.
|
| - static bool paused_;
|
| + bool paused_;
|
| };
|
|
|
| -bool Profiler::paused_ = false;
|
|
|
| -
|
| //
|
| // StackTracer implementation
|
| //
|
| -void StackTracer::Trace(TickSample* sample) {
|
| +void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
|
| + ASSERT(isolate->IsInitialized());
|
| +
|
| sample->tos = NULL;
|
| sample->frames_count = 0;
|
|
|
| // Avoid collecting traces while doing GC.
|
| if (sample->state == GC) return;
|
|
|
| - const Address js_entry_sp = Top::js_entry_sp(Top::GetCurrentThread());
|
| + const Address js_entry_sp =
|
| + Isolate::js_entry_sp(isolate->thread_local_top());
|
| if (js_entry_sp == 0) {
|
| // Not executing JS now.
|
| return;
|
| @@ -164,7 +165,7 @@
|
| sample->tos = Memory::Address_at(sample->sp);
|
|
|
| int i = 0;
|
| - const Address callback = Top::external_callback();
|
| + const Address callback = isolate->external_callback();
|
| // Surprisingly, PC can point _exactly_ to callback start, with good
|
| // probability, and this will result in reporting fake nested
|
| // callback call.
|
| @@ -172,7 +173,8 @@
|
| sample->stack[i++] = callback;
|
| }
|
|
|
| - SafeStackTraceFrameIterator it(sample->fp, sample->sp,
|
| + SafeStackTraceFrameIterator it(isolate,
|
| + sample->fp, sample->sp,
|
| sample->sp, js_entry_sp);
|
| while (!it.done() && i < TickSample::kMaxFramesCount) {
|
| sample->stack[i++] = it.frame()->pc();
|
| @@ -188,8 +190,8 @@
|
| //
|
| class Ticker: public Sampler {
|
| public:
|
| - explicit Ticker(int interval) :
|
| - Sampler(interval),
|
| + explicit Ticker(Isolate* isolate, int interval):
|
| + Sampler(isolate, interval),
|
| window_(NULL),
|
| profiler_(NULL) {}
|
|
|
| @@ -225,7 +227,7 @@
|
|
|
| protected:
|
| virtual void DoSampleStack(TickSample* sample) {
|
| - StackTracer::Trace(sample);
|
| + StackTracer::Trace(isolate(), sample);
|
| }
|
|
|
| private:
|
| @@ -241,12 +243,12 @@
|
| for (int i = 0; i < kBufferSize; i++) {
|
| buffer_[i] = static_cast<byte>(OTHER);
|
| }
|
| - Logger::ticker_->SetWindow(this);
|
| + LOGGER->ticker_->SetWindow(this);
|
| }
|
|
|
|
|
| SlidingStateWindow::~SlidingStateWindow() {
|
| - Logger::ticker_->ClearWindow();
|
| + LOGGER->ticker_->ClearWindow();
|
| }
|
|
|
|
|
| @@ -266,14 +268,15 @@
|
| //
|
| // Profiler implementation.
|
| //
|
| -Profiler::Profiler()
|
| - : Thread("v8:Profiler"),
|
| +Profiler::Profiler(Isolate* isolate)
|
| + : Thread(isolate, "v8:Profiler"),
|
| head_(0),
|
| tail_(0),
|
| overflow_(false),
|
| buffer_semaphore_(OS::CreateSemaphore(0)),
|
| engaged_(false),
|
| - running_(false) {
|
| + running_(false),
|
| + paused_(false) {
|
| }
|
|
|
|
|
| @@ -292,9 +295,9 @@
|
| Start();
|
|
|
| // Register to get ticks.
|
| - Logger::ticker_->SetProfiler(this);
|
| + LOGGER->ticker_->SetProfiler(this);
|
|
|
| - Logger::ProfilerBeginEvent();
|
| + LOGGER->ProfilerBeginEvent();
|
| }
|
|
|
|
|
| @@ -302,7 +305,7 @@
|
| if (!engaged_) return;
|
|
|
| // Stop receiving ticks.
|
| - Logger::ticker_->ClearProfiler();
|
| + LOGGER->ticker_->ClearProfiler();
|
|
|
| // Terminate the worker thread by setting running_ to false,
|
| // inserting a fake element in the queue and then wait for
|
| @@ -314,15 +317,16 @@
|
| Insert(&sample);
|
| Join();
|
|
|
| - LOG(UncheckedStringEvent("profiler", "end"));
|
| + LOG(ISOLATE, UncheckedStringEvent("profiler", "end"));
|
| }
|
|
|
|
|
| void Profiler::Run() {
|
| TickSample sample;
|
| bool overflow = Remove(&sample);
|
| + i::Isolate* isolate = ISOLATE;
|
| while (running_) {
|
| - LOG(TickEvent(&sample, overflow));
|
| + LOG(isolate, TickEvent(&sample, overflow));
|
| overflow = Remove(&sample);
|
| }
|
| }
|
| @@ -331,23 +335,38 @@
|
| //
|
| // Logger class implementation.
|
| //
|
| -Ticker* Logger::ticker_ = NULL;
|
| -Profiler* Logger::profiler_ = NULL;
|
| -SlidingStateWindow* Logger::sliding_state_window_ = NULL;
|
| -int Logger::logging_nesting_ = 0;
|
| -int Logger::cpu_profiler_nesting_ = 0;
|
| -int Logger::heap_profiler_nesting_ = 0;
|
|
|
| +Logger::Logger()
|
| + : ticker_(NULL),
|
| + profiler_(NULL),
|
| + sliding_state_window_(NULL),
|
| + log_events_(NULL),
|
| + logging_nesting_(0),
|
| + cpu_profiler_nesting_(0),
|
| + heap_profiler_nesting_(0),
|
| + log_(new Log(this)),
|
| + is_initialized_(false),
|
| + last_address_(NULL),
|
| + prev_sp_(NULL),
|
| + prev_function_(NULL),
|
| + prev_to_(NULL),
|
| + prev_code_(NULL) {
|
| +}
|
| +
|
| +Logger::~Logger() {
|
| + delete log_;
|
| +}
|
| +
|
| #define DECLARE_EVENT(ignore1, name) name,
|
| -const char* kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
|
| +static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
|
| LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
|
| };
|
| #undef DECLARE_EVENT
|
|
|
|
|
| void Logger::ProfilerBeginEvent() {
|
| - if (!Log::IsEnabled()) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled()) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs);
|
| msg.WriteToLogFile();
|
| }
|
| @@ -364,8 +383,8 @@
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::UncheckedStringEvent(const char* name, const char* value) {
|
| - if (!Log::IsEnabled()) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled()) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,\"%s\"\n", name, value);
|
| msg.WriteToLogFile();
|
| }
|
| @@ -388,8 +407,8 @@
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::UncheckedIntEvent(const char* name, int value) {
|
| - if (!Log::IsEnabled()) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled()) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%d\n", name, value);
|
| msg.WriteToLogFile();
|
| }
|
| @@ -398,8 +417,8 @@
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
|
| - if (!Log::IsEnabled()) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled()) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
|
| msg.WriteToLogFile();
|
| }
|
| @@ -408,8 +427,8 @@
|
|
|
| void Logger::HandleEvent(const char* name, Object** location) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_handles) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_handles) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
|
| msg.WriteToLogFile();
|
| #endif
|
| @@ -421,8 +440,8 @@
|
| // caller's responsibility to ensure that log is enabled and that
|
| // FLAG_log_api is true.
|
| void Logger::ApiEvent(const char* format, ...) {
|
| - ASSERT(Log::IsEnabled() && FLAG_log_api);
|
| - LogMessageBuilder msg;
|
| + ASSERT(log_->IsEnabled() && FLAG_log_api);
|
| + LogMessageBuilder msg(this);
|
| va_list ap;
|
| va_start(ap, format);
|
| msg.AppendVA(format, ap);
|
| @@ -434,7 +453,7 @@
|
|
|
| void Logger::ApiNamedSecurityCheck(Object* key) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| if (key->IsString()) {
|
| SmartPointer<char> str =
|
| String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| @@ -452,8 +471,8 @@
|
| uintptr_t start,
|
| uintptr_t end) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_prof) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_prof) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
|
| library_path,
|
| start,
|
| @@ -467,8 +486,8 @@
|
| uintptr_t start,
|
| uintptr_t end) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_prof) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_prof) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
|
| library_path,
|
| start,
|
| @@ -482,7 +501,7 @@
|
| void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
|
| // Prints "/" + re.source + "/" +
|
| // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
|
| - LogMessageBuilder msg;
|
| + LogMessageBuilder msg(this);
|
|
|
| Handle<Object> source = GetProperty(regexp, "source");
|
| if (!source->IsString()) {
|
| @@ -524,8 +543,8 @@
|
|
|
| void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_regexp) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_regexp) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("regexp-compile,");
|
| LogRegExpSource(regexp);
|
| msg.Append(in_cache ? ",hit\n" : ",miss\n");
|
| @@ -536,9 +555,9 @@
|
|
|
| void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_runtime) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_runtime) return;
|
| HandleScope scope;
|
| - LogMessageBuilder msg;
|
| + LogMessageBuilder msg(this);
|
| for (int i = 0; i < format.length(); i++) {
|
| char c = format[i];
|
| if (c == '%' && i <= format.length() - 2) {
|
| @@ -582,7 +601,7 @@
|
|
|
| void Logger::ApiIndexedSecurityCheck(uint32_t index) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| ApiEvent("api,check-security,%u\n", index);
|
| #endif
|
| }
|
| @@ -593,13 +612,13 @@
|
| Object* name) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| ASSERT(name->IsString());
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| String* class_name_obj = holder->class_name();
|
| SmartPointer<char> class_name =
|
| class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| SmartPointer<char> property_name =
|
| String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| - Logger::ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
|
| + LOGGER->ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
|
| #endif
|
| }
|
|
|
| @@ -607,37 +626,37 @@
|
| JSObject* holder,
|
| uint32_t index) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| String* class_name_obj = holder->class_name();
|
| SmartPointer<char> class_name =
|
| class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| - Logger::ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
|
| + LOGGER->ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
|
| #endif
|
| }
|
|
|
| void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| String* class_name_obj = object->class_name();
|
| SmartPointer<char> class_name =
|
| class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| - Logger::ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
|
| + LOGGER->ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
|
| #endif
|
| }
|
|
|
|
|
| void Logger::ApiEntryCall(const char* name) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_api) return;
|
| - Logger::ApiEvent("api,%s\n", name);
|
| + if (!log_->IsEnabled() || !FLAG_log_api) return;
|
| + LOGGER->ApiEvent("api,%s\n", name);
|
| #endif
|
| }
|
|
|
|
|
| void Logger::NewEvent(const char* name, void* object, size_t size) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
|
| static_cast<unsigned int>(size));
|
| msg.WriteToLogFile();
|
| @@ -647,19 +666,28 @@
|
|
|
| void Logger::DeleteEvent(const char* name, void* object) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
|
| msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
|
|
| +void Logger::NewEventStatic(const char* name, void* object, size_t size) {
|
| + LOGGER->NewEvent(name, object, size);
|
| +}
|
| +
|
| +
|
| +void Logger::DeleteEventStatic(const char* name, void* object) {
|
| + LOGGER->DeleteEvent(name, object);
|
| +}
|
| +
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::CallbackEventInternal(const char* prefix, const char* name,
|
| Address entry_point) {
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%s,",
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[CALLBACK_TAG]);
|
| @@ -673,7 +701,7 @@
|
|
|
| void Logger::CallbackEvent(String* name, Address entry_point) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| SmartPointer<char> str =
|
| name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| CallbackEventInternal("", *str, entry_point);
|
| @@ -683,7 +711,7 @@
|
|
|
| void Logger::GetterCallbackEvent(String* name, Address entry_point) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| SmartPointer<char> str =
|
| name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| CallbackEventInternal("get ", *str, entry_point);
|
| @@ -693,7 +721,7 @@
|
|
|
| void Logger::SetterCallbackEvent(String* name, Address entry_point) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| SmartPointer<char> str =
|
| name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| CallbackEventInternal("set ", *str, entry_point);
|
| @@ -705,8 +733,8 @@
|
| Code* code,
|
| const char* comment) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%s,",
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[tag]);
|
| @@ -758,9 +786,12 @@
|
| SharedFunctionInfo* shared,
|
| String* name) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - if (code == Builtins::builtin(Builtins::LazyCompile)) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + if (code == Isolate::Current()->builtins()->builtin(
|
| + Builtins::LazyCompile))
|
| + return;
|
| +
|
| + LogMessageBuilder msg(this);
|
| SmartPointer<char> str =
|
| name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| msg.Append("%s,%s,",
|
| @@ -785,8 +816,8 @@
|
| SharedFunctionInfo* shared,
|
| String* source, int line) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| SmartPointer<char> name =
|
| shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
|
| SmartPointer<char> sourcestr =
|
| @@ -811,8 +842,8 @@
|
|
|
| void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%s,",
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[tag]);
|
| @@ -827,8 +858,8 @@
|
|
|
| void Logger::CodeMovingGCEvent() {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s\n", kLogEventsNames[CODE_MOVING_GC]);
|
| msg.WriteToLogFile();
|
| OS::SignalCodeMovingGC();
|
| @@ -838,8 +869,8 @@
|
|
|
| void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%s,",
|
| kLogEventsNames[CODE_CREATION_EVENT],
|
| kLogEventsNames[REG_EXP_TAG]);
|
| @@ -870,8 +901,8 @@
|
|
|
| void Logger::SnapshotPositionEvent(Address addr, int pos) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_snapshot_positions) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_snapshot_positions) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
|
| msg.AppendAddress(addr);
|
| msg.Append(",%d", pos);
|
| @@ -892,8 +923,8 @@
|
| void Logger::MoveEventInternal(LogEventsAndTags event,
|
| Address from,
|
| Address to) {
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,", kLogEventsNames[event]);
|
| msg.AppendAddress(from);
|
| msg.Append(',');
|
| @@ -906,8 +937,8 @@
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) {
|
| - if (!Log::IsEnabled() || !FLAG_log_code) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_code) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,", kLogEventsNames[event]);
|
| msg.AppendAddress(from);
|
| msg.Append('\n');
|
| @@ -918,8 +949,8 @@
|
|
|
| void Logger::ResourceEvent(const char* name, const char* tag) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,%s,", name, tag);
|
|
|
| uint32_t sec, usec;
|
| @@ -936,11 +967,11 @@
|
|
|
| void Logger::SuspectReadEvent(String* name, Object* obj) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_suspect) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_suspect) return;
|
| + LogMessageBuilder msg(this);
|
| String* class_name = obj->IsJSObject()
|
| ? JSObject::cast(obj)->class_name()
|
| - : Heap::empty_string();
|
| + : HEAP->empty_string();
|
| msg.Append("suspect-read,");
|
| msg.Append(class_name);
|
| msg.Append(',');
|
| @@ -955,8 +986,8 @@
|
|
|
| void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| // Using non-relative system time in order to be able to synchronize with
|
| // external memory profiling events (e.g. DOM memory size).
|
| msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
|
| @@ -969,8 +1000,8 @@
|
| void Logger::HeapSampleStats(const char* space, const char* kind,
|
| intptr_t capacity, intptr_t used) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("heap-sample-stats,\"%s\",\"%s\","
|
| "%" V8_PTR_PREFIX "d,%" V8_PTR_PREFIX "d\n",
|
| space, kind, capacity, used);
|
| @@ -981,8 +1012,8 @@
|
|
|
| void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
|
| msg.WriteToLogFile();
|
| #endif
|
| @@ -991,8 +1022,8 @@
|
|
|
| void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
|
| msg.WriteToLogFile();
|
| #endif
|
| @@ -1002,32 +1033,32 @@
|
| void Logger::HeapSampleJSConstructorEvent(const char* constructor,
|
| int number, int bytes) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes);
|
| msg.WriteToLogFile();
|
| #endif
|
| }
|
|
|
| +// Event starts with comma, so we don't have it in the format string.
|
| +static const char kEventText[] = "heap-js-ret-item,%s";
|
| +// We take placeholder strings into account, but it's OK to be conservative.
|
| +static const int kEventTextLen = sizeof(kEventText)/sizeof(kEventText[0]);
|
|
|
| void Logger::HeapSampleJSRetainersEvent(
|
| const char* constructor, const char* event) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - // Event starts with comma, so we don't have it in the format string.
|
| - static const char* event_text = "heap-js-ret-item,%s";
|
| - // We take placeholder strings into account, but it's OK to be conservative.
|
| - static const int event_text_len = StrLength(event_text);
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| const int cons_len = StrLength(constructor);
|
| const int event_len = StrLength(event);
|
| int pos = 0;
|
| // Retainer lists can be long. We may need to split them into multiple events.
|
| do {
|
| - LogMessageBuilder msg;
|
| - msg.Append(event_text, constructor);
|
| + LogMessageBuilder msg(this);
|
| + msg.Append(kEventText, constructor);
|
| int to_write = event_len - pos;
|
| - if (to_write > Log::kMessageBufferSize - (cons_len + event_text_len)) {
|
| - int cut_pos = pos + Log::kMessageBufferSize - (cons_len + event_text_len);
|
| + if (to_write > Log::kMessageBufferSize - (cons_len + kEventTextLen)) {
|
| + int cut_pos = pos + Log::kMessageBufferSize - (cons_len + kEventTextLen);
|
| ASSERT(cut_pos < event_len);
|
| while (cut_pos > pos && event[cut_pos] != ',') --cut_pos;
|
| if (event[cut_pos] != ',') {
|
| @@ -1053,8 +1084,8 @@
|
| void Logger::HeapSampleJSProducerEvent(const char* constructor,
|
| Address* stack) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_gc) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log_gc) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("heap-js-prod-item,%s", constructor);
|
| while (*stack != NULL) {
|
| msg.Append(",0x%" V8PRIxPTR, *stack++);
|
| @@ -1067,8 +1098,8 @@
|
|
|
| void Logger::DebugTag(const char* call_site_tag) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_log) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("debug-tag,%s\n", call_site_tag);
|
| msg.WriteToLogFile();
|
| #endif
|
| @@ -1077,13 +1108,13 @@
|
|
|
| void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log) return;
|
| + if (!log_->IsEnabled() || !FLAG_log) return;
|
| StringBuilder s(parameter.length() + 1);
|
| for (int i = 0; i < parameter.length(); ++i) {
|
| s.AddCharacter(static_cast<char>(parameter[i]));
|
| }
|
| char* parameter_string = s.Finalize();
|
| - LogMessageBuilder msg;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("debug-queue-event,%s,%15.3f,%s\n",
|
| event_type,
|
| OS::TimeCurrentMillis(),
|
| @@ -1096,8 +1127,8 @@
|
|
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| void Logger::TickEvent(TickSample* sample, bool overflow) {
|
| - if (!Log::IsEnabled() || !FLAG_prof) return;
|
| - LogMessageBuilder msg;
|
| + if (!log_->IsEnabled() || !FLAG_prof) return;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
|
| msg.AppendAddress(sample->pc);
|
| msg.Append(',');
|
| @@ -1130,7 +1161,7 @@
|
|
|
|
|
| void Logger::PauseProfiler(int flags, int tag) {
|
| - if (!Log::IsEnabled()) return;
|
| + if (!log_->IsEnabled()) return;
|
| if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) {
|
| // It is OK to have negative nesting.
|
| if (--cpu_profiler_nesting_ == 0) {
|
| @@ -1141,7 +1172,7 @@
|
| }
|
| FLAG_log_code = false;
|
| // Must be the same message as Log::kDynamicBufferSeal.
|
| - LOG(UncheckedStringEvent("profiler", "pause"));
|
| + LOG(ISOLATE, UncheckedStringEvent("profiler", "pause"));
|
| }
|
| --logging_nesting_;
|
| }
|
| @@ -1160,7 +1191,7 @@
|
|
|
|
|
| void Logger::ResumeProfiler(int flags, int tag) {
|
| - if (!Log::IsEnabled()) return;
|
| + if (!log_->IsEnabled()) return;
|
| if (tag != 0) {
|
| UncheckedIntEvent("open-tag", tag);
|
| }
|
| @@ -1169,7 +1200,7 @@
|
| ++logging_nesting_;
|
| if (FLAG_prof_lazy) {
|
| profiler_->Engage();
|
| - LOG(UncheckedStringEvent("profiler", "resume"));
|
| + LOG(ISOLATE, UncheckedStringEvent("profiler", "resume"));
|
| FLAG_log_code = true;
|
| LogCompiledFunctions();
|
| LogAccessorCallbacks();
|
| @@ -1192,8 +1223,7 @@
|
|
|
| // This function can be called when Log's mutex is acquired,
|
| // either from main or Profiler's thread.
|
| -void Logger::StopLoggingAndProfiling() {
|
| - Log::stop();
|
| +void Logger::LogFailure() {
|
| PauseProfiler(PROFILER_MODULE_CPU, 0);
|
| }
|
|
|
| @@ -1204,7 +1234,7 @@
|
|
|
|
|
| int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
|
| - return Log::GetLogLines(from_pos, dest_buf, max_size);
|
| + return log_->GetLogLines(from_pos, dest_buf, max_size);
|
| }
|
|
|
|
|
| @@ -1326,14 +1356,14 @@
|
| tag = Logger::KEYED_CALL_IC_TAG;
|
| break;
|
| }
|
| - PROFILE(CodeCreateEvent(tag, code_object, description));
|
| + PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description));
|
| }
|
| }
|
|
|
|
|
| void Logger::LogCodeInfo() {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - if (!Log::IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
|
| + if (!log_->IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
|
| #if V8_TARGET_ARCH_IA32
|
| const char arch[] = "ia32";
|
| #elif V8_TARGET_ARCH_X64
|
| @@ -1343,7 +1373,7 @@
|
| #else
|
| const char arch[] = "unknown";
|
| #endif
|
| - LogMessageBuilder msg;
|
| + LogMessageBuilder msg(this);
|
| msg.Append("code-info,%s,%d\n", arch, Code::kHeaderSize);
|
| msg.WriteToLogFile();
|
| #endif // ENABLE_LOGGING_AND_PROFILING
|
| @@ -1351,10 +1381,10 @@
|
|
|
|
|
| void Logger::LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg) {
|
| - if (!FLAG_ll_prof || Log::output_code_handle_ == NULL) return;
|
| - int pos = static_cast<int>(ftell(Log::output_code_handle_));
|
| + if (!FLAG_ll_prof || log_->output_code_handle_ == NULL) return;
|
| + int pos = static_cast<int>(ftell(log_->output_code_handle_));
|
| size_t rv = fwrite(code->instruction_start(), 1, code->instruction_size(),
|
| - Log::output_code_handle_);
|
| + log_->output_code_handle_);
|
| ASSERT(static_cast<size_t>(code->instruction_size()) == rv);
|
| USE(rv);
|
| msg->Append(",%d", pos);
|
| @@ -1380,7 +1410,9 @@
|
| // During iteration, there can be heap allocation due to
|
| // GetScriptLineNumber call.
|
| for (int i = 0; i < compiled_funcs_count; ++i) {
|
| - if (*code_objects[i] == Builtins::builtin(Builtins::LazyCompile)) continue;
|
| + if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
|
| + Builtins::LazyCompile))
|
| + continue;
|
| Handle<SharedFunctionInfo> shared = sfis[i];
|
| Handle<String> func_name(shared->DebugName());
|
| if (shared->script()->IsScript()) {
|
| @@ -1389,20 +1421,23 @@
|
| Handle<String> script_name(String::cast(script->name()));
|
| int line_num = GetScriptLineNumber(script, shared->start_position());
|
| if (line_num > 0) {
|
| - PROFILE(CodeCreateEvent(
|
| - Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| - *code_objects[i], *shared,
|
| - *script_name, line_num + 1));
|
| + PROFILE(ISOLATE,
|
| + CodeCreateEvent(
|
| + Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| + *code_objects[i], *shared,
|
| + *script_name, line_num + 1));
|
| } else {
|
| // Can't distinguish eval and script here, so always use Script.
|
| - PROFILE(CodeCreateEvent(
|
| - Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
|
| - *code_objects[i], *shared, *script_name));
|
| + PROFILE(ISOLATE,
|
| + CodeCreateEvent(
|
| + Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
|
| + *code_objects[i], *shared, *script_name));
|
| }
|
| } else {
|
| - PROFILE(CodeCreateEvent(
|
| - Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| - *code_objects[i], *shared, *func_name));
|
| + PROFILE(ISOLATE,
|
| + CodeCreateEvent(
|
| + Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
|
| + *code_objects[i], *shared, *func_name));
|
| }
|
| } else if (shared->IsApiFunction()) {
|
| // API function.
|
| @@ -1412,11 +1447,13 @@
|
| CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
|
| Object* callback_obj = call_data->callback();
|
| Address entry_point = v8::ToCData<Address>(callback_obj);
|
| - PROFILE(CallbackEvent(*func_name, entry_point));
|
| + PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
|
| }
|
| } else {
|
| - PROFILE(CodeCreateEvent(
|
| - Logger::LAZY_COMPILE_TAG, *code_objects[i], *shared, *func_name));
|
| + PROFILE(ISOLATE,
|
| + CodeCreateEvent(
|
| + Logger::LAZY_COMPILE_TAG, *code_objects[i],
|
| + *shared, *func_name));
|
| }
|
| }
|
| }
|
| @@ -1425,6 +1462,7 @@
|
| void Logger::LogAccessorCallbacks() {
|
| AssertNoAllocation no_alloc;
|
| HeapIterator iterator;
|
| + i::Isolate* isolate = ISOLATE;
|
| for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
|
| if (!obj->IsAccessorInfo()) continue;
|
| AccessorInfo* ai = AccessorInfo::cast(obj);
|
| @@ -1432,11 +1470,11 @@
|
| String* name = String::cast(ai->name());
|
| Address getter_entry = v8::ToCData<Address>(ai->getter());
|
| if (getter_entry != 0) {
|
| - PROFILE(GetterCallbackEvent(name, getter_entry));
|
| + PROFILE(isolate, GetterCallbackEvent(name, getter_entry));
|
| }
|
| Address setter_entry = v8::ToCData<Address>(ai->setter());
|
| if (setter_entry != 0) {
|
| - PROFILE(SetterCallbackEvent(name, setter_entry));
|
| + PROFILE(isolate, SetterCallbackEvent(name, setter_entry));
|
| }
|
| }
|
| }
|
| @@ -1446,20 +1484,10 @@
|
|
|
| bool Logger::Setup() {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - // --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;
|
| - }
|
| + // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
|
| + if (is_initialized_) return true;
|
| + is_initialized_ = true;
|
|
|
| - // --prof implies --log-code.
|
| - if (FLAG_prof) FLAG_log_code = true;
|
| -
|
| // --ll-prof implies --log-code and --log-snapshot-positions.
|
| if (FLAG_ll_prof) {
|
| FLAG_log_code = true;
|
| @@ -1472,73 +1500,30 @@
|
| 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;
|
| + // TODO(isolates): this assert introduces cyclic dependency (logger
|
| + // -> thread local top -> heap -> logger).
|
| + // ASSERT(VMState::is_outermost_external());
|
|
|
| - bool open_log_file = start_logging || FLAG_prof_lazy;
|
| + log_->Initialize();
|
|
|
| - // If we're logging anything, we need to open the log file.
|
| - if (open_log_file) {
|
| - if (strcmp(FLAG_logfile, "-") == 0) {
|
| - Log::OpenStdout();
|
| - } else if (strcmp(FLAG_logfile, "*") == 0) {
|
| - Log::OpenMemoryBuffer();
|
| - } else if (strchr(FLAG_logfile, '%') != NULL) {
|
| - // If there's a '%' in the log file name we have to expand
|
| - // placeholders.
|
| - HeapStringAllocator allocator;
|
| - StringStream stream(&allocator);
|
| - 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();
|
| - Log::OpenFile(*expanded);
|
| - } else {
|
| - Log::OpenFile(FLAG_logfile);
|
| - }
|
| - }
|
| -
|
| if (FLAG_ll_prof) LogCodeInfo();
|
|
|
| - ticker_ = new Ticker(kSamplingIntervalMs);
|
| + ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs);
|
|
|
| if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
|
| sliding_state_window_ = new SlidingStateWindow();
|
| }
|
|
|
| + 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;
|
| +
|
| if (start_logging) {
|
| logging_nesting_ = 1;
|
| }
|
|
|
| if (FLAG_prof) {
|
| - profiler_ = new Profiler();
|
| + profiler_ = new Profiler(Isolate::Current());
|
| if (!FLAG_prof_auto) {
|
| profiler_->pause();
|
| } else {
|
| @@ -1549,7 +1534,6 @@
|
| }
|
| }
|
|
|
| - LogMessageBuilder::set_write_failure_handler(StopLoggingAndProfiling);
|
| return true;
|
|
|
| #else
|
| @@ -1558,6 +1542,11 @@
|
| }
|
|
|
|
|
| +Sampler* Logger::sampler() {
|
| + return ticker_;
|
| +}
|
| +
|
| +
|
| void Logger::EnsureTickerStarted() {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| ASSERT(ticker_ != NULL);
|
| @@ -1575,7 +1564,8 @@
|
|
|
| void Logger::TearDown() {
|
| #ifdef ENABLE_LOGGING_AND_PROFILING
|
| - LogMessageBuilder::set_write_failure_handler(NULL);
|
| + if (!is_initialized_) return;
|
| + is_initialized_ = false;
|
|
|
| // Stop the profiler before closing the file.
|
| if (profiler_ != NULL) {
|
| @@ -1590,7 +1580,7 @@
|
| delete ticker_;
|
| ticker_ = NULL;
|
|
|
| - Log::Close();
|
| + log_->Close();
|
| #endif
|
| }
|
|
|
| @@ -1613,4 +1603,56 @@
|
| #endif
|
| }
|
|
|
| +
|
| +Mutex* SamplerRegistry::mutex_ = OS::CreateMutex();
|
| +List<Sampler*>* SamplerRegistry::active_samplers_ = NULL;
|
| +
|
| +
|
| +bool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void* param) {
|
| + ScopedLock lock(mutex_);
|
| + for (int i = 0;
|
| + ActiveSamplersExist() && i < active_samplers_->length();
|
| + ++i) {
|
| + func(active_samplers_->at(i), param);
|
| + }
|
| + return ActiveSamplersExist();
|
| +}
|
| +
|
| +
|
| +static void ComputeCpuProfiling(Sampler* sampler, void* flag_ptr) {
|
| + bool* flag = reinterpret_cast<bool*>(flag_ptr);
|
| + *flag |= sampler->IsProfiling();
|
| +}
|
| +
|
| +
|
| +SamplerRegistry::State SamplerRegistry::GetState() {
|
| + bool flag = false;
|
| + if (!IterateActiveSamplers(&ComputeCpuProfiling, &flag)) {
|
| + return HAS_NO_SAMPLERS;
|
| + }
|
| + return flag ? HAS_CPU_PROFILING_SAMPLERS : HAS_SAMPLERS;
|
| +}
|
| +
|
| +
|
| +void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
|
| + ASSERT(sampler->IsActive());
|
| + ScopedLock lock(mutex_);
|
| + if (active_samplers_ == NULL) {
|
| + active_samplers_ = new List<Sampler*>;
|
| + } else {
|
| + ASSERT(!active_samplers_->Contains(sampler));
|
| + }
|
| + active_samplers_->Add(sampler);
|
| +}
|
| +
|
| +
|
| +void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) {
|
| + ASSERT(sampler->IsActive());
|
| + ScopedLock lock(mutex_);
|
| + ASSERT(active_samplers_ != NULL);
|
| + bool removed = active_samplers_->RemoveElement(sampler);
|
| + ASSERT(removed);
|
| + USE(removed);
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|