Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 51 additions & 49 deletions NativeScript/ffi/jni/jsi/metadata/MetadataNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,74 +900,72 @@ void MetadataNode::CreateTopLevelNamespaces(JsRuntime &rt) {
}

MetadataTreeNode *MetadataNode::GetOrCreateTreeNodeByName(const string &className) {
MetadataTreeNode *result = nullptr;

auto itFound = s_name2TreeNodeCache.find(className);

if (itFound != s_name2TreeNodeCache.end()) {
result = itFound->second;
} else {
result = s_metadataReader.GetOrCreateTreeNodeByName(className);

s_name2TreeNodeCache.emplace(className, result);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto itFound = s_name2TreeNodeCache.find(className);
if (itFound != s_name2TreeNodeCache.end()) {
return itFound->second;
}
}

return result;
MetadataTreeNode *created = s_metadataReader.GetOrCreateTreeNodeByName(className);

std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
return s_name2TreeNodeCache.emplace(className, created).first->second;
}

string MetadataNode::GetName() {
return m_name;
}

MetadataNode *MetadataNode::GetOrCreate(const string &className) {
MetadataNode *node = nullptr;

auto it = s_name2NodeCache.find(className);

if (it == s_name2NodeCache.end()) {
MetadataTreeNode *treeNode = GetOrCreateTreeNodeByName(className);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_name2NodeCache.find(className);
if (it != s_name2NodeCache.end()) {
return it->second;
}
}

node = GetOrCreateInternal(treeNode);
MetadataTreeNode *treeNode = GetOrCreateTreeNodeByName(className);

s_name2NodeCache.emplace(className, node);
} else {
node = it->second;
}
MetadataNode *node = GetOrCreateInternal(treeNode);

return node;
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
return s_name2NodeCache.emplace(className, node).first->second;
}

MetadataNode *MetadataNode::GetOrCreateInternal(MetadataTreeNode *treeNode) {
MetadataNode *result = nullptr;
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_treeNode2NodeCache.find(treeNode);
if (it != s_treeNode2NodeCache.end()) {
return it->second;
}
}

auto it = s_treeNode2NodeCache.find(treeNode);
auto name = GetJniClassName(treeNode);
if (!name.empty()) {
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_name2NodeCache.find(name);
if (it != s_name2NodeCache.end()) {
s_treeNode2NodeCache.emplace(treeNode, it->second);
return it->second;
}
}

