void mozilla_sampler_stop() { if (!stack_key_initialized) profiler_init(); TableTicker *t = tlsTicker.get(); if (!t) { return; } bool disableJS = t->ProfileJS(); t->Stop(); delete t; tlsTicker.set(NULL); PseudoStack *stack = tlsPseudoStack.get(); ASSERT(stack != NULL); if (disableJS) stack->disableJSSampling(); sIsProfiling = false; nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-stopped", nullptr); }
NS_IMETHOD Run() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); char buff[MAXPATHLEN]; #ifdef ANDROID #define FOLDER "/sdcard/" #elif defined(XP_WIN) #define FOLDER "%TEMP%\\" #else #define FOLDER "/tmp/" #endif snprintf(buff, MAXPATHLEN, "%sprofile_%i_%i.txt", FOLDER, XRE_GetProcessType(), getpid()); #ifdef XP_WIN // Expand %TEMP% on Windows { char tmp[MAXPATHLEN]; ExpandEnvironmentStringsA(buff, tmp, mozilla::ArrayLength(tmp)); strcpy(buff, tmp); } #endif FILE* stream = ::fopen(buff, "w"); if (stream) { t->GetProfile()->WriteProfile(stream); ::fclose(stream); LOG("Saved to " FOLDER "profile_TYPE_PID.txt"); } else { LOG("Fail to open profile log file."); } return NS_OK; }
void mozilla_sampler_shutdown() { sInitCount--; if (sInitCount > 0) return; // Save the profile on shutdown if requested. TableTicker *t = tlsTicker.get(); if (t) { const char *val = PR_GetEnv("MOZ_PROFILER_SHUTDOWN"); if (val) { std::ofstream stream; stream.open(val); if (stream.is_open()) { t->ToStreamAsJSON(stream); stream.close(); } } } profiler_stop(); set_stderr_callback(nullptr); Sampler::Shutdown(); PseudoStack *stack = tlsPseudoStack.get(); stack->deref(); tlsPseudoStack.set(nullptr); }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount) { if (!stack_key_initialized) mozilla_sampler_init(); ProfileStack *stack = tlsStack.get(); if (!stack) { ASSERT(false); return; } mozilla_sampler_stop(); TableTicker *t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, stack, aFeatures, aFeatureCount); tlsTicker.set(t); t->Start(); if (t->ProfileJS()) stack->enableJSSampling(); nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-started", nullptr); }
void mozilla_sampler_shutdown() { sInitCount--; if (sInitCount > 0) return; // Save the profile on shutdown if requested. TableTicker *t = tlsTicker.get(); if (t) { const char *val = PR_GetEnv("MOZ_PROFILER_SHUTDOWN"); if (val) { std::ofstream stream; stream.open(val); if (stream.is_open()) { t->ToStreamAsJSON(stream); stream.close(); } } } profiler_stop(); set_stderr_callback(nullptr); Sampler::Shutdown(); // We can't delete the Stack because we can be between a // sampler call_enter/call_exit point. // TODO Need to find a safe time to delete Stack }
void PseudoStack::flushSamplerOnJSShutdown() { MOZ_ASSERT(mRuntime); TableTicker* t = tlsTicker.get(); if (t) { t->FlushOnJSShutdown(mRuntime); } }
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx) { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return NULL; } return t->ToJSObject(aCx); }
bool mozilla_sampler_is_active() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return false; } return t->IsActive(); }
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx, float aSinceTime) { TableTicker *t = Sampler::GetActiveSampler(); if (!t) { return nullptr; } return t->ToJSObject(aCx, aSinceTime); }
mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(float aSinceTime) { TableTicker *t = Sampler::GetActiveSampler(); if (!t) { return nullptr; } return t->ToJSON(aSinceTime); }
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx) { TableTicker *t = tlsTicker.get(); if (!t) { return nullptr; } return t->ToJSObject(aCx); }
void mozilla_sampler_stop() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return; } t->Stop(); mozilla::tls::set(pkey_ticker, (Stack*)NULL); }
void mozilla_sampler_save() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return; } t->RequestSave(); // We're on the main thread already so we don't // have to wait to handle the save request. t->HandleSaveRequest(); }
char* mozilla_sampler_get_profile() { TableTicker *t = tlsTicker.get(); if (!t) { return nullptr; } std::stringstream stream; t->ToStreamAsJSON(stream); char* profile = strdup(stream.str().c_str()); return profile; }
bool mozilla_sampler_is_active() { if (!stack_key_initialized) mozilla_sampler_init(); TableTicker *t = tlsTicker.get(); if (!t) { return false; } return t->IsActive(); }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount) { if (!stack_key_initialized) profiler_init(); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; PseudoStack *stack = tlsPseudoStack.get(); if (!stack) { ASSERT(false); return; } // Reset the current state if the profiler is running profiler_stop(); TableTicker* t; if (sps_version2()) { t = new BreakpadSampler(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount); } else { t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount); } tlsTicker.set(t); t->Start(); if (t->ProfileJS()) { mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex); std::vector<ThreadInfo*> threads = t->GetRegisteredThreads(); for (uint32_t i = 0; i < threads.size(); i++) { ThreadInfo* info = threads[i]; ThreadProfile* thread_profile = info->Profile(); if (!thread_profile) { continue; } thread_profile->GetPseudoStack()->enableJSSampling(); } } sIsProfiling = true; nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-started", nullptr); }
void mozilla_sampler_stop() { LOG("BEGIN mozilla_sampler_stop"); if (!stack_key_initialized) profiler_init(nullptr); TableTicker *t = tlsTicker.get(); if (!t) { LOG("END mozilla_sampler_stop-early"); return; } bool disableJS = t->ProfileJS(); bool unwinderThreader = t->HasUnwinderThread(); // Shut down and reap the unwinder thread. We have to do this // before stopping the sampler, so as to guarantee that the unwinder // thread doesn't try to access memory that the subsequent call to // mozilla_sampler_stop causes to be freed. if (unwinderThreader) { uwt__stop(); } t->Stop(); delete t; tlsTicker.set(nullptr); if (disableJS) { PseudoStack *stack = tlsPseudoStack.get(); ASSERT(stack != nullptr); stack->disableJSSampling(); } if (unwinderThreader) { uwt__deinit(); } mozilla::IOInterposer::Unregister(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); sInterposeObserver = nullptr; sIsProfiling = false; if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-stopped", nullptr); } LOG("END mozilla_sampler_stop"); }
char* mozilla_sampler_get_profile() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return NULL; } string profile; t->GetProfile()->ToString(&profile); char *rtn = (char*)malloc( (strlen(profile.c_str())+1) * sizeof(char) ); strcpy(rtn, profile.c_str()); return rtn; }
char* mozilla_sampler_get_profile() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return NULL; } StringBuilder profile; t->GetPrimaryThreadProfile()->ToString(profile); char *rtn = (char*)malloc( (profile.Length()+1) * sizeof(char) ); strcpy(rtn, profile.Buffer()); return rtn; }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval) { Stack *stack = mozilla::tls::get<Stack>(pkey_stack); if (!stack) { ASSERT(false); return; } mozilla_sampler_stop(); TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack); mozilla::tls::set(pkey_ticker, t); t->Start(); }
void mozilla_sampler_stop() { if (!stack_key_initialized) mozilla_sampler_init(); TableTicker *t = tlsTicker.get(); if (!t) { return; } t->Stop(); delete t; tlsTicker.set(NULL); }
char* mozilla_sampler_get_profile() { TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker); if (!t) { return NULL; } std::stringstream profile; profile << *(t->GetPrimaryThreadProfile()); std::string profileString = profile.str(); char *rtn = (char*)malloc( (profileString.length() + 1) * sizeof(char) ); strcpy(rtn, profileString.c_str()); return rtn; }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount) { ProfileStack *stack = mozilla::tls::get<ProfileStack>(pkey_stack); if (!stack) { ASSERT(false); return; } mozilla_sampler_stop(); TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack, aFeatures, aFeatureCount); mozilla::tls::set(pkey_ticker, t); t->Start(); }
void mozilla_sampler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint32_t *aGeneration) { *aCurrentPosition = 0; *aTotalSize = 0; *aGeneration = 0; if (!stack_key_initialized) return; TableTicker *t = tlsTicker.get(); if (!t) return; t->GetBufferInfo(aCurrentPosition, aTotalSize, aGeneration); }
void mozilla_sampler_stop() { LOG("BEGIN mozilla_sampler_stop"); if (!stack_key_initialized) return; TableTicker *t = tlsTicker.get(); if (!t) { LOG("END mozilla_sampler_stop-early"); return; } bool disableJS = t->ProfileJS(); t->Stop(); delete t; tlsTicker.set(nullptr); #ifndef SPS_STANDALONE if (disableJS) { PseudoStack *stack = tlsPseudoStack.get(); ASSERT(stack != nullptr); stack->disableJSSampling(); } mozilla::IOInterposer::Unregister(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); sInterposeObserver = nullptr; #endif sIsProfiling = false; #ifndef SPS_STANDALONE sIsGPUProfiling = false; sIsLayersDump = false; sIsDisplayListDump = false; sIsRestyleProfiling = false; if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-stopped", nullptr); } #endif LOG("END mozilla_sampler_stop"); }
void mozilla_sampler_save_profile_to_file(const char* aFilename) { TableTicker *t = tlsTicker.get(); if (!t) { return; } std::ofstream stream; stream.open(aFilename); if (stream.is_open()) { t->ToStreamAsJSON(stream); stream.close(); LOGF("Saved to %s", aFilename); } else { LOG("Fail to open profile log file."); } }
char* mozilla_sampler_get_profile() { TableTicker *t = tlsTicker.get(); if (!t) { return NULL; } std::stringstream profile; t->SetPaused(true); profile << *(t->GetPrimaryThreadProfile()); t->SetPaused(false); std::string profileString = profile.str(); char *rtn = (char*)malloc( (profileString.length() + 1) * sizeof(char) ); strcpy(rtn, profileString.c_str()); return rtn; }
NS_IMETHOD Run() { TableTicker *t = tlsTicker.get(); char buff[MAXPATHLEN]; #ifdef ANDROID #define FOLDER "/sdcard/" #elif defined(XP_WIN) #define FOLDER "%TEMP%\\" #else #define FOLDER "/tmp/" #endif snprintf(buff, MAXPATHLEN, "%sprofile_%i_%i.txt", FOLDER, XRE_GetProcessType(), getpid()); #ifdef XP_WIN // Expand %TEMP% on Windows { char tmp[MAXPATHLEN]; ExpandEnvironmentStringsA(buff, tmp, mozilla::ArrayLength(tmp)); strcpy(buff, tmp); } #endif // Pause the profiler during saving. // This will prevent us from recording sampling // regarding profile saving. This will also // prevent bugs caused by the circular buffer not // being thread safe. Bug 750989. std::ofstream stream; stream.open(buff); t->SetPaused(true); if (stream.is_open()) { stream << *(t->GetPrimaryThreadProfile()); stream << "h-" << GetSharedLibraryInfoString() << std::endl; stream.close(); LOG("Saved to " FOLDER "profile_TYPE_PID.txt"); } else { LOG("Fail to open profile log file."); } t->SetPaused(false); return NS_OK; }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount) { if (!stack_key_initialized) mozilla_sampler_init(); ProfileStack *stack = tlsStack.get(); if (!stack) { ASSERT(false); return; } mozilla_sampler_stop(); TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack, aFeatures, aFeatureCount); tlsTicker.set(t); t->Start(); }
void mozilla_sampler_shutdown() { TableTicker *t = tlsTicker.get(); if (t) { const char *val = PR_GetEnv("MOZ_PROFILER_SHUTDOWN"); if (val) { std::ofstream stream; stream.open(val); if (stream.is_open()) { t->ToStreamAsJSON(stream); stream.close(); } } } mozilla_sampler_stop(); // We can't delete the Stack because we can be between a // sampler call_enter/call_exit point. // TODO Need to find a safe time to delete Stack }