Source/JavaScriptCore:
authorburg@cs.washington.edu <burg@cs.washington.edu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2014 21:59:13 +0000 (21:59 +0000)
committerburg@cs.washington.edu <burg@cs.washington.edu@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2014 21:59:13 +0000 (21:59 +0000)
Web Replay: Check event loop input extents during replaying too
https://bugs.webkit.org/show_bug.cgi?id=136316

Reviewed by Timothy Hatcher.

Sometimes we see different nondeterminism during capture and replay
executions, so we should add determinism checks during replay too.

Move the withinEventLoopInputExtent flag to the base class, and tighten
the assertion to address <http://webkit.org/b/133019>.

* replay/InputCursor.h:
(JSC::InputCursor::InputCursor):
(JSC::InputCursor::setWithinEventLoopInputExtent): Added.
This assertion is slightly wrong because it does not account for nested run loops.
We can be within two input extents when a nested run loop processes additional
user inputs while the debugger is paused.

This should only be the case when execution is being neither captured or
replayed. The debugger should not pause when capturing, and we should not replay
event loop inputs while in a nested run loop.

(JSC::InputCursor::withinEventLoopInputExtent): Added.

Source/WebCore:
Web Replay: Check event loop input extents during replay too
https://bugs.webkit.org/show_bug.cgi?id=136316

Reviewed by Timothy Hatcher.

Sometimes we see different nondeterminism during capture and replay
executions, so we should support determinism checks during replay too.

Move the withinEventLoopInputExtent flag to the base class.

No new tests, no behavior changed.

* replay/CapturingInputCursor.cpp:
(WebCore::CapturingInputCursor::CapturingInputCursor):
(WebCore::CapturingInputCursor::setWithinEventLoopInputExtent): Deleted.
* replay/CapturingInputCursor.h:
* replay/EventLoopInput.cpp:
(WebCore::EventLoopInputExtent::EventLoopInputExtent):
(WebCore::EventLoopInputExtent::~EventLoopInputExtent):
Make m_cursor a pointer and add a new constructor so we can conditionally
enter event loop input extents. This is useful in some network replay situations.

* replay/EventLoopInput.h:
* replay/ReplayController.cpp:
(WebCore::ReplayController::willDispatchEvent): Expand the assertion to include replaying.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173978 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/replay/InputCursor.h
Source/WebCore/ChangeLog
Source/WebCore/replay/CapturingInputCursor.cpp
Source/WebCore/replay/CapturingInputCursor.h
Source/WebCore/replay/EventLoopInput.cpp
Source/WebCore/replay/EventLoopInput.h
Source/WebCore/replay/ReplayController.cpp

index f4f8bc4..e86f877 100644 (file)
@@ -1,3 +1,29 @@
+2014-09-25  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: Check event loop input extents during replaying too
+        https://bugs.webkit.org/show_bug.cgi?id=136316
+
+        Reviewed by Timothy Hatcher.
+
+        Sometimes we see different nondeterminism during capture and replay
+        executions, so we should add determinism checks during replay too.
+
+        Move the withinEventLoopInputExtent flag to the base class, and tighten
+        the assertion to address <http://webkit.org/b/133019>.
+
+        * replay/InputCursor.h:
+        (JSC::InputCursor::InputCursor):
+        (JSC::InputCursor::setWithinEventLoopInputExtent): Added.
+        This assertion is slightly wrong because it does not account for nested run loops.
+        We can be within two input extents when a nested run loop processes additional
+        user inputs while the debugger is paused.
+
+        This should only be the case when execution is being neither captured or
+        replayed. The debugger should not pause when capturing, and we should not replay
+        event loop inputs while in a nested run loop.
+
+        (JSC::InputCursor::withinEventLoopInputExtent): Added.
+
 2014-09-25  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Remove WinCE port from trunk
index 6102a7f..5c2a85e 100644 (file)
@@ -40,13 +40,28 @@ namespace JSC {
 class InputCursor : public RefCounted<InputCursor> {
     WTF_MAKE_NONCOPYABLE(InputCursor);
 public:
-    InputCursor() { }
+    InputCursor()
+        : m_withinEventLoopInputExtent(false)
+    {
+    }
 
     virtual ~InputCursor() { }
 
     virtual bool isCapturing() const = 0;
     virtual bool isReplaying() const = 0;
 
+    void setWithinEventLoopInputExtent(bool withinEventLoopInputExtent)
+    {
+        // We can be within two input extents when a nested run loop
+        // processes additional user inputs while the debugger is paused.
+        // However, the debugger should not pause when capturing, and we
+        // should not replay event loop inputs while in a nested run loop.
+        ASSERT(m_withinEventLoopInputExtent != withinEventLoopInputExtent || !(isCapturing() || isReplaying()));
+        m_withinEventLoopInputExtent = withinEventLoopInputExtent;
+    }
+
+    bool withinEventLoopInputExtent() const { return m_withinEventLoopInputExtent; }
+
     template <class InputType, class... Args> inline
     void appendInput(Args&&... args)
     {
@@ -64,6 +79,9 @@ public:
     virtual NondeterministicInputBase* uncheckedLoadInput(InputQueue) = 0;
 protected:
     virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString&) = 0;
+
+private:
+    bool m_withinEventLoopInputExtent;
 };
 
 } // namespace JSC