if (it != s_treeNode2NodeCache.end()) {
result = it->second;
} else {
auto name = GetJniClassName(treeNode);
if (!name.empty()) {
auto it2 = s_name2NodeCache.find(name);
if ( it2 != s_name2NodeCache.end()) {
result = it2->second;
}
}
auto *created = new MetadataNode(treeNode);

if (!result) {
result = new MetadataNode(treeNode);
s_treeNode2NodeCache.emplace(treeNode, result);
if (!result->m_name.empty()) {
s_name2NodeCache.emplace(result->m_name, result);
}
}
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto inserted = s_treeNode2NodeCache.emplace(treeNode, created);
if (!inserted.second) {
delete created;
return inserted.first->second;
}

auto found = s_treeNode2NodeCache.find(treeNode);
if (found == s_treeNode2NodeCache.end()) {
s_treeNode2NodeCache.emplace(treeNode, result);
if (!created->m_name.empty()) {
s_name2NodeCache.emplace(created->m_name, created);
}

return result;
return created;
}

MetadataEntry MetadataNode::GetChildMetadataForPackage(MetadataNode *node, const char *propName) {
Expand Down Expand Up @@ -2125,7 +2123,10 @@ JsValue MetadataNode::ExtendMethodCallback(JsRuntime &rt, const JsValue &thisVal
extendFuncCtor.setProperty(rt, PRIVATE_TYPE_NAME,
ArgConverter::convertToJsString(rt, fullExtendedName));

s_name2NodeCache.emplace(fullExtendedName, node);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
s_name2NodeCache.emplace(fullExtendedName, node);
}

auto cache = GetMetadataNodeCache(rt);

Expand Down Expand Up @@ -2711,6 +2712,7 @@ MetadataReader MetadataNode::s_metadataReader;
robin_hood::unordered_map<std::string, MetadataNode *> MetadataNode::s_name2NodeCache;
robin_hood::unordered_map<std::string, MetadataTreeNode *> MetadataNode::s_name2TreeNodeCache;
robin_hood::unordered_map<MetadataTreeNode *, MetadataNode *> MetadataNode::s_treeNode2NodeCache;
std::mutex MetadataNode::s_nodeCacheMutex;
tns::ConcurrentMap<const void *, MetadataNode::MetadataNodeCache *> MetadataNode::s_metadata_node_cache;
robin_hood::unordered_map<const void *, JsValue> MetadataNode::s_arrayObjects;

Expand Down
3 changes: 3 additions & 0 deletions NativeScript/ffi/jni/jsi/metadata/MetadataNode.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef METADATA_NODE_H
#define METADATA_NODE_H

#include <mutex>
#include <string>
#include "MetadataTreeNode.h"
#include "MetadataEntry.h"
Expand Down Expand Up @@ -269,6 +270,8 @@ class MetadataNode {
static robin_hood::unordered_map<std::string, MetadataNode *> s_name2NodeCache;
static robin_hood::unordered_map<std::string, MetadataTreeNode *> s_name2TreeNodeCache;
static robin_hood::unordered_map<MetadataTreeNode *, MetadataNode *> s_treeNode2NodeCache;
// Guards the three caches above. Held only for map access, never across the metadata reader.
static std::mutex s_nodeCacheMutex;
// Both keyed by JsRuntime::identity(); &rt is not stable across callbacks.
static tns::ConcurrentMap<const void *, MetadataNodeCache *> s_metadata_node_cache;
static robin_hood::unordered_map<const void *, JsValue> s_arrayObjects;
Expand Down
100 changes: 51 additions & 49 deletions NativeScript/ffi/jni/napi/metadata/MetadataNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,74 +1136,72 @@ void MetadataNode::CreateTopLevelNamespaces(napi_env env) {
}

MetadataTreeNode *MetadataNode::GetOrCreateTreeNodeByName(const string &className) {
MetadataTreeNode *result = nullptr;

auto itFound = s_name2TreeNodeCache.find(className);

if (itFound != s_name2TreeNodeCache.end()) {
result = itFound->second;
} else {
result = s_metadataReader.GetOrCreateTreeNodeByName(className);

s_name2TreeNodeCache.emplace(className, result);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto itFound = s_name2TreeNodeCache.find(className);
if (itFound != s_name2TreeNodeCache.end()) {
return itFound->second;
}
}

return result;
MetadataTreeNode *created = s_metadataReader.GetOrCreateTreeNodeByName(className);

std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
return s_name2TreeNodeCache.emplace(className, created).first->second;
}

string MetadataNode::GetName() {
return m_name;
}

MetadataNode *MetadataNode::GetOrCreate(const string &className) {
MetadataNode *node = nullptr;

auto it = s_name2NodeCache.find(className);

if (it == s_name2NodeCache.end()) {
MetadataTreeNode *treeNode = GetOrCreateTreeNodeByName(className);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_name2NodeCache.find(className);
if (it != s_name2NodeCache.end()) {
return it->second;
}
}

node = GetOrCreateInternal(treeNode);
MetadataTreeNode *treeNode = GetOrCreateTreeNodeByName(className);

s_name2NodeCache.emplace(className, node);
} else {
node = it->second;
}
MetadataNode *node = GetOrCreateInternal(treeNode);

return node;
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
return s_name2NodeCache.emplace(className, node).first->second;
}

MetadataNode *MetadataNode::GetOrCreateInternal(MetadataTreeNode *treeNode) {
MetadataNode *result = nullptr;
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_treeNode2NodeCache.find(treeNode);
if (it != s_treeNode2NodeCache.end()) {
return it->second;
}
}

auto it = s_treeNode2NodeCache.find(treeNode);
auto name = GetJniClassName(treeNode);
if (!name.empty()) {
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto it = s_name2NodeCache.find(name);
if (it != s_name2NodeCache.end()) {
s_treeNode2NodeCache.emplace(treeNode, it->second);
return it->second;
}
}

if (it != s_treeNode2NodeCache.end()) {
result = it->second;
} else {
auto name = GetJniClassName(treeNode);
if (!name.empty()) {
auto it2 = s_name2NodeCache.find(name);
if ( it2 != s_name2NodeCache.end()) {
result = it2->second;
}
}
auto *created = new MetadataNode(treeNode);

if (!result) {
result = new MetadataNode(treeNode);
s_treeNode2NodeCache.emplace(treeNode, result);
if (!result->m_name.empty()) {
s_name2NodeCache.emplace(result->m_name, result);
}
}
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
auto inserted = s_treeNode2NodeCache.emplace(treeNode, created);
if (!inserted.second) {
delete created;
return inserted.first->second;
}

auto found = s_treeNode2NodeCache.find(treeNode);
if (found == s_treeNode2NodeCache.end()) {
s_treeNode2NodeCache.emplace(treeNode, result);
if (!created->m_name.empty()) {
s_name2NodeCache.emplace(created->m_name, created);
}

return result;
return created;
}

MetadataEntry MetadataNode::GetChildMetadataForPackage(MetadataNode *node, const char *propName) {
Expand Down Expand Up @@ -2502,7 +2500,10 @@ napi_value MetadataNode::ExtendMethodCallback(napi_env env, napi_callback_info i
NAPI_GUARD(napi_set_named_property(env, extendFuncCtor, PRIVATE_TYPE_NAME,
ArgConverter::convertToJsString(env, fullExtendedName))) {}

s_name2NodeCache.emplace(fullExtendedName, node);
{
std::lock_guard<std::mutex> lock(s_nodeCacheMutex);
s_name2NodeCache.emplace(fullExtendedName, node);
}

auto cache = GetMetadataNodeCache(env);

Expand Down Expand Up @@ -3224,6 +3225,7 @@ MetadataReader MetadataNode::s_metadataReader;
robin_hood::unordered_map<std::string, MetadataNode *> MetadataNode::s_name2NodeCache;
robin_hood::unordered_map<std::string, MetadataTreeNode *> MetadataNode::s_name2TreeNodeCache;
robin_hood::unordered_map<MetadataTreeNode *, MetadataNode *> MetadataNode::s_treeNode2NodeCache;
std::mutex MetadataNode::s_nodeCacheMutex;
tns::ConcurrentMap<napi_env, MetadataNode::MetadataNodeCache *> MetadataNode::s_metadata_node_cache;
robin_hood::unordered_map<napi_env, napi_ref> MetadataNode::s_arrayObjects;

Expand Down
3 changes: 3 additions & 0 deletions NativeScript/ffi/jni/napi/metadata/MetadataNode.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef METADATA_NODE_H
#define METADATA_NODE_H

#include <mutex>
#include <string>
#include "MetadataTreeNode.h"
#include "MetadataEntry.h"
Expand Down Expand Up @@ -250,6 +251,8 @@ class MetadataNode {
static robin_hood::unordered_map<std::string, MetadataNode *> s_name2NodeCache;
static robin_hood::unordered_map<std::string, MetadataTreeNode *> s_name2TreeNodeCache;
static robin_hood::unordered_map<MetadataTreeNode *, MetadataNode *> s_treeNode2NodeCache;
// Guards the three caches above. Held only for map access, never across the metadata reader.
static std::mutex s_nodeCacheMutex;
static tns::ConcurrentMap<napi_env, MetadataNodeCache *> s_metadata_node_cache;
static robin_hood::unordered_map<napi_env, napi_ref> s_arrayObjects;

Expand Down
Loading