Skip to content

Commit

Permalink
src: avoid copy by using std::views::keys
Browse files Browse the repository at this point in the history
PR-URL: #56080
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Lemire <daniel@lemire.me>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
anonrig authored and targos committed Feb 7, 2025
1 parent 086cdc2 commit 9e9ac3c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 27 deletions.
41 changes: 15 additions & 26 deletions src/node_builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,6 @@ Local<String> BuiltinLoader::GetConfigString(Isolate* isolate) {
return config_.ToStringChecked(isolate);
}

std::vector<std::string_view> BuiltinLoader::GetBuiltinIds() const {
std::vector<std::string_view> ids;
auto source = source_.read();
ids.reserve(source->size());
for (auto const& x : *source) {
ids.emplace_back(x.first);
}
return ids;
}

BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const {
BuiltinCategories builtin_categories;

Expand Down Expand Up @@ -515,26 +505,25 @@ bool BuiltinLoader::CompileAllBuiltinsAndCopyCodeCache(
Local<Context> context,
const std::vector<std::string>& eager_builtins,
std::vector<CodeCacheInfo>* out) {
std::vector<std::string_view> ids = GetBuiltinIds();
auto ids = GetBuiltinIds();
bool all_succeeded = true;
std::string v8_tools_prefix = "internal/deps/v8/tools/";
std::string primordial_prefix = "internal/per_context/";
std::string bootstrap_prefix = "internal/bootstrap/";
std::string main_prefix = "internal/main/";
to_eager_compile_ = std::unordered_set<std::string>(eager_builtins.begin(),
eager_builtins.end());
constexpr std::string_view v8_tools_prefix = "internal/deps/v8/tools/";
constexpr std::string_view primordial_prefix = "internal/per_context/";
constexpr std::string_view bootstrap_prefix = "internal/bootstrap/";
constexpr std::string_view main_prefix = "internal/main/";
to_eager_compile_ =
std::unordered_set(eager_builtins.begin(), eager_builtins.end());

for (const auto& id : ids) {
if (id.compare(0, v8_tools_prefix.size(), v8_tools_prefix) == 0) {
if (id.starts_with(v8_tools_prefix)) {
// No need to generate code cache for v8 scripts.
continue;
}

// Eagerly compile primordials/boostrap/main scripts during code cache
// generation.
if (id.compare(0, primordial_prefix.size(), primordial_prefix) == 0 ||
id.compare(0, bootstrap_prefix.size(), bootstrap_prefix) == 0 ||
id.compare(0, main_prefix.size(), main_prefix) == 0) {
if (id.starts_with(primordial_prefix) || id.starts_with(bootstrap_prefix) ||
id.starts_with(main_prefix)) {
to_eager_compile_.emplace(id);
}

Expand All @@ -554,8 +543,8 @@ bool BuiltinLoader::CompileAllBuiltinsAndCopyCodeCache(
}

RwLock::ScopedReadLock lock(code_cache_->mutex);
for (auto const& item : code_cache_->map) {
out->push_back({item.first, item.second});
for (const auto& [id, data] : code_cache_->map) {
out->push_back({id, data});
}
return all_succeeded;
}
Expand All @@ -564,8 +553,8 @@ void BuiltinLoader::RefreshCodeCache(const std::vector<CodeCacheInfo>& in) {
RwLock::ScopedLock lock(code_cache_->mutex);
code_cache_->map.reserve(in.size());
DCHECK(code_cache_->map.empty());
for (auto const& item : in) {
auto result = code_cache_->map.emplace(item.id, item.data);
for (auto const& [id, data] : in) {
auto result = code_cache_->map.emplace(id, data);
USE(result.second);
DCHECK(result.second);
}
Expand Down Expand Up @@ -665,7 +654,7 @@ void BuiltinLoader::BuiltinIdsGetter(Local<Name> property,
Environment* env = Environment::GetCurrent(info);
Isolate* isolate = env->isolate();

std::vector<std::string_view> ids = env->builtin_loader()->GetBuiltinIds();
auto ids = env->builtin_loader()->GetBuiltinIds();
info.GetReturnValue().Set(
ToV8Value(isolate->GetCurrentContext(), ids).ToLocalChecked());
}
Expand Down
5 changes: 4 additions & 1 deletion src/node_builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <map>
#include <memory>
#include <optional>
#include <ranges>
#include <string>
#include <unordered_set>
#include <vector>
Expand Down Expand Up @@ -126,7 +127,9 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {

void CopySourceAndCodeCacheReferenceFrom(const BuiltinLoader* other);

std::vector<std::string_view> GetBuiltinIds() const;
[[nodiscard]] auto GetBuiltinIds() const {
return std::views::keys(*source_.read());
}

void SetEagerCompile() { should_eager_compile_ = true; }

Expand Down
20 changes: 20 additions & 0 deletions src/util-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <cmath>
#include <cstring>
#include <locale>
#include <ranges>
#include <regex> // NOLINT(build/c++11)
#include "node_revert.h"
#include "util.h"
Expand Down Expand Up @@ -379,6 +380,25 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
return set_js;
}

template <typename T, std::size_t U>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::ranges::elements_view<T, U>& vec,
v8::Isolate* isolate) {
if (isolate == nullptr) isolate = context->GetIsolate();
v8::EscapableHandleScope handle_scope(isolate);

MaybeStackBuffer<v8::Local<v8::Value>, 128> arr(vec.size());
arr.SetLength(vec.size());
auto it = vec.begin();
for (size_t i = 0; i < vec.size(); ++i) {
if (!ToV8Value(context, *it, isolate).ToLocal(&arr[i]))
return v8::MaybeLocal<v8::Value>();
std::advance(it, 1);
}

return handle_scope.Escape(v8::Array::New(isolate, arr.out(), arr.length()));
}

template <typename T, typename U>
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::unordered_map<T, U>& map,
Expand Down
7 changes: 7 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <limits>
#include <memory>
#include <optional>
#include <ranges>
#include <set>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -733,6 +734,12 @@ inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
const std::unordered_map<T, U>& map,
v8::Isolate* isolate = nullptr);

template <typename T, std::size_t U>
inline v8::MaybeLocal<v8::Value> ToV8Value(
v8::Local<v8::Context> context,
const std::ranges::elements_view<T, U>& vec,
v8::Isolate* isolate = nullptr);

// These macros expects a `Isolate* isolate` and a `Local<Context> context`
// to be in the scope.
#define READONLY_PROPERTY(obj, name, value) \
Expand Down

0 comments on commit 9e9ac3c

Please sign in to comment.