Backout 61e1edc0b6bf (bug 793735), 77014412cd4a (bug 793735), and 8c5aa269c3cd (bug 793735) for botching FHR data
authorNathan Froyd <froydnj@mozilla.com>
Tue, 09 Apr 2013 16:25:42 -0400
changeset 128218 a9042561f00448c053facf92ab1a7d0abfb1fdab
parent 128217 e1e464427681aea65b396c6bfe08210ad91dac66
child 128219 3c7ab35260ef884120820b12860c491ebfd11fda
push id26203
push usernfroyd@mozilla.com
push dateTue, 09 Apr 2013 20:27:26 +0000
treeherdermozilla-inbound@a9042561f004 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs793735
milestone23.0a1
backs out61e1edc0b6bff52d690cbdca4e888f4ab38172a3
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 61e1edc0b6bf (bug 793735), 77014412cd4a (bug 793735), and 8c5aa269c3cd (bug 793735) for botching FHR data
browser/app/Makefile.in
browser/app/nsBrowserApp.cpp
mozglue/android/APKOpen.cpp
toolkit/components/startup/StartupTimeline.cpp
toolkit/components/startup/StartupTimeline.h
toolkit/components/startup/nsAppStartup.cpp
xpcom/ds/TimeStamp.h
xpcom/ds/TimeStamp_darwin.cpp
xpcom/ds/TimeStamp_posix.cpp
xpcom/ds/TimeStamp_windows.cpp
xpcom/ds/TimeStamp_windows.h
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -61,20 +61,16 @@ LIBS += \
 	$(EXTRA_DSO_LIBS) \
 	$(XPCOM_STANDALONE_GLUE_LDOPTS) \
 	$(NULL)
 
 ifdef MOZ_LINKER
 LIBS += $(MOZ_ZLIB_LIBS)
 endif
 
-ifdef HAVE_CLOCK_MONOTONIC
-LIBS += $(REALTIME_LIBS)
-endif
-
 ifndef MOZ_WINCONSOLE
 ifdef MOZ_DEBUG
 MOZ_WINCONSOLE = 1
 else
 MOZ_WINCONSOLE = 0
 endif
 endif
 
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -8,23 +8,22 @@
 #include "application.ini.h"
 #include "nsXPCOMGlue.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #include <io.h>
 #include <fcntl.h>
 #elif defined(XP_UNIX)
+#include <sys/time.h>
 #include <sys/resource.h>
-#include <time.h>
 #include <unistd.h>
 #endif
 
 #ifdef XP_MACOSX
-#include <mach/mach_time.h>
 #include "MacQuirks.h"
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
 #include <time.h>
 
 #include "nsCOMPtr.h"
