Bug 1516578 Part 1 - Merge HitCheckpoint and HitBreakpoint messages, r=mccr8.
☠☠ backed out by 9e3564442734 ☠ ☠
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 27 Dec 2018 13:24:55 -1000
changeset 453652 cf0578ce6aa3
parent 453637 5d5711d0125d
child 453653 0426a61d27a9
push id35365
push userdvarga@mozilla.com
push dateSun, 13 Jan 2019 10:05:55 +0000
treeherdermozilla-central@1218e374fbc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1516578
milestone66.0a1
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
Bug 1516578 Part 1 - Merge HitCheckpoint and HitBreakpoint messages, r=mccr8.
toolkit/recordreplay/ipc/Channel.cpp
toolkit/recordreplay/ipc/Channel.h
toolkit/recordreplay/ipc/ChildIPC.cpp
toolkit/recordreplay/ipc/ChildInternal.h
toolkit/recordreplay/ipc/ChildNavigation.cpp
--- a/toolkit/recordreplay/ipc/Channel.cpp
+++ b/toolkit/recordreplay/ipc/Channel.cpp
@@ -232,28 +232,25 @@ Message* Channel::WaitForMessage() {
 
 void Channel::PrintMessage(const char* aPrefix, const Message& aMsg) {
   if (!SpewEnabled()) {
     return;
   }
   AutoEnsurePassThroughThreadEvents pt;
   nsCString data;
   switch (aMsg.mType) {
-    case MessageType::HitCheckpoint: {
-      const HitCheckpointMessage& nmsg = (const HitCheckpointMessage&)aMsg;
-      data.AppendPrintf("Id %d Endpoint %d Duration %.2f ms",
-                        (int)nmsg.mCheckpointId, nmsg.mRecordingEndpoint,
+    case MessageType::HitExecutionPoint: {
+      const HitExecutionPointMessage& nmsg =
+        (const HitExecutionPointMessage&)aMsg;
+      nmsg.mPoint.ToString(data);
+      data.AppendPrintf(" Endpoint %d Duration %.2f ms",
+                        nmsg.mRecordingEndpoint,
                         nmsg.mDurationMicroseconds / 1000.0);
       break;
     }
-    case MessageType::HitBreakpoint: {
-      const HitBreakpointMessage& nmsg = (const HitBreakpointMessage&)aMsg;
-      data.AppendPrintf("Endpoint %d", nmsg.mRecordingEndpoint);
-      break;
-    }
     case MessageType::Resume: {
       const ResumeMessage& nmsg = (const ResumeMessage&)aMsg;
       data.AppendPrintf("Forward %d", nmsg.mForward);
       break;
     }
     case MessageType::RestoreCheckpoint: {
       const RestoreCheckpointMessage& nmsg =
           (const RestoreCheckpointMessage&)aMsg;
--- a/toolkit/recordreplay/ipc/Channel.h
+++ b/toolkit/recordreplay/ipc/Channel.h
@@ -71,18 +71,18 @@ namespace recordreplay {
   _Macro(CreateCheckpoint)                                     \
                                                                \
   /* Debugger JSON messages are initially sent from the parent. The child unpauses */ \
   /* after receiving the message and will pause after it sends a DebuggerResponse. */ \
   _Macro(DebuggerRequest)                                      \
                                                                \
   /* Add a breakpoint position to stop at. Because a single entry point is used for */ \
   /* calling into the ReplayDebugger after pausing, the set of breakpoints is simply */ \
-  /* a set of positions at which the child process should pause and send a HitBreakpoint */ \
-  /* message. */                                               \
+  /* a set of positions at which the child process should pause and send a */ \
+  /* HitExecutionPoint message. */                             \
   _Macro(AddBreakpoint)                                        \
                                                                \
   /* Clear all installed breakpoints. */                       \
   _Macro(ClearBreakpoints)                                     \
                                                                \
   /* Unpause the child and play execution either to the next point when a */ \
   /* breakpoint is hit, or to the next checkpoint. Resumption may be either */ \
   /* forward or backward. */                                   \
@@ -121,20 +121,18 @@ namespace recordreplay {
                                                                \
   /* Sent when a fatal error has occurred, but before the minidump has been */ \
   /* generated. */                                             \
   _Macro(BeginFatalError)                                      \
                                                                \
   /* The child's graphics were repainted. */                   \
   _Macro(Paint)                                                \
                                                                \
-  /* Notify the middleman that a checkpoint or breakpoint was hit. */ \
-  /* The child will pause after sending these messages. */     \
-  _Macro(HitCheckpoint)                                        \
-  _Macro(HitBreakpoint)                                        \
+  /* Notify the middleman that the child has hit an execution point and paused. */ \
+  _Macro(HitExecutionPoint)                                    \
                                                                \
   /* Send a response to a DebuggerRequest message. */          \
   _Macro(DebuggerResponse)                                     \
                                                                \
   /* Call a system function from the middleman process which the child has */ \
   /* encountered after diverging from the recording. */        \
   _Macro(MiddlemanCallRequest)                                 \
                                                                \
@@ -376,40 +374,36 @@ struct PaintMessage : public Message {
 
   PaintMessage(uint32_t aCheckpointId, uint32_t aWidth, uint32_t aHeight)
       : Message(MessageType::Paint, sizeof(*this)),
         mCheckpointId(aCheckpointId),
         mWidth(aWidth),
         mHeight(aHeight) {}
 };
 
-struct HitCheckpointMessage : public Message {
-  uint32_t mCheckpointId;
+struct HitExecutionPointMessage : public Message {
+  // The point the child paused at.
+  js::ExecutionPoint mPoint;
+
+  // Whether the pause occurred due to hitting the end of the recording.
   bool mRecordingEndpoint;
 
-  // When recording, the amount of non-idle time taken to get to this
-  // checkpoint from the previous one.
+  // The amount of non-idle time taken to get to this pause from the last time
+  // the child paused.
   double mDurationMicroseconds;
 
-  HitCheckpointMessage(uint32_t aCheckpointId, bool aRecordingEndpoint,
-                       double aDurationMicroseconds)
-      : Message(MessageType::HitCheckpoint, sizeof(*this)),
-        mCheckpointId(aCheckpointId),
+  HitExecutionPointMessage(const js::ExecutionPoint& aPoint,
+                           bool aRecordingEndpoint,
+                           double aDurationMicroseconds)
+      : Message(MessageType::HitExecutionPoint, sizeof(*this)),
+        mPoint(aPoint),
         mRecordingEndpoint(aRecordingEndpoint),
         mDurationMicroseconds(aDurationMicroseconds) {}
 };
 
-struct HitBreakpointMessage : public Message {
-  bool mRecordingEndpoint;
-
-  explicit HitBreakpointMessage(bool aRecordingEndpoint)
-      : Message(MessageType::HitBreakpoint, sizeof(*this)),
-        mRecordingEndpoint(aRecordingEndpoint) {}
-};
-
 typedef EmptyMessage<MessageType::AlwaysMarkMajorCheckpoints>
     AlwaysMarkMajorCheckpointsMessage;
 
 template <MessageType Type>
 struct BinaryMessage : public Message {
   explicit BinaryMessage(uint32_t aSize) : Message(Type, aSize) {}
 
   const char* BinaryData() const { return Data<BinaryMessage<Type>, char>(); }
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -289,17 +289,17 @@ void InitRecordingOrReplayingProcess(int
   // performed by another child.
   AddInitialUntrackedMemoryRegion((uint8_t*)gGraphicsShmem,
                                   parent::GraphicsMemorySize);
 
   pt.reset();
 
   // We are ready to receive initialization messages from the middleman, pause
   // so they can be sent.
-  HitCheckpoint(CheckpointId::Invalid, /* aRecordingEndpoint = */ false);
+  HitExecutionPoint(js::ExecutionPoint(), /* aRecordingEndpoint = */ false);
 
   // If we failed to initialize then report it to the user.
   if (gInitializationFailureMessage) {
     ReportFatalError(Nothing(), "%s", gInitializationFailureMessage);
     Unreachable();
   }
 
   // Process the introduction message to fill in arguments.
@@ -629,69 +629,63 @@ void Repaint(size_t* aWidth, size_t* aHe
 bool CurrentRepaintCannotFail() {
   return gRepainting && !gAllowRepaintFailures;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Checkpoint Messages
 ///////////////////////////////////////////////////////////////////////////////
 
-// The time when the last HitCheckpoint message was sent.
-static double gLastCheckpointTime;
+// The time when the last HitExecutionPoint message was sent.
+static double gLastPauseTime;
 
 // When recording and we are idle, the time when we became idle.
 static double gIdleTimeStart;
 
 void BeginIdleTime() {
   MOZ_RELEASE_ASSERT(IsRecording() && NS_IsMainThread() && !gIdleTimeStart);
   gIdleTimeStart = CurrentTime();
 }
 
 void EndIdleTime() {
   MOZ_RELEASE_ASSERT(IsRecording() && NS_IsMainThread() && gIdleTimeStart);
 
   // Erase the idle time from our measurements by advancing the last checkpoint
   // time.
-  gLastCheckpointTime += CurrentTime() - gIdleTimeStart;
+  gLastPauseTime += CurrentTime() - gIdleTimeStart;
   gIdleTimeStart = 0;
 }
 
-void HitCheckpoint(size_t aId, bool aRecordingEndpoint) {
+void HitExecutionPoint(const js::ExecutionPoint& aPoint,
+                       bool aRecordingEndpoint) {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   double time = CurrentTime();
   PauseMainThreadAndInvokeCallback([=]() {
     double duration = 0;
-    if (aId > CheckpointId::First) {
-      duration = time - gLastCheckpointTime;
+    if (gLastPauseTime) {
+      duration = time - gLastPauseTime;
       MOZ_RELEASE_ASSERT(duration > 0);
     }
     gChannel->SendMessage(
-        HitCheckpointMessage(aId, aRecordingEndpoint, duration));
+        HitExecutionPointMessage(aPoint, aRecordingEndpoint, duration));
   });
-  gLastCheckpointTime = time;
+  gLastPauseTime = time;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Message Helpers
 ///////////////////////////////////////////////////////////////////////////////
 
 void RespondToRequest(const js::CharBuffer& aBuffer) {
   DebuggerResponseMessage* msg =
       DebuggerResponseMessage::New(aBuffer.begin(), aBuffer.length());
   gChannel->SendMessage(*msg);
   free(msg);
 }
 
-void HitBreakpoint(bool aRecordingEndpoint) {
-  MOZ_RELEASE_ASSERT(NS_IsMainThread());
-  PauseMainThreadAndInvokeCallback([=]() {
-    gChannel->SendMessage(HitBreakpointMessage(aRecordingEndpoint));
-  });
-}
-
 void SendMiddlemanCallRequest(const char* aInputData, size_t aInputSize,
                               InfallibleVector<char>* aOutputData) {
   AutoPassThroughThreadEvents pt;
   MonitorAutoLock lock(*gMonitor);
 
   while (gWaitingForCallResponse) {
     gMonitor->Wait();
   }
--- a/toolkit/recordreplay/ipc/ChildInternal.h
+++ b/toolkit/recordreplay/ipc/ChildInternal.h
@@ -82,18 +82,17 @@ void AfterCheckpoint(const CheckpointId&
 size_t LastNormalCheckpoint();
 
 }  // namespace navigation
 
 namespace child {
 
 // IPC activity that can be triggered by navigation.
 void RespondToRequest(const js::CharBuffer& aBuffer);
-void HitCheckpoint(size_t aId, bool aRecordingEndpoint);
-void HitBreakpoint(bool aRecordingEndpoint);
+void HitExecutionPoint(const js::ExecutionPoint& aPoint, bool aRecordingEndpoint);
 
 // Optional information about a crash that occurred. If not provided to
 // ReportFatalError, the current thread will be treated as crashed.
 struct MinidumpInfo {
   int mExceptionType;
   int mCode;
   int mSubcode;
   mach_port_t mThread;
--- a/toolkit/recordreplay/ipc/ChildNavigation.cpp
+++ b/toolkit/recordreplay/ipc/ChildNavigation.cpp
@@ -489,30 +489,26 @@ void PausedPhase::Enter(const ExecutionP
   gNavigation->SetPhase(this);
 
   if (aRewind) {
     MOZ_RELEASE_ASSERT(!aPoint.HasPosition());
     RestoreCheckpointAndResume(CheckpointId(aPoint.mCheckpoint));
     Unreachable();
   }
 
-  if (aPoint.HasPosition()) {
-    child::HitBreakpoint(aRecordingEndpoint);
-  } else {
-    child::HitCheckpoint(aPoint.mCheckpoint, aRecordingEndpoint);
-  }
+  child::HitExecutionPoint(aPoint, aRecordingEndpoint);
 }
 
 void PausedPhase::AfterCheckpoint(const CheckpointId& aCheckpoint) {
   MOZ_RELEASE_ASSERT(!mRecoveringFromDivergence);
   if (!aCheckpoint.mTemporary) {
     // We just rewound here, and are now where we should pause.
     MOZ_RELEASE_ASSERT(
         mPoint == gNavigation->CheckpointExecutionPoint(aCheckpoint.mNormal));
-    child::HitCheckpoint(mPoint.mCheckpoint, mRecordingEndpoint);
+    child::HitExecutionPoint(mPoint, mRecordingEndpoint);
   } else {
     // We just saved or restored the temporary checkpoint taken while
     // processing debugger requests here.
     MOZ_RELEASE_ASSERT(ThisProcessCanRewind());
     MOZ_RELEASE_ASSERT(mSavedTemporaryCheckpoint);
   }
 }