diff --git a/src/env-inl.h b/src/env-inl.h index 1aa7faaadc4d17..ab0f1ed9b8c244 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -218,9 +218,11 @@ inline T* Environment::GetBindingData(v8::Local context) { context->GetAlignedPointerFromEmbedderData( ContextEmbedderIndex::kBindingListIndex)); DCHECK_NOT_NULL(map); - auto it = map->find(static_cast(T::type_int)); - if (UNLIKELY(it == map->end())) return nullptr; - T* result = static_cast(it->second.get()); + constexpr size_t binding_index = static_cast(T::type_int); + static_assert(binding_index < std::tuple_size_v); + auto ptr = (*map)[binding_index]; + if (UNLIKELY(!ptr)) return nullptr; + T* result = static_cast(ptr.get()); DCHECK_NOT_NULL(result); DCHECK_EQ(result->env(), GetCurrent(context)); return result; @@ -237,8 +239,10 @@ inline T* Environment::AddBindingData( context->GetAlignedPointerFromEmbedderData( ContextEmbedderIndex::kBindingListIndex)); DCHECK_NOT_NULL(map); - auto result = map->emplace(static_cast(T::type_int), item); - CHECK(result.second); + constexpr size_t binding_index = static_cast(T::type_int); + static_assert(binding_index < std::tuple_size_v); + CHECK(!(*map)[binding_index]); // Should not insert the binding twice. + (*map)[binding_index] = item; DCHECK_EQ(GetBindingData(context), item.get()); return item.get(); } diff --git a/src/env.cc b/src/env.cc index 692a344703a196..f85b0177aace33 100644 --- a/src/env.cc +++ b/src/env.cc @@ -1018,7 +1018,9 @@ MaybeLocal Environment::RunSnapshotDeserializeMain() const { void Environment::RunCleanup() { started_cleanup_ = true; TRACE_EVENT0(TRACING_CATEGORY_NODE1(environment), "RunCleanup"); - bindings_.clear(); + for (size_t i = 0; i < bindings_.size(); ++i) { + bindings_[i].reset(); + } // Only BaseObject's cleanups are registered as per-realm cleanup hooks now. // Defer the BaseObject cleanup after handles are cleaned up. CleanupHandles(); diff --git a/src/env.h b/src/env.h index c4b8df6be280c2..c4d4419ed82113 100644 --- a/src/env.h +++ b/src/env.h @@ -601,7 +601,9 @@ class Environment : public MemoryRetainer { template static inline T* GetBindingData(v8::Local context); - typedef std::unordered_map> + typedef std::array, + static_cast( + EmbedderObjectType::kEmbedderObjectTypeCount)> BindingDataStore; // Create an Environment without initializing a main Context. Use diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h index 2c1c8ef2809f3d..86bc9d96bdfad8 100644 --- a/src/node_snapshotable.h +++ b/src/node_snapshotable.h @@ -37,6 +37,7 @@ enum class EmbedderObjectType : uint8_t { #define V(PropertyName, NativeType) k_##PropertyName, SERIALIZABLE_OBJECT_TYPES(V) UNSERIALIZABLE_OBJECT_TYPES(V) #undef V + kEmbedderObjectTypeCount }; typedef size_t SnapshotIndex;