Skip to content

Commit 4a1c86d

Browse files
authored
Merge branch 'main' into perf-timessync
2 parents ae73a09 + 783f64b commit 4a1c86d

25 files changed

+467
-226
lines changed

.github/workflows/tools.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ on:
2323
- corepack
2424
- doc
2525
- eslint
26+
- github_reporter
2627
- googletest
2728
- histogram
2829
- icu

benchmark/fs/bench-unlinkSync.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const tmpdir = require('../../test/common/tmpdir');
6+
tmpdir.refresh();
7+
8+
const bench = common.createBenchmark(main, {
9+
type: ['existing', 'non-existing'],
10+
n: [1e3],
11+
});
12+
13+
function main({ n, type }) {
14+
let files;
15+
16+
switch (type) {
17+
case 'existing':
18+
files = [];
19+
20+
// Populate tmpdir with mock files
21+
for (let i = 0; i < n; i++) {
22+
const path = tmpdir.resolve(`unlinksync-bench-file-${i}`);
23+
fs.writeFileSync(path, 'bench');
24+
files.push(path);
25+
}
26+
break;
27+
case 'non-existing':
28+
files = new Array(n).fill(tmpdir.resolve(`.non-existing-file-${Date.now()}`));
29+
break;
30+
default:
31+
new Error('Invalid type');
32+
}
33+
34+
bench.start();
35+
for (let i = 0; i < n; i++) {
36+
try {
37+
fs.unlinkSync(files[i]);
38+
} catch {
39+
// do nothing
40+
}
41+
}
42+
bench.end(n);
43+
}

benchmark/fs/readFileSync.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@ const fs = require('fs');
66
const bench = common.createBenchmark(main, {
77
encoding: ['undefined', 'utf8'],
88
path: ['existing', 'non-existing'],
9-
n: [60e1],
9+
hasFileDescriptor: ['true', 'false'],
10+
n: [1e4],
1011
});
1112

