Skip to content

Commit 0a0df16

Browse files
committed
src: use type_int as binding data store key
Locally the hashing of the binding names sometimes has significant presence in the profile of bindings, which makes the cost of adding a new binding data non-trivial, but it's wasteful to spend time on hashing them at all, since we can just use the numeric type as the key, as the names are not actually used beyond debugging purposes.
1 parent a37c083 commit 0a0df16

12 files changed

+33
-30
lines changed

src/README.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -486,18 +486,28 @@ that state is through the use of `Environment::AddBindingData`, which gives
486486
binding functions access to an object for storing such state.
487487
That object is always a [`BaseObject`][].
488488

489-
Its class needs to have a static `type_name` field based on a
490-
constant string, in order to disambiguate it from other classes of this type,
491-
and which could e.g. match the binding's name (in the example above, that would
492-
be `cares_wrap`).
489+
If the binding should be supported in a snapshot, it needs to be in the
490+
`SERIALIZABLE_OBJECT_TYPES` list in `node_snapshotable.h` and implement the
491+
serialization and deserialization methods. See the comments of
492+
`SnapshotableObject` on how to implement them. Otherwise, the `type_int` field
493+
needs to be added to the `UNSERIALIZABLE_OBJECT_TYPES` list.
493494

494495
```cpp
496+
// In node_snapshotable.h, add the binding to either UNSERIALIZABLE_OBJECT_TYPES
497+
// or SERIALIZABLE_OBJECT_TYPES. The second parameter is a descriptive name
498+
// of the class, which is usually the class name with the (actual or conceptual)
499+
// namespace.
500+
501+
#define UNSERIALIZABLE_OBJECT_TYPES(V) \
502+
V(http_parser_binding_data, http_parser::BindingData)
503+
495504
// In the HTTP parser source code file:
496505
class BindingData : public BaseObject {
497506
public:
498507
BindingData(Environment* env, Local<Object> obj) : BaseObject(env, obj) {}
499508

500-
static constexpr FastStringKey type_name { "http_parser" };
509+
static constexpr EmbedderObjectType type_int =
510+
EmbedderObjectType::k_http_parser_binding_data;
501511

502512
std::vector<char> parser_buffer;
503513
bool parser_buffer_in_use = false;
@@ -527,12 +537,6 @@ void InitializeHttpParser(Local<Object> target,
527537
}
528538
```
529539
530-
If the binding is loaded during bootstrap, add it to the
531-
`SERIALIZABLE_OBJECT_TYPES` list in `src/node_snapshotable.h` and
532-
inherit from the `SnapshotableObject` class instead. See the comments
533-
of `SnapshotableObject` on how to implement its serialization and
534-
deserialization.
535-
536540
<a id="exception-handling"></a>
537541
538542
### Exception handling

src/env-inl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ inline T* Environment::GetBindingData(v8::Local<v8::Context> context) {
218218
context->GetAlignedPointerFromEmbedderData(
219219
ContextEmbedderIndex::kBindingListIndex));
220220
DCHECK_NOT_NULL(map);
221-
auto it = map->find(T::type_name);
221+
auto it = map->find(static_cast<uint8_t>(T::type_int));
222222
if (UNLIKELY(it == map->end())) return nullptr;
223223
T* result = static_cast<T*>(it->second.get());
224224
DCHECK_NOT_NULL(result);
@@ -237,7 +237,7 @@ inline T* Environment::AddBindingData(
237237
context->GetAlignedPointerFromEmbedderData(
238238
ContextEmbedderIndex::kBindingListIndex));
239239
DCHECK_NOT_NULL(map);
240-
auto result = map->emplace(T::type_name, item);
240+
auto result = map->emplace(static_cast<uint8_t>(T::type_int), item);
241241
CHECK(result.second);
242242
DCHECK_EQ(GetBindingData<T>(context), item.get());
243243
return item.get();

