diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 87a73caf0..0e0267056 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -290,24 +290,44 @@ Local ObjectManager::CreateJSWrapper(jint javaObjectID, JEnv env; JniLocalRef clazz(env.GetObjectClass(instance)); - return CreateJSWrapperHelper(javaObjectID, typeName, clazz); + auto& seen = m_wrapperClasses[typeName]; + for (const auto& entry : seen) { + if (env.isSameObject(entry.clazz, clazz)) { + return CreateJSWrapperHelper(javaObjectID, entry.className, entry.clazz); + } + } + + auto className = GetClassName((jclass)clazz); + jclass linked = nullptr; + auto jsWrapper = CreateJSWrapperHelper(javaObjectID, className, nullptr, &linked); + if (linked != nullptr) { + if (seen.size() >= 4) { + seen.erase(seen.begin()); + } + seen.push_back({linked, className}); + } + return jsWrapper; } Local ObjectManager::CreateJSWrapperHelper(jint javaObjectID, - const string& typeName, - jclass clazz) { + const string& className, + jclass globalClazz, + jclass* linkedClazz) { auto isolate = m_isolate; - auto className = (clazz != nullptr) ? GetClassName(clazz) : typeName; - auto node = MetadataNode::GetOrCreate(className); auto jsWrapper = node->CreateJSWrapper(isolate, this); if (!jsWrapper.IsEmpty()) { - JEnv env; - auto claz = env.FindClass(className); - Link(jsWrapper, javaObjectID, claz); + if (globalClazz == nullptr) { + JEnv env; + globalClazz = env.FindClass(className); + } + Link(jsWrapper, javaObjectID, globalClazz); + if (linkedClazz != nullptr) { + *linkedClazz = globalClazz; + } } return jsWrapper; } diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 5fbe4afce..85c80bf61 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -212,8 +212,14 @@ class ObjectManager { DirectBuffer& inputBuff, DirectBuffer& outputBuff); v8::Local CreateJSWrapperHelper(jint javaObjectID, - const std::string& typeName, - jclass clazz); + const std::string& className, + jclass globalClazz, + jclass* linkedClazz = nullptr); + + struct WrapperClassEntry { + jclass clazz; + std::string className; + }; static void JSObjectWeakCallbackStatic( const v8::WeakCallbackInfo& data); @@ -253,6 +259,9 @@ class ObjectManager { std::unordered_map m_idToObject; + // Recent runtime classes per declared type. + std::unordered_map> m_wrapperClasses; + PersistentObjectIdSet m_released; std::set m_visited;