Web Replay: capture and replay nondeterminism of Date.now() and Math.random()
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Feb 2014 03:34:33 +0000 (03:34 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Feb 2014 03:34:33 +0000 (03:34 +0000)
commitc4353862d81dfd9a0bcc2a70b33feb08732852d8
treebb4f65258b01aba6a47ae38baffc3d1348d6257c
parent3873c3e2443f5c3aa6a7c3ec1fa8e575a72bde76
Web Replay: capture and replay nondeterminism of Date.now() and Math.random()
https://bugs.webkit.org/show_bug.cgi?id=128633

Reviewed by Filip Pizlo.

Upstream the only two sources of script-visible nondeterminism in JavaScriptCore.

The random seed for WeakRandom is memoized when the owning JSGlobalObject is
constructed. It is deterministically initialized during replay before any
scripts execute with the global object.

The implementations of `Date.now()` and `new Date()` eventually obtain the
current time from jsCurrentTime(). When capturing, we save return values of
jsCurrentTime() into the recording. When replaying, we use memoized values from
the recording instead of obtaining values from the platform-specific currentTime()
implementation. No other code calls jsCurrentTime().

* DerivedSources.make: Add rules to make JSReplayInputs.h from JSInputs.json.
* JavaScriptCore.xcodeproj/project.pbxproj:
* replay/JSInputs.json: Added. Includes specifications for replay inputs
"GetCurrentTime" and "SetRandomSeed". Tests will be added for both input
cases once sufficient replay machinery has been added.

* replay/NondeterministicInput.h: NondeterministicInput should not have
been marked 'final'.

* runtime/DateConstructor.cpp:
(JSC::deterministicCurrentTime): Added. Load or store the current time depending
on what kind of InputCursor is attached to the JSGlobalObject.

(JSC::constructDate): Use deterministicCurrentTime().
(JSC::dateNow): Use deterministicCurrentTime().
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::setInputCursor): When setting a non-empty input cursor,
immediately store or load the "SetRandomSeed" input and initialize WeakRandom's
random seed with it. The input cursor (and thus random seed) must be set before
any scripts are evaluated with this JSGlobalObject.

* runtime/WeakRandom.h:
(JSC::WeakRandom::WeakRandom): Add JSGlobalObject as a friend class.
(JSC::WeakRandom::initializeSeed): Extract the seed initialization into a
separate method so it can be called outside of the JSGlobalObject constructor.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@164007 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/replay/JSInputs.json [new file with mode: 0644]
Source/JavaScriptCore/replay/NondeterministicInput.h
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/WeakRandom.h