Changeset 267402 in webkit
- Timestamp:
- Sep 22, 2020, 1:46:36 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 11 added
- 39 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/case-sensitivity.any-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/case-sensitivity.any.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/case-sensitivity.any.js (added)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/case-sensitivity.any.worker-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/case-sensitivity.any.worker.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any-expected.txt (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any.worker-expected.txt (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/performance-measure-invalid.worker-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any-expected.txt (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any.worker-expected.txt (modified) (1 diff)
-
LayoutTests/performance-api/performance-measure-name-expected.txt (modified) (1 diff)
-
LayoutTests/performance-api/performance-now-api-expected.txt (modified) (2 diffs)
-
LayoutTests/performance-api/user-timing-apis-expected.txt (modified) (2 diffs)
-
Source/WebCore/CMakeLists.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/DerivedSources-input.xcfilelist (modified) (1 diff)
-
Source/WebCore/DerivedSources-output.xcfilelist (modified) (1 diff)
-
Source/WebCore/DerivedSources.make (modified) (1 diff)
-
Source/WebCore/Sources.txt (modified) (2 diffs)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/WebCore/page/Performance.cpp (modified) (4 diffs)
-
Source/WebCore/page/Performance.h (modified) (4 diffs)
-
Source/WebCore/page/Performance.idl (modified) (1 diff)
-
Source/WebCore/page/PerformanceMark.cpp (added)
-
Source/WebCore/page/PerformanceMark.h (modified) (1 diff)
-
Source/WebCore/page/PerformanceMark.idl (modified) (1 diff)
-
Source/WebCore/page/PerformanceMarkOptions.h (added)
-
Source/WebCore/page/PerformanceMarkOptions.idl (added)
-
Source/WebCore/page/PerformanceMeasure.cpp (added)
-
Source/WebCore/page/PerformanceMeasure.h (modified) (1 diff)
-
Source/WebCore/page/PerformanceMeasure.idl (modified) (1 diff)
-
Source/WebCore/page/PerformanceMeasureOptions.h (added)
-
Source/WebCore/page/PerformanceMeasureOptions.idl (added)
-
Source/WebCore/page/PerformanceUserTiming.cpp (modified) (4 diffs)
-
Source/WebCore/page/PerformanceUserTiming.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r267401 r267402 1 2020-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 1 15 2020-09-22 Youenn Fablet <youenn@apple.com> 2 16 -
trunk/LayoutTests/imported/w3c/ChangeLog
r267376 r267402 1 2020-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 1 35 2020-09-21 Chris Dumez <cdumez@apple.com> 2 36 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any-expected.txt
r264255 r267402 5 5 PASS Partial interface Performance: member names are unique 6 6 PASS 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 7 PASS PerformanceMark interface object length 8 8 PASS PerformanceMark interface object name 9 9 PASS PerformanceMark interface: existence and properties of interface prototype object 10 10 PASS PerformanceMark interface: existence and properties of interface prototype object's "constructor" property 11 11 PASS 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 12 PASS PerformanceMark interface: attribute detail 13 13 PASS PerformanceMark must be primary interface of mark 14 14 PASS 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 15 PASS PerformanceMark interface: mark must inherit property "detail" with the proper type 16 16 PASS PerformanceMeasure interface: existence and properties of interface object 17 17 PASS PerformanceMeasure interface object length … … 20 20 PASS PerformanceMeasure interface: existence and properties of interface prototype object's "constructor" property 21 21 PASS 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 22 PASS PerformanceMeasure interface: attribute detail 23 23 PASS PerformanceMeasure must be primary interface of measure 24 24 PASS 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 25 PASS PerformanceMeasure interface: measure must inherit property "detail" with the proper type 26 26 PASS Performance interface: operation mark(DOMString, optional PerformanceMarkOptions) 27 27 PASS Performance interface: operation clearMarks(optional DOMString) -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/idlharness.any.worker-expected.txt
r264255 r267402 5 5 PASS Partial interface Performance: member names are unique 6 6 PASS 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 7 PASS PerformanceMark interface object length 8 8 PASS PerformanceMark interface object name 9 9 PASS PerformanceMark interface: existence and properties of interface prototype object 10 10 PASS PerformanceMark interface: existence and properties of interface prototype object's "constructor" property 11 11 PASS 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 12 PASS PerformanceMark interface: attribute detail 13 13 PASS PerformanceMark must be primary interface of mark 14 14 PASS 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 15 PASS PerformanceMark interface: mark must inherit property "detail" with the proper type 16 16 PASS PerformanceMeasure interface: existence and properties of interface object 17 17 PASS PerformanceMeasure interface object length … … 20 20 PASS PerformanceMeasure interface: existence and properties of interface prototype object's "constructor" property 21 21 PASS 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 22 PASS PerformanceMeasure interface: attribute detail 23 23 PASS PerformanceMeasure must be primary interface of measure 24 24 PASS 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 25 PASS PerformanceMeasure interface: measure must inherit property "detail" with the proper type 26 26 PASS Performance interface: operation mark(DOMString, optional PerformanceMarkOptions) 27 27 PASS Performance interface: operation clearMarks(optional DOMString) -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any-expected.txt
r265749 r267402 1 1 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 2 PASS Mark entry can be created by 'new PerformanceMark(string)'. 3 PASS Mark entry can be created by 'new PerformanceMark(string, {})'. 4 PASS Mark entry can be created by 'new PerformanceMark(string, {startTime})'. 5 PASS Mark entry can be created by 'new PerformanceMark(string, {detail})'. 6 PASS Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'. 7 PASS Using new PerformanceMark() shouldn't add the entry to performance timeline. 8 8 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-entry-constructor.any.worker-expected.txt
r265749 r267402 1 1 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 2 PASS Mark entry can be created by 'new PerformanceMark(string)'. 3 PASS Mark entry can be created by 'new PerformanceMark(string, {})'. 4 PASS Mark entry can be created by 'new PerformanceMark(string, {startTime})'. 5 PASS Mark entry can be created by 'new PerformanceMark(string, {detail})'. 6 PASS Mark entry can be created by 'new PerformanceMark(string, {startTime, detail})'. 7 PASS Using new PerformanceMark() shouldn't add the entry to performance timeline. 8 8 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any-expected.txt
r264255 r267402 1 1 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 2 PASS Number should be rejected as the mark-options. 3 PASS NaN should be rejected as the mark-options. 4 PASS Infinity should be rejected as the mark-options. 5 PASS String should be rejected as the mark-options. 6 6 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-errors.any.worker-expected.txt
r264255 r267402 1 1 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 2 PASS Number should be rejected as the mark-options. 3 PASS NaN should be rejected as the mark-options. 4 PASS Infinity should be rejected as the mark-options. 5 PASS String should be rejected as the mark-options. 6 6 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any-expected.txt
r264255 r267402 1 1 2 FAIL mark entries' detail and startTime are customizable. undefined is not an object (evaluating 'ae.name') 2 PASS mark entries' detail and startTime are customizable. 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-l3.any.worker-expected.txt
r264255 r267402 1 1 2 FAIL mark entries' detail and startTime are customizable. undefined is not an object (evaluating 'ae.name') 2 PASS mark entries' detail and startTime are customizable. 3 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any-expected.txt
r264255 r267402 1 1 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 2 PASS L3: performance.measure(name) should return an entry. 3 PASS L3: performance.measure(name, param1) should return an entry. 4 PASS L3: performance.measure(name, param1, param2) should return an entry. 5 PASS L3: performance.mark(name) should return an entry. 6 PASS L3: performance.mark(name, param) should return an entry. 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/mark-measure-return-objects.any.worker-expected.txt
r264255 r267402 1 1 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 2 PASS L3: performance.measure(name) should return an entry. 3 PASS L3: performance.measure(name, param1) should return an entry. 4 PASS L3: performance.measure(name, param1, param2) should return an entry. 5 PASS L3: performance.mark(name) should return an entry. 6 PASS L3: performance.mark(name, param) should return an entry. 7 7 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any-expected.txt
r264255 r267402 1 1 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') 2 PASS 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. 3 PASS 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. 4 PASS 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 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-l3.any.worker-expected.txt
r264255 r267402 1 1 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') 2 PASS 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. 3 PASS 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. 4 PASS 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 5 5 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any-expected.txt
r264255 r267402 1 1 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") 2 PASS measure entries' detail and start/end are customizable 3 PASS measure should throw a TypeError when passed an invalid argument combination 8 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure-with-dict.any.worker-expected.txt
r264255 r267402 1 1 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") 2 PASS measure entries' detail and start/end are customizable 3 PASS measure should throw a TypeError when passed an invalid argument combination 8 4 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exception-expected.txt
r264255 r267402 12 12 PASS Invocation of performance.measure("Exception6", "NonExistMark1", "NonExistMark2") should throw SYNTAX_ERR Exception. 13 13 PASS 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") 14 PASS Invocation of performance.measure("Exception8", {"detail": "non-empty"}) should throw TypeError Exception. 15 PASS Invocation of performance.measure("Exception9", {"start": 1, "duration": 2, "end": 3}) should throw TypeError Exception. 20 16 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/performance-measure-invalid.worker-expected.txt
r264255 r267402 1 1 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") 2 PASS When converting 'navigationStart' to a timestamp, the global object has to be a Window object. 7 3 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any-expected.txt
r265749 r267402 1 1 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') 2 PASS The detail property in the mark constructor should be structured-clone. 3 PASS The detail property in the mark method should be structured-clone. 4 PASS When accessing detail from a mark entry and the detail is not provided, just return a null value. 5 PASS Mark: Throw an exception when the detail property cannot be structured-serialized. 6 PASS The detail property in the measure method should be structured-clone. 7 PASS The detail property in the measure method should be the same reference. 8 PASS When accessing detail from a measure entry and the detail is not provided, just return a null value. 9 PASS Measure: Throw an exception when the detail property cannot be structured-serialized. 10 PASS The detail object is cloned when passed to mark API. 15 11 -
trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/structured-serialize-detail.any.worker-expected.txt
r265749 r267402 1 1 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') 2 PASS The detail property in the mark constructor should be structured-clone. 3 PASS The detail property in the mark method should be structured-clone. 4 PASS When accessing detail from a mark entry and the detail is not provided, just return a null value. 5 PASS Mark: Throw an exception when the detail property cannot be structured-serialized. 6 PASS The detail property in the measure method should be structured-clone. 7 PASS The detail property in the measure method should be the same reference. 8 PASS When accessing detail from a measure entry and the detail is not provided, just return a null value. 9 PASS Measure: Throw an exception when the detail property cannot be structured-serialized. 10 PASS The detail object is cloned when passed to mark API. 15 11 -
trunk/LayoutTests/performance-api/performance-measure-name-expected.txt
r219663 r267402 5 5 6 6 PASS 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..7 PASS performance.measure("measure-name", "x") threw exception SyntaxError: No mark named 'x' exists. 8 PASS performance.measure("measure-name", "existing-mark-name", "x") threw exception SyntaxError: No mark named 'x' exists. 9 9 PASS performance.mark("x") did not throw exception. 10 10 PASS performance.measure("measure-name", "x") did not throw exception. -
trunk/LayoutTests/performance-api/performance-now-api-expected.txt
r211594 r267402 7 7 PASS Performance is defined. 8 8 PASS Performance.prototype.now is defined. 9 PASS new Performance() threw exception TypeError: function is not a constructor (evaluating 'new Performance()').9 PASS new Performance() threw exception TypeError: Illegal constructor. 10 10 performance 11 11 PASS performance is defined. … … 19 19 PASS [Worker] Performance is defined. 20 20 PASS [Worker] Performance.prototype.now is defined. 21 PASS [Worker] new Performance() threw exception TypeError: function is not a constructor (evaluating 'new Performance()').21 PASS [Worker] new Performance() threw exception TypeError: Illegal constructor. 22 22 [Worker] performance 23 23 PASS [Worker] performance is defined. -
trunk/LayoutTests/performance-api/user-timing-apis-expected.txt
r265749 r267402 6 6 PerformanceMark 7 7 PASS PerformanceMark is defined. 8 PASS new PerformanceMark() threw exception TypeError: Illegal constructor.8 PASS new PerformanceMark() threw exception TypeError: Not enough arguments. 9 9 10 10 PerformanceMeasure … … 29 29 [Worker] PerformanceMark 30 30 PASS [Worker] PerformanceMark is defined. 31 PASS [Worker] new PerformanceMark() threw exception TypeError: Illegal constructor.31 PASS [Worker] new PerformanceMark() threw exception TypeError: Not enough arguments. 32 32 [Worker] 33 33 [Worker] PerformanceMeasure -
trunk/Source/WebCore/CMakeLists.txt
r267328 r267402 1053 1053 page/PerformanceEntry.idl 1054 1054 page/PerformanceMark.idl 1055 page/PerformanceMarkOptions.idl 1055 1056 page/PerformanceMeasure.idl 1057 page/PerformanceMeasureOptions.idl 1056 1058 page/PerformanceObserver.idl 1057 1059 page/PerformanceObserverCallback.idl -
trunk/Source/WebCore/ChangeLog
r267401 r267402 1 2020-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 1 85 2020-09-22 Youenn Fablet <youenn@apple.com> 2 86 -
trunk/Source/WebCore/DerivedSources-input.xcfilelist
r267146 r267402 1031 1031 $(PROJECT_DIR)/page/PerformanceEntry.idl 1032 1032 $(PROJECT_DIR)/page/PerformanceMark.idl 1033 $(PROJECT_DIR)/page/PerformanceMarkOptions.idl 1033 1034 $(PROJECT_DIR)/page/PerformanceMeasure.idl 1035 $(PROJECT_DIR)/page/PerformanceMeasureOptions.idl 1034 1036 $(PROJECT_DIR)/page/PerformanceNavigation.idl 1035 1037 $(PROJECT_DIR)/page/PerformanceObserver.idl -
trunk/Source/WebCore/DerivedSources-output.xcfilelist
r267146 r267402 1391 1391 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMark.cpp 1392 1392 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMark.h 1393 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMarkOptions.cpp 1394 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMarkOptions.h 1393 1395 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasure.cpp 1394 1396 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasure.h 1397 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasureOptions.cpp 1398 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceMeasureOptions.h 1395 1399 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceNavigation.cpp 1396 1400 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceNavigation.h -
trunk/Source/WebCore/DerivedSources.make
r267166 r267402 1042 1042 $(WebCore)/page/PerformanceEntry.idl \ 1043 1043 $(WebCore)/page/PerformanceMark.idl \ 1044 $(WebCore)/page/PerformanceMarkOptions.idl \ 1044 1045 $(WebCore)/page/PerformanceMeasure.idl \ 1046 $(WebCore)/page/PerformanceMeasureOptions.idl \ 1045 1047 $(WebCore)/page/PerformanceNavigation.idl \ 1046 1048 $(WebCore)/page/PerformanceObserver.idl \ -
trunk/Source/WebCore/Sources.txt
r267328 r267402 1634 1634 page/PerformanceLogging.cpp 1635 1635 page/PerformanceLoggingClient.cpp 1636 page/PerformanceMark.cpp 1637 page/PerformanceMeasure.cpp 1636 1638 page/PerformanceMonitor.cpp 1637 1639 page/PerformanceNavigation.cpp … … 3205 3207 JSPerformanceEntry.cpp 3206 3208 JSPerformanceMark.cpp 3209 JSPerformanceMarkOptions.cpp 3207 3210 JSPerformanceMeasure.cpp 3211 JSPerformanceMeasureOptions.cpp 3208 3212 JSPerformanceNavigation.cpp 3209 3213 JSPerformanceObserver.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r267328 r267402 2301 2301 7C7903B31F86F95C00463A70 /* ImageBitmapRenderingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7903B01F86F95C00463A70 /* ImageBitmapRenderingContext.h */; }; 2302 2302 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 */; }; 2303 2305 7C8139A61ED6286A00CE26E8 /* JSDOMAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8139A31ED6281D00CE26E8 /* JSDOMAttribute.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2304 2306 7C8139A71ED6287400CE26E8 /* JSDOMOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8139A41ED6281D00CE26E8 /* JSDOMOperation.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 10263 10265 7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; }; 10264 10266 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>"; }; 10265 10273 7C7C769C22F67ECD0032BCCD /* WHLSLMangledNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLMangledNames.h; sourceTree = "<group>"; }; 10266 10274 7C8139A31ED6281D00CE26E8 /* JSDOMAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMAttribute.h; sourceTree = "<group>"; }; … … 21575 21583 0FF2E80C1EE0D430009EABD4 /* PerformanceLoggingClient.cpp */, 21576 21584 0F850FE21ED7C18300FB77A7 /* PerformanceLoggingClient.h */, 21585 7C7BF9442516CC9200808682 /* PerformanceMark.cpp */, 21577 21586 37C738E81EDBD2ED003F2B0B /* PerformanceMark.h */, 21578 21587 7CE221EE251429F40006886B /* PerformanceMark.idl */, 21588 7C7BF93E2516C8BC00808682 /* PerformanceMarkOptions.h */, 21589 7C7BF9402516C8BC00808682 /* PerformanceMarkOptions.idl */, 21590 7C7BF9502516FB5400808682 /* PerformanceMeasure.cpp */, 21579 21591 37C738EA1EDBD381003F2B0B /* PerformanceMeasure.h */, 21580 21592 7CE221F0251429F50006886B /* PerformanceMeasure.idl */, 21593 7C7BF9492516FA5400808682 /* PerformanceMeasureOptions.h */, 21594 7C7BF94B2516FA5400808682 /* PerformanceMeasureOptions.idl */, 21581 21595 83FE90251E307C1C003E9199 /* PerformanceMonitor.cpp */, 21582 21596 83FE90261E307C1C003E9199 /* PerformanceMonitor.h */, … … 33168 33182 0F850FE31ED7C18300FB77A7 /* PerformanceLoggingClient.h in Headers */, 33169 33183 37C738E91EDBD2FA003F2B0B /* PerformanceMark.h in Headers */, 33184 7C7BF9422516C90C00808682 /* PerformanceMarkOptions.h in Headers */, 33170 33185 37C738EB1EDBD384003F2B0B /* PerformanceMeasure.h in Headers */, 33186 7C7BF94C2516FA5400808682 /* PerformanceMeasureOptions.h in Headers */, 33171 33187 83FE90271E307C30003E9199 /* PerformanceMonitor.h in Headers */, 33172 33188 8AF4E55611DC5A36000ED3DE /* PerformanceNavigation.h in Headers */, -
trunk/Source/WebCore/page/Performance.cpp
r266027 r267402 40 40 #include "Frame.h" 41 41 #include "PerformanceEntry.h" 42 #include "PerformanceMarkOptions.h" 43 #include "PerformanceMeasureOptions.h" 42 44 #include "PerformanceNavigation.h" 43 45 #include "PerformanceObserver.h" … … 297 299 } 298 300 299 ExceptionOr< void> Performance::mark(const String& markName)301 ExceptionOr<Ref<PerformanceMark>> Performance::mark(JSC::JSGlobalObject& globalObject, const String& markName, Optional<PerformanceMarkOptions>&& markOptions) 300 302 { 301 303 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(); 311 312 } 312 313 … … 314 315 { 315 316 if (!m_userTiming) 316 m_userTiming = makeUnique< UserTiming>(*this);317 m_userTiming = makeUnique<PerformanceUserTiming>(*this); 317 318 m_userTiming->clearMarks(markName); 318 319 } 319 320 320 ExceptionOr< void> Performance::measure(const String& measureName, const String& startMark, const String& endMark)321 ExceptionOr<Ref<PerformanceMeasure>> Performance::measure(JSC::JSGlobalObject& globalObject, const String& measureName, Optional<StartOrMeasureOptions>&& startOrMeasureOptions, const String& endMark) 321 322 { 322 323 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(); 332 332 } 333 333 … … 335 335 { 336 336 if (!m_userTiming) 337 m_userTiming = makeUnique< UserTiming>(*this);337 m_userTiming = makeUnique<PerformanceUserTiming>(*this); 338 338 m_userTiming->clearMeasures(measureName); 339 339 } -
trunk/Source/WebCore/page/Performance.h
r266027 r267402 40 40 #include "ReducedResolutionSeconds.h" 41 41 #include <wtf/ListHashSet.h> 42 #include <wtf/Variant.h> 43 44 namespace JSC { 45 class JSGlobalObject; 46 } 42 47 43 48 namespace WebCore { 44 49 45 50 class LoadTiming; 51 class PerformanceUserTiming; 46 52 class PerformanceEntry; 53 class PerformanceMark; 54 class PerformanceMeasure; 47 55 class PerformanceNavigation; 48 56 class PerformanceObserver; … … 52 60 class ResourceTiming; 53 61 class ScriptExecutionContext; 54 class UserTiming; 62 struct PerformanceMarkOptions; 63 struct PerformanceMeasureOptions; 55 64 56 65 class Performance final : public RefCounted<Performance>, public ContextDestructionObserver, public EventTargetWithInlineData { … … 74 83 void setResourceTimingBufferSize(unsigned); 75 84 76 ExceptionOr< void> mark(const String& markName);85 ExceptionOr<Ref<PerformanceMark>> mark(JSC::JSGlobalObject&, const String& markName, Optional<PerformanceMarkOptions>&&); 77 86 void clearMarks(const String& markName); 78 87 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); 80 90 void clearMeasures(const String& measureName); 81 91 … … 129 139 130 140 RefPtr<PerformancePaintTiming> m_firstContentfulPaint; 131 std::unique_ptr< UserTiming> m_userTiming;141 std::unique_ptr<PerformanceUserTiming> m_userTiming; 132 142 133 143 GenericTaskQueue<ScriptExecutionContext> m_performanceTimelineTaskQueue; -
trunk/Source/WebCore/page/Performance.idl
r267333 r267402 58 58 59 59 // 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); 62 61 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); 65 63 undefined clearMeasures(optional DOMString measureName); 66 64 }; -
trunk/Source/WebCore/page/PerformanceMark.h
r257727 r267402 29 29 #include <wtf/text/WTFString.h> 30 30 31 namespace JSC { 32 class JSGlobalObject; 33 class JSValue; 34 } 35 31 36 namespace WebCore { 37 38 class SerializedScriptValue; 39 class ScriptExecutionContext; 32 40 33 41 class PerformanceMark final : public PerformanceEntry { 34 42 public: 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&); 36 46 37 47 private: 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(); 42 50 43 51 Type type() const final { return Type::Mark; } 44 52 ASCIILiteral entryType() const final { return "mark"_s; } 45 53 46 ~PerformanceMark() = default;54 Ref<SerializedScriptValue> m_serializedDetail; 47 55 }; 48 56 -
trunk/Source/WebCore/page/PerformanceMark.idl
r267316 r267402 28 28 Exposed=(Window,Worker), 29 29 ] 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; 34 32 }; -
trunk/Source/WebCore/page/PerformanceMeasure.h
r257727 r267402 29 29 #include <wtf/text/WTFString.h> 30 30 31 namespace JSC { 32 class JSGlobalObject; 33 class JSValue; 34 } 35 31 36 namespace WebCore { 37 38 class SerializedScriptValue; 39 class ScriptExecutionContext; 32 40 33 41 class PerformanceMeasure final : public PerformanceEntry { 34 42 public: 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&); 36 46 37 47 private: 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(); 42 50 43 51 Type type() const final { return Type::Measure; } 44 52 ASCIILiteral entryType() const final { return "measure"_s; } 45 53 46 ~PerformanceMeasure() = default;54 Ref<SerializedScriptValue> m_serializedDetail; 47 55 }; 48 56 -
trunk/Source/WebCore/page/PerformanceMeasure.idl
r267316 r267402 28 28 Exposed=(Window,Worker), 29 29 ] interface PerformanceMeasure : PerformanceEntry { 30 // FIXME: Implement 'detail'. 31 // readonly attribute any detail; 30 [CallWith=GlobalObject, CachedAttribute] readonly attribute any detail; 32 31 }; -
trunk/Source/WebCore/page/PerformanceUserTiming.cpp
r243163 r267402 29 29 30 30 #include "Document.h" 31 #include "MessagePort.h" 32 #include "PerformanceMarkOptions.h" 33 #include "PerformanceMeasureOptions.h" 31 34 #include "PerformanceTiming.h" 35 #include "SerializedScriptValue.h" 32 36 #include <wtf/NeverDestroyed.h> 33 37 … … 35 39 36 40 using NavigationTimingFunction = unsigned long long (PerformanceTiming::*)() const; 41 static 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 } 37 71 38 72 static NavigationTimingFunction restrictedMarkFunction(const String& markName) 39 73 { 40 74 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 78 static 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 89 bool PerformanceUserTiming::isRestrictedMarkName(const String& markName) 90 { 91 ASSERT(isMainThread()); 92 return restrictedMarkNamesToNavigationTimingFunctionMap().contains(markName); 93 } 94 95 PerformanceUserTiming::PerformanceUserTiming(Performance& performance) 76 96 : m_performance(performance) 77 97 { … … 86 106 } 87 107 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) 108 static 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 114 ExceptionOr<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 124 void PerformanceUserTiming::clearMarks(const String& markName) 100 125 { 101 126 clearPerformanceEntries(m_marksMap, markName); 102 127 } 103 128 104 ExceptionOr<double> UserTiming::findExistingMarkStartTime(const String& markName) 105 { 106 auto iterator = m_marksMap.find(markName); 129 ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(const Variant<String, double>& mark) const 130 { 131 return WTF::switchOn(mark, [&](auto& value) { 132 return convertMarkToTimestamp(value); 133 }); 134 } 135 136 ExceptionOr<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); 107 158 if (iterator != m_marksMap.end()) 108 159 return iterator->value.last()->startTime(); 109 160 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 164 ExceptionOr<double> PerformanceUserTiming::convertMarkToTimestamp(double mark) const 165 { 166 if (mark < 0) 167 return Exception { TypeError }; 168 return mark; 169 } 170 171 ExceptionOr<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 199 ExceptionOr<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 253 static bool isNonEmptyDictionary(const PerformanceMeasureOptions& measureOptions) 254 { 255 return !measureOptions.detail.isUndefined() || measureOptions.start || measureOptions.duration || measureOptions.end; 256 } 257 258 ExceptionOr<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 ); 119 278 } 120 279 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 283 void PerformanceUserTiming::clearMeasures(const String& measureName) 155 284 { 156 285 clearPerformanceEntries(m_measuresMap, measureName); … … 165 294 } 166 295 167 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks() const296 Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMarks() const 168 297 { 169 298 return convertToEntrySequence(m_marksMap); 170 299 } 171 300 172 Vector<RefPtr<PerformanceEntry>> UserTiming::getMarks(const String& name) const301 Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMarks(const String& name) const 173 302 { 174 303 return m_marksMap.get(name); 175 304 } 176 305 177 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures() const306 Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMeasures() const 178 307 { 179 308 return convertToEntrySequence(m_measuresMap); 180 309 } 181 310 182 Vector<RefPtr<PerformanceEntry>> UserTiming::getMeasures(const String& name) const311 Vector<RefPtr<PerformanceEntry>> PerformanceUserTiming::getMeasures(const String& name) const 183 312 { 184 313 return m_measuresMap.get(name); -
trunk/Source/WebCore/page/PerformanceUserTiming.h
r241183 r267402 32 32 #include <wtf/text/StringHash.h> 33 33 34 namespace JSC { 35 class JSGlobalObject; 36 } 37 34 38 namespace WebCore { 35 39 … … 38 42 using PerformanceEntryMap = HashMap<String, Vector<RefPtr<PerformanceEntry>>>; 39 43 40 class UserTiming {44 class PerformanceUserTiming { 41 45 WTF_MAKE_FAST_ALLOCATED; 42 46 public: 43 explicit UserTiming(Performance&);47 explicit PerformanceUserTiming(Performance&); 44 48 45 ExceptionOr<Ref<PerformanceMark>> mark( const String& markName);49 ExceptionOr<Ref<PerformanceMark>> mark(JSC::JSGlobalObject&, const String& markName, Optional<PerformanceMarkOptions>&&); 46 50 void clearMarks(const String& markName); 47 51 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); 49 54 void clearMeasures(const String& measureName); 50 55 … … 55 60 Vector<RefPtr<PerformanceEntry>> getMeasures(const String& name) const; 56 61 62 static bool isRestrictedMarkName(const String& markName); 63 57 64 private: 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&); 59 71 60 72 Performance& m_performance;
Note:
See TracChangeset
for help on using the changeset viewer.