Skip to content

Commit

Permalink
fix runtime class loading performance
Browse files Browse the repository at this point in the history
  • Loading branch information
ammarahm-ed committed Oct 7, 2024
1 parent a184875 commit 98a2ccb
Show file tree
Hide file tree
Showing 12 changed files with 646 additions and 537 deletions.
3 changes: 2 additions & 1 deletion test-app/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ endif (CCACHE_FOUND AND (USE_CCACHE))
# "-DANDROID_STL=c++_static" is just not enough for clang++ to find some libraries in the ndk
MESSAGE(STATUS "## ANDROID_NDK_ROOT: " ${ANDROID_NDK_ROOT})

set(COMMON_CMAKE_ARGUMENTS "-std=c++17 -Werror -Wno-unused-result -mstackrealign -fexceptions -fno-builtin-stpcpy -fno-rtti -DV8_31BIT_SMIS_ON_64BIT_ARCH -DV8_31BIT_SMIS_ON_64BIT_ARCH -DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -DV8_EMBEDDED_BUILTINS")
set(COMMON_CMAKE_ARGUMENTS "-std=c++17 -Wno-unused-result -mstackrealign -fexceptions -fno-builtin-stpcpy -fno-rtti -DV8_31BIT_SMIS_ON_64BIT_ARCH -DV8_31BIT_SMIS_ON_64BIT_ARCH -DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -DV8_EMBEDDED_BUILTINS")

if("${ANDROID_ABI}" MATCHES "arm64-v8a$" OR "${ANDROID_ABI}" MATCHES "x86_64$")
# Enable pointer compression on 64 bit platforms
Expand Down Expand Up @@ -115,6 +115,7 @@ add_library(
src/main/cpp/MetadataNode.cpp
src/main/cpp/MetadataReader.cpp
src/main/cpp/MetadataTreeNode.cpp
src/main/cpp/MetadataEntry.cpp
src/main/cpp/MethodCache.cpp
src/main/cpp/ModuleBinding.cpp
src/main/cpp/ModuleInternal.cpp
Expand Down
21 changes: 11 additions & 10 deletions test-app/runtime/src/main/cpp/CallbackHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,11 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string
string *returnType = nullptr;
auto retType = MethodReturnType::Unknown;
MethodCache::CacheMethodInfo mi;
auto &entrySignature = entry->getSig();

auto isolate = args.GetIsolate();

if ((entry != nullptr) && entry->isResolved) {
if ((entry != nullptr) && entry->getIsResolved()) {
isStatic = entry->isStatic;

if (entry->memberId == nullptr) {
Expand All @@ -236,14 +237,14 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string
if (isFromInterface) {
auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className,
methodName,
entry->sig);
entrySignature);
entry->memberId = methodAndClassPair.first;
clazz = methodAndClassPair.second;
} else {
entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetStaticMethodID(clazz, methodName, entrySignature);
}
} else {
entry->memberId = env.GetMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetMethodID(clazz, methodName, entrySignature);
}

if (entry->memberId == nullptr) {
Expand All @@ -257,14 +258,14 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string
if (isFromInterface) {
auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className,
methodName,
entry->sig);
entrySignature);
entry->memberId = methodAndClassPair.first;
clazz = methodAndClassPair.second;
} else {
entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetStaticMethodID(clazz, methodName, entrySignature);
}
} else {
entry->memberId = env.GetMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetMethodID(clazz, methodName, entrySignature);
}

if (entry->memberId == nullptr) {
Expand All @@ -279,9 +280,9 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string

mid = reinterpret_cast<jmethodID>(entry->memberId);
clazz = entry->clazz;
sig = &entry->sig;
returnType = &entry->returnType;
retType = entry->retType;
sig = &entrySignature;
returnType = &entry->getReturnType();
retType = entry->getRetType();
} else {
DEBUG_WRITE("Resolving method: %s on className %s", methodName.c_str(), className.c_str());

Expand Down
33 changes: 19 additions & 14 deletions test-app/runtime/src/main/cpp/FieldAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&

JniLocalRef targetJavaObject;

const auto& fieldTypeName = fieldData->signature;
auto isStatic = fieldData->isStatic;
auto fieldMetadata = fieldData->metadata;

const auto& fieldTypeName = fieldMetadata->getSig();
auto isStatic = fieldMetadata->isStatic;

auto isPrimitiveType = fieldTypeName.size() == 1;
auto isFieldArray = fieldTypeName[0] == '[';
Expand All @@ -35,11 +37,11 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&
("L" + fieldTypeName + ";"));

if (isStatic) {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->clazz = env.FindClass(fieldMetadata->getDeclaringType());
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldMetadata->name, fieldJniSig);
} else {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->clazz = env.FindClass(fieldMetadata->getDeclaringType());
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldMetadata->name, fieldJniSig);
}
}

Expand All @@ -48,7 +50,7 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&

if (targetJavaObject.IsNull()) {
stringstream ss;
ss << "Cannot access property '" << fieldData->name.c_str() << "' because there is no corresponding Java object";
ss << "Cannot access property '" << fieldMetadata->name.c_str() << "' because there is no corresponding Java object";
throw NativeScriptException(ss.str());
}
}
Expand Down Expand Up @@ -186,14 +188,17 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&
void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target, const Local<Value>& value, FieldCallbackData* fieldData) {
JEnv env;

auto fieldMetadata = fieldData->metadata;

HandleScope handleScope(isolate);
auto runtime = Runtime::GetRuntime(isolate);
auto objectManager = runtime->GetObjectManager();

JniLocalRef targetJavaObject;

const auto& fieldTypeName = fieldData->signature;
auto isStatic = fieldData->isStatic;
const auto& fieldTypeName = fieldMetadata->getSig();
auto isStatic = fieldMetadata->isStatic;


auto isPrimitiveType = fieldTypeName.size() == 1;
auto isFieldArray = fieldTypeName[0] == '[';
Expand All @@ -208,14 +213,14 @@ void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target,
("L" + fieldTypeName + ";"));

