void mozilla_sampler_init() { sInitCount++; if (stack_key_initialized) return; LOG("BEGIN mozilla_sampler_init"); if (!tlsPseudoStack.init() || !tlsTicker.init()) { LOG("Failed to init."); return; } stack_key_initialized = true; Sampler::Startup(); PseudoStack *stack = new PseudoStack(); tlsPseudoStack.set(stack); Sampler::RegisterCurrentThread("Gecko", stack, true); if (sps_version2()) { // Read mode settings from MOZ_PROFILER_MODE and interval // settings from MOZ_PROFILER_INTERVAL and stack-scan threshhold // from MOZ_PROFILER_STACK_SCAN. read_profiler_env_vars(); // Create the unwinder thread. ATM there is only one. uwt__init(); # if defined(SPS_PLAT_amd64_linux) || defined(SPS_PLAT_arm_android) \ || defined(SPS_PLAT_x86_linux) || defined(SPS_PLAT_x86_android) \ || defined(SPS_PLAT_x86_windows) || defined(SPS_PLAT_amd64_windows) /* no idea if windows is correct */ // On Linuxes, register this thread (temporarily) for profiling int aLocal; uwt__register_thread_for_profiling( &aLocal ); # elif defined(SPS_PLAT_amd64_darwin) || defined(SPS_PLAT_x86_darwin) // Registration is done in platform-macos.cc # else # error "Unknown plat" # endif } // Allow the profiler to be started using signals OS::RegisterStartHandler(); // We can't open pref so we use an environment variable // to know if we should trigger the profiler on startup // NOTE: Default const char *val = PR_GetEnv("MOZ_PROFILER_STARTUP"); if (!val || !*val) { return; } const char* features[] = {"js" , "leaf" #if defined(XP_WIN) || defined(XP_MACOSX) , "stackwalk" #endif }; profiler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL, features, sizeof(features)/sizeof(const char*)); LOG("END mozilla_sampler_init"); }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, double aInterval, const char** aFeatures, uint32_t aFeatureCount, const char** aThreadNameFilters, uint32_t aFilterCount) { LOG("BEGIN mozilla_sampler_start"); if (!stack_key_initialized) profiler_init(nullptr); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; /* If the entry count was set using env vars, use that, too: */ if (sProfileEntries > 0) aProfileEntries = sProfileEntries; // Reset the current state if the profiler is running profiler_stop(); TableTicker* t; t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount, aThreadNameFilters, aFilterCount); tlsTicker.set(t); t->Start(); if (t->ProfileJS() || t->InPrivacyMode()) { ::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex); std::vector<ThreadInfo*> threads = t->GetRegisteredThreads(); for (uint32_t i = 0; i < threads.size(); i++) { ThreadInfo* info = threads[i]; if (info->IsPendingDelete()) { continue; } ThreadProfile* thread_profile = info->Profile(); if (!thread_profile) { continue; } thread_profile->GetPseudoStack()->reinitializeOnResume(); #ifndef SPS_STANDALONE if (t->ProfileJS()) { thread_profile->GetPseudoStack()->enableJSSampling(); } if (t->InPrivacyMode()) { thread_profile->GetPseudoStack()->mPrivacyMode = true; } #endif } } #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (t->ProfileJava()) { int javaInterval = aInterval; // Java sampling doesn't accuratly keep up with 1ms sampling if (javaInterval < 10) { aInterval = 10; } mozilla::widget::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); } #endif #ifndef SPS_STANDALONE if (t->AddMainThreadIO()) { if (!sInterposeObserver) { // Lazily create IO interposer observer sInterposeObserver = new mozilla::ProfilerIOInterposeObserver(); } mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); } #endif sIsProfiling = true; #ifndef SPS_STANDALONE sIsGPUProfiling = t->ProfileGPU(); sIsLayersDump = t->LayersDump(); sIsDisplayListDump = t->DisplayListDump(); sIsRestyleProfiling = t->ProfileRestyle(); if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) { nsTArray<nsCString> featuresArray; nsTArray<nsCString> threadNameFiltersArray; for (size_t i = 0; i < aFeatureCount; ++i) { featuresArray.AppendElement(aFeatures[i]); } for (size_t i = 0; i < aFilterCount; ++i) { threadNameFiltersArray.AppendElement(aThreadNameFilters[i]); } nsCOMPtr<nsIProfilerStartParams> params = new nsProfilerStartParams(aProfileEntries, aInterval, featuresArray, threadNameFiltersArray); os->NotifyObservers(params, "profiler-started", nullptr); } } #endif LOG("END mozilla_sampler_start"); }
void mozilla_sampler_init(void* stackTop) { sInitCount++; if (stack_key_initialized) return; #ifdef SPS_STANDALONE mozilla::TimeStamp::Startup(); #endif LOG("BEGIN mozilla_sampler_init"); if (!tlsPseudoStack.init() || !tlsTicker.init() || !tlsStackTop.init()) { LOG("Failed to init."); return; } stack_key_initialized = true; Sampler::Startup(); PseudoStack *stack = PseudoStack::create(); tlsPseudoStack.set(stack); bool isMainThread = true; Sampler::RegisterCurrentThread(isMainThread ? gGeckoThreadName : "Application Thread", stack, isMainThread, stackTop); // Read interval settings from MOZ_PROFILER_INTERVAL and stack-scan // threshhold from MOZ_PROFILER_STACK_SCAN. read_profiler_env_vars(); // platform specific initialization OS::Startup(); #ifndef SPS_STANDALONE set_stderr_callback(mozilla_sampler_log); #endif // We can't open pref so we use an environment variable // to know if we should trigger the profiler on startup // NOTE: Default const char *val = getenv("MOZ_PROFILER_STARTUP"); if (!val || !*val) { return; } const char* features[] = {"js" , "leaf" , "threads" #if defined(XP_WIN) || defined(XP_MACOSX) \ || (defined(SPS_ARCH_arm) && defined(linux)) \ || defined(SPS_PLAT_amd64_linux) || defined(SPS_PLAT_x86_linux) , "stackwalk" #endif #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) , "java" #endif }; const char* threadFilters[] = { "GeckoMain", "Compositor" }; profiler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL, features, MOZ_ARRAY_LENGTH(features), threadFilters, MOZ_ARRAY_LENGTH(threadFilters)); LOG("END mozilla_sampler_init"); }
static void Pop(ScriptSettingsStackEntry *aEntry) { MOZ_ASSERT(aEntry == Top()); sScriptSettingsTLS.set(aEntry->mOlder); }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, double aInterval, const char** aFeatures, uint32_t aFeatureCount, const char** aThreadNameFilters, uint32_t aFilterCount) { LOG("BEGIN mozilla_sampler_start"); if (!stack_key_initialized) profiler_init(nullptr); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; /* If the entry count was set using env vars, use that, too: */ if (sProfileEntries > 0) aProfileEntries = sProfileEntries; // Reset the current state if the profiler is running profiler_stop(); TableTicker* t; t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount, aThreadNameFilters, aFilterCount); if (t->HasUnwinderThread()) { // Create the unwinder thread. ATM there is only one. uwt__init(); } tlsTicker.set(t); t->Start(); if (t->ProfileJS() || t->InPrivacyMode()) { 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()->reinitializeOnResume(); if (t->ProfileJS()) { thread_profile->GetPseudoStack()->enableJSSampling(); } if (t->InPrivacyMode()) { thread_profile->GetPseudoStack()->mPrivacyMode = true; } } } #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (t->ProfileJava()) { int javaInterval = aInterval; // Java sampling doesn't accuratly keep up with 1ms sampling if (javaInterval < 10) { aInterval = 10; } mozilla::widget::android::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); } #endif if (t->AddMainThreadIO()) { if (!sInterposeObserver) { // Lazily create IO interposer observer sInterposeObserver = new mozilla::ProfilerIOInterposeObserver(); } mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); } sIsProfiling = true; if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-started", nullptr); } LOG("END mozilla_sampler_start"); }
void mozilla_sampler_init(void* stackTop) { sInitCount++; if (stack_key_initialized) return; LOG("BEGIN mozilla_sampler_init"); if (!tlsPseudoStack.init() || !tlsTicker.init() || !tlsStackTop.init()) { LOG("Failed to init."); return; } stack_key_initialized = true; Sampler::Startup(); PseudoStack *stack = new PseudoStack(); tlsPseudoStack.set(stack); bool isMainThread = true; #ifdef XP_WIN // For metrofx, we'll register the main thread once it's created. isMainThread = !(XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro); #endif Sampler::RegisterCurrentThread(isMainThread ? gGeckoThreadName : "Application Thread", stack, isMainThread, stackTop); // Read mode settings from MOZ_PROFILER_MODE and interval // settings from MOZ_PROFILER_INTERVAL and stack-scan threshhold // from MOZ_PROFILER_STACK_SCAN. read_profiler_env_vars(); // platform specific initialization OS::Startup(); set_stderr_callback(profiler_log); // We can't open pref so we use an environment variable // to know if we should trigger the profiler on startup // NOTE: Default const char *val = PR_GetEnv("MOZ_PROFILER_STARTUP"); if (!val || !*val) { return; } const char* features[] = {"js" , "leaf" #if defined(XP_WIN) || defined(XP_MACOSX) || (defined(SPS_ARCH_arm) && defined(linux)) , "stackwalk" #endif #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) , "java" #endif }; profiler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL, features, sizeof(features)/sizeof(const char*), // TODO Add env variable to select threads nullptr, 0); LOG("END mozilla_sampler_init"); }