From 390654e996ad036265f420d487555326e7946bae Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Tue, 29 Apr 2025 13:53:12 -0400 Subject: [PATCH 1/3] src: fix internalModuleStat v8 fast path PR-URL: https://github.com/nodejs/node/pull/58054 Backport-PR-URL: https://github.com/nodejs/node/pull/59065 Reviewed-By: James M Snell Reviewed-By: Robert Nagy Reviewed-By: Antoine du Hamel --- lib/fs.js | 4 ++-- lib/internal/fs/promises.js | 2 +- lib/internal/modules/cjs/loader.js | 4 ++-- lib/internal/modules/esm/resolve.js | 1 - lib/internal/modules/package_json_reader.js | 1 - src/node_external_reference.h | 5 ++-- src/node_file.cc | 20 +++++++++------- ...test-permission-fs-internal-module-stat.js | 24 ++++++++++++++----- 8 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index adfbbccc6e66c9..c8e0c2a36da5f5 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1448,7 +1448,7 @@ function handleDirents({ result, currentPath, context }) { const dirent = getDirent(currentPath, names[i], types[i]); ArrayPrototypePush(context.readdirResults, dirent); - if (dirent.isDirectory() || binding.internalModuleStat(binding, fullPath) === 1) { + if (dirent.isDirectory() || binding.internalModuleStat(fullPath) === 1) { ArrayPrototypePush(context.pathsQueue, fullPath); } } @@ -1458,7 +1458,7 @@ function handleFilePaths({ result, currentPath, context }) { for (let i = 0; i < result.length; i++) { const resultPath = pathModule.join(currentPath, result[i]); const relativeResultPath = pathModule.relative(context.basePath, resultPath); - const stat = binding.internalModuleStat(binding, resultPath); + const stat = binding.internalModuleStat(resultPath); ArrayPrototypePush(context.readdirResults, relativeResultPath); if (stat === 1) { diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index e43fb2a3daa29d..96a60a55d69504 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -915,7 +915,7 @@ async function readdirRecursive(originalPath, options) { const { 0: path, 1: readdir } = ArrayPrototypePop(queue); for (const ent of readdir) { const direntPath = pathModule.join(path, ent); - const stat = binding.internalModuleStat(binding, direntPath); + const stat = binding.internalModuleStat(direntPath); ArrayPrototypePush( result, pathModule.relative(originalPath, direntPath), diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 11ca6aa489c8ac..9b51e5bf4cdfbc 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -255,9 +255,9 @@ function stat(filename) { const result = statCache.get(filename); if (result !== undefined) { return result; } } - const result = internalFsBinding.internalModuleStat(internalFsBinding, filename); + const result = internalFsBinding.internalModuleStat(filename); if (statCache !== null && result >= 0) { - // Only set cache when `internalModuleStat(internalFsBinding, filename)` succeeds. + // Only set cache when `internalModuleStat(filename)` succeeds. statCache.set(filename, result); } return result; diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index bfd9bd3d127404..859b6bfedac4bb 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -248,7 +248,6 @@ function finalizeResolution(resolved, base, preserveSymlinks) { } const stats = internalFsBinding.internalModuleStat( - internalFsBinding, StringPrototypeEndsWith(internalFsBinding, path, '/') ? StringPrototypeSlice(path, -1) : path, ); diff --git a/lib/internal/modules/package_json_reader.js b/lib/internal/modules/package_json_reader.js index df23a30b1b9bdf..47b248c2ae6306 100644 --- a/lib/internal/modules/package_json_reader.js +++ b/lib/internal/modules/package_json_reader.js @@ -235,7 +235,6 @@ function getPackageJSONURL(specifier, base) { let lastPath; do { const stat = internalFsBinding.internalModuleStat( - internalFsBinding, StringPrototypeSlice(packageJSONPath, 0, packageJSONPath.length - 13), ); // Check for !stat.isDirectory() diff --git a/src/node_external_reference.h b/src/node_external_reference.h index 3bc7b2cab5a12e..9cafc70f8a3435 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -20,9 +20,8 @@ using CFunctionCallback = void (*)(v8::Local unused, using CFunctionCallbackReturnDouble = double (*)(v8::Local unused, v8::Local receiver); using CFunctionCallbackReturnInt32 = - int32_t (*)(v8::Local unused, - v8::Local receiver, - const v8::FastOneByteString& input, + int32_t (*)(v8::Local receiver, + v8::Local input, // NOLINTNEXTLINE(runtime/references) This is V8 api. v8::FastApiCallbackOptions& options); using CFunctionCallbackValueReturnDouble = diff --git a/src/node_file.cc b/src/node_file.cc index e46fb13173137d..d2a372446cfd0c 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -23,6 +23,7 @@ #include "aliased_buffer-inl.h" #include "memory_tracker-inl.h" #include "node_buffer.h" +#include "node_debug.h" #include "node_errors.h" #include "node_external_reference.h" #include "node_file-inl.h" @@ -60,8 +61,6 @@ using v8::BigInt; using v8::Context; using v8::EscapableHandleScope; using v8::FastApiCallbackOptions; -using v8::FastOneByteString; -using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; @@ -1051,9 +1050,9 @@ static void ExistsSync(const FunctionCallbackInfo& args) { static void InternalModuleStat(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK_GE(args.Length(), 2); - CHECK(args[1]->IsString()); - BufferValue path(env->isolate(), args[1]); + CHECK_EQ(args.Length(), 1); + CHECK(args[0]->IsString()); + BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); ToNamespacedPath(env, &path); @@ -1069,9 +1068,8 @@ static void InternalModuleStat(const FunctionCallbackInfo& args) { } static int32_t FastInternalModuleStat( - Local unused, - Local recv, - const FastOneByteString& input, + Local recv, + Local input_, // NOLINTNEXTLINE(runtime/references) This is V8 api. FastApiCallbackOptions& options) { // This needs a HandleScope which needs an isolate. @@ -1081,9 +1079,13 @@ static int32_t FastInternalModuleStat( return -1; } + TRACK_V8_FAST_API_CALL("fs.internalModuleStat"); HandleScope scope(isolate); - auto path = std::filesystem::path(input.data, input.data + input.length); + CHECK(input_->IsString()); + Utf8Value input(isolate, input_.As()); + + auto path = std::filesystem::path(input.ToStringView()); switch (std::filesystem::status(path).type()) { case std::filesystem::file_type::directory: diff --git a/test/parallel/test-permission-fs-internal-module-stat.js b/test/parallel/test-permission-fs-internal-module-stat.js index ef99e4cca73a4f..5b1dd6679c7019 100644 --- a/test/parallel/test-permission-fs-internal-module-stat.js +++ b/test/parallel/test-permission-fs-internal-module-stat.js @@ -1,8 +1,9 @@ -// Flags: --expose-internals --permission --allow-fs-read=test/common* --allow-fs-read=tools* --allow-fs-read=test/parallel* --allow-child-process +// Flags: --expose-internals --permission --allow-fs-read=test/common* --allow-fs-read=tools* --allow-fs-read=test/parallel* --allow-child-process --allow-natives-syntax 'use strict'; const common = require('../common'); const { isMainThread } = require('worker_threads'); +const { strictEqual } = require('assert'); if (!isMainThread) { common.skip('This test only works on a main thread'); @@ -18,9 +19,20 @@ const fixtures = require('../common/fixtures'); const blockedFile = fixtures.path('permission', 'deny', 'protected-file.md'); const internalFsBinding = internalBinding('fs'); -// Run this inside a for loop to trigger the fast API -for (let i = 0; i < 10_000; i++) { - // internalModuleStat does not use permission model. - // doesNotThrow - internalFsBinding.internalModuleStat(internalFsBinding, blockedFile); +strictEqual(internalFsBinding.internalModuleStat(blockedFile), 0); + +// Only javascript methods can be optimized through %OptimizeFunctionOnNextCall +// This is why we surround the C++ method we want to optimize with a JS function. +function testFastPaths(file) { + return internalFsBinding.internalModuleStat(file); +} + +eval('%PrepareFunctionForOptimization(testFastPaths)'); +testFastPaths(blockedFile); +eval('%OptimizeFunctionOnNextCall(testFastPaths)'); +strictEqual(testFastPaths(blockedFile), 0); + +if (common.isDebug) { + const { getV8FastApiCallCount } = internalBinding('debug'); + strictEqual(getV8FastApiCallCount('fs.internalModuleStat'), 1); } From a381b4d990995f0c0d609e2b284899202ee70cf7 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 3 Jun 2025 12:15:39 +0200 Subject: [PATCH 2/3] src: remove fast API for InternalModuleStat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are several motivation for removing this: 1. The implementation does not align with InternalModuleStat, most noticably it does not namespace the path or convert it to UTF-16 before using it with std::filesystem::path on Windows which could crash on non-English locale. 2. It needs the Environment - if not for decoding the string, at least for env->exec_path() to resolve the path for namespacing - and therefore needs a handle to the Context which requires a handle scope which actually makes the fast API version slower than the normal binding. For simplicity this just removes the fast API to fix the bug and improve the performance. PR-URL: https://github.com/nodejs/node/pull/58489 Backport-PR-URL: https://github.com/nodejs/node/pull/59065 Reviewed-By: Chengzhong Wu Reviewed-By: Yagiz Nizipli Reviewed-By: Vinícius Lourenço Claro Cardoso Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Antoine du Hamel --- src/node_file.cc | 42 +------------------ ...test-permission-fs-internal-module-stat.js | 16 ------- 2 files changed, 1 insertion(+), 57 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index d2a372446cfd0c..7d174113a22cb2 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -60,7 +60,6 @@ using v8::Array; using v8::BigInt; using v8::Context; using v8::EscapableHandleScope; -using v8::FastApiCallbackOptions; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; @@ -1067,39 +1066,6 @@ static void InternalModuleStat(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(rc); } -static int32_t FastInternalModuleStat( - Local recv, - Local input_, - // NOLINTNEXTLINE(runtime/references) This is V8 api. - FastApiCallbackOptions& options) { - // This needs a HandleScope which needs an isolate. - Isolate* isolate = Isolate::TryGetCurrent(); - if (!isolate) { - options.fallback = true; - return -1; - } - - TRACK_V8_FAST_API_CALL("fs.internalModuleStat"); - HandleScope scope(isolate); - - CHECK(input_->IsString()); - Utf8Value input(isolate, input_.As()); - - auto path = std::filesystem::path(input.ToStringView()); - - switch (std::filesystem::status(path).type()) { - case std::filesystem::file_type::directory: - return 1; - case std::filesystem::file_type::regular: - return 0; - default: - return -1; - } -} - -v8::CFunction fast_internal_module_stat_( - v8::CFunction::Make(FastInternalModuleStat)); - constexpr bool is_uv_error_except_no_entry(int result) { return result < 0 && result != UV_ENOENT; } @@ -3819,11 +3785,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, SetMethod(isolate, target, "rmdir", RMDir); SetMethod(isolate, target, "mkdir", MKDir); SetMethod(isolate, target, "readdir", ReadDir); - SetFastMethod(isolate, - target, - "internalModuleStat", - InternalModuleStat, - &fast_internal_module_stat_); + SetMethod(isolate, target, "internalModuleStat", InternalModuleStat); SetMethod(isolate, target, "stat", Stat); SetMethod(isolate, target, "lstat", LStat); SetMethod(isolate, target, "fstat", FStat); @@ -3948,8 +3910,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(MKDir); registry->Register(ReadDir); registry->Register(InternalModuleStat); - registry->Register(FastInternalModuleStat); - registry->Register(fast_internal_module_stat_.GetTypeInfo()); registry->Register(Stat); registry->Register(LStat); registry->Register(FStat); diff --git a/test/parallel/test-permission-fs-internal-module-stat.js b/test/parallel/test-permission-fs-internal-module-stat.js index 5b1dd6679c7019..db7129e8554f23 100644 --- a/test/parallel/test-permission-fs-internal-module-stat.js +++ b/test/parallel/test-permission-fs-internal-module-stat.js @@ -20,19 +20,3 @@ const blockedFile = fixtures.path('permission', 'deny', 'protected-file.md'); const internalFsBinding = internalBinding('fs'); strictEqual(internalFsBinding.internalModuleStat(blockedFile), 0); - -// Only javascript methods can be optimized through %OptimizeFunctionOnNextCall -// This is why we surround the C++ method we want to optimize with a JS function. -function testFastPaths(file) { - return internalFsBinding.internalModuleStat(file); -} - -eval('%PrepareFunctionForOptimization(testFastPaths)'); -testFastPaths(blockedFile); -eval('%OptimizeFunctionOnNextCall(testFastPaths)'); -strictEqual(testFastPaths(blockedFile), 0); - -if (common.isDebug) { - const { getV8FastApiCallCount } = internalBinding('debug'); - strictEqual(getV8FastApiCallCount('fs.internalModuleStat'), 1); -} From 690525881e8d257b149dc84a1c0ef0b862457da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 4 Jul 2025 14:32:13 +0100 Subject: [PATCH 3/3] src: simplify adding fast APIs to ExternalReferenceRegistry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/58896 Backport-PR-URL: https://github.com/nodejs/node/pull/59065 Reviewed-By: Joyee Cheung Reviewed-By: Tobias Nießen Reviewed-By: Chengzhong Wu Reviewed-By: Antoine du Hamel --- src/crypto/crypto_timing.cc | 13 +++-- src/histogram.cc | 36 ++++-------- src/node_buffer.cc | 21 +++---- src/node_external_reference.h | 104 +++------------------------------- src/node_os.cc | 9 +-- src/node_perf.cc | 3 +- src/node_process_methods.cc | 6 +- src/node_types.cc | 9 +-- src/node_url.cc | 5 +- src/node_util.cc | 3 +- src/node_v8.cc | 3 +- src/timers.cc | 16 ++---- src/timers.h | 2 +- 13 files changed, 53 insertions(+), 177 deletions(-) diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc index 3d8ccc77b5952a..dbc46400501b61 100644 --- a/src/crypto/crypto_timing.cc +++ b/src/crypto/crypto_timing.cc @@ -10,6 +10,7 @@ namespace node { +using v8::CFunction; using v8::FastApiCallbackOptions; using v8::FastApiTypedArray; using v8::FunctionCallbackInfo; @@ -67,16 +68,18 @@ bool FastTimingSafeEqual(Local receiver, return CRYPTO_memcmp(data_a, data_b, a.length()) == 0; } -static v8::CFunction fast_equal(v8::CFunction::Make(FastTimingSafeEqual)); +static CFunction fast_timing_safe_equal(CFunction::Make(FastTimingSafeEqual)); void Initialize(Environment* env, Local target) { - SetFastMethodNoSideEffect( - env->context(), target, "timingSafeEqual", TimingSafeEqual, &fast_equal); + SetFastMethodNoSideEffect(env->context(), + target, + "timingSafeEqual", + TimingSafeEqual, + &fast_timing_safe_equal); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(TimingSafeEqual); - registry->Register(FastTimingSafeEqual); - registry->Register(fast_equal.GetTypeInfo()); + registry->Register(fast_timing_safe_equal); } } // namespace Timing diff --git a/src/histogram.cc b/src/histogram.cc index 5641990e0bac45..b655808e43d7c7 100644 --- a/src/histogram.cc +++ b/src/histogram.cc @@ -116,22 +116,14 @@ void HistogramImpl::RegisterExternalReferences( registry->Register(GetPercentiles); registry->Register(GetPercentilesBigInt); registry->Register(DoReset); - registry->Register(fast_reset_.GetTypeInfo()); - registry->Register(fast_get_count_.GetTypeInfo()); - registry->Register(fast_get_min_.GetTypeInfo()); - registry->Register(fast_get_max_.GetTypeInfo()); - registry->Register(fast_get_mean_.GetTypeInfo()); - registry->Register(fast_get_exceeds_.GetTypeInfo()); - registry->Register(fast_get_stddev_.GetTypeInfo()); - registry->Register(fast_get_percentile_.GetTypeInfo()); - registry->Register(FastReset); - registry->Register(FastGetCount); - registry->Register(FastGetMin); - registry->Register(FastGetMax); - registry->Register(FastGetMean); - registry->Register(FastGetExceeds); - registry->Register(FastGetStddev); - registry->Register(FastGetPercentile); + registry->Register(fast_reset_); + registry->Register(fast_get_count_); + registry->Register(fast_get_min_); + registry->Register(fast_get_max_); + registry->Register(fast_get_mean_); + registry->Register(fast_get_exceeds_); + registry->Register(fast_get_stddev_); + registry->Register(fast_get_percentile_); is_registered = true; } @@ -300,10 +292,8 @@ void HistogramBase::RegisterExternalReferences( registry->Register(Add); registry->Register(Record); registry->Register(RecordDelta); - registry->Register(fast_record_.GetTypeInfo()); - registry->Register(fast_record_delta_.GetTypeInfo()); - registry->Register(FastRecord); - registry->Register(FastRecordDelta); + registry->Register(fast_record_); + registry->Register(fast_record_delta_); HistogramImpl::RegisterExternalReferences(registry); } @@ -354,10 +344,8 @@ void IntervalHistogram::RegisterExternalReferences( ExternalReferenceRegistry* registry) { registry->Register(Start); registry->Register(Stop); - registry->Register(fast_start_.GetTypeInfo()); - registry->Register(fast_stop_.GetTypeInfo()); - registry->Register(FastStart); - registry->Register(FastStop); + registry->Register(fast_start_); + registry->Register(fast_stop_); HistogramImpl::RegisterExternalReferences(registry); } diff --git a/src/node_buffer.cc b/src/node_buffer.cc index b8021c079ca6b1..d0338b8a2d9cd3 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -1608,20 +1608,16 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(SetBufferPrototype); registry->Register(SlowByteLengthUtf8); - registry->Register(fast_byte_length_utf8.GetTypeInfo()); - registry->Register(FastByteLengthUtf8); + registry->Register(fast_byte_length_utf8); registry->Register(SlowCopy); - registry->Register(fast_copy.GetTypeInfo()); - registry->Register(FastCopy); + registry->Register(fast_copy); registry->Register(Compare); - registry->Register(FastCompare); - registry->Register(fast_compare.GetTypeInfo()); + registry->Register(fast_compare); registry->Register(CompareOffset); registry->Register(Fill); registry->Register(IndexOfBuffer); registry->Register(SlowIndexOfNumber); - registry->Register(FastIndexOfNumber); - registry->Register(fast_index_of_number.GetTypeInfo()); + registry->Register(fast_index_of_number); registry->Register(IndexOfString); registry->Register(Swap16); @@ -1642,12 +1638,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(SlowWriteString); registry->Register(SlowWriteString); registry->Register(SlowWriteString); - registry->Register(FastWriteString); - registry->Register(fast_write_string_ascii.GetTypeInfo()); - registry->Register(FastWriteString); - registry->Register(fast_write_string_latin1.GetTypeInfo()); - registry->Register(FastWriteString); - registry->Register(fast_write_string_utf8.GetTypeInfo()); + registry->Register(fast_write_string_ascii); + registry->Register(fast_write_string_latin1); + registry->Register(fast_write_string_utf8); registry->Register(StringWrite); registry->Register(StringWrite); registry->Register(StringWrite); diff --git a/src/node_external_reference.h b/src/node_external_reference.h index 9cafc70f8a3435..b97f306ddf4974 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -10,81 +10,6 @@ namespace node { -using CFunctionCallbackWithOneByteString = - uint32_t (*)(v8::Local, const v8::FastOneByteString&); - -using CFunctionCallbackReturnBool = bool (*)(v8::Local unused, - v8::Local receiver); -using CFunctionCallback = void (*)(v8::Local unused, - v8::Local receiver); -using CFunctionCallbackReturnDouble = - double (*)(v8::Local unused, v8::Local receiver); -using CFunctionCallbackReturnInt32 = - int32_t (*)(v8::Local receiver, - v8::Local input, - // NOLINTNEXTLINE(runtime/references) This is V8 api. - v8::FastApiCallbackOptions& options); -using CFunctionCallbackValueReturnDouble = - double (*)(v8::Local receiver); -using CFunctionCallbackValueReturnDoubleUnusedReceiver = - double (*)(v8::Local unused, v8::Local receiver); -using CFunctionCallbackWithInt64 = void (*)(v8::Local unused, - v8::Local receiver, - int64_t); -using CFunctionCallbackWithBool = void (*)(v8::Local unused, - v8::Local receiver, - bool); -using CFunctionCallbackWithString = - bool (*)(v8::Local, const v8::FastOneByteString& input); -using CFunctionCallbackWithStrings = - bool (*)(v8::Local, - const v8::FastOneByteString& input, - const v8::FastOneByteString& base); -using CFunctionCallbackWithTwoUint8Arrays = - int32_t (*)(v8::Local, - const v8::FastApiTypedArray&, - const v8::FastApiTypedArray&); -using CFunctionCallbackWithTwoUint8ArraysFallback = - bool (*)(v8::Local, - const v8::FastApiTypedArray&, - const v8::FastApiTypedArray&, - v8::FastApiCallbackOptions&); -using CFunctionCallbackWithUint8ArrayUint32Int64Bool = - int32_t (*)(v8::Local, - const v8::FastApiTypedArray&, - uint32_t, - int64_t, - bool); -using CFunctionWithUint32 = uint32_t (*)(v8::Local, - const uint32_t input); -using CFunctionWithReturnUint32 = uint32_t (*)(v8::Local); -using CFunctionWithReturnDouble = double (*)(v8::Local); -using CFunctionWithDoubleReturnDouble = double (*)(v8::Local, - v8::Local, - const double); -using CFunctionWithInt64Fallback = void (*)(v8::Local, - v8::Local, - const int64_t, - v8::FastApiCallbackOptions&); -using CFunctionWithBool = void (*)(v8::Local, - v8::Local, - bool); - -using CFunctionWriteString = - uint32_t (*)(v8::Local receiver, - const v8::FastApiTypedArray& dst, - const v8::FastOneByteString& src, - uint32_t offset, - uint32_t max_length); - -using CFunctionBufferCopy = - uint32_t (*)(v8::Local receiver, - const v8::FastApiTypedArray& source, - const v8::FastApiTypedArray& target, - uint32_t target_start, - uint32_t source_start, - uint32_t to_copy); - // This class manages the external references from the V8 heap // to the C++ addresses in Node.js. class ExternalReferenceRegistry { @@ -92,28 +17,6 @@ class ExternalReferenceRegistry { ExternalReferenceRegistry(); #define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \ - V(CFunctionCallback) \ - V(CFunctionCallbackWithOneByteString) \ - V(CFunctionCallbackReturnBool) \ - V(CFunctionCallbackReturnDouble) \ - V(CFunctionCallbackReturnInt32) \ - V(CFunctionWithReturnUint32) \ - V(CFunctionCallbackValueReturnDouble) \ - V(CFunctionCallbackValueReturnDoubleUnusedReceiver) \ - V(CFunctionCallbackWithInt64) \ - V(CFunctionCallbackWithBool) \ - V(CFunctionCallbackWithString) \ - V(CFunctionCallbackWithStrings) \ - V(CFunctionCallbackWithTwoUint8Arrays) \ - V(CFunctionCallbackWithTwoUint8ArraysFallback) \ - V(CFunctionCallbackWithUint8ArrayUint32Int64Bool) \ - V(CFunctionWithUint32) \ - V(CFunctionWithDoubleReturnDouble) \ - V(CFunctionWithInt64Fallback) \ - V(CFunctionWithBool) \ - V(CFunctionBufferCopy) \ - V(CFunctionWriteString) \ - V(const v8::CFunctionInfo*) \ V(v8::FunctionCallback) \ V(v8::AccessorNameGetterCallback) \ V(v8::AccessorNameSetterCallback) \ @@ -135,6 +38,13 @@ class ExternalReferenceRegistry { ALLOWED_EXTERNAL_REFERENCE_TYPES(V) #undef V + // Registers both the underlying function pointer + // and the corresponding CFunctionInfo. + void Register(const v8::CFunction& c_func) { + RegisterT(c_func.GetAddress()); + RegisterT(c_func.GetTypeInfo()); + } + // This can be called only once. const std::vector& external_references(); diff --git a/src/node_os.cc b/src/node_os.cc index 2f0dba5db6890d..39edad8f6b3f59 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -467,11 +467,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetLoadAvg); registry->Register(GetUptime); registry->Register(GetTotalMemory); - registry->Register(FastGetTotalMemory); - registry->Register(fast_get_total_memory.GetTypeInfo()); + registry->Register(fast_get_total_memory); registry->Register(GetFreeMemory); - registry->Register(FastGetFreeMemory); - registry->Register(fast_get_free_memory.GetTypeInfo()); + registry->Register(fast_get_free_memory); registry->Register(GetCPUInfo); registry->Register(GetInterfaceAddresses); registry->Register(GetHomeDirectory); @@ -479,8 +477,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(SetPriority); registry->Register(GetPriority); registry->Register(GetAvailableParallelism); - registry->Register(FastGetAvailableParallelism); - registry->Register(fast_get_available_parallelism.GetTypeInfo()); + registry->Register(fast_get_available_parallelism); registry->Register(GetOSInformation); } diff --git a/src/node_perf.cc b/src/node_perf.cc index d8b26f5c845be1..e984fd4c3bf003 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -410,8 +410,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(MarkBootstrapComplete); registry->Register(UvMetricsInfo); registry->Register(SlowPerformanceNow); - registry->Register(FastPerformanceNow); - registry->Register(fast_performance_now.GetTypeInfo()); + registry->Register(fast_performance_now); HistogramBase::RegisterExternalReferences(registry); IntervalHistogram::RegisterExternalReferences(registry); } diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index 16a8005fa65a3f..f46ad6b9c81b45 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -642,10 +642,8 @@ void BindingData::RegisterExternalReferences( ExternalReferenceRegistry* registry) { registry->Register(SlowNumber); registry->Register(SlowBigInt); - registry->Register(FastNumber); - registry->Register(FastBigInt); - registry->Register(fast_number_.GetTypeInfo()); - registry->Register(fast_bigint_.GetTypeInfo()); + registry->Register(fast_number_); + registry->Register(fast_bigint_); } BindingData* BindingData::FromV8Value(Local value) { diff --git a/src/node_types.cc b/src/node_types.cc index ed96fd6fd50a4f..ae4d76803a7db4 100644 --- a/src/node_types.cc +++ b/src/node_types.cc @@ -113,18 +113,15 @@ void InitializeTypes(Local target, void RegisterTypesExternalReferences(ExternalReferenceRegistry* registry) { #define V(type) \ registry->Register(Is##type); \ - registry->Register(Is##type##FastApi); \ - registry->Register(fast_is_##type##_.GetTypeInfo()); + registry->Register(fast_is_##type##_); VALUE_METHOD_MAP(V) #undef V registry->Register(IsAnyArrayBuffer); - registry->Register(IsAnyArrayBufferFastApi); - registry->Register(fast_is_any_array_buffer_.GetTypeInfo()); + registry->Register(fast_is_any_array_buffer_); registry->Register(IsBoxedPrimitive); - registry->Register(IsBoxedPrimitiveFastApi); - registry->Register(fast_is_boxed_primitive_.GetTypeInfo()); + registry->Register(fast_is_boxed_primitive_); } } // namespace node diff --git a/src/node_url.cc b/src/node_url.cc index a233eea39b66d0..09589e85e8bc13 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -516,11 +516,8 @@ void BindingData::RegisterExternalReferences( registry->Register(PathToFileURL); registry->Register(Update); registry->Register(CanParse); - registry->Register(FastCanParse); - registry->Register(FastCanParseWithBase); - for (const CFunction& method : fast_can_parse_methods_) { - registry->Register(method.GetTypeInfo()); + registry->Register(method); } } diff --git a/src/node_util.cc b/src/node_util.cc index 2ac4a130cb65fe..1972d30b9b3899 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -442,8 +442,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(Sleep); registry->Register(ArrayBufferViewHasBuffer); registry->Register(GuessHandleType); - registry->Register(FastGuessHandleType); - registry->Register(fast_guess_handle_type_.GetTypeInfo()); + registry->Register(fast_guess_handle_type_); registry->Register(ParseEnv); registry->Register(IsInsideNodeModules); registry->Register(DefineLazyProperties); diff --git a/src/node_v8.cc b/src/node_v8.cc index 5fdc8193f61ce7..430d5dd4f808af 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -716,8 +716,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GCProfiler::Stop); registry->Register(GetCppHeapStatistics); registry->Register(IsStringOneByteRepresentation); - registry->Register(FastIsStringOneByteRepresentation); - registry->Register(fast_is_string_one_byte_representation_.GetTypeInfo()); + registry->Register(fast_is_string_one_byte_representation_); } } // namespace v8_utils diff --git a/src/timers.cc b/src/timers.cc index 2c7b1813602d6f..bf90e68479da14 100644 --- a/src/timers.cc +++ b/src/timers.cc @@ -126,7 +126,7 @@ void BindingData::Deserialize(Local context, v8::CFunction BindingData::fast_get_libuv_now_( v8::CFunction::Make(FastGetLibuvNow)); -v8::CFunction BindingData::fast_schedule_timers_( +v8::CFunction BindingData::fast_schedule_timer_( v8::CFunction::Make(FastScheduleTimer)); v8::CFunction BindingData::fast_toggle_timer_ref_( v8::CFunction::Make(FastToggleTimerRef)); @@ -144,7 +144,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, target, "scheduleTimer", SlowScheduleTimer, - &fast_schedule_timers_); + &fast_schedule_timer_); SetFastMethod(isolate, target, "toggleTimerRef", @@ -185,20 +185,16 @@ void BindingData::RegisterTimerExternalReferences( registry->Register(SetupTimers); registry->Register(SlowGetLibuvNow); - registry->Register(FastGetLibuvNow); - registry->Register(fast_get_libuv_now_.GetTypeInfo()); + registry->Register(fast_get_libuv_now_); registry->Register(SlowScheduleTimer); - registry->Register(FastScheduleTimer); - registry->Register(fast_schedule_timers_.GetTypeInfo()); + registry->Register(fast_schedule_timer_); registry->Register(SlowToggleTimerRef); - registry->Register(FastToggleTimerRef); - registry->Register(fast_toggle_timer_ref_.GetTypeInfo()); + registry->Register(fast_toggle_timer_ref_); registry->Register(SlowToggleImmediateRef); - registry->Register(FastToggleImmediateRef); - registry->Register(fast_toggle_immediate_ref_.GetTypeInfo()); + registry->Register(fast_toggle_immediate_ref_); } } // namespace timers diff --git a/src/timers.h b/src/timers.h index 5148ea5bc7bd82..3c3a4d60d34ae8 100644 --- a/src/timers.h +++ b/src/timers.h @@ -61,7 +61,7 @@ class BindingData : public SnapshotableObject { private: static v8::CFunction fast_get_libuv_now_; - static v8::CFunction fast_schedule_timers_; + static v8::CFunction fast_schedule_timer_; static v8::CFunction fast_toggle_timer_ref_; static v8::CFunction fast_toggle_immediate_ref_; };