if (isStatic) {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->clazz = env.FindClass(fieldMetadata->getDeclaringType());
assert(fieldData->clazz != nullptr);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldMetadata->name, fieldJniSig);
assert(fieldData->fid != nullptr);
} else {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->clazz = env.FindClass(fieldMetadata->getDeclaringType());
assert(fieldData->clazz != nullptr);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldMetadata->name, fieldJniSig);
assert(fieldData->fid != nullptr);
}
}
Expand All @@ -225,7 +230,7 @@ void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target,

if (targetJavaObject.IsNull()) {
stringstream ss;
ss << "Cannot access property '" << fieldData->name.c_str() << "' because there is no corresponding Java object";
ss << "Cannot access property '" << fieldMetadata->name.c_str() << "' because there is no corresponding Java object";
throw NativeScriptException(ss.str());
}
}
Expand Down
28 changes: 10 additions & 18 deletions test-app/runtime/src/main/cpp/FieldCallbackData.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,17 @@
#include "MetadataEntry.h"

namespace tns {
struct FieldCallbackData {
FieldCallbackData(const MetadataEntry& metadata)
:
fid(nullptr), clazz(nullptr) {
name = metadata.name;
signature = metadata.sig;
declaringType = metadata.declaringType;
isStatic = metadata.isStatic;
isFinal = metadata.isFinal;
}
struct FieldCallbackData {
FieldCallbackData(MetadataEntry *metadata)
:
metadata(metadata), fid(nullptr), clazz(nullptr) {

std::string name;
std::string signature;
std::string declaringType;
bool isStatic;
bool isFinal;
jfieldID fid;
jclass clazz;
};
}

MetadataEntry* metadata;
jfieldID fid;
jclass clazz;
};

}

Expand Down
133 changes: 133 additions & 0 deletions test-app/runtime/src/main/cpp/MetadataEntry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include "MetadataNode.h"
#include "MetadataEntry.h"
#include "MetadataMethodInfo.h"
#include "MetadataReader.h"

using namespace tns;

MetadataEntry::MetadataEntry(MetadataTreeNode *m_treeNode, NodeType nodeType) :
treeNode(m_treeNode), type(nodeType), isExtensionFunction(false), isStatic(false),
isTypeMember(false), memberId(nullptr), clazz(nullptr), mi(nullptr),fi(nullptr), sfi(nullptr),
retType(MethodReturnType::Unknown),
paramCount(-1), isFinal(false), isResolved(false), retTypeParsed(false),
isFinalSet(false), isResolvedSet(false) {}

std::string &MetadataEntry::getName() {
if (!name.empty()) return name;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Field) {
name = reader->ReadName(fi->nameOffset);
} else if (type == NodeType::StaticField) {
name = reader->ReadName(sfi->nameOffset);
} else if (type == NodeType::Method) {
name = mi->GetName();
}

return name;
}

std::string &MetadataEntry::getSig() {
if (!sig.empty()) return sig;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Field) {
sig = reader->ReadTypeName(fi->nodeId);
} else if (type == NodeType::StaticField) {
sig = reader->ReadTypeName(sfi->nodeId);
} else if (type == NodeType::Method) {
uint8_t sigLength = mi->GetSignatureLength();
if (sigLength > 0)
sig = mi->GetSignature();

}

return sig;
}

std::string &MetadataEntry::getReturnType() {
if (!returnType.empty()) return returnType;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method) {
if (mi->GetSignatureLength() > 0) {
returnType = MetadataReader::ParseReturnType(this->getSig());
}
} else {
return returnType;
}

return returnType;
}

MethodReturnType MetadataEntry::getRetType() {
if (retTypeParsed) return retType;
auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method && !this->getReturnType().empty()) {
retType = MetadataReader::GetReturnType(this->getReturnType());
}

retTypeParsed = true;

return retType;
}

std::string &MetadataEntry::getDeclaringType() {
if (!declaringType.empty()) return declaringType;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::StaticField) {
declaringType = reader->ReadTypeName(sfi->declaringType);
}

return declaringType;
}

int MetadataEntry::getParamCount() {
if (paramCount != -1) return paramCount;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method) {
auto sigLength = mi->GetSignatureLength();
if (sigLength > 0) {
paramCount = sigLength - 1;
} else {
paramCount = 0;
}
}

return paramCount;
}

bool MetadataEntry::getIsFinal() {
if (isFinalSet) return isFinal;

if (type == NodeType::Field) {
isFinal = fi->finalModifier == MetadataTreeNode::FINAL;
} else if (type == NodeType::StaticField) {
isFinal = sfi->finalModifier == MetadataTreeNode::FINAL;
}

isFinalSet = true;

return isFinal;
}

bool MetadataEntry::getIsResolved() {
if (isResolvedSet) return isResolved;

auto reader = MetadataNode::getMetadataReader();
if (type == NodeType::Method) {
isResolved = mi->CheckIsResolved() == 1;
}

isResolvedSet = true;

return isResolved;
}
Loading

0 comments on commit 98a2ccb

Please sign in to comment.