12-
function main({ n, encoding, path }) {
13+
function main({ n, encoding, path, hasFileDescriptor }) {
1314
const enc = encoding === 'undefined' ? undefined : encoding;
14-
const file = path === 'existing' ? __filename : '/tmp/not-found';
15+
let file;
16+
let shouldClose = false;
17+
18+
if (hasFileDescriptor === 'true') {
19+
shouldClose = path === 'existing';
20+
file = path === 'existing' ? fs.openSync(__filename) : -1;
21+
} else {
22+
file = path === 'existing' ? __filename : '/tmp/not-found';
23+
}
1524
bench.start();
1625
for (let i = 0; i < n; ++i) {
1726
try {
@@ -21,4 +30,7 @@ function main({ n, encoding, path }) {
2130
}
2231
}
2332
bench.end(n);
33+
if (shouldClose) {
34+
fs.closeSync(file);
35+
}
2436
}

benchmark/perf_hooks/timerfied.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const common = require('../common.js');
5+
6+
const {
7+
PerformanceObserver,
8+
performance,
9+
} = require('perf_hooks');
10+
11+
function randomFn() {
12+
return Math.random();
13+
}
14+
15+
const bench = common.createBenchmark(main, {
16+
n: [1e5],
17+
observe: ['function'],
18+
});
19+
20+
let _result;
21+
22+
function main({ n, observe }) {
23+
const obs = new PerformanceObserver(() => {
24+
bench.end(n);
25+
});
26+
obs.observe({ entryTypes: [observe], buffered: true });
27+
28+
const timerfied = performance.timerify(randomFn);
29+
30+
bench.start();
31+
for (let i = 0; i < n; i++)
32+
_result = timerfied();
33+
34+
// Avoid V8 deadcode (elimination)
35+
assert.ok(_result);
36+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const url = require('url');
4+
const URL = url.URL;
5+
6+
const bench = common.createBenchmark(main, {
7+
type: ['valid', 'invalid'],
8+
e: [1e5],
9+
});
10+
11+
// This benchmark is used to compare the `Invalid URL` path of the URL parser
12+
function main({ type, e }) {
13+
const url = type === 'valid' ? 'https://www.nodejs.org' : 'www.nodejs.org';
14+
bench.start();
15+
for (let i = 0; i < e; i++) {
16+
try {
17+
new URL(url);
18+
} catch {
19+
// do nothing
20+
}
21+
}
22+
bench.end(e);
23+
}

lib/fs.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,11 @@ function tryReadSync(fd, isUserFd, buffer, pos, len) {
437437
function readFileSync(path, options) {
438438
options = getOptions(options, { flag: 'r' });
439439

440-
const isUserFd = isFd(path); // File descriptor ownership
441-
442-
// TODO(@anonrig): Do not handle file descriptor ownership for now.
443-
if (!isUserFd && (options.encoding === 'utf8' || options.encoding === 'utf-8')) {
440+
if (options.encoding === 'utf8' || options.encoding === 'utf-8') {
444441
return syncFs.readFileUtf8(path, options.flag);
445442
}
446443

444+
const isUserFd = isFd(path); // File descriptor ownership
447445
const fd = isUserFd ? path : fs.openSync(path, options.flag, 0o666);
448446

449447
const stats = tryStatSync(fd, isUserFd);
@@ -1852,10 +1850,7 @@ function unlink(path, callback) {
18521850
* @returns {void}
18531851
*/
18541852
function unlinkSync(path) {
1855-
path = getValidatedPath(path);
1856-
const ctx = { path };
1857-
binding.unlink(pathModule.toNamespacedPath(path), undefined, ctx);
1858-
handleErrorFromBinding(ctx);
1853+
return syncFs.unlink(path);
18591854
}
18601855

18611856
/**

lib/internal/errors.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,8 +1370,13 @@ E('ERR_INVALID_SYNC_FORK_INPUT',
13701370
E('ERR_INVALID_THIS', 'Value of "this" must be of type %s', TypeError);
13711371
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple', TypeError);
13721372
E('ERR_INVALID_URI', 'URI malformed', URIError);
1373-
E('ERR_INVALID_URL', function(input) {
1373+
E('ERR_INVALID_URL', function(input, base = null) {
13741374
this.input = input;
1375+
1376+
if (base != null) {
1377+
this.base = base;
1378+
}
1379+
13751380
// Don't include URL in message.
13761381
// (See https://github.com/nodejs/node/pull/38614)
13771382
return 'Invalid URL';

lib/internal/fs/sync.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const {
1010
getValidatedFd,
1111
toUnixTimestamp,
1212
} = require('internal/fs/utils');
13-
const { parseFileMode } = require('internal/validators');
13+
const { parseFileMode, isInt32 } = require('internal/validators');
1414

1515
const binding = internalBinding('fs');
1616

@@ -20,7 +20,9 @@ const binding = internalBinding('fs');
2020
* @return {string}
2121
*/
2222
function readFileUtf8(path, flag) {
23-
path = pathModule.toNamespacedPath(getValidatedPath(path));
23+
if (!isInt32(path)) {
24+
path = pathModule.toNamespacedPath(getValidatedPath(path));
25+
}
2426
return binding.readFileUtf8(path, stringToFlags(flag));
2527
}
2628

@@ -104,6 +106,11 @@ function lutimes(path, atime, mtime) {
104106
return binding.lutimesSync(path, toUnixTimestamp(atime), toUnixTimestamp(mtime));
105107
}
106108

109+
function unlink(path) {
110+
path = pathModule.toNamespacedPath(getValidatedPath(path));
111+
return binding.unlinkSync(path);
112+
}
113+
107114
module.exports = {
108115
readFileUtf8,
109116
exists,
@@ -116,4 +123,5 @@ module.exports = {
116123
utimes,
117124
futimes,
118125
lutimes,
126+
unlink,
119127
};

lib/internal/perf/performance_entry.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const {
44
ObjectDefineProperties,
5-
ReflectConstruct,
65
Symbol,
76
} = primordials;
87

@@ -25,14 +24,17 @@ const kEntryType = Symbol('PerformanceEntry.EntryType');
2524
const kStartTime = Symbol('PerformanceEntry.StartTime');
2625
const kDuration = Symbol('PerformanceEntry.Duration');
2726
const kDetail = Symbol('NodePerformanceEntry.Detail');
27+
const kSkipThrow = Symbol('kSkipThrow');
2828

2929
function isPerformanceEntry(obj) {
3030
return obj?.[kName] !== undefined;
3131
}
3232

3333
class PerformanceEntry {
34-
constructor() {
35-
throw new ERR_ILLEGAL_CONSTRUCTOR();
34+
constructor(skipThrowSymbol = undefined) {
35+
if (skipThrowSymbol !== kSkipThrow) {
36+
throw new ERR_ILLEGAL_CONSTRUCTOR();
37+
}
3638
}
3739

3840
get name() {
@@ -92,9 +94,11 @@ function initPerformanceEntry(entry, name, type, start, duration) {
9294
}
9395

9496
function createPerformanceEntry(name, type, start, duration) {
95-
return ReflectConstruct(function PerformanceEntry() {
96-
initPerformanceEntry(this, name, type, start, duration);
97-
}, [], PerformanceEntry);
97+
const entry = new PerformanceEntry(kSkipThrow);
98+
99+
initPerformanceEntry(entry, name, type, start, duration);
100+
101+
return entry;
98102
}
99103

100104
/**
@@ -119,10 +123,12 @@ class PerformanceNodeEntry extends PerformanceEntry {
119123
}
120124

121125
function createPerformanceNodeEntry(name, type, start, duration, detail) {
122-
return ReflectConstruct(function PerformanceNodeEntry() {
123-
initPerformanceEntry(this, name, type, start, duration);
124-
this[kDetail] = detail;
125-
}, [], PerformanceNodeEntry);
126+
const entry = new PerformanceNodeEntry(kSkipThrow);
127+
128+
initPerformanceEntry(entry, name, type, start, duration);
129+
entry[kDetail] = detail;
130+
131+
return entry;
126132
}
127133

128134
module.exports = {

0 commit comments

Comments
 (0)