src: add a couple fast apis in node_os

PR-URL: https://github.com/nodejs/node/pull/58210
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
James M Snell 2025-05-06 21:37:18 -07:00
parent acb3d922cb
commit 292263e378
3 changed files with 71 additions and 4 deletions

View File

@ -66,6 +66,8 @@ using CFunctionCallbackWithUint8ArrayUint32Int64Bool =
v8::FastApiCallbackOptions&); v8::FastApiCallbackOptions&);
using CFunctionWithUint32 = uint32_t (*)(v8::Local<v8::Value>, using CFunctionWithUint32 = uint32_t (*)(v8::Local<v8::Value>,
const uint32_t input); const uint32_t input);
using CFunctionWithReturnUint32 = uint32_t (*)(v8::Local<v8::Value>);
using CFunctionWithReturnDouble = double (*)(v8::Local<v8::Value>);
using CFunctionWithDoubleReturnDouble = double (*)(v8::Local<v8::Value>, using CFunctionWithDoubleReturnDouble = double (*)(v8::Local<v8::Value>,
v8::Local<v8::Value>, v8::Local<v8::Value>,
const double); const double);
@ -107,6 +109,7 @@ class ExternalReferenceRegistry {
V(CFunctionCallbackReturnBool) \ V(CFunctionCallbackReturnBool) \
V(CFunctionCallbackReturnDouble) \ V(CFunctionCallbackReturnDouble) \
V(CFunctionCallbackReturnInt32) \ V(CFunctionCallbackReturnInt32) \
V(CFunctionWithReturnUint32) \
V(CFunctionCallbackValueReturnDouble) \ V(CFunctionCallbackValueReturnDouble) \
V(CFunctionCallbackValueReturnDoubleUnusedReceiver) \ V(CFunctionCallbackValueReturnDoubleUnusedReceiver) \
V(CFunctionCallbackWithInt64) \ V(CFunctionCallbackWithInt64) \

View File

@ -20,6 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "env-inl.h" #include "env-inl.h"
#include "node_debug.h"
#include "node_external_reference.h" #include "node_external_reference.h"
#include "string_bytes.h" #include "string_bytes.h"
@ -148,12 +149,26 @@ static void GetFreeMemory(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(amount); args.GetReturnValue().Set(amount);
} }
static double FastGetFreeMemory(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("os.freemem");
return static_cast<double>(uv_get_free_memory());
}
static v8::CFunction fast_get_free_memory(
v8::CFunction::Make(FastGetFreeMemory));
static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) { static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
double amount = static_cast<double>(uv_get_total_memory()); double amount = static_cast<double>(uv_get_total_memory());
args.GetReturnValue().Set(amount); args.GetReturnValue().Set(amount);
} }
double FastGetTotalMemory(Local<Value> receiver) {
TRACK_V8_FAST_API_CALL("os.totalmem");
return static_cast<double>(uv_get_total_memory());
}
static v8::CFunction fast_get_total_memory(
v8::CFunction::Make(FastGetTotalMemory));
static void GetUptime(const FunctionCallbackInfo<Value>& args) { static void GetUptime(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args); Environment* env = Environment::GetCurrent(args);
@ -398,6 +413,14 @@ static void GetAvailableParallelism(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(parallelism); args.GetReturnValue().Set(parallelism);
} }
uint32_t FastGetAvailableParallelism(v8::Local<v8::Value> receiver) {
TRACK_V8_FAST_API_CALL("os.availableParallelism");
return uv_available_parallelism();
}
static v8::CFunction fast_get_available_parallelism(
v8::CFunction::Make(FastGetAvailableParallelism));
void Initialize(Local<Object> target, void Initialize(Local<Object> target,
Local<Value> unused, Local<Value> unused,
Local<Context> context, Local<Context> context,
@ -406,16 +429,21 @@ void Initialize(Local<Object> target,
SetMethod(context, target, "getHostname", GetHostname); SetMethod(context, target, "getHostname", GetHostname);
SetMethod(context, target, "getLoadAvg", GetLoadAvg); SetMethod(context, target, "getLoadAvg", GetLoadAvg);
SetMethod(context, target, "getUptime", GetUptime); SetMethod(context, target, "getUptime", GetUptime);
SetMethod(context, target, "getTotalMem", GetTotalMemory); SetFastMethodNoSideEffect(
SetMethod(context, target, "getFreeMem", GetFreeMemory); context, target, "getTotalMem", GetTotalMemory, &fast_get_total_memory);
SetFastMethodNoSideEffect(
context, target, "getFreeMem", GetFreeMemory, &fast_get_free_memory);
SetMethod(context, target, "getCPUs", GetCPUInfo); SetMethod(context, target, "getCPUs", GetCPUInfo);
SetMethod(context, target, "getInterfaceAddresses", GetInterfaceAddresses); SetMethod(context, target, "getInterfaceAddresses", GetInterfaceAddresses);
SetMethod(context, target, "getHomeDirectory", GetHomeDirectory); SetMethod(context, target, "getHomeDirectory", GetHomeDirectory);
SetMethod(context, target, "getUserInfo", GetUserInfo); SetMethod(context, target, "getUserInfo", GetUserInfo);
SetMethod(context, target, "setPriority", SetPriority); SetMethod(context, target, "setPriority", SetPriority);
SetMethod(context, target, "getPriority", GetPriority); SetMethod(context, target, "getPriority", GetPriority);
SetMethod( SetFastMethodNoSideEffect(context,
context, target, "getAvailableParallelism", GetAvailableParallelism); target,
"getAvailableParallelism",
GetAvailableParallelism,
&fast_get_available_parallelism);
SetMethod(context, target, "getOSInformation", GetOSInformation); SetMethod(context, target, "getOSInformation", GetOSInformation);
target target
->Set(context, ->Set(context,
@ -429,7 +457,11 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetLoadAvg); registry->Register(GetLoadAvg);
registry->Register(GetUptime); registry->Register(GetUptime);
registry->Register(GetTotalMemory); registry->Register(GetTotalMemory);
registry->Register(FastGetTotalMemory);
registry->Register(fast_get_total_memory.GetTypeInfo());
registry->Register(GetFreeMemory); registry->Register(GetFreeMemory);
registry->Register(FastGetFreeMemory);
registry->Register(fast_get_free_memory.GetTypeInfo());
registry->Register(GetCPUInfo); registry->Register(GetCPUInfo);
registry->Register(GetInterfaceAddresses); registry->Register(GetInterfaceAddresses);
registry->Register(GetHomeDirectory); registry->Register(GetHomeDirectory);
@ -437,6 +469,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(SetPriority); registry->Register(SetPriority);
registry->Register(GetPriority); registry->Register(GetPriority);
registry->Register(GetAvailableParallelism); registry->Register(GetAvailableParallelism);
registry->Register(FastGetAvailableParallelism);
registry->Register(fast_get_available_parallelism.GetTypeInfo());
registry->Register(GetOSInformation); registry->Register(GetOSInformation);
} }

View File

@ -0,0 +1,30 @@
// Flags: --expose-internals --no-warnings --allow-natives-syntax
'use strict';
const common = require('../common');
const assert = require('assert');
const {
totalmem,
freemem,
availableParallelism,
} = require('os');
const { internalBinding } = require('internal/test/binding');
function testFastOs() {
assert.strictEqual(typeof totalmem(), 'number');
assert.strictEqual(typeof freemem(), 'number');
assert.strictEqual(typeof availableParallelism(), 'number');
}
eval('%PrepareFunctionForOptimization(testFastOs)');
testFastOs();
eval('%OptimizeFunctionOnNextCall(testFastOs)');
testFastOs();
if (common.isDebug) {
const { getV8FastApiCallCount } = internalBinding('debug');
assert.strictEqual(getV8FastApiCallCount('os.totalmem'), 1);
assert.strictEqual(getV8FastApiCallCount('os.freemem'), 1);
assert.strictEqual(getV8FastApiCallCount('os.availableParallelism'), 1);
}