Skip to content

Commit f76f7a7

Browse files
committed
Optimizing Stack (merge all var stack arrays into single one)
1 parent 22939e2 commit f76f7a7

File tree

5 files changed

+113
-112
lines changed

5 files changed

+113
-112
lines changed

net.tascalate.javaflow.api/src/main/java/org/apache/commons/javaflow/core/Stack.java

Lines changed: 106 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,25 @@
3434
public class Stack implements Serializable {
3535

3636
private static final Log log = LogFactory.getLog(Stack.class);
37-
private static final long serialVersionUID = 2L;
37+
private static final long serialVersionUID = 3L;
3838

39-
private int[] istack;
40-
private float[] fstack;
41-
private double[] dstack;
42-
private long[] lstack;
39+
private long[] pstack;
4340
private Object[] ostack;
4441
private Object[] rstack;
4542
private int iTop, fTop, dTop, lTop, oTop, rTop;
43+
private int ret;
4644
protected Runnable runnable;
4745

4846
Stack(Runnable pRunnable) {
49-
istack = new int[8];
50-
lstack = new long[4];
51-
dstack = new double[4];
52-
fstack = new float[4];
47+
ret = -1;
48+
pstack = new long[16];
5349
ostack = new Object[8];
5450
rstack = new Object[4];
5551
runnable = pRunnable;
5652
}
5753

5854
Stack(final Stack pParent) {
59-
istack = new int[pParent.istack.length];
60-
lstack = new long[pParent.lstack.length];
61-
dstack = new double[pParent.dstack.length];
62-
fstack = new float[pParent.fstack.length];
55+
pstack = new long[pParent.pstack.length];
6356
ostack = new Object[pParent.ostack.length];
6457
rstack = new Object[pParent.rstack.length];
6558
iTop = pParent.iTop;
@@ -68,12 +61,10 @@ public class Stack implements Serializable {
6861
lTop = pParent.lTop;
6962
oTop = pParent.oTop;
7063
rTop = pParent.rTop;
71-
System.arraycopy(pParent.istack, 0, istack, 0, iTop);
72-
System.arraycopy(pParent.fstack, 0, fstack, 0, fTop);
73-
System.arraycopy(pParent.dstack, 0, dstack, 0, dTop);
74-
System.arraycopy(pParent.lstack, 0, lstack, 0, lTop);
64+
System.arraycopy(pParent.pstack, 0, pstack, 0, dTop + fTop + lTop);
7565
System.arraycopy(pParent.ostack, 0, ostack, 0, oTop);
7666
System.arraycopy(pParent.rstack, 0, rstack, 0, rTop);
67+
ret = pParent.ret;
7768
runnable = pParent.runnable;
7869
}
7970

@@ -86,13 +77,38 @@ public final double popDouble() {
8677
throw new EmptyStackException("pop double");
8778
}
8879

89-
final double d = dstack[--dTop];
80+
final double d = Double.longBitsToDouble(popPrimitive());
81+
--dTop;
9082
if (log.isDebugEnabled()) {
9183
log.debug("pop double " + d + " " + getStats());
9284
}
9385
return d;
9486
}
9587

88+
public final int popRet() {
89+
if (ret < 0) {
90+
throw new EmptyStackException("pop ret");
91+
}
92+
if (log.isDebugEnabled()) {
93+
log.debug("pop ret " + ret + " " + getStats());
94+
}
95+
final int result = ret;
96+
ret = -1;
97+
return result;
98+
}
99+
100+
public final void pushRet(int idx) {
101+
if (log.isDebugEnabled()) {
102+
log.debug("push ret " + idx + " " + getStats());
103+
}
104+
105+
if (ret != -1) {
106+
throw new IllegalStateException("ret is already set");
107+
}
108+
109+
ret = idx;
110+
}
111+
96112
public final boolean hasFloat() {
97113
return fTop > 0;
98114
}
@@ -102,43 +118,46 @@ public final float popFloat() {
102118
throw new EmptyStackException("pop float");
103119
}
104120

105-
final float f = fstack[--fTop];
121+
final float f = Float.intBitsToFloat((int)popPrimitive());
122+
--fTop;
106123
if (log.isDebugEnabled()) {
107124
log.debug("pop float " + f + " " + getStats());
108125
}
109126
return f;
110127
}
111-
112-
public final boolean hasInt() {
113-
return iTop > 0;
128+
129+
public final boolean hasLong() {
130+
return lTop > 0;
114131
}
115132

116-
public final int popInt() {
117-
if (iTop == 0) {
118-
throw new EmptyStackException("pop int");
133+
public final long popLong() {
134+
if (lTop == 0) {
135+
throw new EmptyStackException("pop long");
119136
}
120137

121-
final int i = istack[--iTop];
138+
final long l = popPrimitive();
139+
--lTop;
122140
if (log.isDebugEnabled()) {
123-
log.debug("pop int " + i + " " + getStats());
141+
log.debug("pop long " + l + " " + getStats());
124142
}
125-
return i;
143+
return l;
126144
}
127145

128-
public final boolean hasLong() {
129-
return lTop > 0;
146+
public final boolean hasInt() {
147+
return iTop > 0;
130148
}
131149

132-
public final long popLong() {
133-
if (lTop == 0) {
134-
throw new EmptyStackException("pop long");
150+
public final int popInt() {
151+
if (iTop == 0) {
152+
throw new EmptyStackException("pop int");
135153
}
136154

137-
final long l = lstack[--lTop];
155+
final int i = (int)popPrimitive();
156+
--iTop;
138157
if (log.isDebugEnabled()) {
139-
log.debug("pop long " + l + " " + getStats());
158+
log.debug("pop int " + i + " " + getStats());
140159
}
141-
return l;
160+
return i;
142161
}
143162

144163
public final boolean hasObject() {
@@ -184,51 +203,38 @@ public final void pushDouble(double d) {
184203
log.debug("push double " + d + " " + getStats());
185204
}
186205

187-
if (dTop == dstack.length) {
188-
double[] hlp = new double[Math.max(8, dstack.length * 2)];
189-
System.arraycopy(dstack, 0, hlp, 0, dstack.length);
190-
dstack = hlp;
191-
}
192-
dstack[dTop++] = d;
206+
ensurePrimitivesStackSize();
207+
pushPrimitive(Double.doubleToLongBits(d));
208+
dTop++;
193209
}
194210

195211
public final void pushFloat(float f) {
196212
if (log.isDebugEnabled()) {
197213
log.debug("push float " + f + " " + getStats());
198214
}
199-
200-
if (fTop == fstack.length) {
201-
float[] hlp = new float[Math.max(8, fstack.length * 2)];
202-
System.arraycopy(fstack, 0, hlp, 0, fstack.length);
203-
fstack = hlp;
204-
}
205-
fstack[fTop++] = f;
215+
216+
ensurePrimitivesStackSize();
217+
pushPrimitive(Float.floatToIntBits(f));
218+
fTop++;
206219
}
207-
208-
public final void pushInt(int i) {
220+
221+
public final void pushLong(long l) {
209222
if (log.isDebugEnabled()) {
210-
log.debug("push int " + i + " " + getStats());
223+
log.debug("push long " + l + " " + getStats());
211224
}
212225

213-
if (iTop == istack.length) {
214-
int[] hlp = new int[Math.max(8, istack.length * 2)];
215-
System.arraycopy(istack, 0, hlp, 0, istack.length);
216-
istack = hlp;
217-
}
218-
istack[iTop++] = i;
226+
ensurePrimitivesStackSize();
227+
pushPrimitive(l);
228+
lTop++;
219229
}
220230

221-
public final void pushLong(long l) {
231+
public final void pushInt(int i) {
222232
if (log.isDebugEnabled()) {
223-
log.debug("push long " + l + " " + getStats());
224-
}
225-
226-
if (lTop == lstack.length) {
227-
long[] hlp = new long[Math.max(8, lstack.length * 2)];
228-
System.arraycopy(lstack, 0, hlp, 0, lstack.length);
229-
lstack = hlp;
233+
log.debug("push int " + i + " " + getStats());
230234
}
231-
lstack[lTop++] = l;
235+
ensurePrimitivesStackSize();
236+
pushPrimitive(i);
237+
iTop++;
232238
}
233239

234240
public final void pushObject(Object o) {
@@ -319,26 +325,33 @@ private String getContent() {
319325
public String toString() {
320326
return getContent();
321327
}
322-
323-
private void writeObject(ObjectOutputStream s) throws IOException {
324-
s.writeInt(iTop);
325-
for (int i = 0; i < iTop; i++) {
326-
s.writeInt(istack[i]);
327-
}
328-
329-
s.writeInt(lTop);
330-
for (int i = 0; i < lTop; i++) {
331-
s.writeLong(lstack[i]);
328+
329+
private final void pushPrimitive(long value) {
330+
pstack[dTop + fTop + lTop + iTop] = value;
331+
}
332+
333+
private final long popPrimitive() {
334+
return pstack[dTop + fTop + lTop + iTop];
335+
}
336+
337+
private final void ensurePrimitivesStackSize() {
338+
if (dTop + fTop + lTop + iTop == pstack.length) {
339+
long[] hlp = new long[Math.max(8, pstack.length * 2)];
340+
System.arraycopy(pstack, 0, hlp, 0, pstack.length);
341+
pstack = hlp;
332342
}
343+
}
333344

345+
private void writeObject(ObjectOutputStream s) throws IOException {
346+
s.writeInt(ret);
347+
334348
s.writeInt(dTop);
335-
for (int i = 0; i < dTop; i++) {
336-
s.writeDouble(dstack[i]);
337-
}
338-
339349
s.writeInt(fTop);
340-
for (int i = 0; i < fTop; i++) {
341-
s.writeDouble(fstack[i]);
350+
s.writeInt(lTop);
351+
s.writeInt(iTop);
352+
int pTop = dTop + fTop + lTop + iTop;
353+
for (int i = 0; i < pTop; i++) {
354+
s.writeLong(pstack[i]);
342355
}
343356

344357
s.writeInt(oTop);
@@ -355,30 +368,18 @@ private void writeObject(ObjectOutputStream s) throws IOException {
355368
}
356369

357370
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
358-
iTop = s.readInt();
359-
istack = new int[iTop];
360-
for (int i = 0; i < iTop; i++) {
361-
istack[i] = s.readInt();
362-
}
363-
364-
lTop = s.readInt();
365-
lstack = new long[lTop];
366-
for (int i = 0; i < lTop; i++) {
367-
lstack[i] = s.readLong();
368-
}
369-
371+
ret = s.readInt();
372+
370373
dTop = s.readInt();
371-
dstack = new double[dTop];
372-
for (int i = 0; i < dTop; i++) {
373-
dstack[i] = s.readDouble();
374-
}
375-
376-
fTop = s.readInt();
377-
fstack = new float[fTop];
378-
for (int i = 0; i < fTop; i++) {
379-
fstack[i] = s.readFloat();
374+
dTop = s.readInt();
375+
lTop = s.readInt();
376+
iTop = s.readInt();
377+
int pTop = dTop + fTop + lTop + iTop;
378+
pstack = new long[pTop];
379+
for (int i = 0; i < pTop; i++) {
380+
pstack[i] = s.readLong();
380381
}
381-
382+
382383
oTop = s.readInt();
383384
ostack = new Object[oTop];
384385
for (int i = 0; i < oTop; i++) {

net.tascalate.javaflow.api/src/main/java/org/apache/commons/javaflow/core/StackRecorder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
public final class StackRecorder extends Stack {
3636

3737
private static final Log log = LogFactory.getLog(StackRecorder.class);
38-
private static final long serialVersionUID = 2L;
38+
private static final long serialVersionUID = 3L;
3939

4040
private static final ThreadLocal<StackRecorder> threadMap = new ThreadLocal<StackRecorder>();
4141

net.tascalate.javaflow.providers.asm3/src/main/java/org/apache/commons/javaflow/providers/asm3/ContinuableMethodVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public void visitCode() {
100100

101101
mv.visitVarInsn(ALOAD, stackRecorderVar);
102102
// PC: stackRecorder.popInt();
103-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Int", "()I");
103+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "popRet", "()I");
104104
mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels);
105105

106106
// switch cases
@@ -300,7 +300,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc)
300300
mv.visitInsn(ICONST_0 + currentIndex);
301301
else
302302
mv.visitIntInsn(SIPUSH, currentIndex);
303-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushInt", "(I)V");
303+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushRet", "(I)V");
304304

305305
if (currentFrame instanceof MonitoringFrame) {
306306
int[] monitoredLocals = ((MonitoringFrame) currentFrame).getMonitored();

net.tascalate.javaflow.providers.asm4/src/main/java/org/apache/commons/javaflow/providers/asm4/ContinuableMethodVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void visitCode() {
105105

106106
mv.visitVarInsn(ALOAD, stackRecorderVar);
107107
// PC: stackRecorder.popInt();
108-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Int", "()I");
108+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "popRet", "()I");
109109
mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels);
110110

111111
// switch cases
@@ -313,7 +313,7 @@ public void visitCall(int opcode, String desc) {
313313
mv.visitInsn(ICONST_0 + currentIndex);
314314
else
315315
mv.visitIntInsn(SIPUSH, currentIndex);
316-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushInt", "(I)V");
316+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushRet", "(I)V");
317317

318318
if (currentFrame instanceof MonitoringFrame) {
319319
int[] monitoredLocals = ((MonitoringFrame) currentFrame).getMonitored();

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/ContinuableMethodVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void visitCode() {
105105

106106
mv.visitVarInsn(ALOAD, stackRecorderVar);
107107
// PC: stackRecorder.popInt();
108-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Int", "()I", false);
108+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "popRet", "()I", false);
109109
mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels);
110110

111111
// switch cases
@@ -319,7 +319,7 @@ public void visitCall(int opcode, String desc) {
319319
mv.visitInsn(ICONST_0 + currentIndex);
320320
else
321321
mv.visitIntInsn(SIPUSH, currentIndex);
322-
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushInt", "(I)V", false);
322+
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushRet", "(I)V", false);
323323

324324
if (currentFrame instanceof MonitoringFrame) {
325325
int[] monitoredLocals = ((MonitoringFrame) currentFrame).getMonitored();

0 commit comments

Comments
 (0)