@@ -384,90 +383,35 @@ static int do_main(int argc, char* argv[
   XRE_FreeAppData(appData);
   return result;
 #endif
 
   NS_NOTREACHED("browser do_main failed to pickup proper initialization");
   return 255;
 }
 
+/* Local implementation of PR_Now, since the executable can't depend on NSPR */
+static PRTime _PR_Now()
+{
 #ifdef XP_WIN
-
-/**
- * Used only when GetTickCount64 is not available on the platform.
- * Last result of GetTickCount call. Kept in [ms].
- */
-static DWORD sLastGTCResult = 0;
-
-/**
- *  Higher part of the 64-bit value of MozGetTickCount64,
- * incremented atomically.
- */
-static DWORD sLastGTCRollover = 0;
-
-/**
- * Function protecting GetTickCount result from rolling over. The original
- * code comes from the Windows implementation of the TimeStamp class minus the
- * locking harness which isn't needed here.
- *
- * @returns The current time in milliseconds
- */
-static ULONGLONG WINAPI
-MozGetTickCount64()
-{
-  DWORD GTC = ::GetTickCount();
-
-  /* Pull the rollover counter forward only if new value of GTC goes way
-   * down under the last saved result */
-  if ((sLastGTCResult > GTC) && ((sLastGTCResult - GTC) > (1UL << 30)))
-    ++sLastGTCRollover;
-
-  sLastGTCResult = GTC;
-  return (ULONGLONG)sLastGTCRollover << 32 | sLastGTCResult;
-}
-
-typedef ULONGLONG (WINAPI* GetTickCount64_t)();
-static GetTickCount64_t sGetTickCount64 = nullptr;
-
+  MOZ_STATIC_ASSERT(sizeof(PRTime) == sizeof(FILETIME), "PRTime must have the same size as FILETIME");
+  FILETIME ft;
+  GetSystemTimeAsFileTime(&ft);
+  PRTime now;
+  CopyMemory(&now, &ft, sizeof(PRTime));
+#ifdef __GNUC__
+  return (now - 116444736000000000LL) / 10LL;
+#else
+  return (now - 116444736000000000i64) / 10i64;
 #endif
 
-/**
- * Local TimeStamp::Now()-compatible implementation used to record timestamps
- * which will be passed to XRE_StartupTimelineRecord().
- */
-static uint64_t
-TimeStamp_Now()
-{
-#ifdef XP_WIN
-  LARGE_INTEGER freq;
-  ::QueryPerformanceFrequency(&freq);
-
-  HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll");
-  sGetTickCount64 = reinterpret_cast<GetTickCount64_t>
-    (GetProcAddress(kernelDLL, "GetTickCount64"));
-
-  if (!sGetTickCount64) {
-    /* If the platform does not support the GetTickCount64 (Windows XP doesn't),
-     * then use our fallback implementation based on GetTickCount. */
-    sGetTickCount64 = MozGetTickCount64;
-  }
-
-  return sGetTickCount64() * freq.QuadPart;
-#elif defined(XP_MACOSX)
-  return mach_absolute_time();
-#elif defined(HAVE_CLOCK_MONOTONIC)
-  struct timespec ts;
-  int rv = clock_gettime(CLOCK_MONOTONIC, &ts);
-
-  if (rv != 0) {
-    return 0;
-  }
-
-  uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
-  return baseNs + (uint64_t)ts.tv_nsec;
+#else
+  struct timeval tm;
+  gettimeofday(&tm, 0);
+  return (((PRTime)tm.tv_sec * 1000000LL) + (PRTime)tm.tv_usec);
 #endif
 }
 
 static bool
 FileExists(const char *path)
 {
 #ifdef XP_WIN
   wchar_t wideDir[MAX_PATH];
@@ -579,17 +523,17 @@ InitXPCOMGlue(const char *argv0, nsIFile
   return rv;
 }
 
 int main(int argc, char* argv[])
 {
 #ifdef DEBUG_delay_start_metro
   Sleep(5000);
 #endif
-  uint64_t start = TimeStamp_Now();
+  PRTime start = _PR_Now();
 
 #ifdef XP_MACOSX
   TriggerQuirks();
 #endif
 
   int gotCounters;
 #if defined(XP_UNIX)
   struct rusage initialRUsage;
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -6,25 +6,25 @@
  * This custom library loading code is only meant to be called
  * during initialization. As a result, it takes no special 
  * precautions to be threadsafe. Any of the library loading functions
  * like mozload should not be available to other code.
  */
 
 #include <jni.h>
 #include <android/log.h>
+#include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/limits.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <zlib.h>
 #include "dlfcn.h"
 #include "APKOpen.h"
 #include <sys/time.h>
 #include <sys/resource.h>
 #include "Zip.h"
@@ -51,42 +51,32 @@ extern "C" {
  * would fix the original problem. On older NDKs, it is not a problem
  * either because the way __dso_handle was used was already broken (and
  * the custom linker works around it).
  */
   NS_EXPORT __attribute__((weak)) void *__dso_handle;
 }
 
 typedef int mozglueresult;
+typedef int64_t MOZTime;
 
 enum StartupEvent {
 #define mozilla_StartupTimeline_Event(ev, z) ev,
 #include "StartupTimeline.h"
 #undef mozilla_StartupTimeline_Event
   MAX_STARTUP_EVENT_ID
 };
 
 using namespace mozilla;
 
-/**
- * Local TimeStamp::Now()-compatible implementation used to record timestamps
- * which will be passed to XRE_StartupTimelineRecord().
- */
-
-static uint64_t TimeStamp_Now()
+static MOZTime MOZ_Now()
 {
-  struct timespec ts;
-  int rv = clock_gettime(CLOCK_MONOTONIC, &ts);
-
-  if (rv != 0) {
-    return 0;
-  }
-
-  uint64_t baseNs = (uint64_t)ts.tv_sec * 1000000000;
-  return baseNs + (uint64_t)ts.tv_nsec;
+  struct timeval tm;
+  gettimeofday(&tm, 0);
+  return (((MOZTime)tm.tv_sec * 1000000LL) + (MOZTime)tm.tv_usec);
 }
 
 static struct mapping_info * lib_mapping = NULL;
 
 NS_EXPORT const struct mapping_info *
 getLibraryMapping()
 {
   return lib_mapping;
@@ -156,17 +146,17 @@ report_mapping(char *name, void *base, u
   info->offset = offset;
 }
 
 static mozglueresult
 loadGeckoLibs(const char *apkName)
 {
   chdir(getenv("GRE_HOME"));
 
-  uint64_t t0 = TimeStamp_Now();
+  MOZTime t0 = MOZ_Now();
   struct rusage usage1;
   getrusage(RUSAGE_THREAD, &usage1);
   
   RefPtr<Zip> zip = ZipCollection::GetZip(apkName);
 
   char *file = new char[strlen(apkName) + sizeof("!/libxul.so")];
   sprintf(file, "%s!/libxul.so", apkName);
   xul_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
@@ -176,20 +166,20 @@ loadGeckoLibs(const char *apkName)
     __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!");
     return FAILURE;
   }
 
 #define JNI_BINDINGS
 #include "jni-stubs.inc"
 #undef JNI_BINDINGS
 
-  void (*XRE_StartupTimelineRecord)(int, uint64_t);
+  void (*XRE_StartupTimelineRecord)(int, MOZTime);
   xul_dlsym("XRE_StartupTimelineRecord", &XRE_StartupTimelineRecord);
 
-  uint64_t t1 = TimeStamp_Now();
+  MOZTime t1 = MOZ_Now();
   struct rusage usage2;
   getrusage(RUSAGE_THREAD, &usage2);
 
   __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loaded libs in %lldms total, %ldms user, %ldms system, %ld faults",
                       (t1 - t0) / 1000,
                       (usage2.ru_utime.tv_sec - usage1.ru_utime.tv_sec)*1000 + (usage2.ru_utime.tv_usec - usage1.ru_utime.tv_usec)/1000,
                       (usage2.ru_stime.tv_sec - usage1.ru_stime.tv_sec)*1000 + (usage2.ru_stime.tv_usec - usage1.ru_stime.tv_usec)/1000,
                       usage2.ru_majflt-usage1.ru_majflt);
--- a/toolkit/components/startup/StartupTimeline.cpp
+++ b/toolkit/components/startup/StartupTimeline.cpp
@@ -1,67 +1,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "StartupTimeline.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/TimeStamp.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 
-TimeStamp StartupTimeline::sStartupTimeline[StartupTimeline::MAX_EVENT_ID];
+PRTime StartupTimeline::sStartupTimeline[StartupTimeline::MAX_EVENT_ID];
 const char *StartupTimeline::sStartupTimelineDesc[StartupTimeline::MAX_EVENT_ID] = {
 #define mozilla_StartupTimeline_Event(ev, desc) desc,
 #include "StartupTimeline.h"
 #undef mozilla_StartupTimeline_Event
 };
 
-/**
- * Implementation of XRE_StartupTimelineRecord()
- *
- * @param aEvent Same as XRE_StartupTimelineRecord() equivalent argument
- * @param aWhen  Same as XRE_StartupTimelineRecord() equivalent argument
- */
-void
-StartupTimelineRecordExternal(int aEvent, uint64_t aWhen)
-{
-#if XP_WIN
-  TimeStamp ts = TimeStampValue(aWhen, 0, 0);
-#else
-  TimeStamp ts = TimeStampValue(aWhen);
-#endif
-  bool error = false;
-
-  // Since the timestamp comes from an external source validate it before
-  // recording it and log a telemetry error if it appears inconsistent.
-  if (ts < TimeStamp::ProcessCreation(error)) {
-    Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS,
-      (StartupTimeline::Event)aEvent);
-  } else {
-    StartupTimeline::Record((StartupTimeline::Event)aEvent, ts);
-  }
-}
-
 } /* namespace mozilla */
 
 /**
- * The XRE_StartupTimeline_Record function is to be used by embedding
- * applications that can't use mozilla::StartupTimeline::Record() directly.
- *
- * It can create timestamps from arbitrary time values and sanitizies them to
- * ensure that they are not inconsistent with those captured using monotonic
- * timers. The value of aWhen must have been captured using the same timer
- * used by the platform's mozilla::TimeStamp implementation. Erroneous values
- * will be flagged as telemetry errors.
- *
- * @param aEvent The event to be recorded, must correspond to an element of the
- *               mozilla::StartupTimeline::Event enumartion
- * @param aWhen  The time at which the event happened, must have been recorded
- *               using the same timer as the platform's mozilla::TimeStamp
- *               implementation
+ * The XRE_StartupTimeline_Record function is to be used by embedding applications
+ * that can't use mozilla::StartupTimeline::Record() directly.
  */
 void
 XRE_StartupTimelineRecord(int aEvent, PRTime aWhen)
 {
-  mozilla::StartupTimelineRecordExternal(aEvent, aWhen);
+  mozilla::StartupTimeline::Record((mozilla::StartupTimeline::Event) aEvent, aWhen);
 }
+
--- a/toolkit/components/startup/StartupTimeline.h
+++ b/toolkit/components/startup/StartupTimeline.h
@@ -16,17 +16,17 @@ mozilla_StartupTimeline_Event(CREATE_TOP
 mozilla_StartupTimeline_Event(LINKER_INITIALIZED, "linkerInitialized")
 mozilla_StartupTimeline_Event(LIBRARIES_LOADED, "librariesLoaded")
 mozilla_StartupTimeline_Event(FIRST_LOAD_URI, "firstLoadURI")
 #else
 
 #ifndef mozilla_StartupTimeline
 #define mozilla_StartupTimeline
 
-#include "mozilla/TimeStamp.h"
+#include "prtime.h"
 #include "nscore.h"
 #include "GeckoProfiler.h"
 
 #ifdef MOZ_LINKER
 extern "C" {
 /* This symbol is resolved by the custom linker. The function it resolves
  * to dumps some statistics about the linker at the key events recorded
  * by the startup timeline. */
@@ -36,59 +36,58 @@ NS_VISIBILITY_DEFAULT __attribute__((wea
 #else
 
 #endif
 
 namespace mozilla {
 
 void RecordShutdownEndTimeStamp();
 void RecordShutdownStartTimeStamp();
-void StartupTimelineRecordExternal(int, uint64_t);
 
 class StartupTimeline {
 public:
   enum Event {
     #define mozilla_StartupTimeline_Event(ev, z) ev,
     #include "StartupTimeline.h"
     #undef mozilla_StartupTimeline_Event
     MAX_EVENT_ID
   };
 
-  static TimeStamp Get(Event ev) {
+  static PRTime Get(Event ev) {
     return sStartupTimeline[ev];
   }
 
   static const char *Describe(Event ev) {
     return sStartupTimelineDesc[ev];
   }
 
   static void Record(Event ev) {
     PROFILER_MARKER(Describe(ev));
-    Record(ev, TimeStamp::Now());
+    Record(ev, PR_Now());
   }
 
-  static void Record(Event ev, TimeStamp when) {
+  static void Record(Event ev, PRTime when) {
     sStartupTimeline[ev] = when;
 #ifdef MOZ_LINKER
     if (__moz_linker_stats)
       __moz_linker_stats(Describe(ev));
 #endif
   }
 
   static void RecordOnce(Event ev) {
     if (!HasRecord(ev))
       Record(ev);
   }
 
   static bool HasRecord(Event ev) {
-    return !sStartupTimeline[ev].IsNull();
+    return sStartupTimeline[ev];
   }
 
 private:
-  static NS_EXTERNAL_VIS_(TimeStamp) sStartupTimeline[MAX_EVENT_ID];
+  static NS_EXTERNAL_VIS_(PRTime) sStartupTimeline[MAX_EVENT_ID];
   static NS_EXTERNAL_VIS_(const char *) sStartupTimelineDesc[MAX_EVENT_ID];
 };
 
 }
 
 #endif /* mozilla_StartupTimeline */
 
 #endif /* mozilla_StartupTimeline_Event */
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -23,35 +23,72 @@
 #include "nsNativeCharsetUtils.h"
 #include "nsThreadUtils.h"
 #include "nsAutoPtr.h"
 #include "nsStringGlue.h"
 #include "mozilla/Preferences.h"
 #include "GeckoProfiler.h"
 
 #include "prprf.h"
+#include "nsCRT.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShellCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "mozilla/Services.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "prenv.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "mozilla/mozPoisonWrite.h"
 
 #if defined(XP_WIN)
-// Prevent collisions with nsAppStartup::GetStartupInfo()
+#include <windows.h>
+// windows.h can go to hell 
 #undef GetStartupInfo
+#elif defined(XP_UNIX)
+#include <unistd.h>
+#include <sys/syscall.h>
+#endif
+
+#if defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
+  || defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
+#if defined(__DragonFly__) || defined(__FreeBSD__)
+#include <sys/user.h>
 #endif
 
 #include "mozilla/Telemetry.h"
 #include "mozilla/StartupTimeline.h"
 
+#if defined(__NetBSD__)
+#undef KERN_PROC
+#define KERN_PROC KERN_PROC2
+#define KINFO_PROC struct kinfo_proc2
+#else
+#define KINFO_PROC struct kinfo_proc
+#endif
+
+#if defined(XP_MACOSX)
+#define KP_START_SEC kp_proc.p_un.__p_starttime.tv_sec
+#define KP_START_USEC kp_proc.p_un.__p_starttime.tv_usec
+#elif defined(__DragonFly__)
+#define KP_START_SEC kp_start.tv_sec
+#define KP_START_USEC kp_start.tv_usec
+#elif defined(__FreeBSD__)
+#define KP_START_SEC ki_start.tv_sec
+#define KP_START_USEC ki_start.tv_usec
+#else
+#define KP_START_SEC p_ustart_sec
+#define KP_START_USEC p_ustart_usec
+#endif
+
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #define kPrefLastSuccess "toolkit.startup.last_success"
 #define kPrefMaxResumedCrashes "toolkit.startup.max_resumed_crashes"
 #define kPrefRecentCrashes "toolkit.startup.recent_crashes"
 
 #if defined(XP_WIN)
 #include "mozilla/perfprobe.h"
@@ -108,33 +145,16 @@ public:
 
     // We're done "shutting down".
     mService->mShuttingDown = false;
     mService->mRunning = false;
     return NS_OK;
   }
 };
 
-/**
- * Computes an approximation of the absolute time represented by @a stamp
- * which is comparable to those obtained via PR_Now(). If the current absolute
- * time varies a lot (e.g. DST adjustments) since the first call then the
- * resulting times may be inconsistent.
- *
- * @param stamp The timestamp to be converted
- * @returns The converted timestamp
- */
-uint64_t ComputeAbsoluteTimestamp(PRTime prnow, TimeStamp now, TimeStamp stamp)
-{
-  static PRTime sAbsoluteNow = PR_Now();
-  static TimeStamp sMonotonicNow = TimeStamp::Now();
-
-  return sAbsoluteNow - (sMonotonicNow - stamp).ToMicroseconds();
-}
-
 //
 // nsAppStartup
 //
 
 nsAppStartup::nsAppStartup() :
   mConsiderQuitStopper(0),
   mRunning(false),
   mShuttingDown(false),
@@ -357,19 +377,18 @@ nsAppStartup::Quit(uint32_t aMode)
     mozilla::RecordShutdownStartTimeStamp();
     mShuttingDown = true;
     if (!mRestart) {
       mRestart = (aMode & eRestart) != 0;
       gRestartMode = (aMode & 0xF0);
     }
 
     if (mRestart) {
-      /* Firefox-restarts reuse the process so regular process start-time isn't
-         a useful indicator of startup time anymore. */
-      TimeStamp::RecordProcessRestart();
+      // Firefox-restarts reuse the process. Process start-time isn't a useful indicator of startup time
+      PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", (int64_t) PR_Now() / PR_USEC_PER_MSEC));
     }
 
     obsService = mozilla::services::GetObserverService();
 
     if (!mAttemptingQuit) {
       mAttemptingQuit = true;
 #ifdef XP_MACOSX
       // now even the Mac wants to quit when the last window is closed
@@ -641,62 +660,170 @@ nsAppStartup::Observe(nsISupports *aSubj
 #endif //defined(XP_WIN)
   } else {
     NS_ERROR("Unexpected observer topic.");
   }
 
   return NS_OK;
 }
 
+#if defined(LINUX) || defined(ANDROID)
+static uint64_t 
+JiffiesSinceBoot(const char *file)
+{
+  char stat[512];
+  FILE *f = fopen(file, "r");
+  if (!f)
+    return 0;
+  int n = fread(&stat, 1, sizeof(stat) - 1, f);
+  fclose(f);
+  if (n <= 0)
+    return 0;
+  stat[n] = 0;
+  
+  long long unsigned starttime = 0; // instead of uint64_t to keep GCC quiet
+  
+  char *s = strrchr(stat, ')');
+  if (!s)
+    return 0;
+  int ret = sscanf(s + 2,
+                   "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u "
+                   "%*u %*u %*u %*u %*u %*d %*d %*d %*d %llu",
+                   &starttime);
+  if (ret != 1 || !starttime)
+    return 0;
+  return starttime;
+}
+
+static void
+ThreadedCalculateProcessCreationTimestamp(void *aClosure)
+{
+  PR_SetCurrentThreadName("Startup Timer");
+
+  PRTime now = PR_Now();
+  long hz = sysconf(_SC_CLK_TCK);
+  if (!hz)
+    return;
+
+  char thread_stat[40];
+  sprintf(thread_stat, "/proc/self/task/%d/stat", (pid_t) syscall(__NR_gettid));
+  
+  uint64_t thread_jiffies = JiffiesSinceBoot(thread_stat);
+  uint64_t self_jiffies = JiffiesSinceBoot("/proc/self/stat");
+  
+  if (!thread_jiffies || !self_jiffies)
+    return;
+
+  PRTime interval = (thread_jiffies - self_jiffies) * PR_USEC_PER_SEC / hz;
+  StartupTimeline::Record(StartupTimeline::PROCESS_CREATION, now - interval);
+}
+
+static PRTime
+CalculateProcessCreationTimestamp()
+{
+ PRThread *thread = PR_CreateThread(PR_USER_THREAD,
+                                    ThreadedCalculateProcessCreationTimestamp,
+                                    NULL,
+                                    PR_PRIORITY_NORMAL,
+                                    PR_LOCAL_THREAD,
+                                    PR_JOINABLE_THREAD,
+                                    0);
+
+  PR_JoinThread(thread);
+  return StartupTimeline::Get(StartupTimeline::PROCESS_CREATION);
+}
+#elif defined(XP_WIN)
+static PRTime
+CalculateProcessCreationTimestamp()
+{
+  FILETIME start, foo, bar, baz;
+  bool success = GetProcessTimes(GetCurrentProcess(), &start, &foo, &bar, &baz);
+  if (!success)
+    return 0;
+  // copied from NSPR _PR_FileTimeToPRTime
+  uint64_t timestamp = 0;
+  CopyMemory(&timestamp, &start, sizeof(PRTime));
+#ifdef __GNUC__
+  timestamp = (timestamp - 116444736000000000LL) / 10LL;
+#else
+  timestamp = (timestamp - 116444736000000000i64) / 10i64;
+#endif
+  return timestamp;
+}
+#elif defined(XP_MACOSX) || defined(__DragonFly__) || defined(__FreeBSD__) \
+  || defined(__NetBSD__) || defined(__OpenBSD__)
+static PRTime
+CalculateProcessCreationTimestamp()
+{
+  int mib[] = {
+    CTL_KERN,
+    KERN_PROC,
+    KERN_PROC_PID,
+    getpid(),
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+    sizeof(KINFO_PROC),
+    1,
+#endif
+  };
+  u_int miblen = sizeof(mib) / sizeof(mib[0]);
+
+  KINFO_PROC proc;
+  size_t buffer_size = sizeof(proc);
+  if (sysctl(mib, miblen, &proc, &buffer_size, NULL, 0))
+    return 0;
+
+  PRTime starttime = static_cast<PRTime>(proc.KP_START_SEC) * PR_USEC_PER_SEC;
+  starttime += proc.KP_START_USEC;
+  return starttime;
+}
+#else
+static PRTime
+CalculateProcessCreationTimestamp()
+{
+  return 0;
+}
+#endif
+ 
 NS_IMETHODIMP
 nsAppStartup::GetStartupInfo(JSContext* aCx, JS::Value* aRetval)
 {
   JSObject *obj = JS_NewObject(aCx, NULL, NULL, NULL);
   *aRetval = OBJECT_TO_JSVAL(obj);
 
-  TimeStamp procTime = StartupTimeline::Get(StartupTimeline::PROCESS_CREATION);
-  TimeStamp now = TimeStamp::Now();
-  PRTime absNow = PR_Now();
-
-  if (procTime.IsNull()) {
-    bool error = false;
+  PRTime ProcessCreationTimestamp = StartupTimeline::Get(StartupTimeline::PROCESS_CREATION);
 
-    procTime = TimeStamp::ProcessCreation(error);
-
-    if (error) {
-      Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS,
-        StartupTimeline::PROCESS_CREATION);
+  if (!ProcessCreationTimestamp) {
+    PRTime MainTimestamp = StartupTimeline::Get(StartupTimeline::MAIN);
+    char *moz_app_restart = PR_GetEnv("MOZ_APP_RESTART");
+    if (moz_app_restart) {
+      ProcessCreationTimestamp = nsCRT::atoll(moz_app_restart) * PR_USEC_PER_MSEC;
+    } else {
+      ProcessCreationTimestamp = CalculateProcessCreationTimestamp();
     }
-
-    StartupTimeline::Record(StartupTimeline::PROCESS_CREATION, procTime);
+    // Bug 670008 & 689256: Avoid obviously invalid process creation times
+    if ((PR_Now() <= ProcessCreationTimestamp) ||
+        (MainTimestamp && (ProcessCreationTimestamp > MainTimestamp)))
+    {
+      ProcessCreationTimestamp = MainTimestamp ? MainTimestamp : -1;
+      Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, StartupTimeline::PROCESS_CREATION);
+    }
+    StartupTimeline::Record(StartupTimeline::PROCESS_CREATION, ProcessCreationTimestamp);
   }
 
-  for (int i = StartupTimeline::PROCESS_CREATION;
-       i < StartupTimeline::MAX_EVENT_ID;
-       ++i)
-  {
+  for (int i = StartupTimeline::PROCESS_CREATION; i < StartupTimeline::MAX_EVENT_ID; ++i) {
     StartupTimeline::Event ev = static_cast<StartupTimeline::Event>(i);
-    TimeStamp stamp = StartupTimeline::Get(ev);
-
-    if (stamp.IsNull() && (ev == StartupTimeline::MAIN)) {
-      // Always define main to aid with bug 689256.
-      stamp = procTime;
-      MOZ_ASSERT(!stamp.IsNull());
-      Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS,
-        StartupTimeline::MAIN);
-    }
-
-    if (!stamp.IsNull()) {
-      if (stamp >= procTime) {
-        PRTime prStamp = ComputeAbsoluteTimestamp(absNow, now, stamp);
-        JSObject *date = JS_NewDateObjectMsec(aCx, prStamp / PR_USEC_PER_MSEC);
-        JS_DefineProperty(aCx, obj, StartupTimeline::Describe(ev),
-          OBJECT_TO_JSVAL(date), NULL, NULL, JSPROP_ENUMERATE);
+    if (StartupTimeline::Get(ev) > 0) {
+      // always define main to aid with bug 689256
+      if ((ev != StartupTimeline::MAIN) &&
+          (StartupTimeline::Get(ev) < StartupTimeline::Get(StartupTimeline::PROCESS_CREATION))) {
+        Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, i);
+        StartupTimeline::Record(ev, -1);
       } else {
-        Telemetry::Accumulate(Telemetry::STARTUP_MEASUREMENT_ERRORS, ev);
+        JSObject *date = JS_NewDateObjectMsec(aCx, StartupTimeline::Get(ev) / PR_USEC_PER_MSEC);
+        JS_DefineProperty(aCx, obj, StartupTimeline::Describe(ev), OBJECT_TO_JSVAL(date), NULL, NULL, JSPROP_ENUMERATE);
       }
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -823,31 +950,24 @@ nsAppStartup::TrackStartupCrashEnd()
   if (mStartupCrashTrackingEnded || (mIsSafeModeNecessary && !inSafeMode))
     return NS_OK;
   mStartupCrashTrackingEnded = true;
 
   StartupTimeline::Record(StartupTimeline::STARTUP_CRASH_DETECTION_END);
 
   // Use the timestamp of XRE_main as an approximation for the lock file timestamp.
   // See MAX_STARTUP_BUFFER for the buffer time period.
-  TimeStamp mainTime = StartupTimeline::Get(StartupTimeline::MAIN);
-  TimeStamp now = TimeStamp::Now();
-  PRTime prNow = PR_Now();
   nsresult rv;
-
-  if (mainTime.IsNull()) {
+  PRTime mainTime = StartupTimeline::Get(StartupTimeline::MAIN);
+  if (mainTime <= 0) {
     NS_WARNING("Could not get StartupTimeline::MAIN time.");
   } else {
-    uint64_t lockFileTime = ComputeAbsoluteTimestamp(prNow, now, mainTime);
-
-    rv = Preferences::SetInt(kPrefLastSuccess,
-      (int32_t)(lockFileTime / PR_USEC_PER_SEC));
-
-    if (NS_FAILED(rv))
-      NS_WARNING("Could not set startup crash detection pref.");
+    int32_t lockFileTime = (int32_t)(mainTime / PR_USEC_PER_SEC);
+    rv = Preferences::SetInt(kPrefLastSuccess, lockFileTime);
+    if (NS_FAILED(rv)) NS_WARNING("Could not set startup crash detection pref.");
   }
 
   if (inSafeMode && mIsSafeModeNecessary) {
     // On a successful startup in automatic safe mode, allow the user one more crash
     // in regular mode before returning to safe mode.
     int32_t maxResumedCrashes = 0;
     int32_t prefType;
     rv = Preferences::GetDefaultRootBranch()->GetPrefType(kPrefMaxResumedCrashes, &prefType);
--- a/xpcom/ds/TimeStamp.h
+++ b/xpcom/ds/TimeStamp.h
@@ -224,38 +224,16 @@ public:
    *
    * NowLoRes() has been introduced to workaround performance problems of
    * QueryPerformanceCounter on the Windows platform.  NowLoRes() is giving
    * lower precision, usually 15.6 ms, but with very good performance benefit.
    * Use it for measurements of longer times, like >200ms timeouts.
    */
   static TimeStamp Now() { return Now(true); }
   static TimeStamp NowLoRes() { return Now(false); }
-
-  /**
-   * Return a timestamp representing the time when the current process was
-   * created which will be comparable with other timestamps taken with this
-   * class. If the actual process creation time is detected to be inconsistent
-   * the @a aIsInconsistent parameter will be set to true, the returned
-   * timestamp however will still be valid though inaccurate.
-   *
-   * @param aIsInconsistent Set to true if an inconsistency was detected in the
-   * process creation time
-   * @returns A timestamp representing the time when the process was created,
-   * this timestamp is always valid even when errors are reported
-   */
-  static TimeStamp ProcessCreation(bool& aIsInconsistent);
-
-  /**
-   * Records a process restart. After this call ProcessCreation() will return
-   * the time when the browser was restarted instead of the actual time when
-   * the process was created.
-   */
-  static void RecordProcessRestart();
-
   /**
    * Compute the difference between two timestamps. Both must be non-null.
    */
   TimeDuration operator-(const TimeStamp& aOther) const {
     MOZ_ASSERT(!IsNull(), "Cannot compute with a null value");
     MOZ_ASSERT(!aOther.IsNull(), "Cannot compute with aOther null value");
     PR_STATIC_ASSERT(-INT64_MAX > INT64_MIN);
     int64_t ticks = int64_t(mValue - aOther.mValue);
@@ -328,17 +306,16 @@ public:
   // two TimeStamps, or scaling TimeStamps, is nonsense and must never
   // be allowed.
 
   static NS_HIDDEN_(nsresult) Startup();
   static NS_HIDDEN_(void) Shutdown();
 
 private:
   friend struct IPC::ParamTraits<mozilla::TimeStamp>;
-  friend void StartupTimelineRecordExternal(int, uint64_t);
 
   TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
 
   static TimeStamp Now(bool aHighResolution);
 
   /**
    * When built with PRIntervalTime, a value of 0 means this instance
    * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
@@ -348,26 +325,13 @@ private:
    * 
    * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
    * time to wrap around is about 2^64/100000 seconds, i.e. about
    * 5,849,424 years.
    *
    * When using a system clock, a value is system dependent.
    */
   TimeStampValue mValue;
-
-  /**
-   * First timestamp taken when the class static initializers are run. This
-   * timestamp is used to sanitize timestamps coming from different sources.
-   */
-  static TimeStamp sFirstTimeStamp;
-
-  /**
-   * Timestamp representing the time when the process was created. This field
-   * is populated lazily the first time this information is required and is
-   * replaced every time the process is restarted.
-   */
-  static TimeStamp sProcessCreation;
 };
 
 }
 
 #endif /* mozilla_TimeStamp_h */
--- a/xpcom/ds/TimeStamp_darwin.cpp
+++ b/xpcom/ds/TimeStamp_darwin.cpp
@@ -12,32 +12,26 @@
 //
 // This code is inspired by Chromium's time_mac.cc. The biggest
 // differences are that we explicitly initialize using
 // TimeStamp::Initialize() instead of lazily in Now() and that
 // we store the time value in ticks and convert when needed instead
 // of storing the time value in nanoseconds.
 
 #include <mach/mach_time.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/sysctl.h>
 #include <time.h>
 
 #include "mozilla/TimeStamp.h"
-#include "nsCRT.h"
-#include "prenv.h"
-#include "prprf.h"
 
 // Estimate of the smallest duration of time we can measure.
 static uint64_t sResolution;
 static uint64_t sResolutionSigDigs;
 
+static const uint16_t kNsPerUs   =       1000;
 static const uint64_t kNsPerMs   =    1000000;
-static const uint64_t kUsPerSec  =    1000000;
 static const uint64_t kNsPerSec  = 1000000000;
 static const double kNsPerMsd    =    1000000.0;
 static const double kNsPerSecd   = 1000000000.0;
 
 static bool gInitialized = false;
 static double sNsPerTick;
 
 static uint64_t
@@ -78,19 +72,16 @@ ClockResolutionNs()
     minres = 1 * kNsPerMs;
   }
 
   return minres;
 }
 
 namespace mozilla {
 
-TimeStamp TimeStamp::sFirstTimeStamp;
-TimeStamp TimeStamp::sProcessCreation;
-
 double
 TimeDuration::ToSeconds() const
 {
   NS_ABORT_IF_FALSE(gInitialized, "calling TimeDuration too early");
   return (mValue * sNsPerTick) / kNsPerSecd;
 }
 
 double
@@ -151,103 +142,23 @@ TimeStamp::Startup()
   // find the number of significant digits in sResolution, for the
   // sake of ToSecondsSigDigits()
   for (sResolutionSigDigs = 1;
        !(sResolutionSigDigs == sResolution
          || 10*sResolutionSigDigs > sResolution);
        sResolutionSigDigs *= 10);
 
   gInitialized = true;
-  sFirstTimeStamp = TimeStamp::Now();
-  sProcessCreation = TimeStamp();
-
   return NS_OK;
 }
 
 void
 TimeStamp::Shutdown()
 {
 }
 
 TimeStamp
 TimeStamp::Now(bool aHighResolution)
 {
   return TimeStamp(ClockTime());
 }
 
-// Computes and returns the process uptime in microseconds.
-// Returns 0 if an error was encountered.
-
-static uint64_t
-ComputeProcessUptime()
-{
-  struct timeval tv;
-  int rv = gettimeofday(&tv, NULL);
-
-  if (rv == -1) {
-    return 0;
-  }
-
-  int mib[] = {
-    CTL_KERN,
-    KERN_PROC,
-    KERN_PROC_PID,
-    getpid(),
-  };
-  u_int mibLen = sizeof(mib) / sizeof(mib[0]);
-
-  struct kinfo_proc proc;
-  size_t bufferSize = sizeof(proc);
-  rv = sysctl(mib, mibLen, &proc, &bufferSize, NULL, 0);
-
-  if (rv == -1)
-    return 0;
-
-  uint64_t startTime =
-    ((uint64_t)proc.kp_proc.p_un.__p_starttime.tv_sec * kUsPerSec) +
-    proc.kp_proc.p_un.__p_starttime.tv_usec;
-  uint64_t now = (tv.tv_sec * kUsPerSec) + tv.tv_usec;
-
-  if (startTime > now)
-    return 0;
-
-  return now - startTime;
 }
-
-TimeStamp
-TimeStamp::ProcessCreation(bool& aIsInconsistent)
-{
-  aIsInconsistent = false;
-
-  if (sProcessCreation.IsNull()) {
-    char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
-    TimeStamp ts;
-
-    if (mozAppRestart) {
-      ts = TimeStamp(nsCRT::atoll(mozAppRestart));
-    } else {
-      TimeStamp now = TimeStamp::Now();
-      uint64_t uptime = ComputeProcessUptime();
-
-      ts = now - TimeDuration::FromMicroseconds(uptime);
-
-      if ((ts > sFirstTimeStamp) || (uptime == 0)) {
-        // If the process creation timestamp was inconsistent replace it with the
-        // first one instead and notify that a telemetry error was detected.
-        aIsInconsistent = true;
-        ts = sFirstTimeStamp;
-      }
-    }
-
-    sProcessCreation = ts;
-  }
-
-  return sProcessCreation;
-}
-
-void
-TimeStamp::RecordProcessRestart()
-{
-  PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ClockTime()));
-  sProcessCreation = TimeStamp();
-}
-
-}
--- a/xpcom/ds/TimeStamp_posix.cpp
+++ b/xpcom/ds/TimeStamp_posix.cpp
@@ -8,54 +8,19 @@
 // Implement TimeStamp::Now() with POSIX clocks.
 //
 // The "tick" unit for POSIX clocks is simply a nanosecond, as this is
 // the smallest unit of time representable by struct timespec.  That
 // doesn't mean that a nanosecond is the resolution of TimeDurations
 // obtained with this API; see TimeDuration::Resolution;
 //
 
-#include <sys/syscall.h>
 #include <time.h>
-#include <unistd.h>
-
-#if defined(__DragonFly__) || defined(__FreeBSD__) \
-    || defined(__NetBSD__) || defined(__OpenBSD__)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#endif
-
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-#include <sys/user.h>
-#endif
-
-#if defined(__NetBSD__)
-#undef KERN_PROC
-#define KERN_PROC KERN_PROC2
-#define KINFO_PROC struct kinfo_proc2
-#else
-#define KINFO_PROC struct kinfo_proc
-#endif
-
-#if defined(__DragonFly__)
-#define KP_START_SEC kp_start.tv_sec
-#define KP_START_USEC kp_start.tv_usec
-#elif defined(__FreeBSD__)
-#define KP_START_SEC ki_start.tv_sec
-#define KP_START_USEC ki_start.tv_usec
-#else
-#define KP_START_SEC p_ustart_sec
-#define KP_START_USEC p_ustart_usec
-#endif
 
 #include "mozilla/TimeStamp.h"
-#include "nsCRT.h"
-#include "prenv.h"
-#include "prprf.h"
-#include "prthread.h"
 
 // Estimate of the smallest duration of time we can measure.
 static uint64_t sResolution;
 static uint64_t sResolutionSigDigs;
 
 static const uint16_t kNsPerUs   =       1000;
 static const uint64_t kNsPerMs   =    1000000;
 static const uint64_t kNsPerSec  = 1000000000; 
@@ -125,21 +90,19 @@ ClockResolutionNs()
     // clock_getres probably failed.  fall back on NSPR's resolution
     // assumption
     minres = 1 * kNsPerMs;
   }
 
   return minres;
 }
 
+
 namespace mozilla {
 
-TimeStamp TimeStamp::sFirstTimeStamp;
-TimeStamp TimeStamp::sProcessCreation;
-
 double
 TimeDuration::ToSeconds() const
 {
   return double(mValue) / kNsPerSecd;
 }
 
 double
 TimeDuration::ToSecondsSigDigits() const
@@ -191,209 +154,23 @@ TimeStamp::Startup()
   // find the number of significant digits in sResolution, for the
   // sake of ToSecondsSigDigits()
   for (sResolutionSigDigs = 1;
        !(sResolutionSigDigs == sResolution
          || 10*sResolutionSigDigs > sResolution);
        sResolutionSigDigs *= 10);
 
   gInitialized = true;
-  sFirstTimeStamp = TimeStamp::Now();
-  sProcessCreation = TimeStamp();
-
   return NS_OK;
 }
 
 void
 TimeStamp::Shutdown()
 {
 }
 
 TimeStamp
 TimeStamp::Now(bool aHighResolution)
 {
   return TimeStamp(ClockTimeNs());
 }
 
-#if defined(LINUX) || defined(ANDROID)
-
-// Calculates the amount of jiffies that have elapsed since boot and up to the
-// starttime value of a specific process as found in its /proc/*/stat file.
-// Returns 0 if an error occurred.
-
-static uint64_t
-JiffiesSinceBoot(const char *aFile)
-{
-  char stat[512];
-
-  FILE *f = fopen(aFile, "r");
-  if (!f)
-    return 0;
-
-  int n = fread(&stat, 1, sizeof(stat) - 1, f);
-
-  fclose(f);
-
-  if (n <= 0)
-    return 0;
-
-  stat[n] = 0;
-
-  long long unsigned startTime = 0; // instead of uint64_t to keep GCC quiet
-  char *s = strrchr(stat, ')');
-
-  if (!s)
-    return 0;
-
-  int rv = sscanf(s + 2,
-                  "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u "
-                  "%*u %*u %*u %*d %*d %*d %*d %*d %*d %llu",
-                  &startTime);
-
-  if (rv != 1 || !startTime)
-    return 0;
-
-  return startTime;
 }
-
-// Computes the interval that has elapsed between the thread creation and the
-// process creation by comparing the starttime fields in the respective
-// /proc/*/stat files. The resulting value will be a good approximation of the
-// process uptime. This value will be stored at the address pointed by aTime;
-// if an error occurred 0 will be stored instead.
-
-static void
-ComputeProcessUptimeThread(void *aTime)
-{
-  uint64_t *uptime = static_cast<uint64_t *>(aTime);
-  long hz = sysconf(_SC_CLK_TCK);
-
-  *uptime = 0;
-
-  if (!hz)
-    return;
-
-  char threadStat[40];
-  sprintf(threadStat, "/proc/self/task/%d/stat", (pid_t) syscall(__NR_gettid));
-
-  uint64_t threadJiffies = JiffiesSinceBoot(threadStat);
-  uint64_t selfJiffies = JiffiesSinceBoot("/proc/self/stat");
-
-  if (!threadJiffies || !selfJiffies)
-    return;
-
-  *uptime = ((threadJiffies - selfJiffies) * kNsPerSec) / hz;
-}
-
-// Computes and returns the process uptime in ns on Linux & its derivatives.
-// Returns 0 if an error was encountered.
-
-static uint64_t
-ComputeProcessUptime()
-{
-  uint64_t uptime = 0;
-  PRThread *thread = PR_CreateThread(PR_USER_THREAD,
-                                     ComputeProcessUptimeThread,
-                                     &uptime,
-                                     PR_PRIORITY_NORMAL,
-                                     PR_LOCAL_THREAD,
-                                     PR_JOINABLE_THREAD,
-                                     0);
-
-  PR_JoinThread(thread);
-
-  return uptime;
-}
-
-#elif defined(__DragonFly__) || defined(__FreeBSD__) \
-      || defined(__NetBSD__) || defined(__OpenBSD__)
-
-// Computes and returns the process uptime in ns on various BSD flavors.
-// Returns 0 if an error was encountered.
-
-static uint64_t
-ComputeProcessUptime()
-{
-  struct timespec ts;
-  int rv = clock_gettime(CLOCK_REALTIME, &ts);
-
-  if (rv == -1) {
-    return 0;
-  }
-
-  int mib[] = {
-    CTL_KERN,
-    KERN_PROC,
-    KERN_PROC_PID,
-    getpid(),
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-    sizeof(KINFO_PROC),
-    1,
-#endif
-  };
-  u_int mibLen = sizeof(mib) / sizeof(mib[0]);
-
-  KINFO_PROC proc;
-  size_t bufferSize = sizeof(proc);
-  rv = sysctl(mib, mibLen, &proc, &bufferSize, NULL, 0);
-
-  if (rv == -1)
-    return 0;
-
-  uint64_t startTime = ((uint64_t)proc.KP_START_SEC * kNsPerSec)
-    + (proc.KP_START_USEC * kNsPerUs);
-  uint64_t now = ((uint64_t)ts.tv_sec * kNsPerSec) + ts.tv_nsec;
-
-  if (startTime > now)
-    return 0;
-
-  return (now - startTime);
-}
-
-#else
-
-static uint64_t
-ComputeProcessUptime()
-{
-  return 0;
-}
-
-#endif
-
-TimeStamp
-TimeStamp::ProcessCreation(bool& aIsInconsistent)
-{
-  aIsInconsistent = false;
-
-  if (sProcessCreation.IsNull()) {
-    char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
-    TimeStamp ts;
-
-    if (mozAppRestart) {
-      ts = TimeStamp(nsCRT::atoll(mozAppRestart));
-    } else {
-      TimeStamp now = TimeStamp::Now();
-      uint64_t uptime = ComputeProcessUptime();
-
-      ts = now - TimeDuration::FromMicroseconds(uptime / 1000);
-
-      if ((ts > sFirstTimeStamp) || (uptime == 0)) {
-        // If the process creation timestamp was inconsistent replace it with the
-        // first one instead and notify that a telemetry error was detected.
-        aIsInconsistent = true;
-        ts = sFirstTimeStamp;
-      }
-    }
-
-    sProcessCreation = ts;
-  }
-
-  return sProcessCreation;
-}
-
-void
-TimeStamp::RecordProcessRestart()
-{
-  PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ClockTimeNs()));
-  sProcessCreation = TimeStamp();
-}
-
-}
--- a/xpcom/ds/TimeStamp_windows.cpp
+++ b/xpcom/ds/TimeStamp_windows.cpp
@@ -11,20 +11,17 @@
 // before this reaches the Release or even Beta channel.
 #define FORCE_PR_LOG
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include <windows.h>
 
-#include "nsCRT.h"
 #include "prlog.h"
-#include "prenv.h"
-#include "prprf.h"
 #include <stdio.h>
 
 #include <intrin.h>
 
 #if defined(PR_LOGGING)
 // Log module for mozilla::TimeStamp for Windows logging...
 //
 // To enable logging (see prlog.h for full details):
@@ -160,19 +157,16 @@ static CRITICAL_SECTION sTimeStampLock;
 static DWORD sLastGTCResult = 0;
 
 // Higher part of the 64-bit value of MozGetTickCount64,
 // incremented atomically.
 static DWORD sLastGTCRollover = 0;
 
 namespace mozilla {
 
-TimeStamp TimeStamp::sFirstTimeStamp;
-TimeStamp TimeStamp::sProcessCreation;
-
 typedef ULONGLONG (WINAPI* GetTickCount64_t)();
 static GetTickCount64_t sGetTickCount64 = nullptr;
 
 // ----------------------------------------------------------------------------
 // Critical Section helper class
 // ----------------------------------------------------------------------------
 
 class AutoCriticalSection
@@ -528,18 +522,16 @@ TimeStamp::Startup()
     return NS_OK;
   }
 
   sFrequencyPerSec = freq.QuadPart;
   LOG(("TimeStamp: QPC frequency=%llu", sFrequencyPerSec));
 
   InitThresholds();
   InitResolution();
-  sFirstTimeStamp = TimeStamp::Now();
-  sProcessCreation = TimeStamp();
 
   return NS_OK;
 }
 
 void
 TimeStamp::Shutdown()
 {
   DeleteCriticalSection(&sTimeStampLock);
@@ -552,79 +544,9 @@ TimeStamp::Now(bool aHighResolution)
   bool useQPC = (aHighResolution && sUseQPC);
 
   // Both values are in [mt] units.
   ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
   ULONGLONG GTC = ms2mt(sGetTickCount64());
   return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
 }
 
