Skip to content

Commit 14d751a

Browse files
BridgeARRafaelGSS
authored andcommitted
src: implement util.types fast API calls
All util.types.is##Type() calls are ported to the fast API. This improves the performance for multiple APIs such as: - util.inspect (and util.format and console methods respectively) - util.isDeepStrictEqual - assert.(not)deepEqual (including strict and partial mode) It will also improve any other API where these APIs are used. PR-URL: #57819 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 073d40b commit 14d751a

File tree

2 files changed

+525
-38
lines changed

2 files changed

+525
-38
lines changed

src/node_types.cc

Lines changed: 80 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "env-inl.h"
22
#include "node.h"
3+
#include "node_debug.h"
34
#include "node_external_reference.h"
45

6+
using v8::CFunction;
57
using v8::Context;
68
using v8::FunctionCallbackInfo;
79
using v8::Local;
@@ -11,47 +13,59 @@ using v8::Value;
1113
namespace node {
1214
namespace {
1315

14-
#define VALUE_METHOD_MAP(V) \
15-
V(External) \
16-
V(Date) \
17-
V(ArgumentsObject) \
18-
V(BigIntObject) \
19-
V(BooleanObject) \
20-
V(NumberObject) \
21-
V(StringObject) \
22-
V(SymbolObject) \
23-
V(NativeError) \
24-
V(RegExp) \
25-
V(AsyncFunction) \
26-
V(GeneratorFunction) \
27-
V(GeneratorObject) \
28-
V(Promise) \
29-
V(Map) \
30-
V(Set) \
31-
V(MapIterator) \
32-
V(SetIterator) \
33-
V(WeakMap) \
34-
V(WeakSet) \
35-
V(ArrayBuffer) \
36-
V(DataView) \
37-
V(SharedArrayBuffer) \
38-
V(Proxy) \
39-
V(ModuleNamespaceObject) \
40-
41-
42-
#define V(type) \
43-
static void Is##type(const FunctionCallbackInfo<Value>& args) { \
44-
args.GetReturnValue().Set(args[0]->Is##type()); \
45-
}
16+
#define VALUE_METHOD_MAP(V) \
17+
V(External) \
18+
V(Date) \
19+
V(ArgumentsObject) \
20+
V(BigIntObject) \
21+
V(BooleanObject) \
22+
V(NumberObject) \
23+
V(StringObject) \
24+
V(SymbolObject) \
25+
V(NativeError) \
26+
V(RegExp) \
27+
V(AsyncFunction) \
28+
V(GeneratorFunction) \
29+
V(GeneratorObject) \
30+
V(Promise) \
31+
V(Map) \
32+
V(Set) \
33+
V(MapIterator) \
34+
V(SetIterator) \
35+
V(WeakMap) \
36+
V(WeakSet) \
37+
V(ArrayBuffer) \
38+
V(DataView) \
39+
V(SharedArrayBuffer) \
40+
V(Proxy) \
41+
V(ModuleNamespaceObject)
4642

47-
VALUE_METHOD_MAP(V)
43+
#define V(type) \
44+
static void Is##type(const FunctionCallbackInfo<Value>& args) { \
45+
args.GetReturnValue().Set(args[0]->Is##type()); \
46+
} \
47+
static bool Is##type##FastApi(Local<Value> unused, Local<Value> value) { \
48+
TRACK_V8_FAST_API_CALL("types.is" #type); \
49+
return value->Is##type(); \
50+
} \
51+
static CFunction fast_is_##type##_ = CFunction::Make(Is##type##FastApi);
52+
53+
VALUE_METHOD_MAP(V)
4854
#undef V
4955

5056
static void IsAnyArrayBuffer(const FunctionCallbackInfo<Value>& args) {
5157
args.GetReturnValue().Set(
5258
args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
5359
}
5460

61+
static bool IsAnyArrayBufferFastApi(Local<Value> unused, Local<Value> value) {
62+
TRACK_V8_FAST_API_CALL("types.isAnyArrayBuffer");
63+
return value->IsArrayBuffer() || value->IsSharedArrayBuffer();
64+
}
65+
66+
static CFunction fast_is_any_array_buffer_ =
67+
CFunction::Make(IsAnyArrayBufferFastApi);
68+
5569
static void IsBoxedPrimitive(const FunctionCallbackInfo<Value>& args) {
5670
args.GetReturnValue().Set(
5771
args[0]->IsNumberObject() ||
@@ -61,27 +75,56 @@ static void IsBoxedPrimitive(const FunctionCallbackInfo<Value>& args) {
6175
args[0]->IsSymbolObject());
6276
}
6377

78+
static bool IsBoxedPrimitiveFastApi(Local<Value> unused, Local<Value> value) {
79+
TRACK_V8_FAST_API_CALL("types.isBoxedPrimitive");
80+
return value->IsNumberObject() || value->IsStringObject() ||
81+
value->IsBooleanObject() || value->IsBigIntObject() ||
82+
value->IsSymbolObject();
83+
}
84+
85+
static CFunction fast_is_boxed_primitive_ =
86+
CFunction::Make(IsBoxedPrimitiveFastApi);
87+
6488
void InitializeTypes(Local<Object> target,
6589
Local<Value> unused,
6690
Local<Context> context,
6791
void* priv) {
68-
#define V(type) SetMethodNoSideEffect(context, target, "is" #type, Is##type);
92+
#define V(type) \
93+
SetFastMethodNoSideEffect( \
94+
context, target, "is" #type, Is##type, &fast_is_##type##_);
95+
6996
VALUE_METHOD_MAP(V)
7097
#undef V
7198

72-
SetMethodNoSideEffect(context, target, "isAnyArrayBuffer", IsAnyArrayBuffer);
73-
SetMethodNoSideEffect(context, target, "isBoxedPrimitive", IsBoxedPrimitive);
99+
SetFastMethodNoSideEffect(context,
100+
target,
101+
"isAnyArrayBuffer",
102+
IsAnyArrayBuffer,
103+
&fast_is_any_array_buffer_);
104+
SetFastMethodNoSideEffect(context,
105+
target,
106+
"isBoxedPrimitive",
107+
IsBoxedPrimitive,
108+
&fast_is_boxed_primitive_);
74109
}
75110

76111
} // anonymous namespace
77112

78113
void RegisterTypesExternalReferences(ExternalReferenceRegistry* registry) {
79-
#define V(type) registry->Register(Is##type);
114+
#define V(type) \
115+
registry->Register(Is##type); \
116+
registry->Register(Is##type##FastApi); \
117+
registry->Register(fast_is_##type##_.GetTypeInfo());
118+
80119
VALUE_METHOD_MAP(V)
81120
#undef V
82121

83122
registry->Register(IsAnyArrayBuffer);
123+
registry->Register(IsAnyArrayBufferFastApi);
124+
registry->Register(fast_is_any_array_buffer_.GetTypeInfo());
84125
registry->Register(IsBoxedPrimitive);
126+
registry->Register(IsBoxedPrimitiveFastApi);
127+
registry->Register(fast_is_boxed_primitive_.GetTypeInfo());
85128
}
86129
} // namespace node
87130

0 commit comments

Comments
 (0)