Skip to content

Commit

Permalink
src: make InternalModuleReadJSON() linear again
Browse files Browse the repository at this point in the history
Commits dcb6929, 4396beb and 8a96d05 turned the O(n) scan in
InternalModuleReadJSON() into an O(4n) scan. Fix the performance
regression by turning that into a linear scan again.
  • Loading branch information
bnoordhuis committed Jan 14, 2020
1 parent f4a4a1a commit da6b66a
Showing 1 changed file with 35 additions and 9 deletions.
44 changes: 35 additions & 9 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -829,20 +829,46 @@ static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) {
}

const size_t size = offset - start;
if (size == 0 || (
size == SearchString(&chars[start], size, "\"name\"") &&
size == SearchString(&chars[start], size, "\"main\"") &&
size == SearchString(&chars[start], size, "\"exports\"") &&
size == SearchString(&chars[start], size, "\"type\""))) {
args.GetReturnValue().Set(env->empty_object_string());
} else {
Local<String> chars_string =
char* p = &chars[start];
char* pe = &chars[size];
char* pos[2];
char** ppos = &pos[0];

while (p < pe) {
char c = *p++;
if (c == '"') goto quote; // Keeps code flat and inner loop small.
if (c == '\\' && p < pe && *p == '"') p++;
continue;
quote:
*ppos++ = p;
if (ppos < &pos[2]) continue;
ppos = &pos[0];

char* s = &pos[0][0];
char* se = &pos[1][-1]; // Exclude quote.
size_t n = se - s;

if (n == 4) {
if (0 == memcmp(s, "main", 4)) break;
if (0 == memcmp(s, "name", 4)) break;
if (0 == memcmp(s, "type", 4)) break;
} else if (n == 7) {
if (0 == memcmp(s, "exports", 7)) break;
}
}

Local<String> return_value;
if (p < pe) {
return_value =
String::NewFromUtf8(isolate,
&chars[start],
v8::NewStringType::kNormal,
size).ToLocalChecked();
args.GetReturnValue().Set(chars_string);
} else {
return_value = env->empty_object_string();
}

args.GetReturnValue().Set(return_value);
}

// Used to speed up module loading. Returns 0 if the path refers to
Expand Down

0 comments on commit da6b66a

Please sign in to comment.