Skip to content

Commit 5809dbd

Browse files
committed
refactor: global reference use one map
1 parent 05dcbc2 commit 5809dbd

File tree

3 files changed

+63
-59
lines changed

3 files changed

+63
-59
lines changed

dart_native/android/src/main/jni/dart_native.cpp

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,21 @@ extern "C"
2121
/// for invoke result compare
2222
static jclass gStrCls;
2323

24-
static std::map<jobject, jclass> objectGlobalCache;
25-
static std::map<jobject, int> referenceCount;
24+
/// key is jobject, value is pai which contain jclass and reference count
25+
static std::map<jobject, std::pair<jclass, int>> objectGlobalReference;
26+
27+
void _addGlobalObject(jobject globalObject, jclass globalClass) {
28+
std::pair<jclass, int> objPair = std::make_pair(globalClass, 0);
29+
objectGlobalReference[globalObject] = objPair;
30+
}
31+
32+
jclass _getGlobalClass(jobject globalObject) {
33+
if (objectGlobalReference.find(globalObject) != objectGlobalReference.end()) {
34+
std::pair<jclass, int> objPair = objectGlobalReference[globalObject];
35+
return objPair.first;
36+
}
37+
return nullptr;
38+
}
2639

2740
void _detachThreadDestructor(void *arg)
2841
{
@@ -31,6 +44,7 @@ extern "C"
3144
detachKey = 0;
3245
}
3346

47+
/// each thread attach once
3448
JNIEnv *_getEnv()
3549
{
3650
if (gJvm == nullptr)
@@ -77,6 +91,7 @@ extern "C"
7791
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass",
7892
"(Ljava/lang/String;)Ljava/lang/Class;");
7993

94+
/// cache string class
8095
jclass strCls = env->FindClass("java/lang/String");
8196
gStrCls = static_cast<jclass>(env->NewGlobalRef(strCls));
8297

@@ -94,6 +109,7 @@ extern "C"
94109
jclass nativeClass = nullptr;
95110
nativeClass = env->FindClass(name);
96111
jthrowable exception = env->ExceptionOccurred();
112+
/// class loader not found class
97113
if (exception)
98114
{
99115
env->ExceptionClear();
@@ -106,6 +122,7 @@ extern "C"
106122
}
107123

