Skip to content

Commit c2a8be7

Browse files
committed
Optimization for xlua_hotfix_flags
背景:开发人员难以保证只对主线程执行的代码进行插桩,也难以保证在 xlua_set_hotfix_flag 的过程中时其他线程不执行到被插桩的代码。考虑到运行效率,加锁是不现实的。 做法:由于 xlua_set_hotfix_flag 的过程可以保证在单线程进行,在 xlua_set_hotfix_flag 时,保证其他线程可以安全执行 xlua_get_hotfix_flag 等方法是一种折中处理方式。 (1) xlua_hotfix_flags 和 DelegateBridge.DelegateBridgeList 的元素修改不是原子操作,需要避免xlua_get_hotfix_flag 返回 true 时 DelegateBridge.DelegateBridgeList[n] 取到NullReference。 (2) realloc(xlua_hotfix_flags, (idx + 1) * sizeof(int)) 执行后,原 xlua_hotfix_flags 内存空间已被释放,新申请的内存空间在之后才重新赋值给 xlua_hotfix_flags。此过程不是原子操作,在此过程中如果执行 xlua_get_hotfix_flag 会出现SIGSEGV。 (3) xlua_hotfix_flags 从 int 标记改为 bool 标记,节省内存使用。
1 parent ad3733c commit c2a8be7

File tree

2 files changed

+51
-30
lines changed

2 files changed

+51
-30
lines changed

Assets/Plugins/iOS/HotfixFlags.cpp

+39-29
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,47 @@
11
#include <stddef.h>
22
#include <stdlib.h>
3+
#include <string.h>
34

4-
int* xlua_hotfix_flags = NULL;
5+
bool* xlua_hotfix_flags = NULL;
56
int xlua_hotfix_flags_len = 0;
67

7-
extern "C" {
8+
extern "C"
9+
{
10+
int xlua_get_hotfix_flag(int idx)
11+
{
12+
if (idx >= xlua_hotfix_flags_len)
13+
{
14+
return 0;
15+
}
16+
else
17+
{
18+
return xlua_hotfix_flags[idx];
19+
}
20+
}
821

9-
int xlua_get_hotfix_flag(int idx) {
10-
if (idx >= xlua_hotfix_flags_len) {
11-
return 0;
12-
} else {
13-
return xlua_hotfix_flags[idx];
14-
}
15-
}
22+
void xlua_set_hotfix_flag(int idx, int flag)
23+
{
24+
if (idx >= xlua_hotfix_flags_len)
25+
{
26+
bool* new_hotfix_flags = (bool*)malloc(idx + 1);
1627

17-
void xlua_set_hotfix_flag(int idx, int flag) {
18-
int i = 0;
19-
int* new_hotfix_flags = NULL;
20-
if (idx >= xlua_hotfix_flags_len) {
21-
if (xlua_hotfix_flags == NULL) {
22-
xlua_hotfix_flags = (int*)malloc((idx + 1) * sizeof(int));
23-
} else {
24-
new_hotfix_flags = (int*)realloc(xlua_hotfix_flags, (idx + 1) * sizeof(int));
25-
if (NULL == new_hotfix_flags) { // just skip operation
26-
return;
27-
}
28-
xlua_hotfix_flags = new_hotfix_flags;
29-
}
30-
for(i = xlua_hotfix_flags_len; i < (idx + 1); i++) {
31-
xlua_hotfix_flags[i] = 0;
32-
}
33-
xlua_hotfix_flags_len = idx + 1;
34-
}
35-
xlua_hotfix_flags[idx] = flag;
36-
}
28+
if (xlua_hotfix_flags == NULL)
29+
{
30+
memset(new_hotfix_flags, 0, (idx + 1));
31+
xlua_hotfix_flags = new_hotfix_flags;
32+
}
33+
else
34+
{
35+
memcpy(new_hotfix_flags, xlua_hotfix_flags, xlua_hotfix_flags_len);
36+
memset(new_hotfix_flags + xlua_hotfix_flags_len, 0, (idx + 1 - xlua_hotfix_flags_len));
37+
bool* tmp = xlua_hotfix_flags;
38+
xlua_hotfix_flags = new_hotfix_flags;
39+
free(tmp);
40+
}
41+
42+
xlua_hotfix_flags_len = idx + 1;
43+
}
44+
45+
xlua_hotfix_flags[idx] = flag;
46+
}
3747
}

Assets/XLua/Src/DelegateBridge.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,21 @@ public static void Set(int idx, DelegateBridge val)
116116
}
117117
DelegateBridge.DelegateBridgeList = newList;
118118
}
119+
120+
#if (UNITY_IPHONE || UNITY_TVOS) && !UNITY_EDITOR
121+
if (val == null)
122+
{
123+
xlua_set_hotfix_flag(idx, false);
124+
}
125+
#endif
119126
DelegateBridge.DelegateBridgeList[idx] = val;
120127
#if (UNITY_IPHONE || UNITY_TVOS) && !UNITY_EDITOR
121-
xlua_set_hotfix_flag(idx, val != null);
128+
if (val != null)
129+
{
130+
xlua_set_hotfix_flag(idx, true);
131+
}
122132
#endif
133+
123134
}
124135
}
125136

0 commit comments

Comments
 (0)