Skip to content

Commit c0ee759

Browse files
author
bors-servo
authored
Auto merge of #25659 - pshaughn:timingresolution, r=jdm,nox
Expose DOMHighResTimeStamps at lower res As explained in https://www.w3.org/TR/hr-time-2/#clock-resolution and tested in a few WPT tests, we're not supposed to show Javascript the full resolution of OS timestamps. This fixes that on all the DOMHighResTimeStamp interfaces that weren't already limiting themselves to integer milliseconds. The specific choice of how to coarsen the resolution is extremely bikesheddable; I commented the reasoning for my arbitrary choice but I admit it's arbitrary. A couple tests of timing resolution still fail, but because they're seeing undefined and NaN values due to unimplemented attributes (#25658). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #25656 fix #25296 fix #21276 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
2 parents 39133ee + 8e65782 commit c0ee759

10 files changed

Lines changed: 46 additions & 51 deletions

File tree

components/script/dom/event.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeS
1010
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceBinding::PerformanceMethods;
1111
use crate::dom::bindings::error::Fallible;
1212
use crate::dom::bindings::inheritance::Castable;
13-
use crate::dom::bindings::num::Finite;
1413
use crate::dom::bindings::refcounted::Trusted;
1514
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
1615
use crate::dom::bindings::root::{DomRoot, DomSlice, MutNullableDom};
@@ -19,6 +18,7 @@ use crate::dom::document::Document;
1918
use crate::dom::eventtarget::{CompiledEventListener, EventTarget, ListenerPhase};
2019
use crate::dom::globalscope::GlobalScope;
2120
use crate::dom::node::Node;
21+
use crate::dom::performance::reduce_timing_resolution;
2222
use crate::dom::virtualmethods::vtable_for;
2323
use crate::dom::window::Window;
2424
use crate::task::TaskOnce;
@@ -333,7 +333,7 @@ impl EventMethods for Event {
333333

334334
// https://dom.spec.whatwg.org/#dom-event-timestamp
335335
fn TimeStamp(&self) -> DOMHighResTimeStamp {
336-
Finite::wrap(
336+
reduce_timing_resolution(
337337
(self.precise_time_ns - (*self.global().performance().TimeOrigin()).round() as u64)
338338
.to_ms(),
339339
)

components/script/dom/performance.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,12 @@ impl PerformanceMethods for Performance {
401401

402402
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
403403
fn Now(&self) -> DOMHighResTimeStamp {
404-
Finite::wrap(self.now())
404+
reduce_timing_resolution(self.now())
405405
}
406406

407407
// https://www.w3.org/TR/hr-time-2/#dom-performance-timeorigin
408408
fn TimeOrigin(&self) -> DOMHighResTimeStamp {
409-
Finite::wrap(self.navigation_start_precise as f64)
409+
reduce_timing_resolution(self.navigation_start_precise as f64)
410410
}
411411

412412
// https://www.w3.org/TR/performance-timeline-2/#dom-performance-getentries
@@ -525,3 +525,14 @@ impl PerformanceMethods for Performance {
525525
SetOnresourcetimingbufferfull
526526
);
527527
}
528+
529+
// https://www.w3.org/TR/hr-time-2/#clock-resolution
530+
pub fn reduce_timing_resolution(exact: f64) -> DOMHighResTimeStamp {
531+
// We need a granularity no finer than 5 microseconds.
532+
// 5 microseconds isn't an exactly representable f64 so WPT tests
533+
// might occasionally corner-case on rounding.
534+
// web-platform-tests/wpt#21526 wants us to use an integer number of
535+
// microseconds; the next divisor of milliseconds up from 5 microseconds
536+
// is 10, which is 1/100th of a millisecond.
537+
Finite::wrap((exact * 100.0).floor() / 100.0)
538+
}

components/script/dom/performanceentry.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5+
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
56
use crate::dom::bindings::codegen::Bindings::PerformanceEntryBinding;
67
use crate::dom::bindings::codegen::Bindings::PerformanceEntryBinding::PerformanceEntryMethods;
7-
use crate::dom::bindings::num::Finite;
88
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
99
use crate::dom::bindings::root::DomRoot;
1010
use crate::dom::bindings::str::DOMString;
1111
use crate::dom::globalscope::GlobalScope;
12+
use crate::dom::performance::reduce_timing_resolution;
1213
use dom_struct::dom_struct;
1314

1415
#[dom_struct]
@@ -77,12 +78,12 @@ impl PerformanceEntryMethods for PerformanceEntry {
7778
}
7879

7980
// https://w3c.github.io/performance-timeline/#dom-performanceentry-starttime
80-
fn StartTime(&self) -> Finite<f64> {
81-
Finite::wrap(self.start_time)
81+
fn StartTime(&self) -> DOMHighResTimeStamp {
82+
reduce_timing_resolution(self.start_time)
8283
}
8384

8485
// https://w3c.github.io/performance-timeline/#dom-performanceentry-duration
85-
fn Duration(&self) -> Finite<f64> {
86-
Finite::wrap(self.duration)
86+
fn Duration(&self) -> DOMHighResTimeStamp {
87+
reduce_timing_resolution(self.duration)
8788
}
8889
}

components/script/dom/performanceresourcetiming.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeS
66
use crate::dom::bindings::codegen::Bindings::PerformanceResourceTimingBinding::{
77
self, PerformanceResourceTimingMethods,
88
};
9-
use crate::dom::bindings::num::Finite;
109
use crate::dom::bindings::reflector::reflect_dom_object;
1110
use crate::dom::bindings::root::DomRoot;
1211
use crate::dom::bindings::str::DOMString;
1312
use crate::dom::globalscope::GlobalScope;
13+
use crate::dom::performance::reduce_timing_resolution;
1414
use crate::dom::performanceentry::PerformanceEntry;
1515
use dom_struct::dom_struct;
1616
use net_traits::ResourceFetchTiming;
@@ -182,17 +182,17 @@ impl PerformanceResourceTimingMethods for PerformanceResourceTiming {
182182

183183
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-domainlookupstart
184184
fn DomainLookupStart(&self) -> DOMHighResTimeStamp {
185-
Finite::wrap(self.domain_lookup_start)
185+
reduce_timing_resolution(self.domain_lookup_start)
186186
}
187187

188188
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-domainlookupend
189189
fn DomainLookupEnd(&self) -> DOMHighResTimeStamp {
190-
Finite::wrap(self.domain_lookup_end)
190+
reduce_timing_resolution(self.domain_lookup_end)
191191
}
192192

193193
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-secureconnectionstart
194194
fn SecureConnectionStart(&self) -> DOMHighResTimeStamp {
195-
Finite::wrap(self.secure_connection_start)
195+
reduce_timing_resolution(self.secure_connection_start)
196196
}
197197

198198
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-transfersize
@@ -212,41 +212,41 @@ impl PerformanceResourceTimingMethods for PerformanceResourceTiming {
212212

213213
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-requeststart
214214
fn RequestStart(&self) -> DOMHighResTimeStamp {
215-
Finite::wrap(self.request_start)
215+
reduce_timing_resolution(self.request_start)
216216
}
217217

218218
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-redirectstart
219219
fn RedirectStart(&self) -> DOMHighResTimeStamp {
220-
Finite::wrap(self.redirect_start)
220+
reduce_timing_resolution(self.redirect_start)
221221
}
222222

223223
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-redirectend
224224
fn RedirectEnd(&self) -> DOMHighResTimeStamp {
225-
Finite::wrap(self.redirect_end)
225+
reduce_timing_resolution(self.redirect_end)
226226
}
227227

228228
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responsestart
229229
fn ResponseStart(&self) -> DOMHighResTimeStamp {
230-
Finite::wrap(self.response_start)
230+
reduce_timing_resolution(self.response_start)
231231
}
232232

233233
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-fetchstart
234234
fn FetchStart(&self) -> DOMHighResTimeStamp {
235-
Finite::wrap(self.fetch_start)
235+
reduce_timing_resolution(self.fetch_start)
236236
}
237237

238238
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-connectstart
239239
fn ConnectStart(&self) -> DOMHighResTimeStamp {
240-
Finite::wrap(self.connect_start)
240+
reduce_timing_resolution(self.connect_start)
241241
}
242242

243243
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-connectend
244244
fn ConnectEnd(&self) -> DOMHighResTimeStamp {
245-
Finite::wrap(self.connect_end)
245+
reduce_timing_resolution(self.connect_end)
246246
}
247247

248248
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responseend
249249
fn ResponseEnd(&self) -> DOMHighResTimeStamp {
250-
Finite::wrap(self.response_end)
250+
reduce_timing_resolution(self.response_end)
251251
}
252252
}

components/script/dom/vrframedata.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5+
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
56
use crate::dom::bindings::codegen::Bindings::VRFrameDataBinding;
67
use crate::dom::bindings::codegen::Bindings::VRFrameDataBinding::VRFrameDataMethods;
78
use crate::dom::bindings::error::Fallible;
8-
use crate::dom::bindings::num::Finite;
99
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
1010
use crate::dom::bindings::root::{Dom, DomRoot};
1111
use crate::dom::globalscope::GlobalScope;
12+
use crate::dom::performance::reduce_timing_resolution;
1213
use crate::dom::vrpose::VRPose;
1314
use crate::dom::window::Window;
1415
use crate::script_runtime::JSContext;
@@ -119,8 +120,8 @@ impl VRFrameData {
119120

120121
impl VRFrameDataMethods for VRFrameData {
121122
// https://w3c.github.io/webvr/#dom-vrframedata-timestamp
122-
fn Timestamp(&self) -> Finite<f64> {
123-
Finite::wrap(self.timestamp.get() - self.first_timestamp.get())
123+
fn Timestamp(&self) -> DOMHighResTimeStamp {
124+
reduce_timing_resolution(self.timestamp.get() - self.first_timestamp.get())
124125
}
125126

126127
#[allow(unsafe_code)]

components/script/dom/xrsession.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState
1919
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
2020
use crate::dom::bindings::error::{Error, ErrorResult};
2121
use crate::dom::bindings::inheritance::Castable;
22-
use crate::dom::bindings::num::Finite;
2322
use crate::dom::bindings::refcounted::Trusted;
2423
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
2524
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
@@ -28,6 +27,7 @@ use crate::dom::eventtarget::EventTarget;
2827
use crate::dom::globalscope::GlobalScope;
2928
use crate::dom::node::Node;
3029
use crate::dom::node::NodeDamage;
30+
use crate::dom::performance::reduce_timing_resolution;
3131
use crate::dom::promise::Promise;
3232
use crate::dom::xrframe::XRFrame;
3333
use crate::dom::xrinputsourcearray::XRInputSourceArray;
@@ -336,7 +336,7 @@ impl XRSession {
336336
// Step 4-5
337337
let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]);
338338
let start = self.global().as_window().get_navigation_start();
339-
let time = (frame.time_ns - start).to_ms();
339+
let time = reduce_timing_resolution((frame.time_ns - start).to_ms());
340340

341341
let frame = XRFrame::new(&self.global(), self, frame);
342342
// Step 6,7
@@ -347,7 +347,7 @@ impl XRSession {
347347
self.outside_raf.set(false);
348348
for (_, callback) in callbacks.drain(..) {
349349
if let Some(callback) = callback {
350-
let _ = callback.Call__(Finite::wrap(time), &frame, ExceptionHandling::Report);
350+
let _ = callback.Call__(time, &frame, ExceptionHandling::Report);
351351
}
352352
}
353353
self.outside_raf.set(true);

tests/wpt/metadata/dom/events/Event-timestamp-safe-resolution.html.ini

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/wpt/metadata/performance-timeline/webtiming-resolution.any.js.ini

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/wpt/mozilla/meta/MANIFEST.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19708,7 +19708,7 @@
1970819708
"testharness"
1970919709
],
1971019710
"mozilla/window_performance.html": [
19711-
"302073e8041763102d678326509d7ef0a1fb5c79",
19711+
"c1e38a1e00147caf82492dc82f1cb5e85759f8e3",
1971219712
"testharness"
1971319713
],
1971419714
"mozilla/window_performance_topLevelDomComplete.html": [

tests/wpt/mozilla/tests/mozilla/window_performance.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@
2727
var last = window.performance.now();
2828
assert_greater_than(last, 0);
2929

30-
// Check that window.performance.now() is monotonically increasing
30+
// Check that window.performance.now() is monotonically nondecreasing
31+
// and eventually increases
32+
var before_loop = window.performance.now();
3133
for (var i = 0; i < 100; i++) {
3234
var next = window.performance.now();
33-
assert_greater_than(next, last);
35+
assert_greater_than_equal(next, last);
3436
last = next;
3537
}
38+
assert_greater_than(last, before_loop, "If this fails, either performance timing is broken, or Servo JS execution has gotten much faster since this test was written.");
3639
});
3740
</script>
3841
</body>

0 commit comments

Comments
 (0)