Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
91858596
J
jadx
项目概览
keyescgm
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
91858596
编写于
11月 13, 2021
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
perf(gui): on rename unload dependent classes instead recompile
上级
cf918a89
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
95 addition
and
13 deletion
+95
-13
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+13
-1
jadx-core/src/main/java/jadx/api/JavaClass.java
jadx-core/src/main/java/jadx/api/JavaClass.java
+7
-1
jadx-core/src/main/java/jadx/core/ProcessClass.java
jadx-core/src/main/java/jadx/core/ProcessClass.java
+4
-0
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
+1
-0
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+28
-4
jadx-gui/src/main/java/jadx/gui/jobs/IndexService.java
jadx-gui/src/main/java/jadx/gui/jobs/IndexService.java
+9
-0
jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
+5
-0
jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java
jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java
+28
-7
未找到文件。
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
浏览文件 @
91858596
...
...
@@ -415,6 +415,18 @@ public final class JadxDecompiler implements Closeable {
}
}
/**
* Get JavaClass by ClassNode without loading and decompilation
*/
JavaClass
convertClassNode
(
ClassNode
cls
)
{
return
classesMap
.
computeIfAbsent
(
cls
,
node
->
{
if
(
cls
.
isInner
())
{
return
new
JavaClass
(
cls
,
convertClassNode
(
cls
.
getParentClass
()));
}
return
new
JavaClass
(
cls
,
this
);
});
}
@Nullable
(
"For not generated classes"
)
@ApiStatus
.
Internal
public
JavaClass
getJavaClassByNode
(
ClassNode
cls
)
{
...
...
@@ -555,7 +567,7 @@ public final class JadxDecompiler implements Closeable {
return
null
;
}
if
(
obj
instanceof
ClassNode
)
{
return
getJavaClassBy
Node
((
ClassNode
)
obj
);
return
convertClass
Node
((
ClassNode
)
obj
);
}
if
(
obj
instanceof
MethodNode
)
{
return
getJavaMethodByNode
(((
MethodNode
)
obj
));
...
...
jadx-core/src/main/java/jadx/api/JavaClass.java
浏览文件 @
91858596
...
...
@@ -63,6 +63,11 @@ public final class JavaClass implements JavaNode {
cls
.
reloadCode
();
}
public
void
unload
()
{
listsLoaded
=
false
;
cls
.
unloadCode
();
}
public
synchronized
String
getSmali
()
{
return
cls
.
getDisassembledCode
();
}
...
...
@@ -81,13 +86,14 @@ public final class JavaClass implements JavaNode {
}
listsLoaded
=
true
;
decompile
();
JadxDecompiler
rootDecompiler
=
getRootDecompiler
();
int
inClsCount
=
cls
.
getInnerClasses
().
size
();
if
(
inClsCount
!=
0
)
{
List
<
JavaClass
>
list
=
new
ArrayList
<>(
inClsCount
);
for
(
ClassNode
inner
:
cls
.
getInnerClasses
())
{
if
(!
inner
.
contains
(
AFlag
.
DONT_GENERATE
))
{
JavaClass
javaClass
=
new
JavaClass
(
inner
,
this
);
JavaClass
javaClass
=
rootDecompiler
.
convertClassNode
(
inner
);
javaClass
.
loadLists
();
list
.
add
(
javaClass
);
}
...
...
jadx-core/src/main/java/jadx/core/ProcessClass.java
浏览文件 @
91858596
...
...
@@ -41,6 +41,10 @@ public final class ProcessClass {
cls
.
deepUnload
();
cls
.
root
().
runPreDecompileStageForClass
(
cls
);
}
if
(
cls
.
contains
(
AFlag
.
CLASS_UNLOADED
))
{
cls
.
remove
(
AFlag
.
CLASS_UNLOADED
);
cls
.
root
().
runPreDecompileStageForClass
(
cls
);
}
if
(
codegen
)
{
if
(
cls
.
getState
()
==
GENERATED_AND_UNLOADED
)
{
// allow to run code generation again
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
浏览文件 @
91858596
...
...
@@ -82,6 +82,7 @@ public enum AFlag {
RESTART_CODEGEN
,
// codegen must be executed again
RELOAD_AT_CODEGEN_STAGE
,
// class can't be analyzed at 'process' stage => unload before 'codegen' stage
CLASS_DEEP_RELOAD
,
// perform deep class unload (reload) before process
CLASS_UNLOADED
,
// class was completely unloaded
DONT_UNLOAD_CLASS
,
// don't unload class after code generation (only for tests and debug!)
}
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
浏览文件 @
91858596
...
...
@@ -274,6 +274,15 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
return
decompile
(
false
);
}
public
void
unloadCode
()
{
if
(
state
==
NOT_LOADED
)
{
return
;
}
add
(
AFlag
.
CLASS_UNLOADED
);
unloadFromCache
();
deepUnload
();
}
public
void
deepUnload
()
{
if
(
clsData
==
null
)
{
// manually added class
...
...
@@ -287,17 +296,27 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
innerClasses
.
forEach
(
ClassNode:
:
deepUnload
);
}
private
void
unloadFromCache
()
{
if
(
isInner
())
{
return
;
}
ICodeCache
codeCache
=
root
().
getCodeCache
();
codeCache
.
remove
(
getRawName
());
}
private
synchronized
ICodeInfo
decompile
(
boolean
searchInCache
)
{
if
(
isInner
())
{
return
ICodeInfo
.
EMPTY
;
}
ICodeCache
codeCache
=
root
().
getCodeCache
();
ClassNode
topParentClass
=
getTopParentClass
();
String
clsRawName
=
topParentClass
.
getRawName
();
String
clsRawName
=
getRawName
();
if
(
searchInCache
)
{
ICodeInfo
code
=
codeCache
.
get
(
clsRawName
);
if
(
code
!=
null
&&
code
!=
ICodeInfo
.
EMPTY
)
{
return
code
;
}
}
ICodeInfo
codeInfo
=
ProcessClass
.
generateCode
(
t
opParentClas
s
);
ICodeInfo
codeInfo
=
ProcessClass
.
generateCode
(
t
hi
s
);
codeCache
.
add
(
clsRawName
,
codeInfo
);
return
codeInfo
;
}
...
...
@@ -510,7 +529,8 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
/**
* Get all inner and inlined classes recursively
*
* @param resultClassesSet all identified inner and inlined classes are added to this set
* @param resultClassesSet
* all identified inner and inlined classes are added to this set
*/
public
void
getInnerAndInlinedClassesRecursive
(
Set
<
ClassNode
>
resultClassesSet
)
{
for
(
ClassNode
innerCls
:
innerClasses
)
{
...
...
@@ -554,6 +574,10 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
return
parentClass
!=
this
;
}
public
boolean
isTopClass
()
{
return
parentClass
==
this
;
}
@Nullable
public
MethodNode
getClassInitMth
()
{
return
searchMethodByShortId
(
"<clinit>()V"
);
...
...
jadx-gui/src/main/java/jadx/gui/jobs/IndexService.java
浏览文件 @
91858596
...
...
@@ -61,6 +61,15 @@ public class IndexService {
indexCls
(
cls
);
}
public
synchronized
void
remove
(
JavaClass
cls
)
{
TextSearchIndex
index
=
cache
.
getTextIndex
();
if
(
index
==
null
)
{
return
;
}
indexSet
.
remove
(
cls
);
index
.
remove
(
cls
);
}
public
boolean
isIndexNeeded
(
JavaClass
cls
)
{
return
!
indexSet
.
contains
(
cls
);
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
浏览文件 @
91858596
...
...
@@ -77,6 +77,11 @@ public class JClass extends JLoadableNode implements Comparable<JClass> {
update
();
}
public
synchronized
void
unload
()
{
cls
.
unload
();
loaded
=
false
;
}
public
synchronized
void
update
()
{
removeAllChildren
();
if
(!
loaded
)
{
...
...
jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java
浏览文件 @
91858596
...
...
@@ -42,6 +42,7 @@ import jadx.core.dex.nodes.RootNode;
import
jadx.core.dex.visitors.rename.RenameVisitor
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.gui.jobs.IndexService
;
import
jadx.gui.jobs.TaskStatus
;
import
jadx.gui.settings.JadxProject
;
import
jadx.gui.treemodel.JClass
;
...
...
@@ -97,6 +98,7 @@ public class RenameDialog extends JDialog {
refreshState
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Rename failed"
,
e
);
UiUtils
.
errorMessage
(
this
,
"Rename failed:\n"
+
Utils
.
getStackTrace
(
e
));
}
dispose
();
}
...
...
@@ -191,7 +193,7 @@ public class RenameDialog extends JDialog {
if
(!
updatedTopClasses
.
isEmpty
())
{
mainWindow
.
getBackgroundExecutor
().
execute
(
"Refreshing"
,
Utils
.
collectionMap
(
updatedTopClasses
,
cls
->
()
->
refreshJClass
(
cls
)
),
()
->
refreshClasses
(
updatedTopClasses
),
(
status
)
->
{
if
(
status
==
TaskStatus
.
CANCEL_BY_MEMORY
)
{
mainWindow
.
showHeapUsageBar
();
...
...
@@ -219,12 +221,31 @@ public class RenameDialog extends JDialog {
}
}
private
void
refreshJClass
(
JClass
cls
)
{
try
{
cls
.
reload
();
cache
.
getIndexService
().
refreshIndex
(
cls
.
getCls
());
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to reload class: {}"
,
cls
.
getFullName
(),
e
);
private
void
refreshClasses
(
Set
<
JClass
>
updatedTopClasses
)
{
IndexService
indexService
=
cache
.
getIndexService
();
if
(
updatedTopClasses
.
size
()
<
10
)
{
// small batch => reload
LOG
.
debug
(
"Classes to reload: {}"
,
updatedTopClasses
.
size
());
for
(
JClass
cls
:
updatedTopClasses
)
{
try
{
cls
.
reload
();
indexService
.
refreshIndex
(
cls
.
getCls
());
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to reload class: {}"
,
cls
.
getFullName
(),
e
);
}
}
}
else
{
// big batch => unload
LOG
.
debug
(
"Classes to unload: {}"
,
updatedTopClasses
.
size
());
indexService
.
setComplete
(
false
);
for
(
JClass
cls
:
updatedTopClasses
)
{
try
{
cls
.
unload
();
indexService
.
remove
(
cls
.
getCls
());
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to unload class: {}"
,
cls
.
getFullName
(),
e
);
}
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录