Bug 888473 - Start GeckoJavaSampler early when profiling startup; r=BenWa

This commit is contained in:
Jim Chen 2013-07-09 16:34:44 -04:00
Родитель ab6dffe101
Коммит 9d1d83bb0f
4 изменённых файлов: 51 добавлений и 2 удалений

Просмотреть файл

@ -1146,6 +1146,24 @@ abstract public class GeckoApp
}); });
} }
/**
* Check and start the Java profiler if MOZ_PROFILER_STARTUP env var is specified
**/
protected void earlyStartJavaSampler(Intent intent)
{
String env = intent.getStringExtra("env0");
for (int i = 1; env != null; i++) {
if (env.startsWith("MOZ_PROFILER_STARTUP=")) {
if (!env.endsWith("=")) {
GeckoJavaSampler.start(10, 1000);
Log.d(LOGTAG, "Profiling Java on startup");
}
break;
}
env = intent.getStringExtra("env" + i);
}
}
/** /**
* Called when the activity is first created. * Called when the activity is first created.
* *
@ -1166,7 +1184,9 @@ abstract public class GeckoApp
mJavaUiStartupTimer = new Telemetry.Timer("FENNEC_STARTUP_TIME_JAVAUI"); mJavaUiStartupTimer = new Telemetry.Timer("FENNEC_STARTUP_TIME_JAVAUI");
mGeckoReadyStartupTimer = new Telemetry.Timer("FENNEC_STARTUP_TIME_GECKOREADY"); mGeckoReadyStartupTimer = new Telemetry.Timer("FENNEC_STARTUP_TIME_GECKOREADY");
String args = getIntent().getStringExtra("args"); Intent intent = getIntent();
String args = intent.getStringExtra("args");
earlyStartJavaSampler(intent);
String profileName = null; String profileName = null;
String profilePath = null; String profilePath = null;

Просмотреть файл

@ -5,6 +5,7 @@
package org.mozilla.gecko; package org.mozilla.gecko;
import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import java.lang.Thread; import java.lang.Thread;
import java.util.HashMap; import java.util.HashMap;
@ -16,6 +17,7 @@ public class GeckoJavaSampler {
private static Thread sSamplingThread = null; private static Thread sSamplingThread = null;
private static SamplingThread sSamplingRunnable = null; private static SamplingThread sSamplingRunnable = null;
private static Thread sMainThread = null; private static Thread sMainThread = null;
private static volatile boolean sLibsLoaded = false;
// Use the same timer primitive as the profiler // Use the same timer primitive as the profiler
// to get a perfect sample syncing. // to get a perfect sample syncing.
@ -24,9 +26,17 @@ public class GeckoJavaSampler {
private static class Sample { private static class Sample {
public Frame[] mFrames; public Frame[] mFrames;
public double mTime; public double mTime;
public long mJavaTime; // non-zero if Android system time is used
public Sample(StackTraceElement[] aStack) { public Sample(StackTraceElement[] aStack) {
mFrames = new Frame[aStack.length]; mFrames = new Frame[aStack.length];
if (sLibsLoaded) {
mTime = getProfilerTime(); mTime = getProfilerTime();
}
if (mTime == 0.0d) {
// getProfilerTime is not available yet; either libs are not loaded,
// or profiling hasn't started on the Gecko side yet
mJavaTime = SystemClock.elapsedRealtime();
}
for (int i = 0; i < aStack.length; i++) { for (int i = 0; i < aStack.length; i++) {
mFrames[aStack.length - 1 - i] = new Frame(); mFrames[aStack.length - 1 - i] = new Frame();
mFrames[aStack.length - 1 - i].fileName = aStack[i].getFileName(); mFrames[aStack.length - 1 - i].fileName = aStack[i].getFileName();
@ -122,9 +132,14 @@ public class GeckoJavaSampler {
private synchronized static Sample getSample(int aThreadId, int aSampleId) { private synchronized static Sample getSample(int aThreadId, int aSampleId) {
return sSamplingRunnable.getSample(aThreadId, aSampleId); return sSamplingRunnable.getSample(aThreadId, aSampleId);
} }
public synchronized static double getSampleTime(int aThreadId, int aSampleId) { public synchronized static double getSampleTime(int aThreadId, int aSampleId) {
Sample sample = getSample(aThreadId, aSampleId); Sample sample = getSample(aThreadId, aSampleId);
if (sample != null) { if (sample != null) {
if (sample.mJavaTime != 0) {
return (double)(sample.mJavaTime -
SystemClock.elapsedRealtime()) + getProfilerTime();
}
System.out.println("Sample: " + sample.mTime); System.out.println("Sample: " + sample.mTime);
return sample.mTime; return sample.mTime;
} }
@ -144,6 +159,9 @@ public class GeckoJavaSampler {
public static void start(int aInterval, int aSamples) { public static void start(int aInterval, int aSamples) {
synchronized (GeckoJavaSampler.class) { synchronized (GeckoJavaSampler.class) {
if (sSamplingRunnable != null) {
return;
}
sSamplingRunnable = new SamplingThread(aInterval, aSamples); sSamplingRunnable = new SamplingThread(aInterval, aSamples);
sSamplingThread = new Thread(sSamplingRunnable, "Java Sampler"); sSamplingThread = new Thread(sSamplingRunnable, "Java Sampler");
sSamplingThread.start(); sSamplingThread.start();
@ -178,6 +196,10 @@ public class GeckoJavaSampler {
sSamplingRunnable = null; sSamplingRunnable = null;
} }
} }
public static void setLibsLoaded() {
sLibsLoaded = true;
}
} }

Просмотреть файл

@ -76,6 +76,7 @@ public class GeckoThread extends Thread implements GeckoEventListener {
GeckoLoader.loadSQLiteLibs(app, resourcePath); GeckoLoader.loadSQLiteLibs(app, resourcePath);
GeckoLoader.loadNSSLibs(app, resourcePath); GeckoLoader.loadNSSLibs(app, resourcePath);
GeckoLoader.loadGeckoLibs(app, resourcePath); GeckoLoader.loadGeckoLibs(app, resourcePath);
GeckoJavaSampler.setLibsLoaded();
Locale.setDefault(locale); Locale.setDefault(locale);

Просмотреть файл

@ -300,6 +300,9 @@ void mozilla_sampler_init(void* stackTop)
, "leaf" , "leaf"
#if defined(XP_WIN) || defined(XP_MACOSX) #if defined(XP_WIN) || defined(XP_MACOSX)
, "stackwalk" , "stackwalk"
#endif
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
, "java"
#endif #endif
}; };
profiler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL, profiler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL,
@ -605,6 +608,9 @@ void mozilla_sampler_unregister_thread()
double mozilla_sampler_time() double mozilla_sampler_time()
{ {
if (!mozilla_sampler_is_active()) {
return 0.0;
}
TimeDuration delta = TimeStamp::Now() - sStartTime; TimeDuration delta = TimeStamp::Now() - sStartTime;
return delta.ToMilliseconds(); return delta.ToMilliseconds();
} }