Fixes stack overflow in certain cases

This commit is contained in:
konsoletyper 2014-05-08 17:04:32 +04:00
parent 27291367b7
commit f892748174
2 changed files with 13 additions and 18 deletions

View File

@ -51,11 +51,10 @@ public class GraphIndexer {
byte[] state = new byte[sz]; byte[] state = new byte[sz];
int lastIndex = 0; int lastIndex = 0;
int lastVisitIndex = 0; int lastVisitIndex = 0;
int[] stack = new int[sz * 2]; IntegerStack stack = new IntegerStack(sz * 2);
int stackSize = 0; stack.push(loopGraph.loopAt(0) != null ? loopGraph.loopAt(0).getHead() : 0);
stack[stackSize++] = loopGraph.loopAt(0) != null ? loopGraph.loopAt(0).getHead() : 0; while (!stack.isEmpty()) {
while (stackSize > 0) { int node = stack.pop();
int node = stack[--stackSize];
switch (state[node]) { switch (state[node]) {
case VISITING: { case VISITING: {
state[node] = VISITED; state[node] = VISITED;
@ -65,7 +64,7 @@ public class GraphIndexer {
case NONE: { case NONE: {
visitIndex[node] = lastVisitIndex++; visitIndex[node] = lastVisitIndex++;
state[node] = VISITING; state[node] = VISITING;
stack[stackSize++] = node; stack.push(node);
int[] successors = graph.outgoingEdges(node); int[] successors = graph.outgoingEdges(node);
LoopEntrance[] edges = new LoopEntrance[successors.length]; LoopEntrance[] edges = new LoopEntrance[successors.length];
for (int i = 0; i < edges.length; ++i) { for (int i = 0; i < edges.length; ++i) {
@ -87,7 +86,7 @@ public class GraphIndexer {
int next = edge.follower; int next = edge.follower;
switch (state[next]) { switch (state[next]) {
case NONE: case NONE:
stack[stackSize++] = next; stack.push(next);
break; break;
default: default:
break; break;

View File

@ -15,10 +15,7 @@
*/ */
package org.teavm.common; package org.teavm.common;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/** /**
* *
@ -81,19 +78,18 @@ public class LoopGraph implements Graph {
walkIndexes = new int[sz]; walkIndexes = new int[sz];
LoopImpl[] createdLoops = new LoopImpl[sz]; LoopImpl[] createdLoops = new LoopImpl[sz];
LoopFrame[] frames = new LoopFrame[sz]; LoopFrame[] frames = new LoopFrame[sz];
LoopFrame[] stack = new LoopFrame[sz * 4]; Deque<LoopFrame> stack = new ArrayDeque<>(sz * 4);
int stackSize = 0;
LoopFrame rootFrame = new LoopFrame(); LoopFrame rootFrame = new LoopFrame();
stack[stackSize++] = rootFrame; stack.push(rootFrame);
int walkIndex = 0; int walkIndex = 0;
int lastSortIndex = sz - 1; int lastSortIndex = sz - 1;
int loopSetSize = 0; int loopSetSize = 0;
while (stackSize > 0) { while (!stack.isEmpty()) {
LoopFrame frame = stack[--stackSize]; LoopFrame frame = stack.pop();
if (frames[frame.index] == null) { if (frames[frame.index] == null) {
frames[frame.index] = frame; frames[frame.index] = frame;
frame.walkIndex = walkIndex++; frame.walkIndex = walkIndex++;
stack[stackSize++] = frame; stack.push(frame);
int[] targetEdges = graph.outgoingEdges(frame.index); int[] targetEdges = graph.outgoingEdges(frame.index);
for (int i = 0; i < targetEdges.length; ++i) { for (int i = 0; i < targetEdges.length; ++i) {
int next = targetEdges[i]; int next = targetEdges[i];
@ -101,7 +97,7 @@ public class LoopGraph implements Graph {
if (nextFrame == null) { if (nextFrame == null) {
nextFrame = new LoopFrame(); nextFrame = new LoopFrame();
nextFrame.index = next; nextFrame.index = next;
stack[stackSize++] = nextFrame; stack.push(nextFrame);
} }
} }
} else { } else {