mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
Several Environments can share a thread, so state in src/ that belongs to one of them cannot be kept in a thread_local. Add a cpplint rule that rejects thread_local in src/ unless the declaration is marked with NOLINTNEXTLINE(runtime/thread_local), and mark the existing uses, which are per-thread by design. Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com> PR-URL: https://github.com/nodejs/node/pull/66411 Refs: https://github.com/nodejs/node/pull/66239 Reviewed-By: Anna Henningsen <anna@addaleax.net>
127 lines
3.7 KiB
C++
127 lines
3.7 KiB
C++
#include "node_debug.h"
|
|
|
|
#ifdef DEBUG
|
|
#include "node_binding.h"
|
|
|
|
#include "env-inl.h"
|
|
#include "util.h"
|
|
#include "v8-fast-api-calls.h"
|
|
#include "v8.h"
|
|
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <unordered_map>
|
|
#endif // DEBUG
|
|
|
|
namespace node::debug {
|
|
|
|
#ifdef DEBUG
|
|
using v8::Context;
|
|
using v8::FastApiCallbackOptions;
|
|
using v8::FunctionCallbackInfo;
|
|
using v8::Local;
|
|
using v8::Number;
|
|
using v8::Object;
|
|
using v8::Value;
|
|
|
|
// NOLINTNEXTLINE(runtime/thread_local)
|
|
thread_local std::unordered_map<FastStringKey, int, FastStringKey::Hash>
|
|
generic_usage_counters;
|
|
// NOLINTNEXTLINE(runtime/thread_local)
|
|
thread_local std::unordered_map<FastStringKey, int, FastStringKey::Hash>
|
|
v8_fast_api_call_counts;
|
|
|
|
void CountGenericUsage(FastStringKey counter_name) {
|
|
generic_usage_counters[counter_name]++;
|
|
}
|
|
|
|
int GetGenericUsageCount(FastStringKey counter_name) {
|
|
return generic_usage_counters[counter_name];
|
|
}
|
|
|
|
void TrackV8FastApiCall(FastStringKey key) {
|
|
v8_fast_api_call_counts[key]++;
|
|
}
|
|
|
|
int GetV8FastApiCallCount(FastStringKey key) {
|
|
return v8_fast_api_call_counts[key];
|
|
}
|
|
|
|
void GetGenericUsageCount(const FunctionCallbackInfo<Value>& args) {
|
|
Environment* env = Environment::GetCurrent(args);
|
|
if (!args[0]->IsString()) {
|
|
env->ThrowError("getGenericUsageCount must be called with a string");
|
|
return;
|
|
}
|
|
Utf8Value utf8_key(env->isolate(), args[0]);
|
|
args.GetReturnValue().Set(GetGenericUsageCount(
|
|
FastStringKey::AllowDynamic(utf8_key.ToStringView())));
|
|
}
|
|
|
|
void GetV8FastApiCallCount(const FunctionCallbackInfo<Value>& args) {
|
|
Environment* env = Environment::GetCurrent(args);
|
|
if (!args[0]->IsString()) {
|
|
env->ThrowError("getV8FastApiCallCount must be called with a string");
|
|
return;
|
|
}
|
|
Utf8Value utf8_key(env->isolate(), args[0]);
|
|
args.GetReturnValue().Set(GetV8FastApiCallCount(
|
|
FastStringKey::AllowDynamic(utf8_key.ToStringView())));
|
|
}
|
|
|
|
void SlowIsEven(const FunctionCallbackInfo<Value>& args) {
|
|
Environment* env = Environment::GetCurrent(args);
|
|
if (!args[0]->IsNumber()) {
|
|
env->ThrowError("isEven must be called with a number");
|
|
return;
|
|
}
|
|
int64_t value = args[0].As<Number>()->Value();
|
|
args.GetReturnValue().Set(value % 2 == 0);
|
|
}
|
|
|
|
bool FastIsEven(Local<Value> receiver,
|
|
const int64_t value,
|
|
// NOLINTNEXTLINE(runtime/references)
|
|
FastApiCallbackOptions& options) {
|
|
TRACK_V8_FAST_API_CALL("debug.isEven");
|
|
return value % 2 == 0;
|
|
}
|
|
|
|
void SlowIsOdd(const FunctionCallbackInfo<Value>& args) {
|
|
Environment* env = Environment::GetCurrent(args);
|
|
if (!args[0]->IsNumber()) {
|
|
env->ThrowError("isOdd must be called with a number");
|
|
return;
|
|
}
|
|
int64_t value = args[0].As<Number>()->Value();
|
|
args.GetReturnValue().Set(value % 2 != 0);
|
|
}
|
|
|
|
bool FastIsOdd(Local<Value> receiver,
|
|
const int64_t value,
|
|
// NOLINTNEXTLINE(runtime/references)
|
|
FastApiCallbackOptions& options) {
|
|
TRACK_V8_FAST_API_CALL("debug.isOdd");
|
|
return value % 2 != 0;
|
|
}
|
|
|
|
static v8::CFunction fast_is_even(v8::CFunction::Make(FastIsEven));
|
|
static v8::CFunction fast_is_odd(v8::CFunction::Make(FastIsOdd));
|
|
|
|
void Initialize(Local<Object> target,
|
|
Local<Value> unused,
|
|
Local<Context> context,
|
|
void* priv) {
|
|
SetMethod(context, target, "getV8FastApiCallCount", GetV8FastApiCallCount);
|
|
SetMethod(context, target, "getGenericUsageCount", GetGenericUsageCount);
|
|
SetFastMethod(context, target, "isEven", SlowIsEven, &fast_is_even);
|
|
SetFastMethod(context, target, "isOdd", SlowIsOdd, &fast_is_odd);
|
|
}
|
|
#endif // DEBUG
|
|
|
|
} // namespace node::debug
|
|
|
|
#ifdef DEBUG
|
|
NODE_BINDING_CONTEXT_AWARE_INTERNAL(debug, node::debug::Initialize)
|
|
#endif // DEBUG
|