Interpreter optimization: use state.resultDbl to store double result accross calls of interpreted functions to avoid creation of Double instance.

git-svn-id: svn://10.0.0.236/trunk@161240 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
igor%mir2.org
2004-08-25 15:19:22 +00:00
parent 15c279140f
commit ce9cf612fa

View File

@@ -151,6 +151,84 @@ public class Interpreter
// Last icode
MIN_ICODE = -52;
// data for parsing
private CompilerEnvirons compilerEnv;
private boolean itsInFunctionFlag;
private InterpreterData itsData;
private ScriptOrFnNode scriptOrFn;
private int itsICodeTop;
private int itsStackDepth;
private int itsWithDepth;
private int itsLineNumber;
private int itsDoubleTableTop;
private ObjToIntMap itsStrings = new ObjToIntMap(20);
private int itsLocalTop;
private static final int MIN_LABEL_TABLE_SIZE = 32;
private static final int MIN_FIXUP_TABLE_SIZE = 40;
private int[] itsLabelTable;
private int itsLabelTableTop;
// itsFixupTable[i] = (label_index << 32) | fixup_site
private long[] itsFixupTable;
private int itsFixupTableTop;
private ObjArray itsLiteralIds = new ObjArray();
private int itsExceptionTableTop;
// 5 = space for try start/end, catch begin, finally begin and with depth
private static final int EXCEPTION_SLOT_SIZE = 6;
private static final int EXCEPTION_TRY_START_SLOT = 0;
private static final int EXCEPTION_TRY_END_SLOT = 1;
private static final int EXCEPTION_CATCH_SLOT = 2;
private static final int EXCEPTION_FINALLY_SLOT = 3;
private static final int EXCEPTION_WITH_DEPTH_SLOT = 4;
private static final int EXCEPTION_LOCAL_SLOT = 5;
private static final Object DBL_MRK = new Object();
private static class State
{
State callerState;
InterpretedFunction fnOrScript;
InterpreterData idata;
// Stack structure
// stack[0 <= i < localShift]: variables
// stack[localShift <= i <= emptyStackTop]: used for local temporaries
// stack[emptyStackTop < i < stack.length]: stack data
// sDbl[i]: if stack[i] is DBL_MRK, sDbl[i] holds the number value
Object[] stack;
double[] sDbl;
int localShift;
int emptyStackTop;
DebugFrame debuggerFrame;
boolean useActivation;
Scriptable thisObj;
Scriptable[] scriptRegExps;
State savedInterpreterLineCounting;
// The values that change during interpretation
Object result;
double resultDbl;
int pc;
int pcPrevBranch;
int pcSourceLineStart;
int withDepth;
Scriptable scope;
int savedStackTop;
int savedCallOp;
}
static {
// Checks for byte code consistencies, good compiler can eliminate them
@@ -1915,45 +1993,6 @@ public class Interpreter
parent.evalScriptFlag);
}
static class State
{
State callerState;
InterpretedFunction fnOrScript;
InterpreterData idata;
// Stack structure
// stack[0 <= i < localShift]: variables
// stack[localShift <= i <= emptyStackTop]: used for local temporaries
// stack[emptyStackTop < i < stack.length]: stack data
// sDbl[i]: if stack[i] is DBL_MRK, sDbl[i] holds the number value
Object[] stack;
double[] sDbl;
int localShift;
int emptyStackTop;
DebugFrame debuggerFrame;
boolean useActivation;
Scriptable thisObj;
Scriptable[] scriptRegExps;
State savedInterpreterLineCounting;
// The values that change during interpretation
Object result;
int pc;
int pcPrevBranch;
int pcSourceLineStart;
int withDepth;
Scriptable scope;
int savedStackTop;
int savedCallOp;
}
static Object interpret(InterpretedFunction ifun,
Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
@@ -1976,7 +2015,8 @@ public class Interpreter
initState(cx, scope, thisObj, args, null, 0, args.length,
ifun, state);
interpret(cx, state);
return state.result;
return (state.result != DBL_MRK)
? state.result : doubleWrap(state.resultDbl);
}
private static void interpret(Context cx, State state)
@@ -2118,7 +2158,7 @@ switch (op) {
continue Loop;
case Icode_POP_RESULT :
state.result = stack[stackTop];
if (state.result == DBL_MRK) state.result = doubleWrap(sDbl[stackTop]);
state.resultDbl = sDbl[stackTop];
stack[stackTop] = null;
--stackTop;
continue Loop;
@@ -2145,7 +2185,7 @@ switch (op) {
}
case Token.RETURN :
state.result = stack[stackTop];
if (state.result == DBL_MRK) state.result = doubleWrap(sDbl[stackTop]);
state.resultDbl = sDbl[stackTop];
--stackTop;
break Loop;
case Token.RETURN_RESULT :
@@ -3045,10 +3085,12 @@ switch (op) {
releaseState(cx, state, null);
if (state.callerState != null) {
Object calleeResult = state.result;
double calleeResultDbl = state.resultDbl;
state = state.callerState;
if (state.savedCallOp == Token.CALL) {
state.stack[state.savedStackTop] = calleeResult;
state.sDbl[state.savedStackTop] = calleeResultDbl;
} else if (state.savedCallOp == Token.NEW) {
// If construct returns scriptable,
// then it replaces on stack top saved original instance
@@ -3543,38 +3585,4 @@ switch (op) {
}
}
private CompilerEnvirons compilerEnv;
private boolean itsInFunctionFlag;
private InterpreterData itsData;
private ScriptOrFnNode scriptOrFn;
private int itsICodeTop;
private int itsStackDepth;
private int itsWithDepth;
private int itsLineNumber;
private int itsDoubleTableTop;
private ObjToIntMap itsStrings = new ObjToIntMap(20);
private int itsLocalTop;
private static final int MIN_LABEL_TABLE_SIZE = 32;
private static final int MIN_FIXUP_TABLE_SIZE = 40;
private int[] itsLabelTable;
private int itsLabelTableTop;
// itsFixupTable[i] = (label_index << 32) | fixup_site
private long[] itsFixupTable;
private int itsFixupTableTop;
private ObjArray itsLiteralIds = new ObjArray();
private int itsExceptionTableTop;
// 5 = space for try start/end, catch begin, finally begin and with depth
private static final int EXCEPTION_SLOT_SIZE = 6;
private static final int EXCEPTION_TRY_START_SLOT = 0;
private static final int EXCEPTION_TRY_END_SLOT = 1;
private static final int EXCEPTION_CATCH_SLOT = 2;
private static final int EXCEPTION_FINALLY_SLOT = 3;
private static final int EXCEPTION_WITH_DEPTH_SLOT = 4;
private static final int EXCEPTION_LOCAL_SLOT = 5;
private static final Object DBL_MRK = new Object();
}