⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267402 in webkit


Ignore:
Timestamp:
Sep 22, 2020, 1:46:36 AM (6 years ago)
Author:
weinig@apple.com
Message:

Update User Timing interfaces to User Timing Level 3
https://bugs.webkit.org/show_bug.cgi?id=216787

Reviewed by Alex Christensen.
LayoutTests/imported/w3c:

Import missing case-sensitivity test case from upstream and update the results
of User Timing tests now that we support Level 3.

  • web-platform-tests/user-timing/case-sensitivity.any-expected.txt: Added.
  • web-platform-tests/user-timing/case-sensitivity.any.html: Added.
  • web-platform-tests/user-timing/case-sensitivity.any.js: Added.
  • web-platform-tests/user-timing/case-sensitivity.any.worker-expected.txt: Added.
  • web-platform-tests/user-timing/case-sensitivity.any.worker.html: Added.
  • web-platform-tests/user-timing/idlharness.any-expected.txt:
  • web-platform-tests/user-timing/idlharness.any.worker-expected.txt:
  • web-platform-tests/user-timing/mark-entry-constructor.any-expected.txt:
  • web-platform-tests/user-timing/mark-entry-constructor.any.worker-expected.txt:
  • web-platform-tests/user-timing/mark-errors.any-expected.txt:
  • web-platform-tests/user-timing/mark-errors.any.worker-expected.txt:
  • web-platform-tests/user-timing/mark-l3.any-expected.txt:
  • web-platform-tests/user-timing/mark-l3.any.worker-expected.txt:
  • web-platform-tests/user-timing/mark-measure-return-objects.any-expected.txt:
  • web-platform-tests/user-timing/mark-measure-return-objects.any.worker-expected.txt:
  • web-platform-tests/user-timing/measure-l3.any-expected.txt:
  • web-platform-tests/user-timing/measure-l3.any.worker-expected.txt:
  • web-platform-tests/user-timing/measure-with-dict.any-expected.txt:
  • web-platform-tests/user-timing/measure-with-dict.any.worker-expected.txt:
  • web-platform-tests/user-timing/measure_exception-expected.txt:
  • web-platform-tests/user-timing/performance-measure-invalid.worker-expected.txt:
  • web-platform-tests/user-timing/structured-serialize-detail.any-expected.txt:
  • web-platform-tests/user-timing/structured-serialize-detail.any.worker-expected.txt:

Source/WebCore:

Adds support for User Timing Level 3 which adds more flexibility in how PerformanceMarks
and PerformanceMeasures are created via synthetic start/end times and associate 'details'
values serialized with events themselves.

Updates results to existing WPT and standalone tests.

  • CMakeLists.txt:
  • DerivedSources-input.xcfilelist:
  • DerivedSources-output.xcfilelist:
  • DerivedSources.make:
  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:

Add new files.

  • page/Performance.cpp:

(WebCore::Performance::mark):
(WebCore::Performance::clearMarks):
(WebCore::Performance::measure):
(WebCore::Performance::clearMeasures):

  • page/Performance.h:
  • page/Performance.idl:

Update for new signatures for mark and measure, and rename of UserTiming to PerformanceUserTiming.

  • page/PerformanceMark.cpp: Added.

(WebCore::peformanceNow):
(WebCore::PerformanceMark::create):
(WebCore::PerformanceMark::PerformanceMark):
(WebCore::PerformanceMark::detail):

  • page/PerformanceMark.h:
  • page/PerformanceMark.idl:

Add support for PerformanceMark's constructor detail getter. While the spec says to
serialize and the deserialize in the constructor, we only serialize, and delay deserialization
until the first access, which is a non-observable difference. We also utilize [CachedAttribute]
to only ever deserialize once per wrapper world (and also greatly simplify the GC shenanigans).

  • page/PerformanceMarkOptions.h: Added.
  • page/PerformanceMarkOptions.idl: Added.

Import and bind PerformanceMarkOptions dictionary to a new struct.

  • page/PerformanceMeasure.cpp: Added.

(WebCore::PerformanceMeasure::create):
(WebCore::PerformanceMeasure::PerformanceMeasure):
(WebCore::PerformanceMeasure::detail):

  • page/PerformanceMeasure.h:
  • page/PerformanceMeasure.idl:

Like with PerformanceMark, but there is no constructor here, so we only need to handle adding
support for the detail getter.

  • page/PerformanceMeasureOptions.h: Added.
  • page/PerformanceMeasureOptions.idl: Added.

Import and bind PerformanceMeasureOptions dictionary to a new struct.

  • page/PerformanceUserTiming.cpp:

(WebCore::restrictedMarkNamesToNavigationTimingFunctionMap):
(WebCore::restrictedMarkFunction):
(WebCore::isRestrictedMarkNameNonMainThread):
(WebCore::PerformanceUserTiming::isRestrictedMarkName):
Split up existing map to enable accessing it safely from a worker using conservative
callOnMainThreadAndWait approach, though since the map is immutable after initialization,
we can probably optimize this to allow concurrent querying in the future.

(WebCore::addPerformanceEntry):
Add helper, mirroring clearPerformanceEntries, to add entries.

(WebCore::PerformanceUserTiming::mark):
Matching the spec language, utilize the new PerformanceMark constructor to create
the mark.

(WebCore::PerformanceUserTiming::convertMarkToTimestamp const):
(WebCore::isNonEmptyDictionary):
(WebCore::PerformanceUserTiming::measure):
Implement measure support by dispatching various combinations of arguments to
overloads manually by inspecting the Variant.

  • page/PerformanceUserTiming.h:

Renames class from UserTiming to PerformanceUserTiming to match file names.

LayoutTests:

Update error text due to some changes in which exceptions are thrown due to
new support for User Timing Level 3.

  • performance-api/performance-measure-name-expected.txt:
  • performance-api/performance-now-api-expected.txt:
  • performance-api/user-timing-apis-expected.txt:
Location:
trunk
Files:
11 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r267401 r267402  
     12020-09-22  Sam Weinig  <weinig@apple.com>
     2
     3        Update User Timing interfaces to User Timing Level 3
     4        https://bugs.webkit.org/show_bug.cgi?id=216787
     5
     6        Reviewed by Alex Christensen.
     7
     8        Update error text due to some changes in which exceptions are thrown due to
     9        new support for User Timing Level 3.
     10
     11        * performance-api/performance-measure-name-expected.txt:
     12        * performance-api/performance-now-api-expected.txt:
     13        * performance-api/user-timing-apis-expected.txt:
     14
    1152020-09-22  Youenn Fablet  <youenn@apple.com>
    216
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r267376 r267402  
     12020-09-22  Sam Weinig  <weinig@apple.com>
     2
     3        Update User Timing interfaces to User Timing Level 3
     4        https://bugs.webkit.org/show_bug.cgi?id=216787
     5
     6        Reviewed by Alex Christensen.
     7       
     8        Import missing case-sensitivity test case from upstream and update the results
     9        of User Timing tests now that we support Level 3.
     10
     11        * web-platform-tests/user-timing/case-sensitivity.any-expected.txt: Added.
     12        * web-platform-tests/user-timing/case-sensitivity.any.html: Added.
     13        * web-platform-tests/user-timing/case-sensitivity.any.js: Added.
     14        * web-platform-tests/user-timing/case-sensitivity.any.worker-expected.txt: Added.
     15        * web-platform-tests/user-timing/case-sensitivity.any.worker.html: Added.
     16        * web-platform-tests/user-timing/idlharness.any-expected.txt:
     17        * web-platform-tests/user-timing/idlharness.any.worker-expected.txt:
     18        * web-platform-tests/user-timing/mark-entry-constructor.any-expected.txt:
     19        * web-platform-tests/user-timing/mark-entry-constructor.any.worker-expected.txt:
     20        * web-platform-tests/user-timing/mark-errors.any-expected.txt:
     21        * web-platform-tests/user-timing/mark-errors.any.worker-expected.txt:
     22        * web-platform-tests/user-timing/mark-l3.any-expected.txt:
     23        * web-platform-tests/user-timing/mark-l3.any.worker-expected.txt:
     24        * web-platform-tests/user-timing/mark-measure-return-objects.any-expected.txt:
     25        * web-platform-tests/user-timing/mark-measure-return-objects.any.worker-expected.txt:
     26        * web-platform-tests/user-timing/measure-l3.any-expected.txt:
     27        * web-platform-tests/user-timing/measure-l3.any.worker-expected.txt:
     28        * web-platform-tests/user-timing/measure-with-dict.any-expected.txt:
     29        * web-platform-tests/user-timing/measure-with-dict.any.worker-expected.txt:
     30        * web-platform-tests/user-timing/measure_exception-expected.txt:
     31        * web-platform-tests/user-timing/performance-measure-invalid.worker-expected.txt:
     32        * web-platform-tests/user-timing/structured-serialize-detail.any-expected.txt:
     33        * web-platform-tests/user-timing/structured-serialize-detail.any.worker-expected.txt:
     34
    1352020-09-21  Chris Dumez  <cdumez@apple.com>
    236
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any-expected.txt

    r264255 r267402  
    55PASS Partial interface Performance: member names are unique
    66PASS PerformanceMark interface: existence and properties of interface object
    7 FAIL PerformanceMark interface object length assert_equals: wrong value for PerformanceMark.length expected 1 but got 0
     7PASS PerformanceMark interface object length
    88PASS PerformanceMark interface object name
    99PASS PerformanceMark interface: existence and properties of interface prototype object
    1010PASS PerformanceMark interface: existence and properties of interface prototype object's "constructor" property
    1111PASS PerformanceMark interface: existence and properties of interface prototype object's @@unscopables property
    12 FAIL PerformanceMark interface: attribute detail assert_true: The prototype object must have a property "detail" expected true got false
     12PASS PerformanceMark interface: attribute detail
    1313PASS PerformanceMark must be primary interface of mark
    1414PASS Stringification of mark
    15 FAIL PerformanceMark interface: mark must inherit property "detail" with the proper type assert_inherits: property "detail" not found in prototype chain
     15PASS PerformanceMark interface: mark must inherit property "detail" with the proper type
    1616PASS PerformanceMeasure interface: existence and properties of interface object
    1717PASS PerformanceMeasure interface object length
     
    2020PASS PerformanceMeasure interface: existence and properties of interface prototype object's "constructor" property
    2121PASS PerformanceMeasure interface: existence and properties of interface prototype object's @@unscopables property
    22 FAIL PerformanceMeasure interface: attribute detail assert_true: The prototype object must have a property "detail" expected true got false
     22PASS PerformanceMeasure interface: attribute detail
    2323PASS PerformanceMeasure must be primary interface of measure
    2424PASS Stringification of measure
    25 FAIL PerformanceMeasure interface: measure must inherit property "detail" with the proper type assert_inherits: property "detail" not found in prototype chain
     25PASS PerformanceMeasure interface: measure must inherit property "detail" with the proper type
    2626PASS Performance interface: operation mark(DOMString, optional PerformanceMarkOptions)
    2727PASS Performance interface: operation clearMarks(optional DOMString)
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any.worker-expected.txt

    r264255 r267402  
    55PASS Partial interface Performance: member names are unique
    66PASS PerformanceMark interface: existence and properties of interface object
    7 FAIL PerformanceMark interface object length assert_equals: wrong value for PerformanceMark.length expected 1 but got 0
     7PASS PerformanceMark interface object length
    88PASS PerformanceMark interface object name
    99PASS PerformanceMark interface: existence and properties of interface prototype object
    1010PASS PerformanceMark interface: existence and properties of interface prototype object's "constructor" property
    1111PASS PerformanceMark interface: existence and properties of interface prototype object's @@unscopables property
    12 FAIL PerformanceMark interface: attribute detail assert_true: The prototype object must have a property "detail" expected true got false
     12PASS PerformanceMark interface: attribute detail
    1313PASS PerformanceMark must be primary interface of mark
    1414PASS Stringification of mark
    15 FAIL PerformanceMark interface: mark must inherit property "detail" with the proper type assert_inherits: property "detail" not found in prototype chain
     15PASS PerformanceMark interface: mark must inherit property "detail" with the proper type
    1616PASS PerformanceMeasure interface: existence and properties of interface object
    1717PASS PerformanceMeasure interface object length
     
    2020PASS PerformanceMeasure interface: existence and properties of interface prototype object's "constructor" property
    2121PASS PerformanceMeasure interface: existence and properties of interface prototype object's @@unscopables property
    22 FAIL PerformanceMeasure interface: attribute detail assert_true: The prototype object must have a property "detail" expected true got false
     22PASS PerformanceMeasure interface: attribute detail
    2323PASS PerformanceMeasure must be primary interface of measure
    2424PASS Stringification of measure
    25 FAIL PerformanceMeasure interface: measure must inherit property "detail" with the proper type assert_inherits: property "detail" not found in prototype chain
     25PASS PerformanceMeasure interface: measure must inherit property "detail" with the proper type
    2626PASS Performance interface: operation mark(DOMString, optional PerformanceMarkOptions)
    2727PASS Performance interface: operation clearMarks(optional DOMString)
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any-expected.txt

    r265749 r267402  
    11
    2 FAIL Mark entry can be created by 'new PerformanceMark(string)'. Illegal constructor
    3 FAIL Mark entry can be created by 'new PerformanceMark(string, {})'. Illegal constructor
    4 FAIL Mark entry can be created by 'new PerformanceMark(string, {startTime})'. Illegal constructor
    5 FAIL Mark entry can be created by 'new PerformanceMark(string, {detail})'. Illegal constructor
    6 FAIL Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'. Illegal constructor
    7 FAIL Using new PerformanceMark() shouldn't add the entry to performance timeline. Illegal constructor
     2PASS Mark entry can be created by 'new PerformanceMark(string)'.
     3PASS Mark entry can be created by 'new PerformanceMark(string, {})'.
     4PASS Mark entry can be created by 'new PerformanceMark(string, {startTime})'.
     5PASS Mark entry can be created by 'new PerformanceMark(string, {detail})'.
     6PASS Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'.
     7PASS Using new PerformanceMark() shouldn't add the entry to performance timeline.
    88
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any.worker-expected.txt

    r265749 r267402  
    11
    2 FAIL Mark entry can be created by 'new PerformanceMark(string)'. Illegal constructor
    3 FAIL Mark entry can be created by 'new PerformanceMark(string, {})'. Illegal constructor
    4 FAIL Mark entry can be created by 'new PerformanceMark(string, {startTime})'. Illegal constructor
    5 FAIL Mark entry can be created by 'new PerformanceMark(string, {detail})'. Illegal constructor
    6 FAIL Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'. Illegal constructor
    7 FAIL Using new PerformanceMark() shouldn't add the entry to performance timeline. Illegal constructor
     2PASS Mark entry can be created by 'new PerformanceMark(string)'.
     3PASS Mark entry can be created by 'new PerformanceMark(string, {})'.
     4PASS Mark entry can be created by 'new PerformanceMark(string, {startTime})'.
     5PASS Mark entry can be created by 'new PerformanceMark(string, {detail})'.
     6PASS Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'.
     7PASS Using new PerformanceMark() shouldn't add the entry to performance timeline.
    88
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any-expected.txt

    r264255 r267402  
    11
    2 FAIL Number should be rejected as the mark-options. assert_throws_js: Number passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", 123); }" did not throw
    3 FAIL NaN should be rejected as the mark-options. assert_throws_js: NaN passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", NaN); }" did not throw
    4 FAIL Infinity should be rejected as the mark-options. assert_throws_js: Infinity passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", Infinity); }" did not throw
    5 FAIL String should be rejected as the mark-options. assert_throws_js: String passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", "string"); }" did not throw
     2PASS Number should be rejected as the mark-options.
     3PASS NaN should be rejected as the mark-options.
     4PASS Infinity should be rejected as the mark-options.
     5PASS String should be rejected as the mark-options.
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL Number should be rejected as the mark-options. assert_throws_js: Number passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", 123); }" did not throw
    3 FAIL NaN should be rejected as the mark-options. assert_throws_js: NaN passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", NaN); }" did not throw
    4 FAIL Infinity should be rejected as the mark-options. assert_throws_js: Infinity passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", Infinity); }" did not throw
    5 FAIL String should be rejected as the mark-options. assert_throws_js: String passed as a dict argument should cause type-error. function "function () { self.performance.mark("mark1", "string"); }" did not throw
     2PASS Number should be rejected as the mark-options.
     3PASS NaN should be rejected as the mark-options.
     4PASS Infinity should be rejected as the mark-options.
     5PASS String should be rejected as the mark-options.
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any-expected.txt

    r264255 r267402  
    11
    2 FAIL mark entries' detail and startTime are customizable. undefined is not an object (evaluating 'ae.name')
     2PASS mark entries' detail and startTime are customizable.
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL mark entries' detail and startTime are customizable. undefined is not an object (evaluating 'ae.name')
     2PASS mark entries' detail and startTime are customizable.
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any-expected.txt

    r264255 r267402  
    11
    2 FAIL L3: performance.measure(name) should return an entry. assert_true: expected true got false
    3 FAIL L3: performance.measure(name, param1) should return an entry. The string did not match the expected pattern.
    4 FAIL L3: performance.measure(name, param1, param2) should return an entry. assert_true: expected true got false
    5 FAIL L3: performance.mark(name) should return an entry. assert_true: expected true got false
    6 FAIL L3: performance.mark(name, param) should return an entry. assert_true: expected true got false
     2PASS L3: performance.measure(name) should return an entry.
     3PASS L3: performance.measure(name, param1) should return an entry.
     4PASS L3: performance.measure(name, param1, param2) should return an entry.
     5PASS L3: performance.mark(name) should return an entry.
     6PASS L3: performance.mark(name, param) should return an entry.
    77
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL L3: performance.measure(name) should return an entry. assert_true: expected true got false
    3 FAIL L3: performance.measure(name, param1) should return an entry. No mark named '[object Object]' exists
    4 FAIL L3: performance.measure(name, param1, param2) should return an entry. assert_true: expected true got false
    5 FAIL L3: performance.mark(name) should return an entry. assert_true: expected true got false
    6 FAIL L3: performance.mark(name, param) should return an entry. assert_true: expected true got false
     2PASS L3: performance.measure(name) should return an entry.
     3PASS L3: performance.measure(name, param1) should return an entry.
     4PASS L3: performance.measure(name, param1, param2) should return an entry.
     5PASS L3: performance.mark(name) should return an entry.
     6PASS L3: performance.mark(name, param) should return an entry.
    77
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any-expected.txt

    r264255 r267402  
    11
    2 FAIL When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0. undefined is not an object (evaluating 'measureEntry.startTime')
    3 FAIL When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now. undefined is not an object (evaluating 'measureEntry.startTime')
    4 FAIL When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively undefined is not an object (evaluating 'entry.startTime')
     2PASS When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0.
     3PASS When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now.
     4PASS When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0. undefined is not an object (evaluating 'measureEntry.startTime')
    3 FAIL When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now. undefined is not an object (evaluating 'measureEntry.startTime')
    4 FAIL When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively undefined is not an object (evaluating 'entry.startTime')
     2PASS When the end mark is given and the start is unprovided, the end time of the measure entry should be the end mark's time, the start time should be 0.
     3PASS When the start mark is given and the end is unprovided, the start time of the measure entry should be the start mark's time, the end should be now.
     4PASS When start and end mark are both given, the start time and end time of the measure entry should be the the marks' time, repectively
    55
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any-expected.txt

    r264255 r267402  
    11
    2 FAIL measure entries' detail and start/end are customizable The string did not match the expected pattern.
    3 FAIL measure should throw a TypeError when passed an invalid argument combination assert_throws_js: measure should throw a TypeError when passed an options object and an end time function "function () {
    4       self.performance.measure("optionsAndNumberEnd", {'start': 2}, 12);
    5     }" threw object "SyntaxError: The string did not match the expected pattern." ("SyntaxError") expected instance of function "function TypeError() {
    6     [native code]
    7 }" ("TypeError")
     2PASS measure entries' detail and start/end are customizable
     3PASS measure should throw a TypeError when passed an invalid argument combination
    84
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL measure entries' detail and start/end are customizable No mark named 'null' exists
    3 FAIL measure should throw a TypeError when passed an invalid argument combination assert_throws_js: measure should throw a TypeError when passed an options object and an end time function "function () {
    4       self.performance.measure("optionsAndNumberEnd", {'start': 2}, 12);
    5     }" threw object "SyntaxError: No mark named '12' exists" ("SyntaxError") expected instance of function "function TypeError() {
    6     [native code]
    7 }" ("TypeError")
     2PASS measure entries' detail and start/end are customizable
     3PASS measure should throw a TypeError when passed an invalid argument combination
    84
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt

    r264255 r267402  
    1212PASS Invocation of performance.measure("Exception6", "NonExistMark1", "NonExistMark2") should throw SYNTAX_ERR Exception.
    1313PASS Invocation of performance.measure("Exception7", "redirectStart") should throw INVALID_ACCESS_ERR Exception.
    14 FAIL Invocation of performance.measure("Exception8", {"detail": "non-empty"}) should throw TypeError Exception. assert_throws_js: Invocation of performance.measure("Exception8", {"detail": "non-empty"}) should throw TypeError Exception. function "function () {eval(func_str)}" threw object "SyntaxError: The string did not match the expected pattern." ("SyntaxError") expected instance of function "function TypeError() {
    15     [native code]
    16 }" ("TypeError")
    17 FAIL Invocation of performance.measure("Exception9", {"start": 1, "duration": 2, "end": 3}) should throw TypeError Exception. assert_throws_js: Invocation of performance.measure("Exception9", {"start": 1, "duration": 2, "end": 3}) should throw TypeError Exception. function "function () {eval(func_str)}" threw object "SyntaxError: The string did not match the expected pattern." ("SyntaxError") expected instance of function "function TypeError() {
    18     [native code]
    19 }" ("TypeError")
     14PASS Invocation of performance.measure("Exception8", {"detail": "non-empty"}) should throw TypeError Exception.
     15PASS Invocation of performance.measure("Exception9", {"start": 1, "duration": 2, "end": 3}) should throw TypeError Exception.
    2016
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/performance-measure-invalid.worker-expected.txt

    r264255 r267402  
    11
    2 FAIL When converting 'navigationStart' to a timestamp, the global object has to be a Window object. assert_throws_js: function "() => {
    3     performance.measure('name', 'navigationStart', 'navigationStart');
    4   }" threw object "SyntaxError: No mark named 'navigationStart' exists" ("SyntaxError") expected instance of function "function TypeError() {
    5     [native code]
    6 }" ("TypeError")
     2PASS When converting 'navigationStart' to a timestamp, the global object has to be a Window object.
    73
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any-expected.txt

    r265749 r267402  
    11
    2 FAIL The detail property in the mark constructor should be structured-clone. Illegal constructor
    3 FAIL The detail property in the mark method should be structured-clone. undefined is not an object (evaluating 'markEntry.detail')
    4 FAIL When accessing detail from a mark entry and the detail is not provided, just return a null value. undefined is not an object (evaluating 'markEntry.detail')
    5 FAIL Mark: Throw an exception when the detail property cannot be structured-serialized. assert_throws_dom: Trying to structured-serialize a Symbol. function "()=>{
    6     new PerformanceMark("A", { detail });
    7   }" threw object "TypeError: Illegal constructor" that is not a DOMException DataCloneError: property "code" is equal to undefined, expected 25
    8 FAIL The detail property in the measure method should be structured-clone. The string did not match the expected pattern.
    9 FAIL The detail property in the measure method should be the same reference. The string did not match the expected pattern.
    10 FAIL When accessing detail from a measure entry and the detail is not provided, just return a null value. undefined is not an object (evaluating 'measureEntry.detail')
    11 FAIL Measure: Throw an exception when the detail property cannot be structured-serialized. assert_throws_dom: Trying to structured-serialize a Symbol. function "()=>{
    12     performance.measure("A", { start: 0, detail });
    13   }" threw object "SyntaxError: The string did not match the expected pattern." that is not a DOMException DataCloneError: property "code" is equal to 12, expected 25
    14 FAIL The detail object is cloned when passed to mark API. undefined is not an object (evaluating 'mark.detail')
     2PASS The detail property in the mark constructor should be structured-clone.
     3PASS The detail property in the mark method should be structured-clone.
     4PASS When accessing detail from a mark entry and the detail is not provided, just return a null value.
     5PASS Mark: Throw an exception when the detail property cannot be structured-serialized.
     6PASS The detail property in the measure method should be structured-clone.
     7PASS The detail property in the measure method should be the same reference.
     8PASS When accessing detail from a measure entry and the detail is not provided, just return a null value.
     9PASS Measure: Throw an exception when the detail property cannot be structured-serialized.
     10PASS The detail object is cloned when passed to mark API.
    1511
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any.worker-expected.txt

    r265749 r267402  
    11
    2 FAIL The detail property in the mark constructor should be structured-clone. Illegal constructor
    3 FAIL The detail property in the mark method should be structured-clone. undefined is not an object (evaluating 'markEntry.detail')
    4 FAIL When accessing detail from a mark entry and the detail is not provided, just return a null value. undefined is not an object (evaluating 'markEntry.detail')
    5 FAIL Mark: Throw an exception when the detail property cannot be structured-serialized. assert_throws_dom: Trying to structured-serialize a Symbol. function "()=>{
    6     new PerformanceMark("A", { detail });
    7   }" threw object "TypeError: Illegal constructor" that is not a DOMException DataCloneError: property "code" is equal to undefined, expected 25
    8 FAIL The detail property in the measure method should be structured-clone. No mark named '[object Object]' exists
    9 FAIL The detail property in the measure method should be the same reference. No mark named '[object Object]' exists
    10 FAIL When accessing detail from a measure entry and the detail is not provided, just return a null value. undefined is not an object (evaluating 'measureEntry.detail')
    11 FAIL Measure: Throw an exception when the detail property cannot be structured-serialized. assert_throws_dom: Trying to structured-serialize a Symbol. function "()=>{
    12     performance.measure("A", { start: 0, detail });
    13   }" threw object "SyntaxError: No mark named '[object Object]' exists" that is not a DOMException DataCloneError: property "code" is equal to 12, expected 25
    14 FAIL The detail object is cloned when passed to mark API. undefined is not an object (evaluating 'mark.detail')
     2PASS The detail property in the mark constructor should be structured-clone.
     3PASS The detail property in the mark method should be structured-clone.
     4PASS When accessing detail from a mark entry and the detail is not provided, just return a null value.
     5PASS Mark: Throw an exception when the detail property cannot be structured-serialized.
     6PASS The detail property in the measure method should be structured-clone.
     7PASS The detail property in the measure method should be the same reference.
     8PASS When accessing detail from a measure entry and the detail is not provided, just return a null value.
     9PASS Measure: Throw an exception when the detail property cannot be structured-serialized.
     10PASS The detail object is cloned when passed to mark API.
    1511
  • trunk/LayoutTests/performance-api/performance-measure-name-expected.txt

    r219663 r267402  
    55
    66PASS performance.mark("existing-mark-name") did not throw exception.
    7 PASS performance.measure("measure-name", "x") threw exception SyntaxError: The string did not match the expected pattern..
    8 PASS performance.measure("measure-name", "existing-mark-name", "x") threw exception SyntaxError: The string did not match the expected pattern..
     7PASS performance.measure("measure-name", "x") threw exception SyntaxError: No mark named 'x' exists.
     8PASS performance.measure("measure-name", "existing-mark-name", "x") threw exception SyntaxError: No mark named 'x' exists.
    99PASS performance.mark("x") did not throw exception.
    1010PASS performance.measure("measure-name", "x") did not throw exception.
  • trunk/LayoutTests/performance-api/performance-now-api-expected.txt

    r211594 r267402  
    77PASS Performance is defined.
    88PASS Performance.prototype.now is defined.
    9 PASS new Performance() threw exception TypeError: function is not a constructor (evaluating 'new Performance()').
     9PASS new Performance() threw exception TypeError: Illegal constructor.
    1010performance
    1111PASS performance is defined.
     
    1919PASS [Worker] Performance is defined.
    2020PASS [Worker] Performance.prototype.now is defined.
    21 PASS [Worker] new Performance() threw exception TypeError: function is not a constructor (evaluating 'new Performance()').
     21PASS [Worker] new Performance() threw exception TypeError: Illegal constructor.
    2222[Worker] performance
    2323PASS [Worker] performance is defined.
  • trunk/LayoutTests/performance-api/user-timing-apis-expected.txt

    r265749 r267402  
    66PerformanceMark
    77PASS PerformanceMark is defined.
    8 PASS new PerformanceMark() threw exception TypeError: Illegal constructor.
     8PASS new PerformanceMark() threw exception TypeError: Not enough arguments.
    99
    1010PerformanceMeasure
     
    2929[Worker] PerformanceMark
    3030PASS [Worker] PerformanceMark is defined.
    31 PASS [Worker] new PerformanceMark() threw exception TypeError: Illegal constructor.
     31PASS [Worker] new PerformanceMark() threw exception TypeError: Not enough arguments.
    3232[Worker]
    3333[Worker] PerformanceMeasure
  • trunk/Source/WebCore/CMakeLists.txt

    r267328 r267402  
    10531053    page/PerformanceEntry.idl
    10541054    page/PerformanceMark.idl
     1055    page/PerformanceMarkOptions.idl
    10551056    page/PerformanceMeasure.idl
     1057    page/PerformanceMeasureOptions.idl
    10561058    page/PerformanceObserver.idl
    10571059    page/PerformanceObserverCallback.idl
  • trunk/Source/WebCore/ChangeLog

    r267401 r267402  
     12020-09-22  Sam Weinig  <weinig@apple.com>
     2
     3        Update User Timing interfaces to User Timing Level 3
     4        https://bugs.webkit.org/show_bug.cgi?id=216787
     5
     6        Reviewed by Alex Christensen.
     7
     8        Adds support for User Timing Level 3 which adds more flexibility in how PerformanceMarks
     9        and PerformanceMeasures are created via synthetic start/end times and associate 'details'
     10        values serialized with events themselves.
     11
     12        Updates results to existing WPT and standalone tests.
     13
     14        * CMakeLists.txt:
     15        * DerivedSources-input.xcfilelist:
     16        * DerivedSources-output.xcfilelist:
     17        * DerivedSources.make:
     18        * Sources.txt:
     19        * WebCore.xcodeproj/project.pbxproj:
     20        Add new files.
     21
     22        * page/Performance.cpp:
     23        (WebCore::Performance::mark):
     24        (WebCore::Performance::clearMarks):
     25        (WebCore::Performance::measure):
     26        (WebCore::Performance::clearMeasures):
     27        * page/Performance.h:
     28        * page/Performance.idl:
     29        Update for new signatures for mark and measure, and rename of UserTiming to PerformanceUserTiming.
     30
     31        * page/PerformanceMark.cpp: Added.
     32        (WebCore::peformanceNow):
     33        (WebCore::PerformanceMark::create):
     34        (WebCore::PerformanceMark::PerformanceMark):
     35        (WebCore::PerformanceMark::detail):
     36        * page/PerformanceMark.h:
     37        * page/PerformanceMark.idl:
     38        Add support for PerformanceMark's constructor `detail` getter. While the spec says to
     39        serialize and the deserialize in the constructor, we only serialize, and delay deserialization
     40        until the first access, which is a non-observable difference. We also utilize [CachedAttribute]
     41        to only ever deserialize once per wrapper world (and also greatly simplify the GC shenanigans).
     42       
     43        * page/PerformanceMarkOptions.h: Added.
     44        * page/PerformanceMarkOptions.idl: Added.
     45        Import and bind PerformanceMarkOptions dictionary to a new struct.
     46       
     47        * page/PerformanceMeasure.cpp: Added.
     48        (WebCore::PerformanceMeasure::create):
     49        (WebCore::PerformanceMeasure::PerformanceMeasure):
     50        (WebCore::PerformanceMeasure::detail):
     51        * page/PerformanceMeasure.h:
     52        * page/PerformanceMeasure.idl:
     53        Like with PerformanceMark, but there is no constructor here, so we only need to handle adding
     54        support for the detail getter.
     55
     56        * page/PerformanceMeasureOptions.h: Added.
     57        * page/PerformanceMeasureOptions.idl: Added.
     58        Import and bind PerformanceMeasureOptions dictionary to a new struct.
     59       
     60        * page/PerformanceUserTiming.cpp:
     61        (WebCore::restrictedMarkNamesToNavigationTimingFunctionMap):
     62        (WebCore::restrictedMarkFunction):
     63        (WebCore::isRestrictedMarkNameNonMainThread):
     64        (WebCore::PerformanceUserTiming::isRestrictedMarkName):
     65        Split up existing map to enable accessing it safely from a worker using conservative
     66        callOnMainThreadAndWait approach, though since the map is immutable after initialization,
     67        we can probably optimize this to allow concurrent querying in the future.
     68
     69        (WebCore::addPerformanceEntry):
     70        Add helper, mirroring clearPerformanceEntries, to add entries.
     71
     72        (WebCore::PerformanceUserTiming::mark):
     73        Matching the spec language, utilize the new PerformanceMark constructor to create
     74        the mark.
     75
     76        (WebCore::PerformanceUserTiming::convertMarkToTimestamp const):
     77        (WebCore::isNonEmptyDictionary):
     78        (WebCore::PerformanceUserTiming::measure):
     79        Implement measure support by dispatching various combinations of arguments to
     80        overloads manually by inspecting the Variant.
     81
     82        * page/PerformanceUserTiming.h:
     83        Renames class from UserTiming to PerformanceUserTiming to match file names.
     84
    1852020-09-22  Youenn Fablet  <youenn@apple.com>
    286
  • trunk/Source/WebCore/DerivedSources-input.xcfilelist

    r267146 r267402  
    10311031$(PROJECT_DIR)/page/PerformanceEntry.idl
    10321032$(PROJECT_DIR)/page/PerformanceMark.idl
     1033$(PROJECT_DIR)/page/PerformanceMarkOptions.idl
    10331034$(PROJECT_DIR)/page/PerformanceMeasure.idl
     1035$(PROJECT_DIR)/page/PerformanceMeasureOptions.idl
    10341036$(PROJECT_DIR)/page/PerformanceNavigation.idl
    10351037$(PROJECT_DIR)/page/PerformanceObserver.idl
  • trunk/Source/WebCore/DerivedSources-output.xcfilelist

    r267146 r267402  
    13911391$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMark.cpp
    13921392$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMark.h
     1393$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMarkOptions.cpp
     1394$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMarkOptions.h
    13931395$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasure.cpp
    13941396$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasure.h
     1397$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasureOptions.cpp
     1398$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasureOptions.h
    13951399$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceNavigation.cpp
    13961400$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceNavigation.h
  • trunk/Source/WebCore/DerivedSources.make

    r267166 r267402  
    10421042    $(WebCore)/page/PerformanceEntry.idl \
    10431043    $(WebCore)/page/PerformanceMark.idl \
     1044    $(WebCore)/page/PerformanceMarkOptions.idl \
    10441045    $(WebCore)/page/PerformanceMeasure.idl \
     1046    $(WebCore)/page/PerformanceMeasureOptions.idl \
    10451047    $(WebCore)/page/PerformanceNavigation.idl \
    10461048    $(WebCore)/page/PerformanceObserver.idl \
  • trunk/Source/WebCore/Sources.txt

    r267328 r267402  
    16341634page/PerformanceLogging.cpp
    16351635page/PerformanceLoggingClient.cpp
     1636page/PerformanceMark.cpp
     1637page/PerformanceMeasure.cpp
    16361638page/PerformanceMonitor.cpp
    16371639page/PerformanceNavigation.cpp
     
    32053207JSPerformanceEntry.cpp
    32063208JSPerformanceMark.cpp
     3209JSPerformanceMarkOptions.cpp
    32073210JSPerformanceMeasure.cpp
     3211JSPerformanceMeasureOptions.cpp
    32083212JSPerformanceNavigation.cpp
    32093213JSPerformanceObserver.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r267328 r267402  
    23012301                7C7903B31F86F95C00463A70 /* ImageBitmapRenderingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7903B01F86F95C00463A70 /* ImageBitmapRenderingContext.h */; };
    23022302                7C7941E51C56C29300A4C58E /* DataDetectorsCoreSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */; };
     2303                7C7BF9422516C90C00808682 /* PerformanceMarkOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7BF93E2516C8BC00808682 /* PerformanceMarkOptions.h */; };
     2304                7C7BF94C2516FA5400808682 /* PerformanceMeasureOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7BF9492516FA5400808682 /* PerformanceMeasureOptions.h */; };
    23032305                7C8139A61ED6286A00CE26E8 /* JSDOMAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8139A31ED6281D00CE26E8 /* JSDOMAttribute.h */; settings = {ATTRIBUTES = (Private, ); }; };
    23042306                7C8139A71ED6287400CE26E8 /* JSDOMOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8139A41ED6281D00CE26E8 /* JSDOMOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1026310265                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
    1026410266                7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataDetectorsCoreSoftLink.h; sourceTree = "<group>"; };
     10267                7C7BF93E2516C8BC00808682 /* PerformanceMarkOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerformanceMarkOptions.h; sourceTree = "<group>"; };
     10268                7C7BF9402516C8BC00808682 /* PerformanceMarkOptions.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PerformanceMarkOptions.idl; sourceTree = "<group>"; };
     10269                7C7BF9442516CC9200808682 /* PerformanceMark.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceMark.cpp; sourceTree = "<group>"; };
     10270                7C7BF9492516FA5400808682 /* PerformanceMeasureOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerformanceMeasureOptions.h; sourceTree = "<group>"; };
     10271                7C7BF94B2516FA5400808682 /* PerformanceMeasureOptions.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = PerformanceMeasureOptions.idl; sourceTree = "<group>"; };
     10272                7C7BF9502516FB5400808682 /* PerformanceMeasure.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceMeasure.cpp; sourceTree = "<group>"; };
    1026510273                7C7C769C22F67ECD0032BCCD /* WHLSLMangledNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLMangledNames.h; sourceTree = "<group>"; };
    1026610274                7C8139A31ED6281D00CE26E8 /* JSDOMAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMAttribute.h; sourceTree = "<group>"; };
     
    2157521583                                0FF2E80C1EE0D430009EABD4 /* PerformanceLoggingClient.cpp */,
    2157621584                                0F850FE21ED7C18300FB77A7 /* PerformanceLoggingClient.h */,
     21585                                7C7BF9442516CC9200808682 /* PerformanceMark.cpp */,
    2157721586                                37C738E81EDBD2ED003F2B0B /* PerformanceMark.h */,
    2157821587                                7CE221EE251429F40006886B /* PerformanceMark.idl */,
     21588                                7C7BF93E2516C8BC00808682 /* PerformanceMarkOptions.h */,
     21589                                7C7BF9402516C8BC00808682 /* PerformanceMarkOptions.idl */,
     21590                                7C7BF9502516FB5400808682 /* PerformanceMeasure.cpp */,
    2157921591                                37C738EA1EDBD381003F2B0B /* PerformanceMeasure.h */,
    2158021592                                7CE221F0251429F50006886B /* PerformanceMeasure.idl */,
     21593                                7C7BF9492516FA5400808682 /* PerformanceMeasureOptions.h */,
     21594                                7C7BF94B2516FA5400808682 /* PerformanceMeasureOptions.idl */,
    2158121595                                83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */,
    2158221596                                83FE90261E307C1C003E9199 /* PerformanceMonitor.h */,
     
    3316833182                                0F850FE31ED7C18300FB77A7 /* PerformanceLoggingClient.h in Headers */,
    3316933183                                37C738E91EDBD2FA003F2B0B /* PerformanceMark.h in Headers */,
     33184                                7C7BF9422516C90C00808682 /* PerformanceMarkOptions.h in Headers */,
    3317033185                                37C738EB1EDBD384003F2B0B /* PerformanceMeasure.h in Headers */,
     33186                                7C7BF94C2516FA5400808682 /* PerformanceMeasureOptions.h in Headers */,
    3317133187                                83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */,
    3317233188                                8AF4E55611DC5A36000ED3DE /* PerformanceNavigation.h in Headers */,
  • trunk/Source/WebCore/page/Performance.cpp

    r266027 r267402  
    4040#include "Frame.h"
    4141#include "PerformanceEntry.h"
     42#include "PerformanceMarkOptions.h"
     43#include "PerformanceMeasureOptions.h"
    4244#include "PerformanceNavigation.h"
    4345#include "PerformanceObserver.h"
     
    297299}
    298300
    299 ExceptionOr<void> Performance::mark(const String& markName)
     301ExceptionOr<Ref<PerformanceMark>> Performance::mark(JSC::JSGlobalObject& globalObject, const String& markName, Optional<PerformanceMarkOptions>&& markOptions)
    300302{
    301303    if (!m_userTiming)
    302         m_userTiming = makeUnique<UserTiming>(*this);
    303 
    304     auto result = m_userTiming->mark(markName);
    305     if (result.hasException())
    306         return result.releaseException();
    307 
    308     queueEntry(result.releaseReturnValue());
    309 
    310     return { };
     304        m_userTiming = makeUnique<PerformanceUserTiming>(*this);
     305
     306    auto mark = m_userTiming->mark(globalObject, markName, WTFMove(markOptions));
     307    if (mark.hasException())
     308        return mark.releaseException();
     309
     310    queueEntry(mark.returnValue().get());
     311    return mark.releaseReturnValue();
    311312}
    312313
     
    314315{
    315316    if (!m_userTiming)
    316         m_userTiming = makeUnique<UserTiming>(*this);
     317        m_userTiming = makeUnique<PerformanceUserTiming>(*this);
    317318    m_userTiming->clearMarks(markName);
    318319}
    319320
    320 ExceptionOr<void> Performance::measure(const String& measureName, const String& startMark, const String& endMark)
     321ExceptionOr<Ref<PerformanceMeasure>> Performance::measure(JSC::JSGlobalObject& globalObject, const String& measureName, Optional<StartOrMeasureOptions>&& startOrMeasureOptions, const String& endMark)
    321322{
    322323    if (!m_userTiming)
    323         m_userTiming = makeUnique<UserTiming>(*this);
    324 
    325     auto result = m_userTiming->measure(measureName, startMark, endMark);
    326     if (result.hasException())
    327         return result.releaseException();
    328 
    329     queueEntry(result.releaseReturnValue());
    330 
    331     return { };
     324        m_userTiming = makeUnique<PerformanceUserTiming>(*this);
     325
     326    auto measure = m_userTiming->measure(globalObject, measureName, WTFMove(startOrMeasureOptions), endMark);
     327    if (measure.hasException())
     328        return measure.releaseException();
     329
     330    queueEntry(measure.returnValue().get());
     331    return measure.releaseReturnValue();
    332332}
    333333
     
    335335{
    336336    if (!m_userTiming)
    337         m_userTiming = makeUnique<UserTiming>(*this);
     337        m_userTiming = makeUnique<PerformanceUserTiming>(*this);
    338338    m_userTiming->clearMeasures(measureName);
    339339}
  • trunk/Source/WebCore/page/Performance.h

    r266027 r267402  
    4040#include "ReducedResolutionSeconds.h"
    4141#include <wtf/ListHashSet.h>
     42#include <wtf/Variant.h>
     43
     44namespace JSC {
     45class JSGlobalObject;
     46}
    4247
    4348namespace WebCore {
    4449
    4550class LoadTiming;
     51class PerformanceUserTiming;
    4652class PerformanceEntry;
     53class PerformanceMark;
     54class PerformanceMeasure;
    4755class PerformanceNavigation;
    4856class PerformanceObserver;
     
    5260class ResourceTiming;
    5361class ScriptExecutionContext;
    54 class UserTiming;
     62struct PerformanceMarkOptions;
     63struct PerformanceMeasureOptions;
    5564
    5665class Performance final : public RefCounted<Performance>, public ContextDestructionObserver, public EventTargetWithInlineData {
     
    7483    void setResourceTimingBufferSize(unsigned);
    7584
    76     ExceptionOr<void> mark(const String& markName);
     85    ExceptionOr<Ref<PerformanceMark>> mark(JSC::JSGlobalObject&, const String& markName, Optional<PerformanceMarkOptions>&&);
    7786    void clearMarks(const String& markName);
    7887
    79     ExceptionOr<void> measure(const String& measureName, const String& startMark, const String& endMark);
     88    using StartOrMeasureOptions = Variant<String, PerformanceMeasureOptions>;
     89    ExceptionOr<Ref<PerformanceMeasure>> measure(JSC::JSGlobalObject&, const String& measureName, Optional<StartOrMeasureOptions>&&, const String& endMark);
    8090    void clearMeasures(const String& measureName);
    8191
     
    129139
    130140    RefPtr<PerformancePaintTiming> m_firstContentfulPaint;
    131     std::unique_ptr<UserTiming> m_userTiming;
     141    std::unique_ptr<PerformanceUserTiming> m_userTiming;
    132142
    133143    GenericTaskQueue<ScriptExecutionContext> m_performanceTimelineTaskQueue;
  • trunk/Source/WebCore/page/Performance.idl

    r267333 r267402  
    5858
    5959    // https://w3c.github.io/user-timing/#extensions-performance-interface
    60     // FIXME: 'mark' should return a PerformanceMark.
    61     [MayThrowException] undefined mark(DOMString markName);
     60    [MayThrowException, CallWith=GlobalObject] PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions);
    6261    undefined clearMarks(optional DOMString markName);
    63     // FIXME: 'measure' should return a PerformanceMeasure.
    64     [MayThrowException] undefined measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
     62    [MayThrowException, CallWith=GlobalObject] PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions, optional DOMString endMark);
    6563    undefined clearMeasures(optional DOMString measureName);
    6664};
  • trunk/Source/WebCore/page/PerformanceMark.h

    r257727 r267402  
    2929#include <wtf/text/WTFString.h>
    3030
     31namespace JSC {
     32class JSGlobalObject;
     33class JSValue;
     34}
     35
    3136namespace WebCore {
     37
     38class SerializedScriptValue;
     39class ScriptExecutionContext;
    3240
    3341class PerformanceMark final : public PerformanceEntry {
    3442public:
    35     static Ref<PerformanceMark> create(const String& name, double startTime) { return adoptRef(*new PerformanceMark(name, startTime)); }
     43    static ExceptionOr<Ref<PerformanceMark>> create(JSC::JSGlobalObject&, ScriptExecutionContext&, const String& name, Optional<PerformanceMarkOptions>&&);
     44
     45    JSC::JSValue detail(JSC::JSGlobalObject&);
    3646
    3747private:
    38     PerformanceMark(const String& name, double startTime)
    39         : PerformanceEntry(name, startTime, startTime)
    40     {
    41     }
     48    PerformanceMark(const String& name, double startTime, Ref<SerializedScriptValue>&&);
     49    ~PerformanceMark();
    4250
    4351    Type type() const final { return Type::Mark; }
    4452    ASCIILiteral entryType() const final { return "mark"_s; }
    4553
    46     ~PerformanceMark() = default;
     54    Ref<SerializedScriptValue> m_serializedDetail;
    4755};
    4856
  • trunk/Source/WebCore/page/PerformanceMark.idl

    r267316 r267402  
    2828    Exposed=(Window,Worker),
    2929] interface PerformanceMark : PerformanceEntry {
    30     // FIXME: Implement constructor.
    31     // constructor(DOMString markName, optional PerformanceMarkOptions markOptions = {});
    32     // FIXME: Implement 'detail'.
    33     // readonly attribute any detail;
     30    [CallWith=GlobalObject&ScriptExecutionContext] constructor(DOMString markName, optional PerformanceMarkOptions markOptions);
     31    [CallWith=GlobalObject, CachedAttribute] readonly attribute any detail;
    3432};
  • trunk/Source/WebCore/page/PerformanceMeasure.h

    r257727 r267402  
    2929#include <wtf/text/WTFString.h>
    3030
     31namespace JSC {
     32class JSGlobalObject;
     33class JSValue;
     34}
     35
    3136namespace WebCore {
     37
     38class SerializedScriptValue;
     39class ScriptExecutionContext;
    3240
    3341class PerformanceMeasure final : public PerformanceEntry {
    3442public:
    35     static Ref<PerformanceMeasure> create(const String& name, double startTime, double duration) { return adoptRef(*new PerformanceMeasure(name, startTime, duration)); }
     43    static ExceptionOr<Ref<PerformanceMeasure>> create(const String& name, double startTime, double endTime, Ref<SerializedScriptValue>&& detail);
     44
     45    JSC::JSValue detail(JSC::JSGlobalObject&);
    3646
    3747private:
    38     PerformanceMeasure(const String& name, double startTime, double duration)
    39         : PerformanceEntry(name, startTime, duration)
    40     {
    41     }
     48    PerformanceMeasure(const String& name, double startTime, double endTime, Ref<SerializedScriptValue>&& detail);
     49    ~PerformanceMeasure();
    4250
    4351    Type type() const final { return Type::Measure; }
    4452    ASCIILiteral entryType() const final { return "measure"_s; }
    4553
    46     ~PerformanceMeasure() = default;
     54    Ref<SerializedScriptValue> m_serializedDetail;
    4755};
    4856
  • trunk/Source/WebCore/page/PerformanceMeasure.idl

    r267316 r267402  
    2828    Exposed=(Window,Worker),
    2929] interface PerformanceMeasure : PerformanceEntry {
    30     // FIXME: Implement 'detail'.
    31     // readonly attribute any detail;
     30    [CallWith=GlobalObject, CachedAttribute] readonly attribute any detail;
    3231};
  • trunk/Source/WebCore/page/PerformanceUserTiming.cpp

    r243163 r267402  
    2929
    3030#include "Document.h"
     31#include "MessagePort.h"
     32#include "PerformanceMarkOptions.h"
     33#include "PerformanceMeasureOptions.h"
    3134#include "PerformanceTiming.h"
     35#include "SerializedScriptValue.h"
    3236#include <wtf/NeverDestroyed.h>
    3337
     
    3539
    3640using NavigationTimingFunction = unsigned long long (PerformanceTiming::*)() const;
     41static const HashMap<String, NavigationTimingFunction>& restrictedMarkNamesToNavigationTimingFunctionMap()
     42{
     43    ASSERT(isMainThread());
     44
     45    static auto map = makeNeverDestroyed<HashMap<String, NavigationTimingFunction>>({
     46        { "connectEnd"_s, &PerformanceTiming::connectEnd },
     47        { "connectStart"_s, &PerformanceTiming::connectStart },
     48        { "domComplete"_s, &PerformanceTiming::domComplete },
     49        { "domContentLoadedEventEnd"_s, &PerformanceTiming::domContentLoadedEventEnd },
     50        { "domContentLoadedEventStart"_s, &PerformanceTiming::domContentLoadedEventStart },
     51        { "domInteractive"_s, &PerformanceTiming::domInteractive },
     52        { "domLoading"_s, &PerformanceTiming::domLoading },
     53        { "domainLookupEnd"_s, &PerformanceTiming::domainLookupEnd },
     54        { "domainLookupStart"_s, &PerformanceTiming::domainLookupStart },
     55        { "fetchStart"_s, &PerformanceTiming::fetchStart },
     56        { "loadEventEnd"_s, &PerformanceTiming::loadEventEnd },
     57        { "loadEventStart"_s, &PerformanceTiming::loadEventStart },
     58        { "navigationStart"_s, &PerformanceTiming::navigationStart },
     59        { "redirectEnd"_s, &PerformanceTiming::redirectEnd },
     60        { "redirectStart"_s, &PerformanceTiming::redirectStart },
     61        { "requestStart"_s, &PerformanceTiming::requestStart },
     62        { "responseEnd"_s, &PerformanceTiming::responseEnd },
     63        { "responseStart"_s, &PerformanceTiming::responseStart },
     64        { "secureConnectionStart"_s, &PerformanceTiming::secureConnectionStart },
     65        { "unloadEventEnd"_s, &PerformanceTiming::unloadEventEnd },
     66        { "unloadEventStart"_s, &PerformanceTiming::unloadEventStart },
     67    });
     68   
     69    return map;
     70}
    3771
    3872static NavigationTimingFunction restrictedMarkFunction(const String& markName)
    3973{
    4074    ASSERT(isMainThread());
    41 
    42     static const auto map = makeNeverDestroyed([] {
    43         static const std::pair<ASCIILiteral, NavigationTimingFunction> pairs[] = {
    44             { "connectEnd"_s, &PerformanceTiming::connectEnd },
    45             { "connectStart"_s, &PerformanceTiming::connectStart },
    46             { "domComplete"_s, &PerformanceTiming::domComplete },
    47             { "domContentLoadedEventEnd"_s, &PerformanceTiming::domContentLoadedEventEnd },
    48             { "domContentLoadedEventStart"_s, &PerformanceTiming::domContentLoadedEventStart },
    49             { "domInteractive"_s, &PerformanceTiming::domInteractive },
    50             { "domLoading"_s, &PerformanceTiming::domLoading },
    51             { "domainLookupEnd"_s, &PerformanceTiming::domainLookupEnd },
    52             { "domainLookupStart"_s, &PerformanceTiming::domainLookupStart },
    53             { "fetchStart"_s, &PerformanceTiming::fetchStart },
    54             { "loadEventEnd"_s, &PerformanceTiming::loadEventEnd },
    55             { "loadEventStart"_s, &PerformanceTiming::loadEventStart },
    56             { "navigationStart"_s, &PerformanceTiming::navigationStart },
    57             { "redirectEnd"_s, &PerformanceTiming::redirectEnd },
    58             { "redirectStart"_s, &PerformanceTiming::redirectStart },
    59             { "requestStart"_s, &PerformanceTiming::requestStart },
    60             { "responseEnd"_s, &PerformanceTiming::responseEnd },
    61             { "responseStart"_s, &PerformanceTiming::responseStart },
    62             { "secureConnectionStart"_s, &PerformanceTiming::secureConnectionStart },
    63             { "unloadEventEnd"_s, &PerformanceTiming::unloadEventEnd },
    64             { "unloadEventStart"_s, &PerformanceTiming::unloadEventStart },
    65         };
    66         HashMap<String, NavigationTimingFunction> map;
    67         for (auto& pair : pairs)
    68             map.add(pair.first, pair.second);
    69         return map;
    70     }());
    71 
    72     return map.get().get(markName);
    73 }
    74 
    75 UserTiming::UserTiming(Performance& performance)
     75    return restrictedMarkNamesToNavigationTimingFunctionMap().get(markName);
     76}
     77
     78static bool isRestrictedMarkNameNonMainThread(const String& markName)
     79{
     80    ASSERT(!isMainThread());
     81
     82    bool isRestricted;
     83    callOnMainThreadAndWait([&isRestricted, markName = markName.isolatedCopy()] {
     84        isRestricted = restrictedMarkNamesToNavigationTimingFunctionMap().contains(markName);
     85    });
     86    return isRestricted;
     87}
     88
     89bool PerformanceUserTiming::isRestrictedMarkName(const String& markName)
     90{
     91    ASSERT(isMainThread());
     92    return restrictedMarkNamesToNavigationTimingFunctionMap().contains(markName);
     93}
     94
     95PerformanceUserTiming::PerformanceUserTiming(Performance& performance)
    7696    : m_performance(performance)
    7797{
     
    86106}
    87107
    88 ExceptionOr<Ref<PerformanceMark>> UserTiming::mark(const String& markName)
    89 {
    90     if (is<Document>(m_performance.scriptExecutionContext()) && restrictedMarkFunction(markName))
    91         return Exception { SyntaxError };
    92 
    93     auto& performanceEntryList = m_marksMap.ensure(markName, [] { return Vector<RefPtr<PerformanceEntry>>(); }).iterator->value;
    94     auto entry = PerformanceMark::create(markName, m_performance.now());
    95     performanceEntryList.append(entry.copyRef());
    96     return entry;
    97 }
    98 
    99 void UserTiming::clearMarks(const String& markName)
     108static void addPerformanceEntry(PerformanceEntryMap& map, const String& name, PerformanceEntry& entry)
     109{
     110    auto& performanceEntryList = map.ensure(name, [] { return Vector<RefPtr<PerformanceEntry>>(); }).iterator->value;
     111    performanceEntryList.append(&entry);
     112}
     113
     114ExceptionOr<Ref<PerformanceMark>> PerformanceUserTiming::mark(JSC::JSGlobalObject& globalObject, const String& markName, Optional<PerformanceMarkOptions>&& markOptions)
     115{
     116    auto mark = PerformanceMark::create(globalObject, *m_performance.scriptExecutionContext(), markName, WTFMove(markOptions));
     117    if (mark.hasException())
     118        return mark.releaseException();
     119
     120    addPerformanceEntry(m_marksMap, markName, mark.returnValue().get());
     121    return mark.releaseReturnValue();
     122}
     123
     124void PerformanceUserTiming::clearMarks(const String& markName)
    100125{
    101126    clearPerformanceEntries(m_marksMap, markName);
    102127}
    103128
    104 ExceptionOr<double> UserTiming::findExistingMarkStartTime(const String& markName)
    105 {
    106     auto iterator = m_marksMap.find(markName);
     129ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(const Variant<String, double>& mark) const
     130{
     131    return WTF::switchOn(mark, [&](auto& value) {
     132        return convertMarkToTimestamp(value);
     133    });
     134}
     135
     136ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(const String& mark) const
     137{
     138    if (!is<Document>(m_performance.scriptExecutionContext())) {
     139        if (isRestrictedMarkNameNonMainThread(mark))
     140            return Exception { TypeError };
     141    } else {
     142        if (auto function = restrictedMarkFunction(mark)) {
     143            if (function == &PerformanceTiming::navigationStart)
     144                return 0.0;
     145
     146            // PerformanceTiming should always be non-null for the Document ScriptExecutionContext.
     147            ASSERT(m_performance.timing());
     148            auto timing = m_performance.timing();
     149            auto startTime = timing->navigationStart();
     150            auto endTime = ((*timing).*(function))();
     151            if (!endTime)
     152                return Exception { InvalidAccessError };
     153            return endTime - startTime;
     154        }
     155    }
     156
     157    auto iterator = m_marksMap.find(mark);
    107158    if (iterator != m_marksMap.end())
    108159        return iterator->value.last()->startTime();
    109160
    110     auto* timing = m_performance.timing();
    111     if (!timing)
    112         return Exception { SyntaxError, makeString("No mark named '", markName, "' exists") };
    113 
    114     if (auto function = restrictedMarkFunction(markName)) {
    115         double value = ((*timing).*(function))();
    116         if (!value)
    117             return Exception { InvalidAccessError };
    118         return value - timing->navigationStart();
     161    return Exception { SyntaxError, makeString("No mark named '", mark, "' exists") };
     162}
     163
     164ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(double mark) const
     165{
     166    if (mark < 0)
     167        return Exception { TypeError };
     168    return mark;
     169}
     170
     171ExceptionOr<Ref<PerformanceMeasure>> PerformanceUserTiming::measure(const String& measureName, const String& startMark, const String& endMark)
     172{
     173    double endTime;
     174    if (!endMark.isNull()) {
     175        auto end = convertMarkToTimestamp(endMark);
     176        if (end.hasException())
     177            return end.releaseException();
     178        endTime = end.returnValue();
     179    } else
     180        endTime = m_performance.now();
     181
     182    double startTime;
     183    if (!startMark.isNull()) {
     184        auto start = convertMarkToTimestamp(startMark);
     185        if (start.hasException())
     186            return start.releaseException();
     187        startTime = start.returnValue();
     188    } else
     189        startTime = 0.0;
     190       
     191    auto measure = PerformanceMeasure::create(measureName, startTime, endTime, SerializedScriptValue::nullValue());
     192    if (measure.hasException())
     193        return measure.releaseException();
     194
     195    addPerformanceEntry(m_measuresMap, measureName, measure.returnValue().get());
     196    return measure.releaseReturnValue();
     197}
     198
     199ExceptionOr<Ref<PerformanceMeasure>> PerformanceUserTiming::measure(JSC::JSGlobalObject& globalObject, const String& measureName, const PerformanceMeasureOptions& measureOptions)
     200{
     201    double endTime;
     202    if (measureOptions.end) {
     203        auto end = convertMarkToTimestamp(*measureOptions.end);
     204        if (end.hasException())
     205            return end.releaseException();
     206        endTime = end.returnValue();
     207    } else if (measureOptions.start && measureOptions.duration) {
     208        auto start = convertMarkToTimestamp(*measureOptions.start);
     209        if (start.hasException())
     210            return start.releaseException();
     211        auto duration = convertMarkToTimestamp(*measureOptions.duration);
     212        if (duration.hasException())
     213            return start.releaseException();
     214        endTime = start.returnValue() + duration.returnValue();
     215    } else
     216        endTime = m_performance.now();
     217
     218    double startTime;
     219    if (measureOptions.start) {
     220        auto start = convertMarkToTimestamp(*measureOptions.start);
     221        if (start.hasException())
     222            return start.releaseException();
     223        startTime = start.returnValue();
     224    } else if (measureOptions.duration && measureOptions.end) {
     225        auto duration = convertMarkToTimestamp(*measureOptions.duration);
     226        if (duration.hasException())
     227            return duration.releaseException();
     228        auto end = convertMarkToTimestamp(*measureOptions.end);
     229        if (end.hasException())
     230            return end.releaseException();
     231        startTime = end.returnValue() - duration.returnValue();
     232    } else
     233        startTime = 0;
     234
     235
     236    JSC::JSValue detail = measureOptions.detail;
     237    if (detail.isUndefined())
     238        detail = JSC::jsNull();
     239
     240    Vector<RefPtr<MessagePort>> ignoredMessagePorts;
     241    auto serializedDetail = SerializedScriptValue::create(globalObject, detail, { }, ignoredMessagePorts);
     242    if (serializedDetail.hasException())
     243        return serializedDetail.releaseException();
     244
     245    auto measure = PerformanceMeasure::create(measureName, startTime, endTime, serializedDetail.releaseReturnValue());
     246    if (measure.hasException())
     247        return measure.releaseException();
     248
     249    addPerformanceEntry(m_measuresMap, measureName, measure.returnValue().get());
     250    return measure.releaseReturnValue();
     251}
     252
     253static bool isNonEmptyDictionary(const PerformanceMeasureOptions& measureOptions)
     254{
     255    return !measureOptions.detail.isUndefined() || measureOptions.start || measureOptions.duration || measureOptions.end;
     256}
     257
     258ExceptionOr<Ref<PerformanceMeasure>> PerformanceUserTiming::measure(JSC::JSGlobalObject& globalObject, const String& measureName, Optional<StartOrMeasureOptions>&& startOrMeasureOptions, const String& endMark)
     259{
     260    if (startOrMeasureOptions) {
     261        return WTF::switchOn(*startOrMeasureOptions,
     262            [&] (const PerformanceMeasureOptions& measureOptions) -> ExceptionOr<Ref<PerformanceMeasure>> {
     263                if (isNonEmptyDictionary(measureOptions)) {
     264                    if (!endMark.isNull())
     265                        return Exception { TypeError };
     266                    if (!measureOptions.start && !measureOptions.end)
     267                        return Exception { TypeError };
     268                    if (measureOptions.start && measureOptions.duration && measureOptions.end)
     269                        return Exception { TypeError };
     270                }
     271
     272                return measure(globalObject, measureName, measureOptions);
     273            },
     274            [&] (const String& startMark) {
     275                return measure(measureName, startMark, endMark);
     276            }
     277        );
    119278    }
    120279
    121     return Exception { SyntaxError };
    122 }
    123 
    124 ExceptionOr<Ref<PerformanceMeasure>> UserTiming::measure(const String& measureName, const String& startMark, const String& endMark)
    125 {
    126     double startTime = 0.0;
    127     double endTime = 0.0;
    128 
    129     if (startMark.isNull())
    130         endTime = m_performance.now();
    131     else if (endMark.isNull()) {
    132         endTime = m_performance.now();
    133         auto startMarkResult = findExistingMarkStartTime(startMark);
    134         if (startMarkResult.hasException())
    135             return startMarkResult.releaseException();
    136         startTime = startMarkResult.releaseReturnValue();
    137     } else {
    138         auto endMarkResult = findExistingMarkStartTime(endMark);
    139         if (endMarkResult.hasException())
    140             return endMarkResult.releaseException();
    141         auto startMarkResult = findExistingMarkStartTime(startMark);
    142         if (startMarkResult.hasException())
    143             return startMarkResult.releaseException();
    144         startTime = startMarkResult.releaseReturnValue();
    145         endTime = endMarkResult.releaseReturnValue();
    146     }
    147 
    148     auto& performanceEntryList = m_measuresMap.ensure(measureName, [] { return Vector<RefPtr<PerformanceEntry>>(); }).iterator->value;
    149     auto entry = PerformanceMeasure::create(measureName, startTime, endTime);
    150     performanceEntryList.append(entry.copyRef());
    151     return entry;
    152 }
    153 
    154 void UserTiming::clearMeasures(const String& measureName)
     280    return measure(measureName, { }, endMark);
     281}
     282
     283void PerformanceUserTiming::clearMeasures(const String& measureName)
    155284{
    156285    clearPerformanceEntries(m_measuresMap, measureName);
     
    165294}
    166295
    167 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks() const
     296Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMarks() const
    168297{
    169298    return convertToEntrySequence(m_marksMap);
    170299}
    171300
    172 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks(const String& name) const
     301Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMarks(const String& name) const
    173302{
    174303    return m_marksMap.get(name);
    175304}
    176305
    177 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures() const
     306Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMeasures() const
    178307{
    179308    return convertToEntrySequence(m_measuresMap);
    180309}
    181310
    182 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures(const String& name) const
     311Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMeasures(const String& name) const
    183312{
    184313    return m_measuresMap.get(name);
  • trunk/Source/WebCore/page/PerformanceUserTiming.h

    r241183 r267402  
    3232#include <wtf/text/StringHash.h>
    3333
     34namespace JSC {
     35class JSGlobalObject;
     36}
     37
    3438namespace WebCore {
    3539
     
    3842using PerformanceEntryMap = HashMap<String, Vector<RefPtr<PerformanceEntry>>>;
    3943
    40 class UserTiming {
     44class PerformanceUserTiming {
    4145    WTF_MAKE_FAST_ALLOCATED;
    4246public:
    43     explicit UserTiming(Performance&);
     47    explicit PerformanceUserTiming(Performance&);
    4448
    45     ExceptionOr<Ref<PerformanceMark>> mark(const String& markName);
     49    ExceptionOr<Ref<PerformanceMark>> mark(JSC::JSGlobalObject&, const String& markName, Optional<PerformanceMarkOptions>&&);
    4650    void clearMarks(const String& markName);
    4751
    48     ExceptionOr<Ref<PerformanceMeasure>> measure(const String& measureName, const String& startMark, const String& endMark);
     52    using StartOrMeasureOptions = Variant<String, PerformanceMeasureOptions>;
     53    ExceptionOr<Ref<PerformanceMeasure>> measure(JSC::JSGlobalObject&, const String& measureName, Optional<StartOrMeasureOptions>&&, const String& endMark);
    4954    void clearMeasures(const String& measureName);
    5055
     
    5560    Vector<RefPtr<PerformanceEntry>> getMeasures(const String& name) const;
    5661
     62    static bool isRestrictedMarkName(const String& markName);
     63
    5764private:
    58     ExceptionOr<double> findExistingMarkStartTime(const String& markName);
     65    ExceptionOr<double> convertMarkToTimestamp(const Variant<String, double>&) const;
     66    ExceptionOr<double> convertMarkToTimestamp(const String& markName) const;
     67    ExceptionOr<double> convertMarkToTimestamp(double) const;
     68
     69    ExceptionOr<Ref<PerformanceMeasure>> measure(const String& measureName, const String& startMark, const String& endMark);
     70    ExceptionOr<Ref<PerformanceMeasure>> measure(JSC::JSGlobalObject&, const String& measureName, const PerformanceMeasureOptions&);
    5971
    6072    Performance& m_performance;
Note: See TracChangeset for help on using the changeset viewer.