Skip to content

Commit ccfa6bf

Browse files
Merge pull request #5097 from cloudflare/harris/EW-9466-perf-event-mark
EW-9466 EW-9596 Add perf event marking to performance.now()
2 parents 5a62487 + e150a22 commit ccfa6bf

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

src/workerd/api/global-scope.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ class ServiceWorkerGlobalScope: public WorkerGlobalScope {
584584
}
585585

586586
jsg::Ref<Performance> getPerformance(jsg::Lock& js) {
587-
return js.alloc<Performance>();
587+
return js.alloc<Performance>(Worker::Isolate::from(js).getLimitEnforcer());
588588
}
589589

590590
jsg::Ref<Cloudflare> getCloudflare(jsg::Lock& js) {

src/workerd/api/performance.c++

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
#include "performance.h"
66

77
#include <workerd/io/io-util.h>
8+
#include <workerd/io/worker.h>
89

910
#include <kj/encoding.h>
1011

1112
namespace workerd::api {
1213

13-
double Performance::now() {
14+
double Performance::now(jsg::Lock& js) {
1415
// We define performance.now() for compatibility purposes, but due to Spectre concerns it
1516
// returns exactly what Date.now() returns.
17+
isolateLimitEnforcer.markPerfEvent("performance_now"_kjc);
1618
return dateNow();
1719
}
1820

@@ -165,7 +167,9 @@ kj::ArrayPtr<jsg::Ref<PerformanceEntry>> PerformanceObserverEntryList::getEntrie
165167

166168
jsg::Ref<PerformanceMark> Performance::mark(
167169
jsg::Lock& js, kj::String name, jsg::Optional<PerformanceMark::Options> options) {
168-
double startTime = now();
170+
// TODO(someday): Include `name` in the perf event name?
171+
isolateLimitEnforcer.markPerfEvent("performance_mark"_kjc);
172+
double startTime = dateNow();
169173
KJ_IF_SOME(opts, options) {
170174
KJ_IF_SOME(time, opts.startTime) {
171175
startTime = time;
@@ -188,7 +192,8 @@ jsg::Ref<PerformanceMeasure> Performance::measure(jsg::Lock& js,
188192
kj::String measureName,
189193
kj::OneOf<PerformanceMeasure::Options, kj::String> measureOptionsOrStartMark,
190194
jsg::Optional<kj::String> maybeEndMark) {
191-
double startTime = now();
195+
isolateLimitEnforcer.markPerfEvent("performance_measure"_kjc);
196+
double startTime = dateNow();
192197
double endTime = startTime;
193198

194199
KJ_SWITCH_ONEOF(measureOptionsOrStartMark) {

src/workerd/api/performance.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <workerd/api/basics.h>
88
#include <workerd/io/compatibility-date.capnp.h>
9+
#include <workerd/io/limit-enforcer.h>
910
#include <workerd/jsg/jsg.h>
1011

1112
namespace workerd::api {
@@ -404,6 +405,9 @@ class Performance: public EventTarget {
404405
public:
405406
static jsg::Ref<Performance> constructor() = delete;
406407

408+
explicit Performance(const IsolateLimitEnforcer& isolateLimitEnforcer)
409+
: isolateLimitEnforcer(isolateLimitEnforcer) {}
410+
407411
// We always return a time origin of 0, making performance.now() equivalent to Date.now(). There
408412
// is no other appropriate time origin to use given that the Worker platform is intended to be
409413
// treated like one big computer rather than many individual instances. In particular, if and
@@ -422,7 +426,7 @@ class Performance: public EventTarget {
422426

423427
jsg::Ref<EventCounts> getEventCounts(jsg::Lock& js);
424428

425-
double now();
429+
double now(jsg::Lock& js);
426430

427431
void clearMarks(jsg::Optional<kj::String> name);
428432
void clearMeasures(jsg::Optional<kj::String> name);
@@ -483,6 +487,7 @@ class Performance: public EventTarget {
483487
}
484488

485489
private:
490+
const IsolateLimitEnforcer& isolateLimitEnforcer;
486491
kj::Vector<jsg::Ref<PerformanceEntry>> entries;
487492
};
488493

src/workerd/io/limit-enforcer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ class IsolateLimitEnforcer: public kj::Refcounted {
8585
}
8686

8787
virtual bool hasExcessivelyExceededHeapLimit() const = 0;
88+
89+
// Inserts a custom mark event named `name` into this isolate's perf event data stream. At
90+
// present, this is only implemented internally. Call this function from various APIs to be able
91+
// to correlate perf event data with usage of those APIs.
92+
//
93+
// TODO(cleanup): This isn't strictly related to limit enforcement, so it's a bit odd here. It's
94+
// observability-related. However, our internal perf event observability is fairly tightly
95+
// coupled with our CPU time limiting system, so adding this function here is a path of least
96+
// resistance.
97+
virtual void markPerfEvent(kj::LiteralStringConst name) const {};
8898
};
8999

90100
// Abstract interface that enforces resource limits on a IoContext.

0 commit comments

Comments
 (0)