Skip to content

Commit 19b5d07

Browse files
addaleaxtargos
authored andcommitted
src: use string_view for report and related code
Use `std::string_view` for process.report code and related code, drop a few unnecessary `std::to_string` calls, and use `MaybeStackBuffer` instead of `MallocedBuffer`, all in order to avoid unnecessary heap allocations. PR-URL: #46723 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent dd66c48 commit 19b5d07

File tree

7 files changed

+76
-64
lines changed

7 files changed

+76
-64
lines changed

src/json_utils.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace node {
44

5-
std::string EscapeJsonChars(const std::string& str) {
6-
const std::string control_symbols[0x20] = {
5+
std::string EscapeJsonChars(std::string_view str) {
6+
static const std::string_view control_symbols[0x20] = {
77
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
88
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b",
99
"\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011",

src/json_utils.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@
44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

66
#include <iomanip>
7-
#include <ostream>
87
#include <limits>
8+
#include <ostream>
99
#include <string>
10+
#include <string_view>
1011

1112
namespace node {
1213

13-
std::string EscapeJsonChars(const std::string& str);
14+
constexpr bool NeedsJsonEscape(std::string_view str) {
15+
for (const char c : str) {
16+
if (c == '\\' || c == '"' || c < 0x20) return true;
17+
}
18+
return false;
19+
}
20+
21+
std::string EscapeJsonChars(std::string_view str);
1422
std::string Reindent(const std::string& str, int indentation);
1523

1624
// JSON compiler definitions.
@@ -135,17 +143,20 @@ class JSONWriter {
135143
}
136144

137145
inline void write_value(Null null) { out_ << "null"; }
138-
inline void write_value(const char* str) { write_string(str); }
139-
inline void write_value(const std::string& str) { write_string(str); }
146+
inline void write_value(std::string_view str) { write_string(str); }
140147

141148
inline void write_value(const ForeignJSON& json) {
142149
out_ << Reindent(json.as_string, indent_);
143150
}
144151

145-
inline void write_string(const std::string& str) {
146-
out_ << '"' << EscapeJsonChars(str) << '"';
152+
inline void write_string(std::string_view str) {
153+
out_ << '"';
154+
if (NeedsJsonEscape(str)) // only create temporary std::string if necessary
155+
out_ << EscapeJsonChars(str);
156+
else
157+
out_ << str;
158+
out_ << '"';
147159
}
148-
inline void write_string(const char* str) { write_string(std::string(str)); }
149160

150161
enum JSONState { kObjectStart, kAfterValue };
151162
std::ostream& out_;

src/node_api.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
657657
// a file system path.
658658
// TODO(gabrielschulhof): Pass the `filename` through unchanged if/when we
659659
// receive it as a URL already.
660-
module_filename = node::url::FromFilePath(filename.ToString());
660+
module_filename = node::url::FromFilePath(filename.ToStringView());
661661
}
662662

663663
// Create a new napi_env for this specific module.

src/node_errors.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,10 @@ static void ReportFatalException(Environment* env,
420420
// Not an error object. Just print as-is.
421421
node::Utf8Value message(env->isolate(), error);
422422

423-
FPrintF(stderr, "%s\n",
424-
*message ? message.ToString() : "<toString() threw exception>");
423+
FPrintF(
424+
stderr,
425+
"%s\n",
426+
*message ? message.ToStringView() : "<toString() threw exception>");
425427
} else {
426428
node::Utf8Value name_string(env->isolate(), name.ToLocalChecked());
427429
node::Utf8Value message_string(env->isolate(), message.ToLocalChecked());

src/node_report.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ static void PrintJavaScriptErrorProperties(JSONWriter* writer,
400400
!value->ToString(context).ToLocal(&value_string)) {
401401
continue;
402402
}
403-
String::Utf8Value k(isolate, key);
403+
node::Utf8Value k(isolate, key);
404404
if (!strcmp(*k, "stack") || !strcmp(*k, "message")) continue;
405-
String::Utf8Value v(isolate, value_string);
406-
writer->json_keyvalue(std::string(*k, k.length()),
407-
std::string(*v, v.length()));
405+
node::Utf8Value v(isolate, value_string);
406+
writer->json_keyvalue(k.ToStringView(), v.ToStringView());
408407
}
409408
}
410409
writer->json_objectend(); // the end of 'errorProperties'
@@ -631,27 +630,26 @@ static void PrintResourceUsage(JSONWriter* writer) {
631630
uint64_t free_memory = uv_get_free_memory();
632631
uint64_t total_memory = uv_get_total_memory();
633632

634-
writer->json_keyvalue("free_memory", std::to_string(free_memory));
635-
writer->json_keyvalue("total_memory", std::to_string(total_memory));
633+
writer->json_keyvalue("free_memory", free_memory);
634+
writer->json_keyvalue("total_memory", total_memory);
636635

637636
size_t rss;
638637
int err = uv_resident_set_memory(&rss);
639638
if (!err) {
640-
writer->json_keyvalue("rss", std::to_string(rss));
639+
writer->json_keyvalue("rss", rss);
641640
}
642641

643642
uint64_t constrained_memory = uv_get_constrained_memory();
644643
if (constrained_memory) {
645-
writer->json_keyvalue("constrained_memory",
646-
std::to_string(constrained_memory));
644+
writer->json_keyvalue("constrained_memory", constrained_memory);
647645
}
648646

649647
// See GuessMemoryAvailableToTheProcess
650648
if (!err && constrained_memory && constrained_memory >= rss) {
651649
uint64_t available_memory = constrained_memory - rss;
652-
writer->json_keyvalue("available_memory", std::to_string(available_memory));
650+
writer->json_keyvalue("available_memory", available_memory);
653651
} else {
654-
writer->json_keyvalue("available_memory", std::to_string(free_memory));
652+
writer->json_keyvalue("available_memory", free_memory);
655653
}
656654

657655
if (uv_getrusage(&rusage) == 0) {
@@ -668,7 +666,7 @@ static void PrintResourceUsage(JSONWriter* writer) {
668666
writer->json_keyvalue("cpuConsumptionPercent", cpu_percentage);
669667
writer->json_keyvalue("userCpuConsumptionPercent", user_cpu_percentage);
670668
writer->json_keyvalue("kernelCpuConsumptionPercent", kernel_cpu_percentage);
671-
writer->json_keyvalue("maxRss", std::to_string(rusage.ru_maxrss * 1024));
669+
writer->json_keyvalue("maxRss", rusage.ru_maxrss * 1024);
672670
writer->json_objectstart("pageFaults");
673671
writer->json_keyvalue("IORequired", rusage.ru_majflt);
674672
writer->json_keyvalue("IONotRequired", rusage.ru_minflt);
@@ -795,13 +793,15 @@ static void PrintComponentVersions(JSONWriter* writer) {
795793
writer->json_objectstart("componentVersions");
796794

797795
#define V(key) +1
798-
std::pair<std::string, std::string> versions_array[NODE_VERSIONS_KEYS(V)];
796+
std::pair<std::string_view, std::string_view>
797+
versions_array[NODE_VERSIONS_KEYS(V)];
799798
#undef V
800799
auto* slot = &versions_array[0];
801800

802801
#define V(key) \
803802
do { \
804-
*slot++ = std::make_pair(#key, per_process::metadata.versions.key); \
803+
*slot++ = std::pair<std::string_view, std::string_view>( \
804+
#key, per_process::metadata.versions.key); \
805805
} while (0);
806806
NODE_VERSIONS_KEYS(V)
807807
#undef V

src/node_report_utils.cc

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,79 +83,75 @@ static void ReportEndpoints(uv_handle_t* h, JSONWriter* writer) {
8383
// Utility function to format libuv pipe information.
8484
static void ReportPipeEndpoints(uv_handle_t* h, JSONWriter* writer) {
8585
uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
86-
MallocedBuffer<char> buffer(0);
87-
size_t buffer_size = 0;
86+
MaybeStackBuffer<char> buffer;
87+
size_t buffer_size = buffer.capacity();
8888
int rc = -1;
8989

9090
// First call to get required buffer size.
91-
rc = uv_pipe_getsockname(&handle->pipe, buffer.data, &buffer_size);
91+
rc = uv_pipe_getsockname(&handle->pipe, buffer.out(), &buffer_size);
9292
if (rc == UV_ENOBUFS) {
93-
buffer = MallocedBuffer<char>(buffer_size);
94-
if (buffer.data != nullptr) {
95-
rc = uv_pipe_getsockname(&handle->pipe, buffer.data, &buffer_size);
96-
} else {
97-
buffer_size = 0;
98-
}
93+
buffer.AllocateSufficientStorage(buffer_size);
94+
rc = uv_pipe_getsockname(&handle->pipe, buffer.out(), &buffer_size);
9995
}
100-
if (rc == 0 && buffer_size != 0 && buffer.data != nullptr) {
101-
writer->json_keyvalue("localEndpoint", buffer.data);
96+
if (rc == 0 && buffer_size != 0) {
97+
buffer.SetLength(buffer_size);
98+
writer->json_keyvalue("localEndpoint", buffer.ToStringView());
10299
} else {
103100
writer->json_keyvalue("localEndpoint", null);
104101
}
105102

106103
// First call to get required buffer size.
107-
rc = uv_pipe_getpeername(&handle->pipe, buffer.data, &buffer_size);
104+
buffer_size = buffer.capacity();
105+
rc = uv_pipe_getpeername(&handle->pipe, buffer.out(), &buffer_size);
108106
if (rc == UV_ENOBUFS) {
109-
buffer = MallocedBuffer<char>(buffer_size);
110-
if (buffer.data != nullptr) {
111-
rc = uv_pipe_getpeername(&handle->pipe, buffer.data, &buffer_size);
112-
}
107+
buffer.AllocateSufficientStorage(buffer_size);
108+
rc = uv_pipe_getpeername(&handle->pipe, buffer.out(), &buffer_size);
113109
}
114-
if (rc == 0 && buffer_size != 0 && buffer.data != nullptr) {
115-
writer->json_keyvalue("remoteEndpoint", buffer.data);
110+
if (rc == 0 && buffer_size != 0) {
111+
buffer.SetLength(buffer_size);
112+
writer->json_keyvalue("remoteEndpoint", buffer.ToStringView());
116113
} else {
117114
writer->json_keyvalue("remoteEndpoint", null);
118115
}
119116
}
120117

121118
// Utility function to format libuv path information.
122119
static void ReportPath(uv_handle_t* h, JSONWriter* writer) {
123-
MallocedBuffer<char> buffer(0);
120+
MaybeStackBuffer<char> buffer;
124121
int rc = -1;
125-
size_t size = 0;
122+
size_t size = buffer.capacity();
126123
uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
127-
bool wrote_filename = false;
128124
// First call to get required buffer size.
129125
switch (h->type) {
130126
case UV_FS_EVENT:
131-
rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
127+
rc = uv_fs_event_getpath(&(handle->fs_event), buffer.out(), &size);
132128
break;
133129
case UV_FS_POLL:
134-
rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
130+
rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.out(), &size);
135131
break;
136132
default:
137133
break;
138134
}
139135
if (rc == UV_ENOBUFS) {
140-
buffer = MallocedBuffer<char>(size + 1);
136+
buffer.AllocateSufficientStorage(size);
141137
switch (h->type) {
142138
case UV_FS_EVENT:
143-
rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
139+
rc = uv_fs_event_getpath(&(handle->fs_event), buffer.out(), &size);
144140
break;
145141
case UV_FS_POLL:
146-
rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
142+
rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.out(), &size);
147143
break;
148144
default:
149145
break;
150146
}
151-
if (rc == 0) {
152-
// buffer is not null terminated.
153-
buffer.data[size] = '\0';
154-
writer->json_keyvalue("filename", buffer.data);
155-
wrote_filename = true;
156-
}
157147
}
158-
if (!wrote_filename) writer->json_keyvalue("filename", null);
148+
149+
if (rc == 0 && size > 0) {
150+
buffer.SetLength(size);
151+
writer->json_keyvalue("filename", buffer.ToStringView());
152+
} else {
153+
writer->json_keyvalue("filename", null);
154+
}
159155
}
160156

161157
// Utility function to walk libuv handles.

src/util.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@
3838
#include <array>
3939
#include <limits>
4040
#include <memory>
41+
#include <set>
4142
#include <string>
4243
#include <string_view>
4344
#include <type_traits>
44-
#include <set>
4545
#include <unordered_map>
4646
#include <utility>
4747
#include <vector>
@@ -486,6 +486,11 @@ class MaybeStackBuffer {
486486
free(buf_);
487487
}
488488

489+
inline std::basic_string<T> ToString() const { return {out(), length()}; }
490+
inline std::basic_string_view<T> ToStringView() const {
491+
return {out(), length()};
492+
}
493+
489494
private:
490495
size_t length_;
491496
// capacity of the malloc'ed buf_
@@ -533,8 +538,6 @@ class Utf8Value : public MaybeStackBuffer<char> {
533538
public:
534539
explicit Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value);
535540

536-
inline std::string ToString() const { return std::string(out(), length()); }
537-
538541
inline bool operator==(const char* a) const {
539542
return strcmp(out(), a) == 0;
540543
}
@@ -609,7 +612,7 @@ struct MallocedBuffer {
609612
}
610613

611614
void Truncate(size_t new_size) {
612-
CHECK(new_size <= size);
615+
CHECK_LE(new_size, size);
613616
size = new_size;
614617
}
615618

@@ -618,7 +621,7 @@ struct MallocedBuffer {
618621
data = UncheckedRealloc(data, new_size);
619622
}
620623

621-
inline bool is_empty() const { return data == nullptr; }
624+
bool is_empty() const { return data == nullptr; }
622625

623626
MallocedBuffer() : data(nullptr), size(0) {}
624627
explicit MallocedBuffer(size_t size) : data(Malloc<T>(size)), size(size) {}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy