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:
parent
98d062e3dc
commit
824cb485c5
2 changed files with 54 additions and 25 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue