Changeset 211594 in webkit


Ignore:
Timestamp:
Feb 2, 2017 2:07:28 PM (7 years ago)
Author:
Joseph Pecoraro
Message:

Support Performance API (performance.now(), UserTiming) in Workers
https://bugs.webkit.org/show_bug.cgi?id=167717

Reviewed by Ryosuke Niwa.

Source/WebCore:

Tests: performance-api/performance-mark-name.html

performance-api/performance-now-api.html
performance-api/performance-now-time-origin-in-worker.html
performance-api/user-timing-apis.html

  • CMakeLists.txt:
  • DerivedSources.make:

New files.

  • page/DOMWindow.idl:
  • page/GlobalPerformance.idl:
  • workers/WorkerGlobalScope.idl:

Add partial interface for performance attribute.

  • page/Performance.idl:
  • page/PerformanceEntry.idl:
  • page/PerformanceMark.idl:
  • page/PerformanceMeasure.idl:
  • page/PerformanceObserver.idl:
  • page/PerformanceObserverEntryList.idl:

Expose these to Workers.

  • page/Performance.cpp:

(WebCore::Performance::Performance):
(WebCore::Performance::contextDestroyed):

  • page/Performance.h:

Use the EventQueue variant that works with any ScriptExectionContext.

  • page/PerformanceObserver.cpp:

(WebCore::PerformanceObserver::PerformanceObserver):
Get the Performance base in a Worker context.

  • page/PerformanceUserTiming.cpp:

(WebCore::UserTiming::mark):
Only reject legacy special mark names in a Window, not a Worker.

(WebCore::UserTiming::findExistingMarkStartTime):
Simple implementation returns 0 as the start time in Workers. The spec
is currently imprecise here, but it does not have the unusual
PerformanceTiming behavior in a Window which is part of User Timing 1.

  • workers/Worker.cpp:

(WebCore::Worker::create):
(WebCore::Worker::notifyFinished):

  • workers/Worker.h:

Record the moment of Worker creation.

  • workers/WorkerGlobalScope.cpp:

(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::performance):

  • workers/WorkerGlobalScope.h:

Construct the Performance object with the moment of creation (timeOrigin).

  • workers/DedicatedWorkerGlobalScope.cpp:

(WebCore::DedicatedWorkerGlobalScope::create):
(WebCore::DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope):

  • workers/DedicatedWorkerGlobalScope.h:
  • workers/DedicatedWorkerThread.cpp:

(WebCore::DedicatedWorkerThread::DedicatedWorkerThread):
(WebCore::DedicatedWorkerThread::createWorkerGlobalScope):

  • workers/DedicatedWorkerThread.h:
  • workers/WorkerGlobalScopeProxy.h:
  • workers/WorkerMessagingProxy.cpp:

(WebCore::WorkerMessagingProxy::startWorkerGlobalScope):

  • workers/WorkerMessagingProxy.h:
  • workers/WorkerThread.cpp:

(WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
(WebCore::WorkerThread::WorkerThread):
(WebCore::WorkerThread::workerThread):

  • workers/WorkerThread.h:

Pass the moment of creation (timeOrigin) through to WorkerGlobalScope creation.

LayoutTests:

  • js/dom/global-constructors-attributes-dedicated-worker-expected.txt:

Updated now that Performance classes are in Workers.

  • performance-api/performance-now-api-expected.txt: Added.
  • performance-api/performance-now-api.html: Added.
  • performance-api/performance-now-time-origin-in-worker-expected.txt: Added.
  • performance-api/performance-now-time-origin-in-worker.html: Added.

New tests to cover performance.now.

  • performance-api/performance-mark-name-expected.txt: Added.
  • performance-api/performance-mark-name.html: Added.
  • performance-api/resources/mark-name.js: Added.
  • performance-api/resources/user-timing-api.js: Added.
  • performance-api/user-timing-apis-expected.txt: Added.
  • performance-api/user-timing-apis.html: Added.

New tests to cover user-timing and performance.mark behavior.

  • performance-api/performance-observer-api-expected.txt:
  • performance-api/performance-observer-api.html:
  • performance-api/performance-observer-basic-expected.txt:
  • performance-api/performance-observer-basic.html:
  • performance-api/performance-timeline-api-expected.txt:
  • performance-api/performance-timeline-api.html:
  • performance-api/resources/now-api.js: Added.
  • performance-api/resources/observer-api.js: Copied from LayoutTests/performance-api/performance-observer-api.html.
  • performance-api/resources/observer-basic.js: Copied from LayoutTests/performance-api/performance-observer-basic.html.
  • performance-api/resources/time-origin-in-worker.js: Added.
  • performance-api/resources/timeline-api.js: Copied from LayoutTests/performance-api/performance-timeline-api.html.

Update some of the existing tests to check in a Document and Worker.

  • imported/w3c/web-platform-tests/user-timing/test_user_timing_mark_and_measure_exception_when_invoke_with_timing_attributes-expected.txt:

Minor progression.

Location:
trunk
Files:
13 added
37 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r211593 r211594  
     12017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support Performance API (performance.now(), UserTiming) in Workers
     4        https://bugs.webkit.org/show_bug.cgi?id=167717
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * js/dom/global-constructors-attributes-dedicated-worker-expected.txt:
     9        Updated now that Performance classes are in Workers.
     10
     11        * performance-api/performance-now-api-expected.txt: Added.
     12        * performance-api/performance-now-api.html: Added.
     13        * performance-api/performance-now-time-origin-in-worker-expected.txt: Added.
     14        * performance-api/performance-now-time-origin-in-worker.html: Added.
     15        New tests to cover performance.now.
     16
     17        * performance-api/performance-mark-name-expected.txt: Added.
     18        * performance-api/performance-mark-name.html: Added.
     19        * performance-api/resources/mark-name.js: Added.
     20        * performance-api/resources/user-timing-api.js: Added.
     21        * performance-api/user-timing-apis-expected.txt: Added.
     22        * performance-api/user-timing-apis.html: Added.
     23        New tests to cover user-timing and performance.mark behavior.
     24
     25        * performance-api/performance-observer-api-expected.txt:
     26        * performance-api/performance-observer-api.html:
     27        * performance-api/performance-observer-basic-expected.txt:
     28        * performance-api/performance-observer-basic.html:
     29        * performance-api/performance-timeline-api-expected.txt:
     30        * performance-api/performance-timeline-api.html:
     31        * performance-api/resources/now-api.js: Added.
     32        * performance-api/resources/observer-api.js: Copied from LayoutTests/performance-api/performance-observer-api.html.
     33        * performance-api/resources/observer-basic.js: Copied from LayoutTests/performance-api/performance-observer-basic.html.
     34        * performance-api/resources/time-origin-in-worker.js: Added.
     35        * performance-api/resources/timeline-api.js: Copied from LayoutTests/performance-api/performance-timeline-api.html.
     36        Update some of the existing tests to check in a Document and Worker.
     37
     38        * imported/w3c/web-platform-tests/user-timing/test_user_timing_mark_and_measure_exception_when_invoke_with_timing_attributes-expected.txt:
     39        Minor progression.
     40
    1412017-02-02  Ryan Haddad  <ryanhaddad@apple.com>
    242
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/test_user_timing_mark_and_measure_exception_when_invoke_with_timing_attributes-expected.txt

    r211333 r211594  
    66PASS window.performance is defined
    77FAIL performance.mark and performance.measure should throw if used with timing attribute values assert_throws: function "function () { window.performance.measure(timingAttributes..." did not throw
    8 FAIL performance.mark and performance.measure should not throw if used with timing attribute values in workers Can't find variable: performance
     8PASS performance.mark and performance.measure should not throw if used with timing attribute values in workers
    99
  • trunk/LayoutTests/js/dom/global-constructors-attributes-dedicated-worker-expected.txt

    r209598 r211594  
    195195PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Object').enumerable is false
    196196PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Object').configurable is true
     197PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Performance').value is Performance
     198PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Performance').hasOwnProperty('get') is false
     199PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Performance').hasOwnProperty('set') is false
     200PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Performance').enumerable is false
     201PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Performance').configurable is true
     202PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceEntry').value is PerformanceEntry
     203PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceEntry').hasOwnProperty('get') is false
     204PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceEntry').hasOwnProperty('set') is false
     205PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceEntry').enumerable is false
     206PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceEntry').configurable is true
     207PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMark').value is PerformanceMark
     208PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMark').hasOwnProperty('get') is false
     209PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMark').hasOwnProperty('set') is false
     210PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMark').enumerable is false
     211PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMark').configurable is true
     212PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMeasure').value is PerformanceMeasure
     213PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMeasure').hasOwnProperty('get') is false
     214PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMeasure').hasOwnProperty('set') is false
     215PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMeasure').enumerable is false
     216PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceMeasure').configurable is true
     217PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserver').value is PerformanceObserver
     218PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserver').hasOwnProperty('get') is false
     219PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserver').hasOwnProperty('set') is false
     220PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserver').enumerable is false
     221PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserver').configurable is true
     222PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserverEntryList').value is PerformanceObserverEntryList
     223PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserverEntryList').hasOwnProperty('get') is false
     224PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserverEntryList').hasOwnProperty('set') is false
     225PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserverEntryList').enumerable is false
     226PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PerformanceObserverEntryList').configurable is true
    197227PASS [Worker] Object.getOwnPropertyDescriptor(global, 'ProgressEvent').value is ProgressEvent
    198228PASS [Worker] Object.getOwnPropertyDescriptor(global, 'ProgressEvent').hasOwnProperty('get') is false
  • trunk/LayoutTests/performance-api/performance-observer-api-expected.txt

    r211406 r211594  
    3030PASS PerformanceObserverEntryList.prototype.getEntriesByName is defined.
    3131PASS new PerformanceObserverEntryList() threw exception TypeError: function is not a constructor (evaluating 'new PerformanceObserverEntryList()').
     32
     33Starting worker: resources/observer-api.js
     34[Worker] PerformanceObserver
     35PASS [Worker] PerformanceObserver is defined.
     36PASS [Worker] PerformanceObserver.prototype.observe is defined.
     37PASS [Worker] PerformanceObserver.prototype.disconnect is defined.
     38PASS [Worker] PerformanceObserver() threw exception TypeError: Constructor requires 'new' operator.
     39PASS [Worker] new PerformanceObserver() threw exception TypeError: Not enough arguments.
     40PASS [Worker] new PerformanceObserver(1) threw exception TypeError: Argument 1 ('callback') to the PerformanceObserver constructor must be a function.
     41PASS [Worker] observer = new PerformanceObserver(function() {}) did not throw exception.
     42PASS [Worker] observer.observe() threw exception TypeError: Not enough arguments.
     43PASS [Worker] observer.observe("mark") threw exception TypeError: Type error.
     44PASS [Worker] observer.observe({}) threw exception TypeError: Member PerformanceObserverInit.entryTypes is required and must be an instance of sequence.
     45PASS [Worker] observer.observe({entryTypes:"mark"}) threw exception TypeError: Value is not a sequence.
     46PASS [Worker] observer.observe({entryTypes:[]}) threw exception TypeError: entryTypes cannot be an empty list.
     47PASS [Worker] observer.observe({entryTypes:["not-real"]}) threw exception TypeError: entryTypes contained only unsupported types.
     48PASS [Worker] observer.observe({entryTypes:["mark"]}) did not throw exception.
     49PASS [Worker] observer.observe({entryTypes:["mark", "not-real"]}) did not throw exception.
     50PASS [Worker] observer.observe({entryTypes:["mark", "measure"]}) did not throw exception.
     51PASS [Worker] observer.disconnect() did not throw exception.
     52PASS [Worker] observer.disconnect() did not throw exception.
     53[Worker]
     54[Worker] PerformanceObserverEntryList
     55PASS [Worker] PerformanceObserverEntryList is defined.
     56PASS [Worker] PerformanceObserverEntryList.prototype.getEntries is defined.
     57PASS [Worker] PerformanceObserverEntryList.prototype.getEntriesByType is defined.
     58PASS [Worker] PerformanceObserverEntryList.prototype.getEntriesByName is defined.
     59PASS [Worker] new PerformanceObserverEntryList() threw exception TypeError: function is not a constructor (evaluating 'new PerformanceObserverEntryList()').
    3260PASS successfullyParsed is true
    3361
  • trunk/LayoutTests/performance-api/performance-observer-api.html

    r211406 r211594  
    55</head>
    66<body>
     7<script src="resources/observer-api.js"></script>
    78<script>
    8 description("Basic Interface test for PerformanceObserver APIs.");
    9 
    10 debug("PerformanceObserver");
    11 shouldBeDefined(`PerformanceObserver`);
    12 shouldBeDefined(`PerformanceObserver.prototype.observe`);
    13 shouldBeDefined(`PerformanceObserver.prototype.disconnect`);
    14 shouldThrow(`PerformanceObserver()`);
    15 shouldThrow(`new PerformanceObserver()`);
    16 shouldThrow(`new PerformanceObserver(1)`);
    17 shouldNotThrow(`observer = new PerformanceObserver(function() {})`);
    18 shouldThrow(`observer.observe()`);
    19 shouldThrow(`observer.observe("mark")`);
    20 shouldThrow(`observer.observe({})`);
    21 shouldThrow(`observer.observe({entryTypes:"mark"})`);
    22 shouldThrow(`observer.observe({entryTypes:[]})`);
    23 shouldThrow(`observer.observe({entryTypes:["not-real"]})`);
    24 shouldNotThrow(`observer.observe({entryTypes:["mark"]})`);
    25 shouldNotThrow(`observer.observe({entryTypes:["mark", "not-real"]})`);
    26 shouldNotThrow(`observer.observe({entryTypes:["mark", "measure"]})`);
    27 shouldNotThrow(`observer.disconnect()`);
    28 shouldNotThrow(`observer.disconnect()`);
    29 
    309debug("");
    31 debug("PerformanceObserverEntryList");
    32 shouldBeDefined(`PerformanceObserverEntryList`);
    33 shouldBeDefined(`PerformanceObserverEntryList.prototype.getEntries`);
    34 shouldBeDefined(`PerformanceObserverEntryList.prototype.getEntriesByType`);
    35 shouldBeDefined(`PerformanceObserverEntryList.prototype.getEntriesByName`);
    36 shouldThrow(`new PerformanceObserverEntryList()`);
     10let worker = startWorker("resources/observer-api.js");
    3711</script>
    3812<script src="../resources/js-test-post.js"></script>
  • trunk/LayoutTests/performance-api/performance-observer-basic-expected.txt

    r211406 r211594  
    4747PASS list.getEntriesByName(null, "mark").length === 0 is true
    4848PASS list.getEntriesByName(undefined, "mark").length === 0 is true
     49
     50Starting worker: resources/observer-basic.js
     51[Worker] Inside PerformanceObserver callback
     52PASS [Worker] argumentsLength === 2 is true
     53PASS [Worker] list instanceof PerformanceObserverEntryList is true
     54PASS [Worker] obs instanceof PerformanceObserver is true
     55PASS [Worker] obs === observer is true
     56FAIL [Worker] thisObject instanceof PerformanceObserver should be true. Was false.
     57FAIL [Worker] thisObject === observer should be true. Was false.
     58[Worker]
     59[Worker] PerformanceObserverEntryList APIs
     60PASS [Worker] list.getEntries() instanceof Array is true
     61PASS [Worker] list.getEntries().length === 2 is true
     62PASS [Worker] list.getEntries()[0] instanceof PerformanceEntry is true
     63PASS [Worker] list.getEntries()[0].name is "mark3"
     64PASS [Worker] list.getEntries()[1].name is "mark4"
     65PASS [Worker] list.getEntries()[0].startTime <= list.getEntries()[1].startTime is true
     66PASS [Worker] list.getEntriesByType() threw exception TypeError: Not enough arguments.
     67PASS [Worker] list.getEntriesByType("not-real").length === 0 is true
     68PASS [Worker] list.getEntriesByType("mark").length === 2 is true
     69PASS [Worker] list.getEntriesByType("mark")[0] instanceof PerformanceEntry is true
     70PASS [Worker] list.getEntriesByType("mark")[0].name is "mark3"
     71PASS [Worker] list.getEntriesByType("mark")[1].name is "mark4"
     72PASS [Worker] list.getEntriesByName() threw exception TypeError: Not enough arguments.
     73PASS [Worker] list.getEntriesByName("not-real").length === 0 is true
     74PASS [Worker] list.getEntriesByName("mark1").length === 0 is true
     75PASS [Worker] list.getEntriesByName("mark3").length === 1 is true
     76PASS [Worker] list.getEntriesByName("mark3")[0] instanceof PerformanceEntry is true
     77PASS [Worker] list.getEntriesByName("mark3")[0].name is "mark3"
     78PASS [Worker] list.getEntriesByName("mark4").length === 1 is true
     79PASS [Worker] list.getEntriesByName("mark4")[0] instanceof PerformanceEntry is true
     80PASS [Worker] list.getEntriesByName("mark4")[0].name is "mark4"
     81PASS [Worker] list.getEntriesByName() threw exception TypeError: Not enough arguments.
     82PASS [Worker] list.getEntriesByName("not-real").length === 0 is true
     83PASS [Worker] list.getEntriesByName("mark1").length === 0 is true
     84PASS [Worker] list.getEntriesByName("mark3").length === 1 is true
     85PASS [Worker] list.getEntriesByName("mark3")[0] instanceof PerformanceEntry is true
     86PASS [Worker] list.getEntriesByName("mark3")[0].name is "mark3"
     87PASS [Worker] list.getEntriesByName("mark4").length === 1 is true
     88PASS [Worker] list.getEntriesByName("mark4")[0] instanceof PerformanceEntry is true
     89PASS [Worker] list.getEntriesByName("mark4")[0].name is "mark4"
     90PASS [Worker] list.getEntriesByName("mark3", "not-real").length === 0 is true
     91PASS [Worker] list.getEntriesByName("mark3", "mark").length === 1 is true
     92PASS [Worker] list.getEntriesByName(null, "mark").length === 0 is true
     93PASS [Worker] list.getEntriesByName(undefined, "mark").length === 0 is true
    4994PASS successfullyParsed is true
    5095
  • trunk/LayoutTests/performance-api/performance-observer-basic.html

    r211406 r211594  
    55</head>
    66<body>
     7<script src="resources/observer-basic.js"></script>
    78<script>
    8 description("Basic Behavior test for PerformanceObserver APIs.");
    9 window.jsTestIsAsync = true;
    10 
    11 // PerformanceObservers that are not actively observing should not fire.
    12 let observerNotObserving = new PerformanceObserver(function() {
    13     testFailed("PerformanceObserver never registered should not be called");
    14 });
    15 
    16 let observerNotObserving2 = new PerformanceObserver(function() {
    17     testFailed("PerformanceObserver not actively observing should not be called");
    18 });
    19 observerNotObserving2.observe({entryTypes: ["mark"]});
    20 observerNotObserving2.disconnect();
    21 
    22 // PerformanceObservers for different entry types should not fire.
    23 let observerNotMarks = new PerformanceObserver(function() {
    24     testFailed("PerformanceObserver observing measures should not be called");
    25 });
    26 
    27 // Observer sees marks while it is registered.
    28 performance.mark("mark1");
    29 window.observer = new PerformanceObserver(function(list, obs) {
    30     window.argumentsLength = arguments.length;
    31     window.list = list;
    32     window.obs = obs;
    33     window.thisObject = this;
    34 
    35     debug("Inside PerformanceObserver callback");
    36     shouldBeTrue(`argumentsLength === 2`);
    37     shouldBeTrue(`list instanceof PerformanceObserverEntryList`);
    38     shouldBeTrue(`obs instanceof PerformanceObserver`);
    39     shouldBeTrue(`obs === observer`);
    40     // FIXME: <https://webkit.org/b/167549> Invoking generated callback should allow setting the `this` object
    41     shouldBeTrue(`thisObject instanceof PerformanceObserver`);
    42     shouldBeTrue(`thisObject === observer`);
    43 
     9function testWorker() {
    4410    debug("");
    45     debug("PerformanceObserverEntryList APIs");
    46 
    47     shouldBeTrue(`list.getEntries() instanceof Array`);
    48     shouldBeTrue(`list.getEntries().length === 2`);
    49     shouldBeTrue(`list.getEntries()[0] instanceof PerformanceEntry`);
    50     shouldBeEqualToString(`list.getEntries()[0].name`, "mark3");
    51     shouldBeEqualToString(`list.getEntries()[1].name`, "mark4");
    52     shouldBeTrue(`list.getEntries()[0].startTime <= list.getEntries()[1].startTime`);
    53 
    54     shouldThrow(`list.getEntriesByType()`);
    55     shouldBeTrue(`list.getEntriesByType("not-real").length === 0`);
    56     shouldBeTrue(`list.getEntriesByType("mark").length === 2`);
    57     shouldBeTrue(`list.getEntriesByType("mark")[0] instanceof PerformanceEntry`);
    58     shouldBeEqualToString(`list.getEntriesByType("mark")[0].name`, "mark3");
    59     shouldBeEqualToString(`list.getEntriesByType("mark")[1].name`, "mark4");
    60 
    61     shouldThrow(`list.getEntriesByName()`);
    62     shouldBeTrue(`list.getEntriesByName("not-real").length === 0`);
    63     shouldBeTrue(`list.getEntriesByName("mark1").length === 0`);
    64     shouldBeTrue(`list.getEntriesByName("mark3").length === 1`);
    65     shouldBeTrue(`list.getEntriesByName("mark3")[0] instanceof PerformanceEntry`);
    66     shouldBeEqualToString(`list.getEntriesByName("mark3")[0].name`, "mark3");
    67     shouldBeTrue(`list.getEntriesByName("mark4").length === 1`);
    68     shouldBeTrue(`list.getEntriesByName("mark4")[0] instanceof PerformanceEntry`);
    69     shouldBeEqualToString(`list.getEntriesByName("mark4")[0].name`, "mark4");
    70 
    71     shouldThrow(`list.getEntriesByName()`);
    72     shouldBeTrue(`list.getEntriesByName("not-real").length === 0`);
    73     shouldBeTrue(`list.getEntriesByName("mark1").length === 0`);
    74     shouldBeTrue(`list.getEntriesByName("mark3").length === 1`);
    75     shouldBeTrue(`list.getEntriesByName("mark3")[0] instanceof PerformanceEntry`);
    76     shouldBeEqualToString(`list.getEntriesByName("mark3")[0].name`, "mark3");
    77     shouldBeTrue(`list.getEntriesByName("mark4").length === 1`);
    78     shouldBeTrue(`list.getEntriesByName("mark4")[0] instanceof PerformanceEntry`);
    79     shouldBeEqualToString(`list.getEntriesByName("mark4")[0].name`, "mark4");
    80 
    81     shouldBeTrue(`list.getEntriesByName("mark3", "not-real").length === 0`);
    82     shouldBeTrue(`list.getEntriesByName("mark3", "mark").length === 1`);
    83     shouldBeTrue(`list.getEntriesByName(null, "mark").length === 0`);
    84     shouldBeTrue(`list.getEntriesByName(undefined, "mark").length === 0`);
    85 
    86     finishJSTest();
    87 });
    88 performance.mark("mark2");
    89 observer.observe({entryTypes: ["mark"]});
    90 performance.mark("mark3");
    91 performance.mark("mark4");
     11    let worker = startWorker("resources/observer-basic.js");
     12}
    9213</script>
    9314<script src="../resources/js-test-post.js"></script>
  • trunk/LayoutTests/performance-api/performance-timeline-api-expected.txt

    r211406 r211594  
    4343PASS performance.getEntriesByName("test", "not-real").length === 0 is true
    4444PASS performance.getEntriesByName("test", "mark").length === 1 is true
     45
     46Starting worker: resources/timeline-api.js
     47[Worker] PerformanceEntry
     48PASS [Worker] PerformanceEntry is defined.
     49PASS [Worker] "name" in PerformanceEntry.prototype is true
     50PASS [Worker] "entryType" in PerformanceEntry.prototype is true
     51PASS [Worker] "startTime" in PerformanceEntry.prototype is true
     52PASS [Worker] "duration" in PerformanceEntry.prototype is true
     53PASS [Worker] new PerformanceEntry() threw exception TypeError: function is not a constructor (evaluating 'new PerformanceEntry()').
     54[Worker]
     55[Worker] Performance extensions
     56PASS [Worker] Performance.prototype.getEntries is defined.
     57PASS [Worker] Performance.prototype.getEntriesByType is defined.
     58PASS [Worker] Performance.prototype.getEntriesByName is defined.
     59PASS [Worker] performance.getEntries() instanceof Array is true
     60PASS [Worker] performance.getEntries().length === 0 is true
     61PASS [Worker] performance.mark("test"); did not throw exception.
     62PASS [Worker] performance.getEntries().length === 1 is true
     63PASS [Worker] performance.getEntries()[0] instanceof PerformanceEntry is true
     64PASS [Worker] performance.getEntries()[0].name is "test"
     65PASS [Worker] performance.getEntries()[0].entryType is "mark"
     66PASS [Worker] typeof performance.getEntries()[0].startTime === "number" is true
     67PASS [Worker] typeof performance.getEntries()[0].duration === "number" is true
     68PASS [Worker] performance.getEntriesByType() threw exception TypeError: Not enough arguments.
     69PASS [Worker] performance.getEntriesByType("not-real").length === 0 is true
     70PASS [Worker] performance.getEntriesByType("mark").length === 1 is true
     71PASS [Worker] performance.getEntriesByType("mark")[0] instanceof PerformanceEntry is true
     72PASS [Worker] performance.getEntriesByType("mark")[0].name is "test"
     73PASS [Worker] performance.getEntriesByType("mark")[0].entryType is "mark"
     74PASS [Worker] typeof performance.getEntriesByType("mark")[0].startTime === "number" is true
     75PASS [Worker] typeof performance.getEntriesByType("mark")[0].duration === "number" is true
     76PASS [Worker] performance.getEntriesByName() threw exception TypeError: Not enough arguments.
     77PASS [Worker] performance.getEntriesByName("not-real").length === 0 is true
     78PASS [Worker] performance.getEntriesByName("test").length === 1 is true
     79PASS [Worker] performance.getEntriesByName("test")[0] instanceof PerformanceEntry is true
     80PASS [Worker] performance.getEntriesByName("test")[0].name is "test"
     81PASS [Worker] performance.getEntriesByName("test")[0].entryType is "mark"
     82PASS [Worker] typeof performance.getEntriesByName("test")[0].startTime === "number" is true
     83PASS [Worker] typeof performance.getEntriesByName("test")[0].duration === "number" is true
     84PASS [Worker] performance.getEntriesByName("test", "not-real").length === 0 is true
     85PASS [Worker] performance.getEntriesByName("test", "mark").length === 1 is true
    4586PASS successfullyParsed is true
    4687
  • trunk/LayoutTests/performance-api/performance-timeline-api.html

    r211406 r211594  
    55</head>
    66<body>
     7<script src="resources/timeline-api.js"></script>
    78<script>
    8 description("Basic Interface test for performance-timeline APIs.");
    9 
    10 debug("PerformanceEntry");
    11 shouldBeDefined("PerformanceEntry");
    12 shouldBeTrue(`"name" in PerformanceEntry.prototype`);
    13 shouldBeTrue(`"entryType" in PerformanceEntry.prototype`);
    14 shouldBeTrue(`"startTime" in PerformanceEntry.prototype`);
    15 shouldBeTrue(`"duration" in PerformanceEntry.prototype`);
    16 shouldThrow(`new PerformanceEntry()`);
    17 
    18 // NOTE: The APIs below may be going away. Replaced by PerformanceObserver.
    19 
    209debug("");
    21 debug("Performance extensions");
    22 shouldBeDefined(`Performance.prototype.getEntries`);
    23 shouldBeDefined(`Performance.prototype.getEntriesByType`);
    24 shouldBeDefined(`Performance.prototype.getEntriesByName`);
    25 
    26 shouldBeTrue(`performance.getEntries() instanceof Array`);
    27 shouldBeTrue(`performance.getEntries().length === 0`);
    28 shouldNotThrow(`performance.mark("test");`);
    29 shouldBeTrue(`performance.getEntries().length === 1`);
    30 shouldBeTrue(`performance.getEntries()[0] instanceof PerformanceEntry`);
    31 shouldBeEqualToString(`performance.getEntries()[0].name`, "test");
    32 shouldBeEqualToString(`performance.getEntries()[0].entryType`, "mark");
    33 shouldBeTrue(`typeof performance.getEntries()[0].startTime === "number"`);
    34 shouldBeTrue(`typeof performance.getEntries()[0].duration === "number"`);
    35 
    36 shouldThrow(`performance.getEntriesByType()`);
    37 shouldBeTrue(`performance.getEntriesByType("not-real").length === 0`);
    38 shouldBeTrue(`performance.getEntriesByType("mark").length === 1`);
    39 shouldBeTrue(`performance.getEntriesByType("mark")[0] instanceof PerformanceEntry`);
    40 shouldBeEqualToString(`performance.getEntriesByType("mark")[0].name`, "test");
    41 shouldBeEqualToString(`performance.getEntriesByType("mark")[0].entryType`, "mark");
    42 shouldBeTrue(`typeof performance.getEntriesByType("mark")[0].startTime === "number"`);
    43 shouldBeTrue(`typeof performance.getEntriesByType("mark")[0].duration === "number"`);
    44 
    45 shouldThrow(`performance.getEntriesByName()`);
    46 shouldBeTrue(`performance.getEntriesByName("not-real").length === 0`);
    47 shouldBeTrue(`performance.getEntriesByName("test").length === 1`);
    48 shouldBeTrue(`performance.getEntriesByName("test")[0] instanceof PerformanceEntry`);
    49 shouldBeEqualToString(`performance.getEntriesByName("test")[0].name`, "test");
    50 shouldBeEqualToString(`performance.getEntriesByName("test")[0].entryType`, "mark");
    51 shouldBeTrue(`typeof performance.getEntriesByName("test")[0].startTime === "number"`);
    52 shouldBeTrue(`typeof performance.getEntriesByName("test")[0].duration === "number"`);
    53 shouldBeTrue(`performance.getEntriesByName("test", "not-real").length === 0`);
    54 shouldBeTrue(`performance.getEntriesByName("test", "mark").length === 1`);
     10let worker = startWorker("resources/timeline-api.js");
    5511</script>
    5612<script src="../resources/js-test-post.js"></script>
  • trunk/LayoutTests/performance-api/resources/observer-api.js

    r211593 r211594  
    1 <!DOCTYPE HTML>
    2 <html>
    3 <head>
    4 <script src="../resources/js-test-pre.js"></script>
    5 </head>
    6 <body>
    7 <script>
    8 description("Basic Interface test for PerformanceObserver APIs.");
     1if (self.importScripts)
     2    importScripts("../../resources/js-test-pre.js");
     3
     4if (self.window)
     5    description("Basic Interface test for PerformanceObserver APIs.");
    96
    107debug("PerformanceObserver");
     
    3532shouldBeDefined(`PerformanceObserverEntryList.prototype.getEntriesByName`);
    3633shouldThrow(`new PerformanceObserverEntryList()`);
    37 </script>
    38 <script src="../resources/js-test-post.js"></script>
    39 </body>
    40 </html>
     34
     35if (self.importScripts)
     36    finishJSTest();
  • trunk/LayoutTests/performance-api/resources/observer-basic.js

    r211593 r211594  
    1 <!DOCTYPE HTML>
    2 <html>
    3 <head>
    4 <script src="../resources/js-test-pre.js"></script>
    5 </head>
    6 <body>
    7 <script>
    8 description("Basic Behavior test for PerformanceObserver APIs.");
    9 window.jsTestIsAsync = true;
     1if (self.importScripts)
     2    importScripts("../../resources/js-test-pre.js");
     3
     4self.jsTestIsAsync = true;
     5
     6if (self.window)
     7    description("Basic Behavior test for PerformanceObserver APIs.");
    108
    119// PerformanceObservers that are not actively observing should not fire.
     
    2725// Observer sees marks while it is registered.
    2826performance.mark("mark1");
    29 window.observer = new PerformanceObserver(function(list, obs) {
    30     window.argumentsLength = arguments.length;
    31     window.list = list;
    32     window.obs = obs;
    33     window.thisObject = this;
    34 
     27self.observer = new PerformanceObserver(function(list, obs) {
     28    self.argumentsLength = arguments.length;
     29    self.list = list;
     30    self.obs = obs;
     31    self.thisObject = this;
     32   
    3533    debug("Inside PerformanceObserver callback");
    3634    shouldBeTrue(`argumentsLength === 2`);
     
    6866    shouldBeTrue(`list.getEntriesByName("mark4")[0] instanceof PerformanceEntry`);
    6967    shouldBeEqualToString(`list.getEntriesByName("mark4")[0].name`, "mark4");
    70 
     68   
    7169    shouldThrow(`list.getEntriesByName()`);
    7270    shouldBeTrue(`list.getEntriesByName("not-real").length === 0`);
     
    8482    shouldBeTrue(`list.getEntriesByName(undefined, "mark").length === 0`);
    8583
    86     finishJSTest();
     84    if (self.importScripts)
     85        finishJSTest();
     86    else
     87        testWorker();
    8788});
    8889performance.mark("mark2");
     
    9091performance.mark("mark3");
    9192performance.mark("mark4");
    92 </script>
    93 <script src="../resources/js-test-post.js"></script>
    94 </body>
    95 </html>
  • trunk/LayoutTests/performance-api/resources/timeline-api.js

    r211593 r211594  
    1 <!DOCTYPE HTML>
    2 <html>
    3 <head>
    4 <script src="../resources/js-test-pre.js"></script>
    5 </head>
    6 <body>
    7 <script>
    8 description("Basic Interface test for performance-timeline APIs.");
     1if (self.importScripts)
     2    importScripts("../../resources/js-test-pre.js");
     3
     4if (self.window)
     5    description("Basic Interface test for performance-timeline APIs.");
    96
    107debug("PerformanceEntry");
     
    5350shouldBeTrue(`performance.getEntriesByName("test", "not-real").length === 0`);
    5451shouldBeTrue(`performance.getEntriesByName("test", "mark").length === 1`);
    55 </script>
    56 <script src="../resources/js-test-post.js"></script>
    57 </body>
    58 </html>
     52
     53if (self.importScripts)
     54    finishJSTest();
  • trunk/Source/WebCore/CMakeLists.txt

    r211406 r211594  
    588588    page/EventSource.idl
    589589    page/GlobalCrypto.idl
     590    page/GlobalPerformance.idl
    590591    page/History.idl
    591592    page/IntersectionObserver.idl
  • trunk/Source/WebCore/ChangeLog

    r211592 r211594  
     12017-02-02  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support Performance API (performance.now(), UserTiming) in Workers
     4        https://bugs.webkit.org/show_bug.cgi?id=167717
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Tests: performance-api/performance-mark-name.html
     9               performance-api/performance-now-api.html
     10               performance-api/performance-now-time-origin-in-worker.html
     11               performance-api/user-timing-apis.html
     12
     13        * CMakeLists.txt:
     14        * DerivedSources.make:
     15        New files.
     16
     17        * page/DOMWindow.idl:
     18        * page/GlobalPerformance.idl:
     19        * workers/WorkerGlobalScope.idl:
     20        Add partial interface for performance attribute.
     21
     22        * page/Performance.idl:
     23        * page/PerformanceEntry.idl:
     24        * page/PerformanceMark.idl:
     25        * page/PerformanceMeasure.idl:
     26        * page/PerformanceObserver.idl:
     27        * page/PerformanceObserverEntryList.idl:
     28        Expose these to Workers.
     29
     30        * page/Performance.cpp:
     31        (WebCore::Performance::Performance):
     32        (WebCore::Performance::contextDestroyed):
     33        * page/Performance.h:
     34        Use the EventQueue variant that works with any ScriptExectionContext.
     35
     36        * page/PerformanceObserver.cpp:
     37        (WebCore::PerformanceObserver::PerformanceObserver):
     38        Get the Performance base in a Worker context.
     39
     40        * page/PerformanceUserTiming.cpp:
     41        (WebCore::UserTiming::mark):
     42        Only reject legacy special mark names in a Window, not a Worker.
     43
     44        (WebCore::UserTiming::findExistingMarkStartTime):
     45        Simple implementation returns 0 as the start time in Workers. The spec
     46        is currently imprecise here, but it does not have the unusual
     47        PerformanceTiming behavior in a Window which is part of User Timing 1.
     48
     49        * workers/Worker.cpp:
     50        (WebCore::Worker::create):
     51        (WebCore::Worker::notifyFinished):
     52        * workers/Worker.h:
     53        Record the moment of Worker creation.
     54
     55        * workers/WorkerGlobalScope.cpp:
     56        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
     57        (WebCore::WorkerGlobalScope::performance):
     58        * workers/WorkerGlobalScope.h:
     59        Construct the Performance object with the moment of creation (timeOrigin).
     60
     61        * workers/DedicatedWorkerGlobalScope.cpp:
     62        (WebCore::DedicatedWorkerGlobalScope::create):
     63        (WebCore::DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope):
     64        * workers/DedicatedWorkerGlobalScope.h:
     65        * workers/DedicatedWorkerThread.cpp:
     66        (WebCore::DedicatedWorkerThread::DedicatedWorkerThread):
     67        (WebCore::DedicatedWorkerThread::createWorkerGlobalScope):
     68        * workers/DedicatedWorkerThread.h:
     69        * workers/WorkerGlobalScopeProxy.h:
     70        * workers/WorkerMessagingProxy.cpp:
     71        (WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
     72        * workers/WorkerMessagingProxy.h:
     73        * workers/WorkerThread.cpp:
     74        (WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
     75        (WebCore::WorkerThread::WorkerThread):
     76        (WebCore::WorkerThread::workerThread):
     77        * workers/WorkerThread.h:
     78        Pass the moment of creation (timeOrigin) through to WorkerGlobalScope creation.
     79
    1802017-02-02  Commit Queue  <commit-queue@webkit.org>
    281
  • trunk/Source/WebCore/DerivedSources.make

    r211406 r211594  
    570570    $(WebCore)/page/EventSource.idl \
    571571    $(WebCore)/page/GlobalCrypto.idl \
     572    $(WebCore)/page/GlobalPerformance.idl \
    572573    $(WebCore)/page/History.idl \
    573574    $(WebCore)/page/IntersectionObserver.idl \
  • trunk/Source/WebCore/page/DOMWindow.idl

    r211139 r211594  
    158158    [CallWith=ScriptState&CallerWindow, DoNotCheckSecurity, ForwardDeclareInHeader, MayThrowException] void postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
    159159
    160     [Conditional=WEB_TIMING, Replaceable] readonly attribute Performance performance;
    161 
    162160    long requestAnimationFrame(RequestAnimationFrameCallback callback);
    163161    void cancelAnimationFrame(long id);
     
    203201DOMWindow implements GlobalCrypto;
    204202DOMWindow implements GlobalEventHandlers;
     203DOMWindow implements GlobalPerformance;
    205204DOMWindow implements WindowEventHandlers;
    206205DOMWindow implements WindowOrWorkerGlobalScope;
  • trunk/Source/WebCore/page/GlobalPerformance.idl

    r211593 r211594  
    11/*
    2  * Copyright (C) 2012 Intel Inc. All rights reserved.
     2 * Copyright (C) 2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 // https://w3c.github.io/user-timing/
     26// https://w3c.github.io/hr-time/
    2727
    2828[
    29     Conditional=WEB_TIMING,
    30     EnabledAtRuntime=UserTiming,
    31 ] interface PerformanceMark : PerformanceEntry {
     29    NoInterfaceObject,
     30    Exposed=(Window,Worker)
     31] interface GlobalPerformance {
     32    [Conditional=WEB_TIMING, Replaceable] readonly attribute Performance performance;
    3233};
  • trunk/Source/WebCore/page/Performance.cpp

    r211527 r211594  
    5555    : ContextDestructionObserver(&context)
    5656    , m_timeOrigin(timeOrigin)
     57    , m_performanceTimelineTaskQueue(context)
    5758{
    5859    ASSERT(m_timeOrigin);
     
    6162Performance::~Performance()
    6263{
     64}
     65
     66void Performance::contextDestroyed()
     67{
     68    m_performanceTimelineTaskQueue.close();
     69
     70    ContextDestructionObserver::contextDestroyed();
    6371}
    6472
  • trunk/Source/WebCore/page/Performance.h

    r211527 r211594  
    9191    Performance(ScriptExecutionContext&, double timeOrigin);
    9292
     93    void contextDestroyed() override;
     94
    9395    EventTargetInterface eventTargetInterface() const final { return PerformanceEventTargetInterfaceType; }
    9496
     
    111113    std::unique_ptr<UserTiming> m_userTiming;
    112114
    113     GenericTaskQueue<Timer> m_performanceTimelineTaskQueue;
     115    GenericTaskQueue<ScriptExecutionContext> m_performanceTimelineTaskQueue;
    114116    ListHashSet<RefPtr<PerformanceObserver>> m_observers;
    115117};
  • trunk/Source/WebCore/page/Performance.idl

    r211527 r211594  
    3636[
    3737    Conditional=WEB_TIMING,
     38    Exposed=(Window,Worker),
    3839    GenerateIsReachable=ImplScriptExecutionContext,
    3940] interface Performance : EventTarget {
  • trunk/Source/WebCore/page/PerformanceEntry.idl

    r211413 r211594  
    3535[
    3636    Conditional=WEB_TIMING,
     37    CustomToJSObject,
    3738    EnabledAtRuntime=PerformanceTimeline,
    38     CustomToJSObject,
     39    Exposed=(Window,Worker),
    3940] interface PerformanceEntry {
    4041    readonly attribute DOMString name;
  • trunk/Source/WebCore/page/PerformanceMark.idl

    r211133 r211594  
    2929    Conditional=WEB_TIMING,
    3030    EnabledAtRuntime=UserTiming,
     31    Exposed=(Window,Worker),
    3132] interface PerformanceMark : PerformanceEntry {
    3233};
  • trunk/Source/WebCore/page/PerformanceMeasure.idl

    r211133 r211594  
    2929    Conditional=WEB_TIMING,
    3030    EnabledAtRuntime=UserTiming,
     31    Exposed=(Window,Worker),
    3132] interface PerformanceMeasure : PerformanceEntry {
    3233};
  • trunk/Source/WebCore/page/PerformanceObserver.cpp

    r211406 r211594  
    4646            m_performance = window->performance();
    4747    } else if (is<WorkerGlobalScope>(scriptExecutionContext)) {
    48         // FIXME: Support Performance Timeline for Workers.
     48        auto& workerGlobalScope = downcast<WorkerGlobalScope>(scriptExecutionContext);
     49        m_performance = &workerGlobalScope.performance();
    4950    } else
    5051        ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/page/PerformanceObserver.idl

    r211406 r211594  
    3131    ConstructorCallWith=ScriptExecutionContext,
    3232    EnabledAtRuntime=PerformanceTimeline,
     33    Exposed=(Window,Worker),
    3334    ImplementationLacksVTable,
    3435] interface PerformanceObserver {
  • trunk/Source/WebCore/page/PerformanceObserverEntryList.idl

    r211406 r211594  
    2929    Conditional=WEB_TIMING,
    3030    EnabledAtRuntime=PerformanceTimeline,
     31    Exposed=(Window,Worker),
    3132    ImplementationLacksVTable,
    3233] interface PerformanceObserverEntryList {
  • trunk/Source/WebCore/page/PerformanceUserTiming.cpp

    r211527 r211594  
    2929#if ENABLE(WEB_TIMING)
    3030
     31#include "Document.h"
    3132#include "ExceptionCode.h"
    3233#include "Performance.h"
    3334#include "PerformanceTiming.h"
    3435#include <array>
     36#include <wtf/MainThread.h>
    3537#include <wtf/NeverDestroyed.h>
    3638#include <wtf/dtoa/utils.h>
     
    4446static NavigationTimingFunction restrictedMarkFunction(const String& markName)
    4547{
    46     // FIXME: Update this list when moving to Navigation Timing Level 2.
     48    ASSERT(isMainThread());
     49
    4750    using MapPair = std::pair<ASCIILiteral, NavigationTimingFunction>;
    4851    static const std::array<MapPair, 21> pairs = { {
     
    98101ExceptionOr<Ref<PerformanceMark>> UserTiming::mark(const String& markName)
    99102{
    100     if (restrictedMarkFunction(markName))
    101         return Exception { SYNTAX_ERR };
     103    if (is<Document>(m_performance.scriptExecutionContext())) {
     104        if (restrictedMarkFunction(markName))
     105            return Exception { SYNTAX_ERR };
     106    }
    102107
    103108    auto& performanceEntryList = m_marksMap.ensure(markName, [] { return Vector<RefPtr<PerformanceEntry>>(); }).iterator->value;
     
    117122        return m_marksMap.get(markName).last()->startTime();
    118123
     124    PerformanceTiming* timing = m_performance.timing();
     125    if (!timing)
     126        return 0.0;
     127
    119128    if (auto function = restrictedMarkFunction(markName)) {
    120         if (PerformanceTiming* timing = m_performance.timing()) {
    121             double value = static_cast<double>(((*timing).*(function))());
    122             if (!value)
    123                 return Exception { INVALID_ACCESS_ERR };
    124             return value - timing->navigationStart();
    125         } else {
    126             // FIXME: Support UserTiming in Workers.
    127             ASSERT_NOT_REACHED();
    128             return Exception { SYNTAX_ERR };
    129         }
     129        double value = static_cast<double>(((*timing).*(function))());
     130        if (!value)
     131            return Exception { INVALID_ACCESS_ERR };
     132        return value - timing->navigationStart();
    130133    }
    131134
  • trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp

    r210923 r211594  
    4242namespace WebCore {
    4343
    44 Ref<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(const URL& url, const String& identifier, const String& userAgent, DedicatedWorkerThread& thread, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
     44Ref<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(const URL& url, const String& identifier, const String& userAgent, DedicatedWorkerThread& thread, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    4545{
    46     auto context = adoptRef(*new DedicatedWorkerGlobalScope(url, identifier, userAgent, thread, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), connectionProxy, socketProvider));
     46    auto context = adoptRef(*new DedicatedWorkerGlobalScope(url, identifier, userAgent, thread, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), timeOrigin, connectionProxy, socketProvider));
    4747    if (!shouldBypassMainWorldContentSecurityPolicy)
    4848        context->applyContentSecurityPolicyResponseHeaders(contentSecurityPolicyResponseHeaders);
     
    5050}
    5151
    52 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, DedicatedWorkerThread& thread, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    53     : WorkerGlobalScope(url, identifier, userAgent, thread, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), connectionProxy, socketProvider)
     52DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, DedicatedWorkerThread& thread, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
     53    : WorkerGlobalScope(url, identifier, userAgent, thread, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), timeOrigin, connectionProxy, socketProvider)
    5454{
    5555}
  • trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.h

    r210923 r211594  
    4949class DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
    5050public:
    51     static Ref<DedicatedWorkerGlobalScope> create(const URL&, const String& identifier, const String& userAgent, DedicatedWorkerThread&, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
     51    static Ref<DedicatedWorkerGlobalScope> create(const URL&, const String& identifier, const String& userAgent, DedicatedWorkerThread&, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
    5252    virtual ~DedicatedWorkerGlobalScope();
    5353
     
    5959    using Base = WorkerGlobalScope;
    6060
    61     DedicatedWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, DedicatedWorkerThread&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
     61    DedicatedWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, DedicatedWorkerThread&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
    6262
    6363    bool isDedicatedWorkerGlobalScope() const final { return true; }
  • trunk/Source/WebCore/workers/DedicatedWorkerThread.cpp

    r210923 r211594  
    3939namespace WebCore {
    4040
    41 DedicatedWorkerThread::DedicatedWorkerThread(const URL& url, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
    42     : WorkerThread(url, identifier, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, topOrigin, connectionProxy, socketProvider, runtimeFlags)
     41DedicatedWorkerThread::DedicatedWorkerThread(const URL& url, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
     42    : WorkerThread(url, identifier, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, topOrigin, timeOrigin, connectionProxy, socketProvider, runtimeFlags)
    4343    , m_workerObjectProxy(workerObjectProxy)
    4444{
     
    4949}
    5050
    51 Ref<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin)
     51Ref<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin)
    5252{
    53     return DedicatedWorkerGlobalScope::create(url, identifier, userAgent, *this, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), idbConnectionProxy(), socketProvider());
     53    return DedicatedWorkerGlobalScope::create(url, identifier, userAgent, *this, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, WTFMove(topOrigin), timeOrigin, idbConnectionProxy(), socketProvider());
    5454}
    5555
  • trunk/Source/WebCore/workers/DedicatedWorkerThread.h

    r210923 r211594  
    5050
    5151protected:
    52     Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin) override;
     52    Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin) override;
    5353    void runEventLoop() override;
    5454
    5555private:
    56     DedicatedWorkerThread(const URL&, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags);
     56    DedicatedWorkerThread(const URL&, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags);
    5757
    5858    WorkerObjectProxy& m_workerObjectProxy;
  • trunk/Source/WebCore/workers/Worker.cpp

    r210323 r211594  
    8888    worker->setPendingActivity(worker.ptr());
    8989
     90    // https://html.spec.whatwg.org/multipage/workers.html#official-moment-of-creation
     91    worker->m_momentOfCreation = monotonicallyIncreasingTime();
     92
    9093    worker->m_scriptLoader = WorkerScriptLoader::create();
    9194    auto contentSecurityPolicyEnforcement = shouldBypassMainWorldContentSecurityPolicy ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceChildSrcDirective;
     
    162165    else {
    163166        const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders = m_contentSecurityPolicyResponseHeaders ? m_contentSecurityPolicyResponseHeaders.value() : scriptExecutionContext()->contentSecurityPolicy()->responseHeaders();
    164         m_contextProxy.startWorkerGlobalScope(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, m_shouldBypassMainWorldContentSecurityPolicy, m_runtimeFlags);
     167        m_contextProxy.startWorkerGlobalScope(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, m_shouldBypassMainWorldContentSecurityPolicy, m_momentOfCreation, m_runtimeFlags);
    165168        InspectorInstrumentation::scriptImported(*scriptExecutionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
    166169    }
  • trunk/Source/WebCore/workers/Worker.h

    r210323 r211594  
    8383    WorkerGlobalScopeProxy& m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
    8484    std::optional<ContentSecurityPolicyResponseHeaders> m_contentSecurityPolicyResponseHeaders;
     85    double m_momentOfCreation { 0 };
    8586    bool m_shouldBypassMainWorldContentSecurityPolicy { false };
    8687    JSC::RuntimeFlags m_runtimeFlags;
  • trunk/Source/WebCore/workers/WorkerGlobalScope.cpp

    r210923 r211594  
    3434#include "IDBConnectionProxy.h"
    3535#include "InspectorInstrumentation.h"
     36#include "Performance.h"
    3637#include "ScheduledAction.h"
    3738#include "ScriptSourceCode.h"
     
    5354namespace WebCore {
    5455
    55 WorkerGlobalScope::WorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, WorkerThread& thread, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
     56WorkerGlobalScope::WorkerGlobalScope(const URL& url, const String& identifier, const String& userAgent, WorkerThread& thread, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
    5657    : m_url(url)
    5758    , m_identifier(identifier)
     
    6970    , m_socketProvider(socketProvider)
    7071#endif
     72#if ENABLE(WEB_TIMING)
     73    , m_performance(Performance::create(*this, timeOrigin))
     74#endif
    7175{
    7276#if !ENABLE(INDEXED_DATABASE)
     
    348352}
    349353
     354#if ENABLE(WEB_TIMING)
     355
     356Performance& WorkerGlobalScope::performance() const
     357{
     358    return m_performance;
     359}
     360
     361#endif
     362
    350363} // namespace WebCore
  • trunk/Source/WebCore/workers/WorkerGlobalScope.h

    r210923 r211594  
    4040class ContentSecurityPolicyResponseHeaders;
    4141class Crypto;
     42class Performance;
    4243class ScheduledAction;
    4344class WorkerInspectorController;
     
    100101    Crypto& crypto();
    101102
     103#if ENABLE(WEB_TIMING)
     104    Performance& performance() const;
     105#endif
     106
    102107protected:
    103     WorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, WorkerThread&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
     108    WorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, WorkerThread&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
    104109
    105110    void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&);
     
    172177#endif
    173178
     179#if ENABLE(WEB_TIMING)
     180    Ref<Performance> m_performance;
     181#endif
     182
    174183    mutable RefPtr<Crypto> m_crypto;
    175184};
  • trunk/Source/WebCore/workers/WorkerGlobalScope.idl

    r210037 r211594  
    6363
    6464WorkerGlobalScope implements GlobalCrypto;
     65WorkerGlobalScope implements GlobalPerformance;
    6566WorkerGlobalScope implements WindowOrWorkerGlobalScope;
  • trunk/Source/WebCore/workers/WorkerGlobalScopeProxy.h

    r210323 r211594  
    4646    static WorkerGlobalScopeProxy& create(Worker&);
    4747
    48     virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, JSC::RuntimeFlags) = 0;
     48    virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, double timeOrigin, JSC::RuntimeFlags) = 0;
    4949    virtual void terminateWorkerGlobalScope() = 0;
    5050    virtual void postMessageToWorkerGlobalScope(RefPtr<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>) = 0;
  • trunk/Source/WebCore/workers/WorkerMessagingProxy.cpp

    r210828 r211594  
    6868}
    6969
    70 void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, JSC::RuntimeFlags runtimeFlags)
     70void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, double timeOrigin, JSC::RuntimeFlags runtimeFlags)
    7171{
    7272    // FIXME: This need to be revisited when we support nested worker one day
     
    8888#endif
    8989
    90     auto thread = DedicatedWorkerThread::create(scriptURL, identifier, userAgent, sourceCode, *this, *this, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, document.topOrigin(), proxy, socketProvider, runtimeFlags);
     90    auto thread = DedicatedWorkerThread::create(scriptURL, identifier, userAgent, sourceCode, *this, *this, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, document.topOrigin(), timeOrigin, proxy, socketProvider, runtimeFlags);
    9191
    9292    workerThreadCreated(thread.get());
  • trunk/Source/WebCore/workers/WorkerMessagingProxy.h

    r210323 r211594  
    4545    // Implementations of WorkerGlobalScopeProxy.
    4646    // (Only use these functions in the worker object thread.)
    47     void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, JSC::RuntimeFlags) final;
     47    void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, double timeOrigin, JSC::RuntimeFlags) final;
    4848    void terminateWorkerGlobalScope() final;
    4949    void postMessageToWorkerGlobalScope(RefPtr<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>) final;
  • trunk/Source/WebCore/workers/WorkerThread.cpp

    r210923 r211594  
    7373    WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData); WTF_MAKE_FAST_ALLOCATED;
    7474public:
    75     WorkerThreadStartupData(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin);
     75    WorkerThreadStartupData(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin);
    7676
    7777    URL m_scriptURL;
     
    8383    bool m_shouldBypassMainWorldContentSecurityPolicy;
    8484    Ref<SecurityOrigin> m_topOrigin;
     85    double m_timeOrigin;
    8586};
    8687
    87 WorkerThreadStartupData::WorkerThreadStartupData(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin)
     88WorkerThreadStartupData::WorkerThreadStartupData(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin)
    8889    : m_scriptURL(scriptURL.isolatedCopy())
    8990    , m_identifier(identifier.isolatedCopy())
     
    9495    , m_shouldBypassMainWorldContentSecurityPolicy(shouldBypassMainWorldContentSecurityPolicy)
    9596    , m_topOrigin(topOrigin.isolatedCopy())
    96 {
    97 }
    98 
    99 WorkerThread::WorkerThread(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
     97    , m_timeOrigin(timeOrigin)
     98{
     99}
     100
     101WorkerThread::WorkerThread(const URL& scriptURL, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
    100102    : m_threadID(0)
    101103    , m_workerLoaderProxy(workerLoaderProxy)
    102104    , m_workerReportingProxy(workerReportingProxy)
    103105    , m_runtimeFlags(runtimeFlags)
    104     , m_startupData(std::make_unique<WorkerThreadStartupData>(scriptURL, identifier, userAgent, sourceCode, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, topOrigin))
     106    , m_startupData(std::make_unique<WorkerThreadStartupData>(scriptURL, identifier, userAgent, sourceCode, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, topOrigin, timeOrigin))
    105107#if ENABLE(INDEXED_DATABASE)
    106108    , m_idbConnectionProxy(connectionProxy)
     
    162164    {
    163165        LockHolder lock(m_threadCreationMutex);
    164         m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_identifier, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_shouldBypassMainWorldContentSecurityPolicy, WTFMove(m_startupData->m_topOrigin));
     166        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_identifier, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_shouldBypassMainWorldContentSecurityPolicy, WTFMove(m_startupData->m_topOrigin), m_startupData->m_timeOrigin);
    165167
    166168        if (m_runLoop.terminated()) {
  • trunk/Source/WebCore/workers/WorkerThread.h

    r210923 r211594  
    8181
    8282protected:
    83     WorkerThread(const URL&, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags);
     83    WorkerThread(const URL&, const String& identifier, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, double timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags);
    8484
    8585    // Factory method for creating a new worker context for the thread.
    86     virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin) = 0;
     86    virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& identifier, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, double timeOrigin) = 0;
    8787
    8888    // Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
Note: See TracChangeset for help on using the changeset viewer.