Changeset 167085 in webkit


Ignore:
Timestamp:
Apr 10, 2014 1:52:31 PM (10 years ago)
Author:
Brian Burg
Message:

Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
https://bugs.webkit.org/show_bug.cgi?id=131341

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Add support for encoding/decoding unsigned long with EncodedValue.
It is a distinct type from uint32_t and uint64_t.

  • replay/EncodedValue.cpp:

(JSC::EncodedValue::convertTo<unsigned long>):

  • replay/EncodedValue.h:

Source/WebCore:

Information about plugins and mime types is nondeterministic and can change
at any time, whether by system events, browser settings changes, or
triggered by script. To avoid interposing on all those code paths, just
memoize the plugin data used by DOMPluginArray and DOMMimeTypeArray.

This is less efficient than controlling mutations to the underlying PluginData
of a Page, but that can be done later if better plugin support is desired.
The point of this change is to make analytics trackers deterministic across
enabling/disabling of plugins.

Test: LayoutTests/inspector/window-navigator-plugins-memoized.hml

  • plugins/DOMMimeTypeArray.cpp:

(WebCore::DOMMimeTypeArray::getPluginData):

  • plugins/DOMPluginArray.cpp:

(WebCore::DOMPluginArray::pluginData): Save or restore memoized plugin
data during capture and replay, respectively.

  • plugins/PluginData.h:

(WebCore::PluginData::PluginData): Add a constructor that uses the
provided plugin data rather than fetching live plugin data. This is
marked protected so it's only used by a subclass specifically for
deserialization.

  • replay/SerializationMethods.cpp: Add encoder specializations.

(JSC::EncodingTraits<MimeClassInfo>::encodeValue):
(JSC::EncodingTraits<MimeClassInfo>::decodeValue):
(JSC::EncodingTraits<PluginInfo>::encodeValue):
(JSC::EncodingTraits<PluginInfo>::decodeValue):
(JSC::EncodingTraits<PluginData>::encodeValue):
(JSC::DeserializedPluginData::DeserializedPluginData): Add a custom
subclass of PluginData that can be initialized from deserialized data.
(JSC::EncodingTraits<PluginData>::decodeValue):

  • replay/SerializationMethods.h:
  • replay/WebInputs.json: Add new input FetchPluginData.

LayoutTests:

Add support for different setup methods before the initial navigation of
capture and replay. This is necessary to test that the value of
navigator.plugins is the same on replay even if the underlying data changed.

  • http/tests/inspector/replay/replay-test.js:

(InspectorTestProxy.runSingleSegmentRefTest): Add calls to optional setup
functions in the test page called setupPreCapture and setupPreReplay.

Location:
trunk
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r167083 r167085  
     12014-04-10  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
     4        https://bugs.webkit.org/show_bug.cgi?id=131341
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Add support for different setup methods before the initial navigation of
     9        capture and replay. This is necessary to test that the value of
     10        navigator.plugins is the same on replay even if the underlying data changed.
     11
     12        * http/tests/inspector/replay/replay-test.js:
     13        (InspectorTestProxy.runSingleSegmentRefTest): Add calls to optional setup
     14        functions in the test page called setupPreCapture and setupPreReplay.
     15
    1162014-04-10  Carlos Alberto Lopez Perez  <clopez@igalia.com>
    217
  • trunk/LayoutTests/http/tests/inspector/replay/replay-test.js

    r166901 r167085  
    1818    .then(function() {
    1919        InspectorTest.log("Test page initial load done.");
     20        return RuntimeAgent.evaluate.promise("if (typeof \"setupPreCapture\" === \"function\") setupPreCapture()");
     21    })
     22    .then(function() {
    2023        return new Promise(function startCapturing(resolve, reject) {
    2124            InspectorTest.log("Waiting for capturing to start...");
     
    4144            WebInspector.replayManager.addEventListener(WebInspector.ReplayManager.Event.CaptureStopped, resolve);
    4245        });
     46    })
     47    .then(function() {
     48        return RuntimeAgent.evaluate.promise("if (typeof \"setupPreCapture\" === \"function\") setupPreReplay()");
    4349    })
    4450    .then(function() {
  • trunk/Source/JavaScriptCore/ChangeLog

    r167076 r167085  
     12014-04-10  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
     4        https://bugs.webkit.org/show_bug.cgi?id=131341
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Add support for encoding/decoding unsigned long with EncodedValue.
     9        It is a distinct type from uint32_t and uint64_t.
     10
     11        * replay/EncodedValue.cpp:
     12        (JSC::EncodedValue::convertTo<unsigned long>):
     13        * replay/EncodedValue.h:
     14
    1152014-04-10  Mark Lam  <mark.lam@apple.com>
    216
  • trunk/Source/JavaScriptCore/replay/EncodedValue.cpp

    r163918 r167085  
    159159}
    160160
     161template<> unsigned long EncodedValue::convertTo<unsigned long>()
     162{
     163    unsigned long result;
     164    bool castSucceeded = m_value->asNumber(&result);
     165    ASSERT_UNUSED(castSucceeded, castSucceeded);
     166
     167    return result;
     168}
     169
    161170template<> String EncodedValue::convertTo<String>()
    162171{
  • trunk/Source/JavaScriptCore/replay/EncodedValue.h

    r163918 r167085  
    9393template<> JS_EXPORT_PRIVATE uint32_t EncodedValue::convertTo<uint32_t>();
    9494template<> JS_EXPORT_PRIVATE uint64_t EncodedValue::convertTo<uint64_t>();
     95template<> JS_EXPORT_PRIVATE unsigned long EncodedValue::convertTo<unsigned long>();
    9596template<> JS_EXPORT_PRIVATE String EncodedValue::convertTo<String>();
    9697
     
    99100    typedef T DecodedType;
    100101
    101     static EncodedValue encodeValue(DecodedType);
    102102    static EncodedValue encodeValue(const DecodedType&);
    103103
     
    157157template<> struct EncodingTraits<uint32_t> : public ScalarEncodingTraits<uint32_t> { };
    158158template<> struct EncodingTraits<uint64_t> : public ScalarEncodingTraits<uint64_t> { };
     159template<> struct EncodingTraits<unsigned long> : public ScalarEncodingTraits<unsigned long> { };
    159160
    160161template<> struct EncodingTraits<String> : public ScalarEncodingTraits<String> {
  • trunk/Source/WebCore/ChangeLog

    r167082 r167085  
     12014-04-10  Brian J. Burg  <burg@cs.washington.edu>
     2
     3        Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
     4        https://bugs.webkit.org/show_bug.cgi?id=131341
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Information about plugins and mime types is nondeterministic and can change
     9        at any time, whether by system events, browser settings changes, or
     10        triggered by script. To avoid interposing on all those code paths, just
     11        memoize the plugin data used by DOMPluginArray and DOMMimeTypeArray.
     12
     13        This is less efficient than controlling mutations to the underlying PluginData
     14        of a Page, but that can be done later if better plugin support is desired.
     15        The point of this change is to make analytics trackers deterministic across
     16        enabling/disabling of plugins.
     17
     18        Test: LayoutTests/inspector/window-navigator-plugins-memoized.hml
     19
     20        * plugins/DOMMimeTypeArray.cpp:
     21        (WebCore::DOMMimeTypeArray::getPluginData):
     22        * plugins/DOMPluginArray.cpp:
     23        (WebCore::DOMPluginArray::pluginData): Save or restore memoized plugin
     24        data during capture and replay, respectively.
     25
     26        * plugins/PluginData.h:
     27        (WebCore::PluginData::PluginData): Add a constructor that uses the
     28        provided plugin data rather than fetching live plugin data. This is
     29        marked protected so it's only used by a subclass specifically for
     30        deserialization.
     31
     32        * replay/SerializationMethods.cpp: Add encoder specializations.
     33        (JSC::EncodingTraits<MimeClassInfo>::encodeValue):
     34        (JSC::EncodingTraits<MimeClassInfo>::decodeValue):
     35        (JSC::EncodingTraits<PluginInfo>::encodeValue):
     36        (JSC::EncodingTraits<PluginInfo>::decodeValue):
     37        (JSC::EncodingTraits<PluginData>::encodeValue):
     38        (JSC::DeserializedPluginData::DeserializedPluginData): Add a custom
     39        subclass of PluginData that can be initialized from deserialized data.
     40        (JSC::EncodingTraits<PluginData>::decodeValue):
     41        * replay/SerializationMethods.h:
     42        * replay/WebInputs.json: Add new input FetchPluginData.
     43
    1442014-04-10  Myles C. Maxfield  <mmaxfield@apple.com>
    245
  • trunk/Source/WebCore/plugins/DOMMimeTypeArray.cpp

    r154743 r167085  
    2626#include "PluginData.h"
    2727#include <wtf/text/AtomicString.h>
     28
     29#if ENABLE(WEB_REPLAY)
     30#include "Document.h"
     31#include "WebReplayInputs.h"
     32#include <replay/InputCursor.h>
     33#endif
    2834
    2935namespace WebCore {
     
    8692{
    8793    if (!m_frame)
    88         return 0;
     94        return nullptr;
     95
    8996    Page* page = m_frame->page();
    9097    if (!page)
    91         return 0;
    92     return &page->pluginData();
     98        return nullptr;
     99
     100    PluginData* pluginData = &page->pluginData();
     101
     102#if ENABLE(WEB_REPLAY)
     103    if (!m_frame->document())
     104        return pluginData;
     105
     106    InputCursor& cursor = m_frame->document()->inputCursor();
     107    if (cursor.isCapturing())
     108        cursor.appendInput<FetchPluginData>(pluginData);
     109    else if (cursor.isReplaying()) {
     110        if (FetchPluginData* input = cursor.fetchInput<FetchPluginData>())
     111            pluginData = input->pluginData().get();
     112    }
     113#endif
     114
     115    return pluginData;
    93116}
    94117
  • trunk/Source/WebCore/plugins/DOMPluginArray.cpp

    r154743 r167085  
    2626#include "PluginData.h"
    2727#include <wtf/text/AtomicString.h>
     28
     29#if ENABLE(WEB_REPLAY)
     30#include "Document.h"
     31#include "WebReplayInputs.h"
     32#include <replay/InputCursor.h>
     33#endif
    2834
    2935namespace WebCore {
     
    9197{
    9298    if (!m_frame)
    93         return 0;
     99        return nullptr;
     100
    94101    Page* page = m_frame->page();
    95102    if (!page)
    96         return 0;
    97     return &page->pluginData();
     103        return nullptr;
     104
     105    PluginData* pluginData = &page->pluginData();
     106
     107#if ENABLE(WEB_REPLAY)
     108    if (!m_frame->document())
     109        return pluginData;
     110
     111    InputCursor& cursor = m_frame->document()->inputCursor();
     112    if (cursor.isCapturing())
     113        cursor.appendInput<FetchPluginData>(pluginData);
     114    else if (cursor.isReplaying()) {
     115        if (FetchPluginData* input = cursor.fetchInput<FetchPluginData>())
     116            pluginData = input->pluginData().get();
     117    }
     118#endif
     119
     120    return pluginData;
    98121}
    99122
  • trunk/Source/WebCore/plugins/PluginData.h

    r150227 r167085  
    7474    const PluginInfo* pluginInfoForMimeType(const String& mimeType) const;
    7575
     76protected:
     77#if ENABLE(WEB_REPLAY)
     78    PluginData(Vector<PluginInfo> plugins, Vector<MimeClassInfo> mimes, Vector<size_t> indices)
     79        : m_plugins(plugins)
     80        , m_mimes(mimes)
     81        , m_mimePluginIndices(indices)
     82    {
     83    }
     84#endif
     85
    7686    Vector<PluginInfo> m_plugins;
    7787    Vector<MimeClassInfo> m_mimes;
  • trunk/Source/WebCore/replay/SerializationMethods.cpp

    r166856 r167085  
    4040#include "PlatformMouseEvent.h"
    4141#include "PlatformWheelEvent.h"
     42#include "PluginData.h"
    4243#include "ReplayInputTypes.h"
    4344#include "SecurityOrigin.h"
     
    4748using WebCore::KeypressCommand;
    4849using WebCore::IntPoint;
     50using WebCore::MimeClassInfo;
    4951using WebCore::MouseButton;
    5052using WebCore::PlatformEvent;
     
    5355using WebCore::PlatformWheelEvent;
    5456using WebCore::PlatformWheelEventGranularity;
     57using WebCore::PluginData;
     58using WebCore::PluginInfo;
    5559using WebCore::SecurityOrigin;
    5660using WebCore::URL;
     
    147151
    148152namespace JSC {
     153
     154template<>
     155EncodedValue EncodingTraits<MimeClassInfo>::encodeValue(const MimeClassInfo& input)
     156{
     157    EncodedValue encodedData = EncodedValue::createObject();
     158
     159    ENCODE_TYPE_WITH_KEY(encodedData, String, type, input.type);
     160    ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
     161    ENCODE_TYPE_WITH_KEY(encodedData, Vector<String>, extensions, input.extensions);
     162
     163    return encodedData;
     164}
     165
     166template<>
     167bool EncodingTraits<MimeClassInfo>::decodeValue(EncodedValue& encodedData, MimeClassInfo& input)
     168{
     169    MimeClassInfo info;
     170
     171    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, type, info.type);
     172    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
     173    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<String>, extensions, info.extensions);
     174
     175    input = info;
     176    return true;
     177}
    149178
    150179EncodedValue EncodingTraits<NondeterministicInputBase>::encodeValue(const NondeterministicInputBase& input)
     
    425454}
    426455
     456EncodedValue EncodingTraits<PluginData>::encodeValue(RefPtr<PluginData> input)
     457{
     458    EncodedValue encodedData = EncodedValue::createObject();
     459
     460    ENCODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins, input->plugins());
     461    ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input->mimes());
     462    ENCODE_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices, input->mimePluginIndices());
     463
     464    return encodedData;
     465}
     466
     467class DeserializedPluginData : public PluginData {
     468public:
     469    DeserializedPluginData(Vector<PluginInfo> plugins, Vector<MimeClassInfo> mimes, Vector<size_t> indices)
     470        : PluginData(plugins, mimes, indices)
     471    {
     472    }
     473};
     474
     475bool EncodingTraits<PluginData>::decodeValue(EncodedValue& encodedData, RefPtr<PluginData>& input)
     476{
     477    DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins);
     478    DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes);
     479    DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices);
     480
     481    input = adoptRef(new DeserializedPluginData(plugins, mimes, mimePluginIndices));
     482
     483    return true;
     484}
     485
     486template<>
     487EncodedValue EncodingTraits<PluginInfo>::encodeValue(const PluginInfo& input)
     488{
     489    EncodedValue encodedData = EncodedValue::createObject();
     490
     491    ENCODE_TYPE_WITH_KEY(encodedData, String, name, input.name);
     492    ENCODE_TYPE_WITH_KEY(encodedData, String, file, input.file);
     493    ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
     494    ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input.mimes);
     495    ENCODE_TYPE_WITH_KEY(encodedData, bool, isApplicationPlugin, input.isApplicationPlugin);
     496
     497    return encodedData;
     498}
     499
     500template<>
     501bool EncodingTraits<PluginInfo>::decodeValue(EncodedValue& encodedData, PluginInfo& input)
     502{
     503    PluginInfo info;
     504
     505    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, name, info.name);
     506    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, file, info.file);
     507    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
     508    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<MimeClassInfo>, mimes, info.mimes);
     509    DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, isApplicationPlugin, info.isApplicationPlugin);
     510
     511    input = info;
     512    return true;
     513}
     514
    427515EncodedValue EncodingTraits<SecurityOrigin>::encodeValue(RefPtr<SecurityOrigin> input)
    428516{
  • trunk/Source/WebCore/replay/SerializationMethods.h

    r166856 r167085  
    4343class PlatformMouseEvent;
    4444class PlatformWheelEvent;
     45class PluginData;
    4546class SecurityOrigin;
    4647class URL;
     
    9798};
    9899
     100template<> struct EncodingTraits<WebCore::PluginData> {
     101    typedef RefPtr<WebCore::PluginData> DecodedType;
     102
     103    static EncodedValue encodeValue(RefPtr<WebCore::PluginData> value);
     104    static bool decodeValue(EncodedValue&, RefPtr<WebCore::PluginData>& value);
     105};
     106
    99107template<> struct EncodingTraits<WebCore::URL> {
    100108    typedef WebCore::URL DecodedType;
  • trunk/Source/WebCore/replay/WebInputs.json

    r166811 r167085  
    8989            },
    9090            {
     91                "name": "PluginData", "mode": "SHARED",
     92                "header": "plugins/PluginData.h"
     93            },
     94            {
    9195                "name": "ScrollDirection", "mode": "SCALAR", "storage": "uint64_t",
    9296                "flags": ["ENUM"],
     
    220224        },
    221225        {
     226            "name": "FetchPluginData",
     227            "description": "Plugin data was requested through DOMPluginArray or DOMMimeTypeArray.",
     228            "queue": "SCRIPT_MEMOIZED",
     229            "members": [
     230                { "name": "pluginData", "type": "PluginData" }
     231            ]
     232        },
     233        {
    222234            "name": "LogicalScrollPage",
    223235            "description": "The embedder signalled a logical scroll event.",
Note: See TracChangeset for help on using the changeset viewer.