Skip to content

Commit a48613b

Browse files
committed
src: reuse parser between runs
1 parent d85f188 commit a48613b

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed

src/env-inl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "node.h"
3131
#include "node_context_data.h"
3232
#include "node_internals.h"
33+
#include "node_json_parser.h"
3334
#include "node_perf_common.h"
3435
#include "node_realm-inl.h"
3536
#include "util-inl.h"
@@ -418,6 +419,13 @@ inline builtins::BuiltinLoader* Environment::builtin_loader() {
418419
return &builtin_loader_;
419420
}
420421

422+
inline json_parser::JsonParser* Environment::json_parser() {
423+
if (!json_parser_) {
424+
json_parser_ = std::make_unique<json_parser::JsonParser>();
425+
}
426+
return json_parser_.get();
427+
}
428+
421429
inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
422430
return embedder_preload_;
423431
}

src/env.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ namespace loader {
109109
class ModuleWrap;
110110
} // namespace loader
111111

112+
namespace json_parser {
113+
class JsonParser;
114+
} // namespace json_parser
115+
112116
class Environment;
113117
class Realm;
114118

@@ -765,6 +769,7 @@ class Environment final : public MemoryRetainer {
765769
inline std::vector<double>* destroy_async_id_list();
766770

767771
builtins::BuiltinLoader* builtin_loader();
772+
json_parser::JsonParser* json_parser();
768773

769774
std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map;
770775

@@ -1246,6 +1251,7 @@ class Environment final : public MemoryRetainer {
12461251
std::unique_ptr<PrincipalRealm> principal_realm_ = nullptr;
12471252

12481253
builtins::BuiltinLoader builtin_loader_;
1254+
std::unique_ptr<json_parser::JsonParser> json_parser_;
12491255
EmbedderPreloadCallback embedder_preload_;
12501256

12511257
// Used by allocate_managed_buffer() and release_managed_buffer() to keep

src/node_json_parser.cc

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@
1616
namespace node {
1717
namespace json_parser {
1818

19+
class JsonParser::Impl {
20+
public:
21+
simdjson::dom::parser parser;
22+
};
23+
24+
JsonParser::JsonParser() : impl_(std::make_unique<Impl>()) {}
25+
26+
JsonParser::~JsonParser() = default;
27+
28+
void* JsonParser::GetParser() {
29+
return &impl_->parser;
30+
}
31+
1932
using std::string;
2033

2134
using v8::Array;
@@ -150,15 +163,18 @@ MaybeLocal<Value> ConvertSimdjsonElement(Isolate* isolate,
150163
}
151164
}
152165

153-
MaybeLocal<Value> ParseInternal(Isolate* isolate,
166+
MaybeLocal<Value> ParseInternal(Environment* env,
154167
const char* data,
155168
size_t length) {
169+
Isolate* isolate = env->isolate();
156170
simdjson::padded_string padded_string(data, length);
157171

158-
simdjson::dom::parser parser;
172+
// Get the cached parser from the Environment
173+
simdjson::dom::parser* parser = static_cast<simdjson::dom::parser*>(
174+
env->json_parser()->GetParser());
159175
simdjson::dom::element doc;
160176

161-
simdjson::error_code error = parser.parse(padded_string).get(doc);
177+
simdjson::error_code error = parser->parse(padded_string).get(doc);
162178

163179
if (error) {
164180
// TODO(araujogui): create a ERR_INVALID_JSON macro
@@ -171,25 +187,27 @@ MaybeLocal<Value> ParseInternal(Isolate* isolate,
171187
}
172188

173189
void Parse(const FunctionCallbackInfo<Value>& args) {
190+
Environment* env = Environment::GetCurrent(args);
174191
if (args.Length() < 1 || !args[0]->IsString()) {
175-
THROW_ERR_INVALID_ARG_TYPE(args.GetIsolate(),
192+
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
176193
"The \"text\" argument must be a string.");
177194
return;
178195
}
179196

180197
Local<String> json_str = args[0].As<String>();
181198

182-
string str = ObjectToString(args.GetIsolate(), json_str);
199+
string str = ObjectToString(env->isolate(), json_str);
183200

184201
Local<Value> result;
185-
if (!ParseInternal(args.GetIsolate(), str.data(), str.size()).ToLocal(&result))
202+
if (!ParseInternal(env, str.data(), str.size()).ToLocal(&result))
186203
return;
187204

188205
args.GetReturnValue().Set(result);
189206
}
190207

191208
void ParseFromBuffer(const FunctionCallbackInfo<Value>& args) {
192-
Isolate* isolate = args.GetIsolate();
209+
Environment* env = Environment::GetCurrent(args);
210+
Isolate* isolate = env->isolate();
193211

194212
if (args.Length() < 1) {
195213
THROW_ERR_INVALID_ARG_TYPE(
@@ -216,7 +234,7 @@ void ParseFromBuffer(const FunctionCallbackInfo<Value>& args) {
216234
}
217235

218236
Local<Value> result;
219-
if (!ParseInternal(isolate, data, length).ToLocal(&result)) return;
237+
if (!ParseInternal(env, data, length).ToLocal(&result)) return;
220238

221239
args.GetReturnValue().Set(result);
222240
}

src/node_json_parser.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@
88
namespace node {
99
namespace json_parser {
1010

11+
class JsonParser {
12+
public:
13+
JsonParser();
14+
~JsonParser();
15+
16+
JsonParser(const JsonParser&) = delete;
17+
JsonParser& operator=(const JsonParser&) = delete;
18+
19+
void* GetParser();
20+
21+
private:
22+
class Impl;
23+
std::unique_ptr<Impl> impl_;
24+
};
25+
1126
void Initialize(v8::Local<v8::Object> target,
1227
v8::Local<v8::Value> unused,
1328
v8::Local<v8::Context> context,

0 commit comments

Comments
 (0)