Skip to content

Commit b46622e

Browse files
committed
module: speed up package.json parsing more
Move the logic from the previous commit to C++ land in order to avoid creating a new string when we know we won't parse it anyway.
1 parent 2e4aae4 commit b46622e

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

lib/module.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function readPackage(requestPath) {
120120
return false;
121121
}
122122

123-
if (!/"main"/.test(json))
123+
if (json === '')
124124
return packageMainCache[requestPath] = undefined;
125125

126126
try {

src/node_file.cc

+5-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "req-wrap-inl.h"
2727
#include "string_bytes.h"
28+
#include "string_search.h"
2829

2930
#include <fcntl.h>
3031
#include <sys/types.h>
@@ -466,8 +467,9 @@ void FillStatsArray(double* fields, const uv_stat_t* s) {
466467
}
467468

468469
// Used to speed up module loading. Returns the contents of the file as
469-
// a string or undefined when the file cannot be opened. The speedup
470-
// comes from not creating Error objects on failure.
470+
// a string or undefined when the file cannot be opened. Returns an empty
471+
// string when the file does not contain the substring '"main"' because that
472+
// is the property we care about.
471473
static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
472474
Environment* env = Environment::GetCurrent(args);
473475
uv_loop_t* loop = env->event_loop();
@@ -516,7 +518,7 @@ static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
516518
}
517519

518520
const size_t size = offset - start;
519-
if (size == 0) {
521+
if (size == 0 || size == SearchString(&chars[start], size, "\"main\"")) {
520522
args.GetReturnValue().SetEmptyString();
521523
} else {
522524
Local<String> chars_string =

src/string_search.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ size_t SearchString(const Char* haystack,
638638
size_t needle_length,
639639
size_t start_index,
640640
bool is_forward) {
641+
if (haystack_length < needle_length) return haystack_length;
641642
// To do a reverse search (lastIndexOf instead of indexOf) without redundant
642643
// code, create two vectors that are reversed views into the input strings.
643644
// For example, v_needle[0] would return the *last* character of the needle.
@@ -646,7 +647,6 @@ size_t SearchString(const Char* haystack,
646647
needle, needle_length, is_forward);
647648
Vector<const Char> v_haystack = Vector<const Char>(
648649
haystack, haystack_length, is_forward);
649-
CHECK(haystack_length >= needle_length);
650650
size_t diff = haystack_length - needle_length;
651651
size_t relative_start_index;
652652
if (is_forward) {
@@ -664,6 +664,15 @@ size_t SearchString(const Char* haystack,
664664
}
665665
return is_forward ? pos : (haystack_length - needle_length - pos);
666666
}
667+
668+
template <size_t N>
669+
size_t SearchString(const char* haystack, size_t haystack_length,
670+
const char (&needle)[N]) {
671+
return SearchString(
672+
reinterpret_cast<const uint8_t*>(haystack), haystack_length,
673+
reinterpret_cast<const uint8_t*>(needle), N - 1, 0, true);
674+
}
675+
667676
} // namespace node
668677

669678
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

test/parallel/test-module-binding.js

+5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
require('../common');
33
const fixtures = require('../common/fixtures');
44
const { internalModuleReadFile } = process.binding('fs');
5+
const { readFileSync } = require('fs');
56
const { strictEqual } = require('assert');
67

78
strictEqual(internalModuleReadFile('nosuchfile'), undefined);
89
strictEqual(internalModuleReadFile(fixtures.path('empty.txt')), '');
910
strictEqual(internalModuleReadFile(fixtures.path('empty-with-bom.txt')), '');
11+
{
12+
const filename = fixtures.path('require-bin/package.json');
13+
strictEqual(internalModuleReadFile(filename), readFileSync(filename, 'utf8'));
14+
}

0 commit comments

Comments
 (0)