1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

perf(ext/websocket): skip Events constructor checks (#16365)

WebSocket internal events can bypass Event's webidl checks and
`ReflectDefineProperty` on the object value. Note, this intentionally
makes websocket events `isTrusted` configurable (not spec-compliant)
which hurts performance a lot.

Before:
```
Msg/sec: 167627.750000
Msg/sec: 168239.250000
Msg/sec: 169690.000000
```

After:
```
Msg/sec: 191065.500000
Msg/sec: 194745.250000
Msg/sec: 194746.000000
```
This commit is contained in:
Divy Srivastava 2022-12-01 06:35:32 -08:00 committed by GitHub
parent 98d062e3dc
commit 824cb485c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 25 deletions

View file

@ -139,6 +139,8 @@
const _dispatched = Symbol("[[dispatched]]");
const _isTrusted = Symbol("[[isTrusted]]");
const _path = Symbol("[[path]]");
// internal.
const _skipInternalInit = Symbol("[[skipSlowInit]]");
class Event {
constructor(type, eventInitDict = {}) {
@ -152,29 +154,47 @@
this[_isTrusted] = false;
this[_path] = [];
webidl.requiredArguments(arguments.length, 1, {
prefix: "Failed to construct 'Event'",
});
type = webidl.converters.DOMString(type, {
prefix: "Failed to construct 'Event'",
context: "Argument 1",
});
const eventInit = eventInitConverter(eventInitDict, {
prefix: "Failed to construct 'Event'",
context: "Argument 2",
});
this[_attributes] = {
type,
...eventInit,
currentTarget: null,
eventPhase: Event.NONE,
target: null,
timeStamp: DateNow(),
};
ReflectDefineProperty(this, "isTrusted", {
enumerable: true,
get: isTrusted,
});
if (!eventInitDict[_skipInternalInit]) {
webidl.requiredArguments(arguments.length, 1, {
prefix: "Failed to construct 'Event'",
});
type = webidl.converters.DOMString(type, {
prefix: "Failed to construct 'Event'",
context: "Argument 1",
});
const eventInit = eventInitConverter(eventInitDict, {
prefix: "Failed to construct 'Event'",
context: "Argument 2",
});
this[_attributes] = {
type,
...eventInit,
currentTarget: null,
eventPhase: Event.NONE,
target: null,
timeStamp: DateNow(),
};
// [LegacyUnforgeable]
ReflectDefineProperty(this, "isTrusted", {
enumerable: true,
get: isTrusted,
});
} else {
this[_attributes] = {
type,
data: eventInitDict.data ?? null,
bubbles: eventInitDict.bubbles ?? false,
cancelable: eventInitDict.cancelable ?? false,
composed: eventInitDict.composed ?? false,
currentTarget: null,
eventPhase: Event.NONE,
target: null,
timeStamp: DateNow(),
};
// TODO(@littledivy): Not spec compliant but performance is hurt badly
// for users of `_skipInternalInit`.
this.isTrusted = false;
}
}
[SymbolFor("Deno.privateCustomInspect")](inspect) {
@ -1191,6 +1211,7 @@
bubbles: eventInitDict?.bubbles ?? false,
cancelable: eventInitDict?.cancelable ?? false,
composed: eventInitDict?.composed ?? false,
[_skipInternalInit]: eventInitDict?.[_skipInternalInit],
});
this.data = eventInitDict?.data ?? null;
@ -1481,6 +1502,7 @@
setIsTrusted,
setTarget,
defineEventHandler,
_skipInternalInit,
Event,
ErrorEvent,
CloseEvent,

View file

@ -10,8 +10,14 @@
const webidl = window.__bootstrap.webidl;
const { HTTP_TOKEN_CODE_POINT_RE } = window.__bootstrap.infra;
const { DOMException } = window.__bootstrap.domException;
const { Event, ErrorEvent, CloseEvent, MessageEvent, defineEventHandler } =
window.__bootstrap.event;
const {
Event,
ErrorEvent,
CloseEvent,
MessageEvent,
defineEventHandler,
_skipInternalInit,
} = window.__bootstrap.event;
const { EventTarget } = window.__bootstrap.eventTarget;
const { Blob, BlobPrototype } = globalThis.__bootstrap.file;
const {
@ -440,6 +446,7 @@
const event = new MessageEvent("message", {
data,
origin: this[_url],
[_skipInternalInit]: true,
});
this.dispatchEvent(event);
break;