src/env.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -601,10 +601,8 @@ class Environment : public MemoryRetainer {
601601
template <typename T>
602602
static inline T* GetBindingData(v8::Local<v8::Context> context);
603603

604-
typedef std::unordered_map<
605-
FastStringKey,
606-
BaseObjectPtr<BaseObject>,
607-
FastStringKey::Hash> BindingDataStore;
604+
typedef std::unordered_map<uint8_t, BaseObjectPtr<BaseObject>>
605+
BindingDataStore;
608606

609607
// Create an Environment without initializing a main Context. Use
610608
// InitializeMainContext() to initialize a main context for it.

src/node_blob.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ class BlobBindingData : public SnapshotableObject {
147147

148148
SERIALIZABLE_OBJECT_METHODS()
149149

150-
static constexpr FastStringKey type_name{"node::BlobBindingData"};
151150
static constexpr EmbedderObjectType type_int =
152151
EmbedderObjectType::k_blob_binding_data;
153152

src/node_file.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ class BindingData : public SnapshotableObject {
6969

7070
using InternalFieldInfo = InternalFieldInfoBase;
7171
SERIALIZABLE_OBJECT_METHODS()
72-
static constexpr FastStringKey type_name{"node::fs::BindingData"};
7372
static constexpr EmbedderObjectType type_int =
7473
EmbedderObjectType::k_fs_binding_data;
7574

src/node_http2_state.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ class Http2State : public BaseObject {
127127
SET_SELF_SIZE(Http2State)
128128
SET_MEMORY_INFO_NAME(Http2State)
129129

130-
static constexpr FastStringKey type_name { "http2" };
130+
static constexpr EmbedderObjectType type_int =
131+
EmbedderObjectType::k_http2_binding_data;
131132

132133
private:
133134
struct http2_state_internal {

src/node_http_parser.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ class BindingData : public BaseObject {
9696
BindingData(Environment* env, Local<Object> obj)
9797
: BaseObject(env, obj) {}
9898

99-
static constexpr FastStringKey type_name { "http_parser" };
99+
static constexpr EmbedderObjectType type_int =
100+
EmbedderObjectType::k_http_parser_binding_data;
100101

101102
std::vector<char> parser_buffer;
102103
bool parser_buffer_in_use = false;

src/node_process.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ class BindingData : public SnapshotableObject {
5454
using InternalFieldInfo = InternalFieldInfoBase;
5555

5656
SERIALIZABLE_OBJECT_METHODS()
57-
static constexpr FastStringKey type_name{"node::process::BindingData"};
5857
static constexpr EmbedderObjectType type_int =
5958
EmbedderObjectType::k_process_binding_data;
6059

src/node_snapshotable.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,11 +1290,11 @@ SnapshotableObject::SnapshotableObject(Environment* env,
12901290
: BaseObject(env, wrap), type_(type) {
12911291
}
12921292

1293-
std::string_view SnapshotableObject::GetTypeName() const {
1293+
std::string SnapshotableObject::GetTypeName() const {
12941294
switch (type_) {
12951295
#define V(PropertyName, NativeTypeName) \
12961296
case EmbedderObjectType::k_##PropertyName: { \
1297-
return NativeTypeName::type_name.as_string_view(); \
1297+
return #NativeTypeName; \
12981298
}
12991299
SERIALIZABLE_OBJECT_TYPES(V)
13001300
#undef V
@@ -1335,7 +1335,7 @@ void DeserializeNodeInternalFields(Local<Object> holder,
13351335
per_process::Debug(DebugCategory::MKSNAPSHOT, \
13361336
"Object %p is %s\n", \
13371337
(*holder), \
1338-
NativeTypeName::type_name.as_string_view()); \
1338+
#NativeTypeName); \
13391339
env_ptr->EnqueueDeserializeRequest( \
13401340
NativeTypeName::Deserialize, \
13411341
holder, \
@@ -1422,7 +1422,7 @@ void SerializeSnapshotableObjects(Realm* realm,
14221422
}
14231423
SnapshotableObject* ptr = static_cast<SnapshotableObject*>(obj);
14241424

1425-
std::string type_name{ptr->GetTypeName()};
1425+
std::string type_name = ptr->GetTypeName();
14261426
per_process::Debug(DebugCategory::MKSNAPSHOT,
14271427
"Serialize snapshotable object %i (%p), "
14281428
"object=%p, type=%s\n",

src/node_snapshotable.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ struct PropInfo {
2222
SnapshotIndex index; // In the snapshot
2323
};
2424

25+
#define UNSERIALIZABLE_OBJECT_TYPES(V) \
26+
V(http2_binding_data, http2::BindingData) \
27+
V(http_parser_binding_data, http_parser::BindingData)
28+
2529
#define SERIALIZABLE_OBJECT_TYPES(V) \
2630
V(fs_binding_data, fs::BindingData) \
2731
V(v8_binding_data, v8_utils::BindingData) \
@@ -31,7 +35,7 @@ struct PropInfo {
3135

3236
enum class EmbedderObjectType : uint8_t {
3337
#define V(PropertyName, NativeType) k_##PropertyName,
34-
SERIALIZABLE_OBJECT_TYPES(V)
38+
SERIALIZABLE_OBJECT_TYPES(V) UNSERIALIZABLE_OBJECT_TYPES(V)
3539
#undef V
3640
};
3741

@@ -101,7 +105,7 @@ class SnapshotableObject : public BaseObject {
101105
SnapshotableObject(Environment* env,
102106
v8::Local<v8::Object> wrap,
103107
EmbedderObjectType type);
104-
std::string_view GetTypeName() const;
108+
std::string GetTypeName() const;
105109

106110
// If returns false, the object will not be serialized.
107111
virtual bool PrepareForSerialization(v8::Local<v8::Context> context,

0 commit comments

Comments
 (0)