Skip to content

Commit db79257

Browse files
committed
Replace for-each/iterator loops in Lua GC hotspot passes
1 parent 895333a commit db79257

2 files changed

Lines changed: 120 additions & 54 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/LuaDispatchPreparation.java

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ public static void prepare(ImProg prog, ImTranslator tr) {
4545

4646
private static List<ImMethod> collectAllMethods(ImProg prog) {
4747
List<ImMethod> methods = new ArrayList<>();
48-
for (ImClass c : prog.getClasses()) {
48+
List<ImClass> classes = prog.getClasses();
49+
for (int i = 0; i < classes.size(); i++) {
50+
ImClass c = classes.get(i);
4951
methods.addAll(c.getMethods());
5052
}
5153
methods.sort(Comparator.comparing(LuaDispatchPreparation::methodSortKey));
@@ -55,34 +57,44 @@ private static List<ImMethod> collectAllMethods(ImProg prog) {
5557
private static void assignDispatchGroupKeys(List<ImMethod> allMethods) {
5658
Set<ImMethod> knownMethods = new HashSet<>(allMethods);
5759
UnionFind<ImMethod> unions = new UnionFind<>();
58-
for (ImMethod method : allMethods) {
60+
for (int i = 0; i < allMethods.size(); i++) {
61+
ImMethod method = allMethods.get(i);
5962
unions.find(method);
60-
for (ImMethod subMethod : method.getSubMethods()) {
63+
List<ImMethod> subMethods = method.getSubMethods();
64+
for (int j = 0; j < subMethods.size(); j++) {
65+
ImMethod subMethod = subMethods.get(j);
6166
if (knownMethods.contains(subMethod)) {
6267
unions.union(method, subMethod);
6368
}
6469
}
6570
}
6671

6772
Map<ImMethod, List<ImMethod>> grouped = new LinkedHashMap<>();
68-
for (ImMethod method : allMethods) {
73+
for (int i = 0; i < allMethods.size(); i++) {
74+
ImMethod method = allMethods.get(i);
6975
ImMethod root = unions.find(method);
7076
grouped.computeIfAbsent(root, ignored -> new ArrayList<>()).add(method);
7177
}
7278

73-
for (List<ImMethod> group : grouped.values()) {
79+
List<List<ImMethod>> groups = new ArrayList<>(grouped.values());
80+
for (int i = 0; i < groups.size(); i++) {
81+
List<ImMethod> group = groups.get(i);
7482
Map<String, List<ImMethod>> partitions = new LinkedHashMap<>();
7583
group.sort(Comparator.comparing(LuaDispatchPreparation::methodSortKey));
76-
for (ImMethod method : group) {
84+
for (int j = 0; j < group.size(); j++) {
85+
ImMethod method = group.get(j);
7786
partitions.computeIfAbsent(dispatchSignatureKey(method), ignored -> new ArrayList<>()).add(method);
7887
}
79-
for (List<ImMethod> partition : partitions.values()) {
88+
List<List<ImMethod>> partitionGroups = new ArrayList<>(partitions.values());
89+
for (int j = 0; j < partitionGroups.size(); j++) {
90+
List<ImMethod> partition = partitionGroups.get(j);
8091
partition.sort(Comparator.comparing(LuaDispatchPreparation::methodSortKey));
8192
if (partition.isEmpty()) {
8293
continue;
8394
}
8495
String key = methodSortKey(partition.get(0)) + "|" + dispatchSignatureKey(partition.get(0));
85-
for (ImMethod method : partition) {
96+
for (int k = 0; k < partition.size(); k++) {
97+
ImMethod method = partition.get(k);
8698
method.setLuaDispatchGroupKey(key);
8799
}
88100
}
@@ -94,12 +106,14 @@ private static void normalizeMethodNames(ImProg prog, List<ImMethod> allMethods,
94106
collectPredefinedNames(prog, usedNames);
95107

96108
Map<String, List<ImMethod>> groupedMethods = new TreeMap<>();
97-
for (ImMethod method : allMethods) {
109+
for (int i = 0; i < allMethods.size(); i++) {
110+
ImMethod method = allMethods.get(i);
98111
groupedMethods.computeIfAbsent(method.getLuaDispatchGroupKey(), ignored -> new ArrayList<>()).add(method);
99112
}
100113
List<List<ImMethod>> groups = new ArrayList<>(groupedMethods.values());
101114
groups.sort(Comparator.comparing(g -> g.isEmpty() ? "" : methodSortKey(g.get(0))));
102-
for (List<ImMethod> group : groups) {
115+
for (int i = 0; i < groups.size(); i++) {
116+
List<ImMethod> group = groups.get(i);
103117
if (group.isEmpty()) {
104118
continue;
105119
}
@@ -113,7 +127,8 @@ private static void normalizeMethodNames(ImProg prog, List<ImMethod> allMethods,
113127
// whose own name appears nowhere in it - which is why no method can work this out for
114128
// itself afterwards.
115129
String segment = segmentOf(name, group.get(0));
116-
for (ImMethod method : group) {
130+
for (int j = 0; j < group.size(); j++) {
131+
ImMethod method = group.get(j);
117132
method.setName(name);
118133
tr.recordDispatchSegment(method, segment);
119134
}
@@ -127,7 +142,8 @@ private static void assignDispatchAliases(ImProg prog, List<ImMethod> allMethods
127142

128143
Set<String> ambiguousDirectAliases = ambiguousDirectAliases(allMethods, tr);
129144

130-
for (ImMethod method : allMethods) {
145+
for (int i = 0; i < allMethods.size(); i++) {
146+
ImMethod method = allMethods.get(i);
131147
TreeSet<String> aliases = new TreeSet<>();
132148
addDirectAliases(method, aliases, ambiguousDirectAliases, tr);
133149
addHierarchyAliases(method, aliases, sortedMethodsByClass, tr);
@@ -137,16 +153,20 @@ private static void assignDispatchAliases(ImProg prog, List<ImMethod> allMethods
137153
}
138154

139155
private static void collectPredefinedNames(ImProg prog, Set<String> usedNames) {
140-
prog.getFunctions().forEach(function -> {
156+
List<ImFunction> functions = prog.getFunctions();
157+
for (int i = 0; i < functions.size(); i++) {
158+
ImFunction function = functions.get(i);
141159
if (function.isBj() || function.isExtern() || function.isNative()) {
142160
usedNames.add(function.getName());
143161
}
144-
});
145-
prog.getGlobals().forEach(global -> {
162+
}
163+
List<ImVar> globals = prog.getGlobals();
164+
for (int i = 0; i < globals.size(); i++) {
165+
ImVar global = globals.get(i);
146166
if (global.getIsBJ()) {
147167
usedNames.add(global.getName());
148168
}
149-
});
169+
}
150170
}
151171

152172
private static String uniqueName(String name, Set<String> usedNames) {
@@ -172,7 +192,8 @@ private static String uniqueName(String name, Set<String> usedNames) {
172192
private static Set<String> ambiguousDirectAliases(List<ImMethod> allMethods, ImTranslator tr) {
173193
Map<String, String> claimedBy = new LinkedHashMap<>();
174194
Set<String> ambiguous = new HashSet<>();
175-
for (ImMethod method : allMethods) {
195+
for (int i = 0; i < allMethods.size(); i++) {
196+
ImMethod method = allMethods.get(i);
176197
String composed = directAliasFor(method, tr);
177198
if (composed == null) {
178199
continue;
@@ -246,7 +267,9 @@ private static void collectHierarchyAliases(ImClass c, ImMethod method, String d
246267
if (c == null || !visited.add(c)) {
247268
return;
248269
}
249-
for (ImMethod candidate : sortedMethodsForClass(c, sortedMethodsByClass)) {
270+
List<ImMethod> candidates = sortedMethodsForClass(c, sortedMethodsByClass);
271+
for (int i = 0; i < candidates.size(); i++) {
272+
ImMethod candidate = candidates.get(i);
250273
if (!dispatchKey.equals(dispatchParameterSignatureKey(candidate))) {
251274
continue;
252275
}
@@ -262,7 +285,9 @@ private static void collectHierarchyAliases(ImClass c, ImMethod method, String d
262285
aliases.add(c.getName() + "_" + candidateName);
263286
}
264287
}
265-
for (ImClassType sc : c.getSuperClasses()) {
288+
List<ImClassType> superClasses = c.getSuperClasses();
289+
for (int i = 0; i < superClasses.size(); i++) {
290+
ImClassType sc = superClasses.get(i);
266291
collectHierarchyAliases(sc.getClassDef(), method, dispatchKey, semanticNames, aliases, sortedMethodsByClass, visited, tr);
267292
}
268293
}
@@ -280,9 +305,15 @@ private static void addClosureFamilyAliases(ImProg prog, ImMethod method, Set<St
280305
return;
281306
}
282307
String runtimeKey = closureRuntimeDispatchKey(method);
283-
for (ImClass anchor : closureFamilyAnchors(owner, closureFamilyAnchorsCache)) {
284-
for (ImClass candidateClass : closureFamilyClassesForAnchor(prog, anchor, closureFamilyClassesByAnchor)) {
285-
for (ImMethod candidate : sortedMethodsForClass(candidateClass, sortedMethodsByClass)) {
308+
List<ImClass> anchors = new ArrayList<>(closureFamilyAnchors(owner, closureFamilyAnchorsCache));
309+
for (int i = 0; i < anchors.size(); i++) {
310+
ImClass anchor = anchors.get(i);
311+
List<ImClass> candidateClasses = closureFamilyClassesForAnchor(prog, anchor, closureFamilyClassesByAnchor);
312+
for (int j = 0; j < candidateClasses.size(); j++) {
313+
ImClass candidateClass = candidateClasses.get(j);
314+
List<ImMethod> candidates = sortedMethodsForClass(candidateClass, sortedMethodsByClass);
315+
for (int k = 0; k < candidates.size(); k++) {
316+
ImMethod candidate = candidates.get(k);
286317
if (!runtimeKey.equals(closureRuntimeDispatchKey(candidate))) {
287318
continue;
288319
}
@@ -377,15 +408,19 @@ private static void collectClosureFamilyAnchors(ImClass c, Set<ImClass> anchors,
377408
if (!isClosureGeneratedClass(c)) {
378409
anchors.add(c);
379410
}
380-
for (ImClassType sc : c.getSuperClasses()) {
411+
List<ImClassType> superClasses = c.getSuperClasses();
412+
for (int i = 0; i < superClasses.size(); i++) {
413+
ImClassType sc = superClasses.get(i);
381414
collectClosureFamilyAnchors(sc.getClassDef(), anchors, visited);
382415
}
383416
}
384417

385418
private static List<ImClass> closureFamilyClassesForAnchor(ImProg prog, ImClass anchor, Map<ImClass, List<ImClass>> cache) {
386419
return cache.computeIfAbsent(anchor, a -> {
387420
List<ImClass> result = new ArrayList<>();
388-
for (ImClass candidate : prog.getClasses()) {
421+
List<ImClass> classes = prog.getClasses();
422+
for (int i = 0; i < classes.size(); i++) {
423+
ImClass candidate = classes.get(i);
389424
if (sharesClosureFamilyAnchor(candidate, a, new HashSet<>())) {
390425
result.add(candidate);
391426
}
@@ -402,7 +437,9 @@ private static boolean sharesClosureFamilyAnchor(ImClass c, ImClass anchor, Set<
402437
if (c == anchor) {
403438
return true;
404439
}
405-
for (ImClassType sc : c.getSuperClasses()) {
440+
List<ImClassType> superClasses = c.getSuperClasses();
441+
for (int i = 0; i < superClasses.size(); i++) {
442+
ImClassType sc = superClasses.get(i);
406443
if (sharesClosureFamilyAnchor(sc.getClassDef(), anchor, visited)) {
407444
return true;
408445
}
@@ -517,7 +554,9 @@ private static boolean reaches(ImMethod current, ImMethod target, Set<ImMethod>
517554
if (current == target) {
518555
return true;
519556
}
520-
for (ImMethod subMethod : current.getSubMethods()) {
557+
List<ImMethod> subMethods = current.getSubMethods();
558+
for (int i = 0; i < subMethods.size(); i++) {
559+
ImMethod subMethod = subMethods.get(i);
521560
if (reaches(subMethod, target, visited)) {
522561
return true;
523562
}
@@ -558,7 +597,8 @@ private static ImFunction resolveDispatchSignatureImplementation(ImMethod method
558597
}
559598
List<ImMethod> subMethods = new ArrayList<>(method.getSubMethods());
560599
subMethods.sort(Comparator.comparing(LuaDispatchPreparation::methodSortKey));
561-
for (ImMethod subMethod : subMethods) {
600+
for (int i = 0; i < subMethods.size(); i++) {
601+
ImMethod subMethod = subMethods.get(i);
562602
ImFunction resolved = resolveDispatchSignatureImplementation(subMethod, visited);
563603
if (resolved != null) {
564604
return resolved;

0 commit comments

Comments
 (0)