mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Limit depth of method analysis in class initializer analysis in order to avoid too deep stack (and therefore SOE)
This commit is contained in:
parent
7efb3c97a0
commit
025801d385
|
@ -43,6 +43,7 @@ import org.teavm.model.optimization.Devirtualization;
|
|||
|
||||
public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
||||
private static final MethodDescriptor CLINIT = new MethodDescriptor("<clinit>", void.class);
|
||||
private static final int METHOD_ANALYSIS_DEPTH_THRESHOLD = 250;
|
||||
private static final byte BEING_ANALYZED = 1;
|
||||
private static final byte DYNAMIC = 2;
|
||||
private static final byte STATIC = 3;
|
||||
|
@ -55,6 +56,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
private List<? extends String> readonlyOrder = Collections.unmodifiableList(order);
|
||||
private String currentAnalyzedClass;
|
||||
private DependencyInfo dependencyInfo;
|
||||
private int methodAnalysisDepth;
|
||||
|
||||
public ClassInitializerAnalysis(ListableClassReaderSource classes, ClassHierarchy hierarchy,
|
||||
String entryPoint) {
|
||||
|
@ -121,11 +123,15 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
var initializer = cls.getMethod(CLINIT);
|
||||
var isStatic = true;
|
||||
if (initializer != null) {
|
||||
if (methodAnalysisDepth >= METHOD_ANALYSIS_DEPTH_THRESHOLD) {
|
||||
isStatic = false;
|
||||
} else {
|
||||
var initializerInfo = analyzeMethod(initializer);
|
||||
if (isDynamicInitializer(initializerInfo, className)) {
|
||||
isStatic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentAnalyzedClass = previousClass;
|
||||
if (classStatuses.get(className) == BEING_ANALYZED) {
|
||||
|
@ -151,6 +157,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
}
|
||||
|
||||
private MethodInfo analyzeMethod(MethodReader method) {
|
||||
methodAnalysisDepth++;
|
||||
var methodInfo = methodInfoMap.get(method.getReference());
|
||||
if (methodInfo == null) {
|
||||
methodInfo = new MethodInfo(method.getReference());
|
||||
|
@ -174,6 +181,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
methodInfo.complete = true;
|
||||
}
|
||||
|
||||
--methodAnalysisDepth;
|
||||
return methodInfo;
|
||||
}
|
||||
|
||||
|
@ -264,12 +272,17 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
private void invokeMethod(MethodReference method) {
|
||||
var cls = classes.get(method.getClassName());
|
||||
if (cls != null) {
|
||||
if (methodAnalysisDepth >= METHOD_ANALYSIS_DEPTH_THRESHOLD) {
|
||||
methodInfo.anyFieldModified = true;
|
||||
methodInfo.classesWithModifiedFields = null;
|
||||
} else {
|
||||
var methodReader = cls.getMethod(method.getDescriptor());
|
||||
if (methodReader != null) {
|
||||
analyzeCalledMethod(analyzeMethod(methodReader));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initClass(String className) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user