Improve bytecode generation.
This commit is contained in:
@@ -48,6 +48,7 @@ public class Slots {
|
|||||||
private static final byte BIT_INVALID = 0x20; // slot becomes invlaid at this pc
|
private static final byte BIT_INVALID = 0x20; // slot becomes invlaid at this pc
|
||||||
private static final byte BIT_NIL = 0x40; // slot initialized to nil at this point
|
private static final byte BIT_NIL = 0x40; // slot initialized to nil at this point
|
||||||
|
|
||||||
|
final Prototype p;
|
||||||
final int n,m;
|
final int n,m;
|
||||||
public final byte[][] slots;
|
public final byte[][] slots;
|
||||||
public final boolean[] branchdest;
|
public final boolean[] branchdest;
|
||||||
@@ -68,22 +69,21 @@ public class Slots {
|
|||||||
return (slots[0][slot] & (BIT_INVALID)) == 0;
|
return (slots[0][slot] & (BIT_INVALID)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Slots(Prototype p) {
|
public Slots(Prototype prototype) {
|
||||||
|
p = prototype;
|
||||||
n = p.code.length;
|
n = p.code.length;
|
||||||
m = p.maxstacksize;
|
m = p.maxstacksize;
|
||||||
slots = new byte[n+1][m];
|
slots = new byte[n+1][m];
|
||||||
branchdest = new boolean[n+1];
|
branchdest = new boolean[n+1];
|
||||||
markassignments( p );
|
markassignments();
|
||||||
markuninitialized( p );
|
while ( propogatebranches() )
|
||||||
markupvalues( p );
|
;
|
||||||
markforloopupvalues( p );
|
markuninitialized();
|
||||||
|
markupvalues();
|
||||||
|
markforloopupvalues();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String tojstring() {
|
private void markassignments() {
|
||||||
return tojstring(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markassignments( Prototype p ) {
|
|
||||||
// mark initial assignments and references
|
// mark initial assignments and references
|
||||||
int j=0;
|
int j=0;
|
||||||
for ( ; j<p.numparams; j++ )
|
for ( ; j<p.numparams; j++ )
|
||||||
@@ -290,8 +290,45 @@ public class Slots {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markuninitialized(Prototype p) {
|
private boolean propogatebranches() {
|
||||||
|
boolean hadchanges = false;
|
||||||
|
for ( int pc=0; pc<n; pc++ ) {
|
||||||
|
int index = pc+1;
|
||||||
|
int ins = p.code[pc];
|
||||||
|
switch ( Lua.GET_OPCODE(ins) ) {
|
||||||
|
case Lua.OP_LOADBOOL:
|
||||||
|
case Lua.OP_EQ:
|
||||||
|
case Lua.OP_LT:
|
||||||
|
case Lua.OP_LE:
|
||||||
|
case Lua.OP_TEST:
|
||||||
|
case Lua.OP_TESTSET:
|
||||||
|
case Lua.OP_TFORLOOP:
|
||||||
|
hadchanges |= propogatebranch( index, index+2 );
|
||||||
|
break;
|
||||||
|
case Lua.OP_JMP:
|
||||||
|
case Lua.OP_FORPREP:
|
||||||
|
case Lua.OP_FORLOOP:
|
||||||
|
hadchanges |= propogatebranch( index, index+1+Lua.GETARG_sBx(ins) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hadchanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean propogatebranch(int src, int dest) {
|
||||||
|
boolean hadchanges = false;
|
||||||
|
byte[] s = slots[src];
|
||||||
|
byte[] d = slots[dest];
|
||||||
|
for ( int j=0; j<m; j++ ) {
|
||||||
|
byte bits = (byte) (s[j] & (BIT_ASSIGN | BIT_INVALID));
|
||||||
|
hadchanges |= ((d[j] & bits) & (BIT_ASSIGN | BIT_INVALID)) != bits;
|
||||||
|
d[j] |= bits;
|
||||||
|
}
|
||||||
|
return hadchanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markuninitialized() {
|
||||||
for ( int j=p.numparams; j<m; j++ )
|
for ( int j=p.numparams; j<m; j++ )
|
||||||
if ( ! isreferrededtofirst(j) )
|
if ( ! isreferrededtofirst(j) )
|
||||||
slots[0][j] |= BIT_INVALID;
|
slots[0][j] |= BIT_INVALID;
|
||||||
@@ -307,7 +344,7 @@ public class Slots {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupvalues( Prototype p ) {
|
private void markupvalues( ) {
|
||||||
for ( int pc=0; pc<n; ++pc ) {
|
for ( int pc=0; pc<n; ++pc ) {
|
||||||
if ( Lua.GET_OPCODE(p.code[pc]) == Lua.OP_CLOSURE ) {
|
if ( Lua.GET_OPCODE(p.code[pc]) == Lua.OP_CLOSURE ) {
|
||||||
int index = pc+1;
|
int index = pc+1;
|
||||||
@@ -322,7 +359,7 @@ public class Slots {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markforloopupvalues( Prototype p ) {
|
private void markforloopupvalues( ) {
|
||||||
for ( int pc1=n; --pc1>=0; ) {
|
for ( int pc1=n; --pc1>=0; ) {
|
||||||
int i = p.code[pc1];
|
int i = p.code[pc1];
|
||||||
if ( Lua.GET_OPCODE(i) == Lua.OP_TFORLOOP ) {
|
if ( Lua.GET_OPCODE(i) == Lua.OP_TFORLOOP ) {
|
||||||
@@ -357,8 +394,9 @@ public class Slots {
|
|||||||
|
|
||||||
private void promoteUpvalueBefore(int index, int j) {
|
private void promoteUpvalueBefore(int index, int j) {
|
||||||
int undef = prevUndefined(index,j);
|
int undef = prevUndefined(index,j);
|
||||||
int branch = firstBranchAfter(undef,index,j);
|
// int branch = firstBranchAfter(undef,index,j);
|
||||||
int assign = lastAssignBefore(branch,undef,j);
|
// int assign = lastAssignBefore(branch,undef,j);
|
||||||
|
int assign = firstAssignAfter(undef,index,j);
|
||||||
slots[assign][j] |= BIT_UP_CREATE;
|
slots[assign][j] |= BIT_UP_CREATE;
|
||||||
while ( index>assign)
|
while ( index>assign)
|
||||||
promoteUpvalue( slots[index--], j );
|
promoteUpvalue( slots[index--], j );
|
||||||
@@ -399,6 +437,13 @@ public class Slots {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int firstAssignAfter(int index, int limit, int j) {
|
||||||
|
for ( int i=index; ++i<limit; )
|
||||||
|
if ( (slots[i][j] & (BIT_ASSIGN | BIT_NIL)) != 0 )
|
||||||
|
return i;
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
private int nextUndefined(int index, int j) {
|
private int nextUndefined(int index, int j) {
|
||||||
while ( index<slots.length && ((slots[index][j] & BIT_INVALID) == 0) )
|
while ( index<slots.length && ((slots[index][j] & BIT_INVALID) == 0) )
|
||||||
++index;
|
++index;
|
||||||
@@ -414,13 +459,6 @@ public class Slots {
|
|||||||
|
|
||||||
// ------------- pretty-print slot info --------------
|
// ------------- pretty-print slot info --------------
|
||||||
|
|
||||||
public static void printSlots(Prototype p) {
|
|
||||||
Slots s = new Slots(p);
|
|
||||||
System.out.println("slots for "+p.source+":\n"+s.tojstring(p) );
|
|
||||||
for ( int i=0; i<p.p.length; i++ )
|
|
||||||
printSlots(p.p[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] toStrings() {
|
String[] toStrings() {
|
||||||
int n = slots.length;
|
int n = slots.length;
|
||||||
int m = slots[0].length;
|
int m = slots[0].length;
|
||||||
@@ -450,7 +488,7 @@ public class Slots {
|
|||||||
return strs;
|
return strs;
|
||||||
}
|
}
|
||||||
|
|
||||||
String tojstring(Prototype p) {
|
public String toString() {
|
||||||
String[] s = toStrings();
|
String[] s = toStrings();
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
PrintStream ps = new PrintStream( baos );
|
PrintStream ps = new PrintStream( baos );
|
||||||
|
|||||||
Reference in New Issue
Block a user