-// Computes and returns the current process uptime in microseconds.
-// Returns 0 if an error was encountered while computing the uptime.
-
-static uint64_t
-ComputeProcessUptime()
-{
-  SYSTEMTIME nowSys;
-  GetSystemTime(&nowSys);
-
-  FILETIME now;
-  bool success = SystemTimeToFileTime(&nowSys, &now);
-
-  if (!success)
-    return 0;
-
-  FILETIME start, foo, bar, baz;
-  success = GetProcessTimes(GetCurrentProcess(), &start, &foo, &bar, &baz);
-
-  if (!success)
-    return 0;
-
-  ULARGE_INTEGER startUsec = {
-    start.dwLowDateTime,
-    start.dwHighDateTime
-  };
-  ULARGE_INTEGER nowUsec = {
-    now.dwLowDateTime,
-    now.dwHighDateTime
-  };
-
-  return (nowUsec.QuadPart - startUsec.QuadPart) / 10ULL;
-}
-
-TimeStamp
-TimeStamp::ProcessCreation(bool& aIsInconsistent)
-{
-  aIsInconsistent = false;
-
-  if (sProcessCreation.IsNull()) {
-    char *mozAppRestart = PR_GetEnv("MOZ_APP_RESTART");
-    TimeStamp ts;
-
-    if (mozAppRestart) {
-      ts = TimeStamp(TimeStampValue(nsCRT::atoll(mozAppRestart), 0, false));
-    } else {
-      TimeStamp now = TimeStamp::Now();
-      uint64_t uptime = ComputeProcessUptime();
-      ts = now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
-
-      if ((ts > sFirstTimeStamp) || (uptime == 0)) {
-        // If the process creation timestamp was inconsistent replace it with the
-        // first one instead and notify that a telemetry error was detected.
-        aIsInconsistent = true;
-        ts = sFirstTimeStamp;
-      }
-    }
-
-    sProcessCreation = ts;
-  }
-
-  return sProcessCreation;
-}
-
-void
-TimeStamp::RecordProcessRestart()
-{
-  PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", ms2mt(sGetTickCount64())));
-  sProcessCreation = TimeStamp();
-}
-
 } // namespace mozilla
--- a/xpcom/ds/TimeStamp_windows.h
+++ b/xpcom/ds/TimeStamp_windows.h
@@ -10,17 +10,16 @@
 namespace mozilla {
 
 class TimeStamp;
 
 class TimeStampValue
 {
   friend struct IPC::ParamTraits<mozilla::TimeStampValue>;
   friend class TimeStamp;
-  friend void StartupTimelineRecordExternal(int, uint64_t);
 
   // Both QPC and GTC are kept in [mt] units.
   uint64_t mGTC;
   uint64_t mQPC;
   bool mHasQPC;
   bool mIsNull;
 
   TimeStampValue(uint64_t GTC, uint64_t QPC, bool hasQPC);