mirror of
https://github.com/oven-sh/bun
synced 2026-02-12 20:09:04 +00:00
176 lines
5.2 KiB
TypeScript
176 lines
5.2 KiB
TypeScript
// Hardcoded module "node:perf_hooks"
|
|
const { throwNotImplemented } = require("internal/shared");
|
|
|
|
var {
|
|
Performance,
|
|
PerformanceEntry,
|
|
PerformanceMark,
|
|
PerformanceMeasure,
|
|
PerformanceObserver,
|
|
PerformanceObserverEntryList,
|
|
} = globalThis;
|
|
|
|
var constants = {
|
|
NODE_PERFORMANCE_GC_MAJOR: 4,
|
|
NODE_PERFORMANCE_GC_MINOR: 1,
|
|
NODE_PERFORMANCE_GC_INCREMENTAL: 8,
|
|
NODE_PERFORMANCE_GC_WEAKCB: 16,
|
|
NODE_PERFORMANCE_GC_FLAGS_NO: 0,
|
|
NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: 2,
|
|
NODE_PERFORMANCE_GC_FLAGS_FORCED: 4,
|
|
NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: 8,
|
|
NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: 16,
|
|
NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: 32,
|
|
NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: 64,
|
|
};
|
|
|
|
// PerformanceEntry is not a valid constructor, so we have to fake it.
|
|
class PerformanceNodeTiming {
|
|
bootstrapComplete: number = 0;
|
|
environment: number = 0;
|
|
idleTime: number = 0;
|
|
loopExit: number = 0;
|
|
loopStart: number = 0;
|
|
nodeStart: number = 0;
|
|
v8Start: number = 0;
|
|
|
|
// we have to fake the properties since it's not real
|
|
get name() {
|
|
return "node";
|
|
}
|
|
|
|
get entryType() {
|
|
return "node";
|
|
}
|
|
|
|
get startTime() {
|
|
return this.nodeStart;
|
|
}
|
|
|
|
get duration() {
|
|
return performance.now();
|
|
}
|
|
|
|
toJSON() {
|
|
return {
|
|
name: this.name,
|
|
entryType: this.entryType,
|
|
startTime: this.startTime,
|
|
duration: this.duration,
|
|
bootstrapComplete: this.bootstrapComplete,
|
|
environment: this.environment,
|
|
idleTime: this.idleTime,
|
|
loopExit: this.loopExit,
|
|
loopStart: this.loopStart,
|
|
nodeStart: this.nodeStart,
|
|
v8Start: this.v8Start,
|
|
};
|
|
}
|
|
}
|
|
Object.setPrototypeOf(PerformanceNodeTiming.prototype, PerformanceEntry.prototype);
|
|
Object.setPrototypeOf(PerformanceNodeTiming, PerformanceEntry);
|
|
|
|
function createPerformanceNodeTiming() {
|
|
const object = Object.create(PerformanceNodeTiming.prototype);
|
|
|
|
object.bootstrapComplete = object.environment = object.nodeStart = object.v8Start = performance.timeOrigin;
|
|
object.loopStart = object.idleTime = 1;
|
|
object.loopExit = -1;
|
|
return object;
|
|
}
|
|
|
|
function eventLoopUtilization(utilization1, utilization2) {
|
|
return {
|
|
idle: 0,
|
|
active: 0,
|
|
utilization: 0,
|
|
};
|
|
}
|
|
|
|
// PerformanceEntry is not a valid constructor, so we have to fake it.
|
|
class PerformanceResourceTiming {
|
|
constructor() {
|
|
throwNotImplemented("PerformanceResourceTiming");
|
|
}
|
|
}
|
|
Object.setPrototypeOf(PerformanceResourceTiming.prototype, PerformanceEntry.prototype);
|
|
Object.setPrototypeOf(PerformanceResourceTiming, PerformanceEntry);
|
|
|
|
export default {
|
|
performance: {
|
|
// perf_hooks is a builtin global, so JSC is aware of it through C++ bindings
|
|
// see JSPerformance.cpp HashTableValue for more details
|
|
// perf_hooks has a performance module with these exported functions,
|
|
// most implemented in C++ but I decide to do timerify in JS
|
|
mark(f) {
|
|
return performance.mark(...arguments);
|
|
},
|
|
measure(f) {
|
|
return performance.measure(...arguments);
|
|
},
|
|
timerify(f) {
|
|
// in this case, we want it to go back to JS function since we're passing a JS function
|
|
// go to JSPerformance.cpp HashTableValue to see how this is handled differently from the rest
|
|
return performance.timerify(...arguments); // this routes to JSPerformance.cpp
|
|
},
|
|
clearMarks(f) {
|
|
return performance.clearMarks(...arguments);
|
|
},
|
|
clearMeasures(f) {
|
|
return performance.clearMeasures(...arguments);
|
|
},
|
|
getEntries(f) {
|
|
return performance.getEntries(...arguments);
|
|
},
|
|
getEntriesByName(f) {
|
|
return performance.getEntriesByName(...arguments);
|
|
},
|
|
getEntriesByType(f) {
|
|
return performance.getEntriesByType(...arguments);
|
|
},
|
|
setResourceTimingBufferSize(f) {
|
|
return performance.setResourceTimingBufferSize(...arguments);
|
|
},
|
|
timeOrigin: performance.timeOrigin,
|
|
toJSON(f) {
|
|
return performance.toJSON(...arguments);
|
|
},
|
|
onresourcetimingbufferfull: performance.onresourcetimingbufferfull,
|
|
nodeTiming: createPerformanceNodeTiming(),
|
|
now: () => performance.now(),
|
|
eventLoopUtilization: eventLoopUtilization,
|
|
clearResourceTimings: function () {},
|
|
},
|
|
// performance: {
|
|
// clearMarks: [Function: clearMarks],
|
|
// clearMeasures: [Function: clearMeasures],
|
|
// clearResourceTimings: [Function: clearResourceTimings],
|
|
// getEntries: [Function: getEntries],
|
|
// getEntriesByName: [Function: getEntriesByName],
|
|
// getEntriesByType: [Function: getEntriesByType],
|
|
// mark: [Function: mark],
|
|
// measure: [Function: measure],
|
|
// now: performance.now,
|
|
// setResourceTimingBufferSize: [Function: setResourceTimingBufferSize],
|
|
// timeOrigin: performance.timeOrigin,
|
|
// toJSON: [Function: toJSON],
|
|
// onresourcetimingbufferfull: [Getter/Setter]
|
|
// },
|
|
constants,
|
|
Performance,
|
|
PerformanceEntry,
|
|
PerformanceMark,
|
|
PerformanceMeasure,
|
|
PerformanceObserver,
|
|
PerformanceObserverEntryList,
|
|
PerformanceNodeTiming,
|
|
monitorEventLoopDelay() {
|
|
throwNotImplemented("perf_hooks.monitorEventLoopDelay");
|
|
},
|
|
createHistogram() {
|
|
const { createHistogram } = $zig("node_perf_hooks_histogram_binding.zig", "createPerfHooksHistogramBinding");
|
|
return createHistogram();
|
|
},
|
|
PerformanceResourceTiming,
|
|
};
|