Skip to content

Commit e7e4162

Browse files
committed
perf(runtime): reuse the cached signature tokens in JsArgConverter
When the metadata entry is resolved, JsArgConverter copied entry->parsedSig into its own vector on every Java call, allocating one std::string per parameter (object tokens such as Ljava/lang/String; exceed the small-string buffer and hit the heap). Read the tokens through a pointer instead: it points at the entry's cached parsedSig when available, and at an owned vector only when the converter has to parse the signature itself. The converter is a per-call stack object while the entry is owned by the class's MethodCallbackData for the isolate's lifetime, so the pointer cannot outlive its target. Copying is deleted since the pointer may refer to the converter's own member.
1 parent b81e4f8 commit e7e4162

2 files changed

Lines changed: 18 additions & 11 deletions

File tree

‎test-app/runtime/src/main/cpp/JsArgConverter.cpp‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ JsArgConverter::JsArgConverter(const Local<Object> &caller,
2828
JniSignatureParser parser(m_methodSignature);
2929
entry->parsedSig = parser.Parse();
3030
}
31-
m_tokens = entry->parsedSig;
31+
m_tokens = &entry->parsedSig;
3232
} else {
3333
JniSignatureParser parser(m_methodSignature);
34-
m_tokens = parser.Parse();
34+
m_ownedTokens = parser.Parse();
3535
}
3636

3737
m_isValid = ConvertArg(caller, 0);
@@ -63,10 +63,10 @@ JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value> &args,
6363
JniSignatureParser parser(m_methodSignature);
6464
entry->parsedSig = parser.Parse();
6565
}
66-
m_tokens = entry->parsedSig;
66+
m_tokens = &entry->parsedSig;
6767
} else {
6868
JniSignatureParser parser(m_methodSignature);
69-
m_tokens = parser.Parse();
69+
m_ownedTokens = parser.Parse();
7070
}
7171

7272
for (int i = 0; i < m_argsLen; i++) {
@@ -86,7 +86,7 @@ JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value> &args,
8686
m_argsLen = args.Length();
8787

8888
JniSignatureParser parser(m_methodSignature);
89-
m_tokens = parser.Parse();
89+
m_ownedTokens = parser.Parse();
9090

9191
for (int i = 0; i < m_argsLen; i++) {
9292
m_isValid = ConvertArg(args[i], i);
@@ -117,7 +117,7 @@ bool JsArgConverter::ConvertArg(const Local<Value> &arg, int index) {
117117

118118
char buff[1024];
119119

120-
const auto &typeSignature = m_tokens.at(index);
120+
const auto &typeSignature = m_tokens->at(index);
121121

122122
if (arg.IsEmpty()) {
123123
SetConvertedObject(index, nullptr);
@@ -394,7 +394,7 @@ bool JsArgConverter::ConvertJavaScriptNumber(const Local<Value> &jsValue, int in
394394
0
395395
};
396396

397-
const auto &typeSignature = m_tokens.at(index);
397+
const auto &typeSignature = m_tokens->at(index);
398398
auto context = m_isolate->GetCurrentContext();
399399

400400
const char typePrefix = typeSignature[0];
@@ -445,7 +445,7 @@ bool JsArgConverter::ConvertJavaScriptNumber(const Local<Value> &jsValue, int in
445445
bool JsArgConverter::ConvertJavaScriptBoolean(const Local<Value> &jsValue, int index) {
446446
bool success;
447447

448-
const auto &typeSignature = m_tokens.at(index);
448+
const auto &typeSignature = m_tokens->at(index);
449449
auto context = m_isolate->GetCurrentContext();
450450

451451
if (typeSignature == "Z") {
@@ -489,7 +489,7 @@ bool JsArgConverter::ConvertJavaScriptArray(const Local<Array> &jsArr, int index
489489

490490
jsize arrLength = jsArr->Length();
491491

492-
const auto &arraySignature = m_tokens.at(index);
492+
const auto &arraySignature = m_tokens->at(index);
493493
auto context = m_isolate->GetCurrentContext();
494494

495495
string elementType = arraySignature.substr(1);
@@ -632,7 +632,7 @@ template<typename T>
632632
bool JsArgConverter::ConvertFromCastFunctionObject(T value, int index) {
633633
bool success = false;
634634

635-
const auto &typeSignature = m_tokens.at(index);
635+
const auto &typeSignature = m_tokens->at(index);
636636

637637
const char typeSignaturePrefix = typeSignature[0];
638638

‎test-app/runtime/src/main/cpp/JsArgConverter.h‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ namespace tns {
2727

2828
JsArgConverter(const v8::FunctionCallbackInfo<v8::Value>& args, const std::string& methodSignature);
2929

30+
JsArgConverter(const JsArgConverter&) = delete;
31+
32+
JsArgConverter& operator=(const JsArgConverter&) = delete;
33+
3034
~JsArgConverter();
3135

3236
jvalue* ToArgs();
@@ -79,7 +83,10 @@ namespace tns {
7983

8084
std::string m_methodSignature;
8185

82-
std::vector<std::string> m_tokens;
86+
std::vector<std::string> m_ownedTokens;
87+
88+
// May point at m_ownedTokens, which is why the converter is not copyable.
89+
const std::vector<std::string>* m_tokens = &m_ownedTokens;
8390

8491
Error m_error;
8592
};

0 commit comments

Comments
 (0)