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 _dispatched = Symbol("[[dispatched]]");
const _isTrusted = Symbol("[[isTrusted]]"); const _isTrusted = Symbol("[[isTrusted]]");
const _path = Symbol("[[path]]"); const _path = Symbol("[[path]]");
// internal.
const _skipInternalInit = Symbol("[[skipSlowInit]]");
class Event { class Event {
constructor(type, eventInitDict = {}) { constructor(type, eventInitDict = {}) {
@ -152,29 +154,47 @@
this[_isTrusted] = false; this[_isTrusted] = false;
this[_path] = []; this[_path] = [];
webidl.requiredArguments(arguments.length, 1, { if (!eventInitDict[_skipInternalInit]) {
prefix: "Failed to construct 'Event'", webidl.requiredArguments(arguments.length, 1, {
}); prefix: "Failed to construct 'Event'",
type = webidl.converters.DOMString(type, { });
prefix: "Failed to construct 'Event'", type = webidl.converters.DOMString(type, {
context: "Argument 1", prefix: "Failed to construct 'Event'",
}); context: "Argument 1",
const eventInit = eventInitConverter(eventInitDict, { });
prefix: "Failed to construct 'Event'", const eventInit = eventInitConverter(eventInitDict, {
context: "Argument 2", prefix: "Failed to construct 'Event'",
}); context: "Argument 2",
this[_attributes] = { });
type, this[_attributes] = {
...eventInit, type,
currentTarget: null, ...eventInit,
eventPhase: Event.NONE, currentTarget: null,
target: null, eventPhase: Event.NONE,
timeStamp: DateNow(), target: null,
}; timeStamp: DateNow(),
ReflectDefineProperty(this, "isTrusted", { };
enumerable: true, // [LegacyUnforgeable]
get: isTrusted, 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) { [SymbolFor("Deno.privateCustomInspect")](inspect) {
@ -1191,6 +1211,7 @@
bubbles: eventInitDict?.bubbles ?? false, bubbles: eventInitDict?.bubbles ?? false,
cancelable: eventInitDict?.cancelable ?? false, cancelable: eventInitDict?.cancelable ?? false,
composed: eventInitDict?.composed ?? false, composed: eventInitDict?.composed ?? false,
[_skipInternalInit]: eventInitDict?.[_skipInternalInit],
}); });
this.data = eventInitDict?.data ?? null; this.data = eventInitDict?.data ?? null;
@ -1481,6 +1502,7 @@
setIsTrusted, setIsTrusted,
setTarget, setTarget,
defineEventHandler, defineEventHandler,
_skipInternalInit,
Event, Event,
ErrorEvent, ErrorEvent,
CloseEvent, CloseEvent,

View file

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