108124
/// fill all arguments to jvalues
125+
/// when argument is string the stringTypeBitmask's bit is 1
109126
void _fillArgs(void **arguments, char **argumentTypes, jvalue *argValues, int argumentCount, uint32_t stringTypeBitmask)
110127
{
111128
JNIEnv *env = _getEnv();
@@ -161,7 +178,7 @@ extern "C"
161178
jclass cls = _findClass(env, targetClassName);
162179
jobject newObj = _newObject(cls, arguments, argumentTypes, argumentCount, stringTypeBitmask);
163180
jobject gObj = env->NewGlobalRef(newObj);
164-
objectGlobalCache[gObj] = static_cast<jclass>(env->NewGlobalRef(cls));
181+
_addGlobalObject(gObj, static_cast<jclass>(env->NewGlobalRef(cls)));
165182

166183
env->DeleteLocalRef(newObj);
167184
env->DeleteLocalRef(cls);
@@ -171,12 +188,17 @@ extern "C"
171188
/// invoke native method
172189
void *invokeNativeMethod(void *objPtr, char *methodName, void **arguments, char **dataTypes, int argumentCount, char *returnType, uint32_t stringTypeBitmask)
173190
{
191+
auto object = static_cast<jobject>(objPtr);
192+
jclass cls = _getGlobalClass(object);
193+
if (cls == nullptr)
194+
{
195+
DNError("invokeNativeMethod not find class");
196+
return nullptr;
197+
}
198+
174199
void *nativeInvokeResult = nullptr;
175200
JNIEnv *env = _getEnv();
176201

177-
auto object = static_cast<jobject>(objPtr);
178-
jclass cls = objectGlobalCache[object];
179-
180202
auto *argValues = new jvalue[argumentCount];
181203
if (argumentCount > 0)
182204
{
@@ -210,7 +232,7 @@ extern "C"
210232
{
211233
jclass objCls = env->GetObjectClass(obj);
212234
jobject gObj = env->NewGlobalRef(obj);
213-
objectGlobalCache[gObj] = static_cast<jclass>(env->NewGlobalRef(objCls));
235+
_addGlobalObject(gObj, static_cast<jclass>(env->NewGlobalRef(objCls)));
214236
nativeInvokeResult = gObj;
215237

216238
env->DeleteLocalRef(objCls);
@@ -257,50 +279,44 @@ extern "C"
257279
return Dart_InitializeApiDL(data);
258280
}
259281

260-
/// retain native object
261-
void _retain(void *objPtr)
262-
{
263-
auto object = static_cast<jobject>(objPtr);
264-
auto it = referenceCount.find(object);
265-
int refCount = it == referenceCount.end() ? 1 : referenceCount[object] + 1;
266-
referenceCount[object] = refCount;
267-
}
268-
269-
/// do release native object
270-
void _releaseTargetObject(void *objPtr)
271-
{
272-
JNIEnv *env = _getEnv();
273-
auto object = static_cast<jobject>(objPtr);
274-
env->DeleteGlobalRef(objectGlobalCache[object]);
275-
objectGlobalCache.erase(object);
276-
env->DeleteGlobalRef(object);
277-
}
282+
/// reference counter
283+
void _updateObjectReference(jobject globalObject, bool isRetain) {
284+
DNDebug("_updateObjectReference %s", isRetain ? "retain" : "release");
285+
auto it = objectGlobalReference.find(globalObject);
286+
if (it == objectGlobalReference.end())
287+
{
288+
DNError("_updateObjectReference %s error not contain this object!!!", isRetain ? "retain" : "release");
289+
return;
290+
}
278291

279-
/// check reference count, if no reference exits then release
280-
void _release(void *objPtr)
281-
{
282-
auto object = static_cast<jobject>(objPtr);
283-
if (referenceCount.find(object) == referenceCount.end())
292+
if (isRetain)
284293
{
285-
DNError("release error not contain object");
294+
/// dart object retain this dart object
295+
/// reference++
296+
it->second.second += 1;
286297
return;
287298
}
288-
int count = referenceCount[object];
289-
if (count <= 1)
299+
300+
/// release reference--
301+
it->second.second -= 1;
302+
303+
/// no dart object retained this native object
304+
if (it->second.second <= 0)
290305
{
291-
referenceCount.erase(object);
292-
_releaseTargetObject(objPtr);
306+
JNIEnv *env = _getEnv();
307+
env->DeleteGlobalRef(it->second.first);
308+
objectGlobalReference.erase(it);
309+
env->DeleteGlobalRef(globalObject);
293310
return;
294311
}
295-
referenceCount[object] = count - 1;
296312
}
297313

298314
/// release native object from cache
299315
static void RunFinalizer(void *isolate_callback_data,
300316
Dart_WeakPersistentHandle handle,
301317
void *peer)
302318
{
303-
_release(peer);
319+
_updateObjectReference(static_cast<jobject>(peer), false);
304320
}
305321

306322
/// retain native object
@@ -311,7 +327,7 @@ extern "C"
311327
DNError("Dart_IsError_DL");
312328
return;
313329
}
314-
_retain(objPtr);
330+
_updateObjectReference(static_cast<jobject>(objPtr), true);
315331
intptr_t size = 8;
316332
Dart_NewWeakPersistentHandle_DL(h, objPtr, size, RunFinalizer);
317333
}
@@ -377,7 +393,7 @@ extern "C"
377393
{
378394
jclass objCls = env->GetObjectClass(argument);
379395
jobject gObj = env->NewGlobalRef(argument);
380-
objectGlobalCache[gObj] = static_cast<jclass>(env->NewGlobalRef(objCls));
396+
_addGlobalObject(gObj, static_cast<jclass>(env->NewGlobalRef(objCls)));
381397
arguments[i] = gObj;
382398

383399
env->DeleteLocalRef(objCls);
@@ -398,7 +414,7 @@ extern "C"
398414

399415
const Work work = [dartObjectAddress, dataTypes, arguments, argumentCount, funName, &sem, isSemInitSuccess]() {
400416
NativeMethodCallback methodCallback = getCallbackMethod(dartObjectAddress, funName);
401-
void *target = getDartObject(dartObjectAddress);
417+
void *target = (void *) dartObjectAddress;
402418
if (methodCallback != nullptr && target != nullptr)
403419
{
404420
methodCallback(target, funName, arguments, dataTypes, argumentCount);

dart_native/android/src/main/jni/dn_callback.cpp

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
#include "dn_log.h"
77
#include "dn_type_convert.h"
88

9-
static std::map<jlong, void *> targetCache;
9+
/// key is dart object pointer address, value is dart port
1010
static std::map<jlong, int64_t> dartPortCache;
11-
static std::map<void *, jobject> callbackObjCache;
11+
/// key is dart object pointer, value is native proxy object
12+
static std::map<void *, jobject> nativeProxyObjectCache;
13+
/// key is dart object pointer address, value is method
1214
static std::map<jlong, std::map<std::string, NativeMethodCallback>> callbackFunctionCache;
1315

1416
void registerCallbackManager(jlong dartObjectAddress, char *functionName, void *callback)
@@ -31,22 +33,21 @@ void registerCallbackManager(jlong dartObjectAddress, char *functionName, void *
3133
void doRegisterNativeCallback(void *dartObject, jobject nativeProxyObject, char *funName, void *callback, Dart_Port dartPort)
3234
{
3335
auto dartObjectAddress = (jlong) dartObject;
34-
callbackObjCache[dartObject] = nativeProxyObject;
35-
targetCache[dartObjectAddress] = dartObject;
36+
nativeProxyObjectCache[dartObject] = nativeProxyObject;
3637
dartPortCache[dartObjectAddress] = dartPort;
3738

3839
registerCallbackManager(dartObjectAddress, funName, callback);
3940
}
4041

4142
jobject getNativeCallbackProxyObject(void *dartObject)
4243
{
43-
if (callbackObjCache.find(dartObject) == callbackObjCache.end())
44+
if (nativeProxyObjectCache.find(dartObject) == nativeProxyObjectCache.end())
4445
{
4546
DNInfo("getNativeCallbackProxyObject: not contain this dart object");
4647
return nullptr;
4748
}
4849

49-
return callbackObjCache[dartObject];
50+
return nativeProxyObjectCache[dartObject];
5051
}
5152

5253
Dart_Port getCallbackDartPort(jlong dartObjectAddress)
@@ -60,17 +61,6 @@ Dart_Port getCallbackDartPort(jlong dartObjectAddress)
6061
return dartPortCache[dartObjectAddress];
6162
}
6263

63-
void *getDartObject(jlong dartObjectAddress)
64-
{
65-
if (targetCache.find(dartObjectAddress) == targetCache.end())
66-
{
67-
DNInfo("getDartObject: targetCache not contain this dart object %d", dartObjectAddress);
68-
return nullptr;
69-
}
70-
71-
return targetCache[dartObjectAddress];
72-
}
73-
7464
NativeMethodCallback getCallbackMethod(jlong dartObjectAddress, char *functionName)
7565
{
7666
if (!callbackFunctionCache.count(dartObjectAddress))

dart_native/android/src/main/jni/dn_callback.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ extern "C"
2424

2525
Dart_Port getCallbackDartPort(jlong dartObjectAddress);
2626

27-
void *getDartObject(jlong dartObjectAddress);
28-
2927
NativeMethodCallback getCallbackMethod(jlong dartObjectAddress, char *functionName);
3028

3129
#ifdef __cplusplus

0 commit comments

Comments
 (0)