From 0b16af16892db583181f3ec95628658252d3eb3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 15 Aug 2024 16:23:43 +0200 Subject: [PATCH] src,test: track `URL.canParse` fast API calls Also regroup two small test files for naming consistency and simplify the tests. PR-URL: https://github.com/nodejs/node/pull/54356 Reviewed-By: Daniel Lemire Reviewed-By: Yagiz Nizipli Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell --- src/node_url.cc | 3 ++ test/parallel/test-url-canParse-whatwg.js | 19 ---------- test/parallel/test-whatwg-url-canparse.js | 45 ++++++++++++++--------- typings/internalBinding/url.d.ts | 1 + 4 files changed, 31 insertions(+), 37 deletions(-) delete mode 100644 test/parallel/test-url-canParse-whatwg.js diff --git a/src/node_url.cc b/src/node_url.cc index 01a6d351f0d437..d49229f2b1f536 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -1,6 +1,7 @@ #include "node_url.h" #include "ada.h" #include "base_object-inl.h" +#include "node_debug.h" #include "node_errors.h" #include "node_external_reference.h" #include "node_i18n.h" @@ -173,12 +174,14 @@ void BindingData::CanParse(const FunctionCallbackInfo& args) { bool BindingData::FastCanParse(Local receiver, const FastOneByteString& input) { + TRACK_V8_FAST_API_CALL("url.canParse"); return ada::can_parse(std::string_view(input.data, input.length)); } bool BindingData::FastCanParseWithBase(Local receiver, const FastOneByteString& input, const FastOneByteString& base) { + TRACK_V8_FAST_API_CALL("url.canParse.withBase"); auto base_view = std::string_view(base.data, base.length); return ada::can_parse(std::string_view(input.data, input.length), &base_view); } diff --git a/test/parallel/test-url-canParse-whatwg.js b/test/parallel/test-url-canParse-whatwg.js deleted file mode 100644 index d5ffee7053a716..00000000000000 --- a/test/parallel/test-url-canParse-whatwg.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); - -// One argument is required -assert.throws(() => { - URL.canParse(); -}, { - code: 'ERR_MISSING_ARGS', - name: 'TypeError', -}); - -{ - // This test is to ensure that the v8 fast api works. - for (let i = 0; i < 1e5; i++) { - assert(URL.canParse('https://www.example.com/path/?query=param#hash')); - } -} diff --git a/test/parallel/test-whatwg-url-canparse.js b/test/parallel/test-whatwg-url-canparse.js index 075ecd2f74886a..c67f957ec65f49 100644 --- a/test/parallel/test-whatwg-url-canparse.js +++ b/test/parallel/test-whatwg-url-canparse.js @@ -1,29 +1,38 @@ -// Flags: --expose-internals +// Flags: --expose-internals --no-warnings --allow-natives-syntax 'use strict'; -require('../common'); +const common = require('../common'); const { URL } = require('url'); const assert = require('assert'); -let internalBinding; -try { - internalBinding = require('internal/test/binding').internalBinding; -} catch (e) { - console.log('using `test/parallel/test-whatwg-url-canparse` requires `--expose-internals`'); - throw e; -} +const { internalBinding } = require('internal/test/binding'); -const { canParse } = internalBinding('url'); +// One argument is required +assert.throws(() => { + URL.canParse(); +}, { + code: 'ERR_MISSING_ARGS', + name: 'TypeError', +}); // It should not throw when called without a base string assert.strictEqual(URL.canParse('https://example.org'), true); -assert.strictEqual(canParse('https://example.org'), true); - -// This for-loop is used to test V8 Fast API optimizations -for (let i = 0; i < 100000; i++) { - // This example is used because only parsing the first parameter - // results in an invalid URL. They have to be used together to - // produce truthy value. - assert.strictEqual(URL.canParse('/', 'http://n'), true); + +if (common.isDebug) { + const { getV8FastApiCallCount } = internalBinding('debug'); + + function testFastPaths() { + // `canParse` binding has two overloads. + assert.strictEqual(URL.canParse('https://www.example.com/path/?query=param#hash'), true); + assert.strictEqual(URL.canParse('/', 'http://n'), true); + } + + eval('%PrepareFunctionForOptimization(URL.canParse)'); + testFastPaths(); + eval('%OptimizeFunctionOnNextCall(URL.canParse)'); + testFastPaths(); + + assert.strictEqual(getV8FastApiCallCount('url.canParse'), 1); + assert.strictEqual(getV8FastApiCallCount('url.canParse.withBase'), 1); } diff --git a/typings/internalBinding/url.d.ts b/typings/internalBinding/url.d.ts index 03d5f6d750f358..b2e1a92ade9141 100644 --- a/typings/internalBinding/url.d.ts +++ b/typings/internalBinding/url.d.ts @@ -6,6 +6,7 @@ export interface URLBinding { domainToASCII(input: string): string; domainToUnicode(input: string): string; canParse(input: string): boolean; + canParse(input: string, base: string): boolean; format(input: string, fragment?: boolean, unicode?: boolean, search?: boolean, auth?: boolean): string; parse(input: string, base?: string): string | false; update(input: string, actionType: typeof urlUpdateActions, value: string): string | false;