index c267142..23ad7b2 100644 (file)
@@ -1,3 +1,31 @@
+2014-09-25  Brian J. Burg  <burg@cs.washington.edu>
+
+        Web Replay: Check event loop input extents during replay too
+        https://bugs.webkit.org/show_bug.cgi?id=136316
+
+        Reviewed by Timothy Hatcher.
+
+        Sometimes we see different nondeterminism during capture and replay
+        executions, so we should support determinism checks during replay too.
+
+        Move the withinEventLoopInputExtent flag to the base class.
+
+        No new tests, no behavior changed.
+
+        * replay/CapturingInputCursor.cpp:
+        (WebCore::CapturingInputCursor::CapturingInputCursor):
+        (WebCore::CapturingInputCursor::setWithinEventLoopInputExtent): Deleted.
+        * replay/CapturingInputCursor.h:
+        * replay/EventLoopInput.cpp:
+        (WebCore::EventLoopInputExtent::EventLoopInputExtent):
+        (WebCore::EventLoopInputExtent::~EventLoopInputExtent):
+        Make m_cursor a pointer and add a new constructor so we can conditionally
+        enter event loop input extents. This is useful in some network replay situations.
+
+        * replay/EventLoopInput.h:
+        * replay/ReplayController.cpp:
+        (WebCore::ReplayController::willDispatchEvent): Expand the assertion to include replaying.
+
 2014-09-25  Jeremy Jones  <jeremyj@apple.com>
 
         Race in ref pointer for WebVideoFullscreenInterfaceAVKit.
index 40db3b6..73b402f 100644 (file)
@@ -40,7 +40,6 @@ namespace WebCore {
 
 CapturingInputCursor::CapturingInputCursor(PassRefPtr<ReplaySessionSegment> segment)
     : m_segment(segment)
-    , m_withinEventLoopInputExtent(false)
 {
     LOG(WebReplay, "%-30sCreated capture cursor=%p.\n", "[ReplayController]", this);
 }
@@ -82,13 +81,6 @@ NondeterministicInputBase* CapturingInputCursor::uncheckedLoadInput(InputQueue)
     return nullptr;
 }
 
-void CapturingInputCursor::setWithinEventLoopInputExtent(bool withinEventLoopInputExtent)
-{
-    // We cannot enter more than one extent at a time, since they represent a single run loop.
-    ASSERT(withinEventLoopInputExtent != m_withinEventLoopInputExtent);
-    m_withinEventLoopInputExtent = withinEventLoopInputExtent;
-}
-
 }; // namespace WebCore
 
 #endif // ENABLE(WEB_REPLAY)
index 59e6d4c..ec25c84 100644 (file)
@@ -48,9 +48,6 @@ public:
     virtual bool isCapturing() const override { return true; }
     virtual bool isReplaying() const override { return false; }
 
-    void setWithinEventLoopInputExtent(bool);
-    bool withinEventLoopInputExtent() const { return m_withinEventLoopInputExtent; }
-
 protected:
     virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString& type) override;
 
@@ -61,7 +58,6 @@ private:
     virtual void storeInput(std::unique_ptr<NondeterministicInputBase>) override;
 
     RefPtr<ReplaySessionSegment> m_segment;
-    bool m_withinEventLoopInputExtent;
 };
 
 } // namespace WebCore
index bb27026..2599a0a 100644 (file)
 
 #if ENABLE(WEB_REPLAY)
 
-#include "CapturingInputCursor.h"
+#include <replay/InputCursor.h>
 
 namespace WebCore {
 
-EventLoopInputExtent::EventLoopInputExtent(InputCursor& cursor)
+EventLoopInputExtent::EventLoopInputExtent(JSC::InputCursor& cursor)
+    : EventLoopInputExtent(&cursor) { }
+
+EventLoopInputExtent::EventLoopInputExtent(JSC::InputCursor* cursor)
     : m_cursor(cursor)
 {
-    if (!m_cursor.isCapturing())
-        return;
-
-    static_cast<CapturingInputCursor&>(cursor).setWithinEventLoopInputExtent(true);
+    if (m_cursor)
+        m_cursor->setWithinEventLoopInputExtent(true);
 }
 
 EventLoopInputExtent::~EventLoopInputExtent()
 {
-    if (!m_cursor.isCapturing())
-        return;
-
-    static_cast<CapturingInputCursor&>(m_cursor).setWithinEventLoopInputExtent(false);
+    if (m_cursor)
+        m_cursor->setWithinEventLoopInputExtent(false);
 }
 
 }; // namespace WebCore
index 250a3db..1081ac0 100644 (file)
@@ -48,9 +48,10 @@ class EventLoopInputExtent {
     WTF_MAKE_NONCOPYABLE(EventLoopInputExtent);
 public:
     EventLoopInputExtent(JSC::InputCursor&);
+    EventLoopInputExtent(JSC::InputCursor*);
     ~EventLoopInputExtent();
 private:
-    JSC::InputCursor& m_cursor;
+    JSC::InputCursor* m_cursor;
 };
 
 class EventLoopInputBase : public NondeterministicInputBase {
index 119f490..8edceb2 100644 (file)
@@ -472,8 +472,8 @@ void ReplayController::willDispatchEvent(const Event& event, Frame* frame)
     // To ensure deterministic JS execution, all DOM events must be dispatched deterministically.
     // If these assertions fail, then this DOM event is being dispatched by a nondeterministic EventLoop
     // cycle, and may cause program execution to diverge if any JS code runs because of the DOM event.
-    if (cursor.isCapturing())
-        ASSERT(static_cast<CapturingInputCursor&>(cursor).withinEventLoopInputExtent());
+    if (cursor.isCapturing() || cursor.isReplaying())
+        ASSERT(cursor.withinEventLoopInputExtent());
     else if (cursor.isReplaying())
         ASSERT(dispatcher().isDispatching());
 #endif