VariableTable changes toward removal of a separated NodeTransformer pass over the parser tree for variable initialization: the code to support a table of optimized variables for functions in the optimizer is moved to optimizer/OptFunctionNode and VariableTable holds only parameters/variables names now. It allowed to simplify VariableTable initialization in NodeTransformer.

This commit is contained in:
igor%mir2.org 2003-02-15 21:35:58 +00:00
Родитель 90c8869435
Коммит aab18156df
10 изменённых файлов: 196 добавлений и 206 удалений

Просмотреть файл

@ -43,7 +43,6 @@ public class FunctionNode extends Node {
public FunctionNode(String name, Node statements) {
super(TokenStream.FUNCTION, statements);
functionName = name;
itsVariableTable = new VariableTable();
}
public String getFunctionName() {
@ -54,6 +53,13 @@ public class FunctionNode extends Node {
return itsVariableTable;
}
public void setVariableTable(VariableTable variableTable) {
// Can do it only once
if (variableTable == null) Context.codeBug();
if (itsVariableTable != null) Context.codeBug();
itsVariableTable = variableTable;
}
public boolean requiresActivation() {
return itsNeedsActivation;
}
@ -97,6 +103,10 @@ public class FunctionNode extends Node {
itsFunctionType = functionType;
}
public int getParameterCount() {
return argNames.size();
}
protected VariableTable itsVariableTable;
protected boolean itsNeedsActivation;
protected boolean itsCheckThis;

Просмотреть файл

@ -230,8 +230,7 @@ public class Interpreter {
+ itsData.itsMaxTryDepth
+ itsData.itsMaxStack;
itsData.argNames = new String[itsVariableTable.size()];
itsVariableTable.getAllVariables(itsData.argNames);
itsData.argNames = itsVariableTable.getAllVariables();
itsData.argCount = itsVariableTable.getParameterCount();
}

Просмотреть файл

@ -64,8 +64,15 @@ public class NodeTransformer {
loops = new ObjArray();
loopEnds = new ObjArray();
inFunction = tree.getType() == TokenStream.FUNCTION;
VariableTable vars = new VariableTable();
if (!inFunction) {
addVariables(tree, getVariableTable(tree));
addVariables(tree, vars);
tree.putProp(Node.VARS_PROP, vars);
} else {
FunctionNode fnNode = (FunctionNode)tree;
addParameters(fnNode, vars);
addVariables(tree, vars);
fnNode.setVariableTable(vars);
}
irFactory = createIRFactory(ts, scope);
@ -82,11 +89,6 @@ public class NodeTransformer {
case TokenStream.FUNCTION:
if (node == tree) {
// Add the variables to variable table, the
// parameters were added earlier.
VariableTable vars = getVariableTable(tree);
addVariables(tree, vars);
// Add return to end if needed.
Node stmts = node.getLastChild();
Node lastStmt = stmts.getLastChild();
@ -109,7 +111,6 @@ public class NodeTransformer {
// see 10.1.6 Activation Object
fnNode.setCheckThis(true);
}
addParameters(fnNode);
NodeTransformer inner = newInstance();
fnNode = (FunctionNode)
inner.transform(fnNode, tree, ts, scope);
@ -435,7 +436,6 @@ public class NodeTransformer {
// use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true);
}
VariableTable vars = getVariableTable(tree);
if (vars.hasVariable(name)) {
if (type == TokenStream.SETNAME) {
node.setType(TokenStream.SETVAR);
@ -477,7 +477,6 @@ public class NodeTransformer {
// Use of "arguments" requires an activation object.
((FunctionNode) tree).setRequiresActivation(true);
}
VariableTable vars = getVariableTable(tree);
if (vars.hasVariable(name)) {
node.setType(TokenStream.GETVAR);
}
@ -520,7 +519,7 @@ public class NodeTransformer {
{
String name = cursor.getString();
if (fNames == null || !fNames.has(name))
vars.addLocal(name, createVariableObject(name, false));
vars.addLocal(name);
}
}
if (inFunction) {
@ -534,7 +533,7 @@ public class NodeTransformer {
// ECMA Ch. 13. We add code to the beginning of the function
// to initialize a local variable of the function's name
// to the function value.
vars.addLocal(name, createVariableObject(name, false));
vars.addLocal(name);
Node block = tree.getLastChild();
Node setFn = new Node(TokenStream.POP,
new Node(TokenStream.SETVAR,
@ -546,22 +545,17 @@ public class NodeTransformer {
}
}
protected void addParameters(FunctionNode fnNode) {
VariableTable vars = fnNode.getVariableTable();
protected void addParameters(FunctionNode fnNode, VariableTable vars) {
if (vars.getParameterCount() == 0) {
ObjArray argNames = fnNode.argNames;
// Add parameters
for (int i = 0, N = argNames.size(); i != N; ++i) {
String arg = (String)argNames.get(i);
vars.addParameter(arg, createVariableObject(arg, true));
vars.addParameter(arg);
}
}
}
protected Object createVariableObject(String name, boolean isParameter) {
return name;
}
protected void visitNew(Node node, Node tree) {
}
@ -679,20 +673,12 @@ public class NodeTransformer {
return false;
}
protected VariableTable createVariableTable() {
return new VariableTable();
}
protected VariableTable getVariableTable(Node tree) {
if (inFunction) {
return ((FunctionNode)tree).getVariableTable();
} else {
return (VariableTable)(tree.getProp(Node.VARS_PROP));
}
VariableTable result = (VariableTable)(tree.getProp(Node.VARS_PROP));
if (result == null) {
result = createVariableTable();
tree.putProp(Node.VARS_PROP, result);
}
return result;
}
protected void reportMessage(Context cx, String msg, Node stmt,

Просмотреть файл

@ -48,31 +48,25 @@ public class VariableTable {
return varStart;
}
public Object getVariable(int index) {
return itsVariables.get(index);
public String getVariable(int index) {
return (String)itsVariables.get(index);
}
public boolean hasVariable(String name) {
return itsVariableNames.has(name);
}
public Object getVariable(String name) {
int vIndex = itsVariableNames.get(name, -1);
if (vIndex != -1)
return itsVariables.get(vIndex);
else
return null;
}
public int getOrdinal(String name) {
return itsVariableNames.get(name, -1);
}
public void getAllVariables(Object[] destination) {
itsVariables.toArray(destination);
public String[] getAllVariables() {
String[] array = new String[itsVariables.size()];
itsVariables.toArray(array);
return array;
}
public void addParameter(String pName, Object paramObj) {
public void addParameter(String pName) {
// Check addParameter is not called after addLocal
if (varStart != itsVariables.size()) Context.codeBug();
int pIndex = itsVariableNames.get(pName, -1);
@ -81,18 +75,18 @@ public class VariableTable {
Context.reportWarning(message, null, 0, null, 0);
}
int index = varStart++;
itsVariables.add(paramObj);
itsVariables.add(pName);
itsVariableNames.put(pName, index);
}
public void addLocal(String vName, Object varObj) {
public void addLocal(String vName) {
int vIndex = itsVariableNames.get(vName, -1);
if (vIndex != -1) {
// There's already a variable or parameter with this name.
return;
}
int index = itsVariables.size();
itsVariables.add(varObj);
itsVariables.add(vName);
itsVariableNames.put(vName, index);
}

Просмотреть файл

@ -193,14 +193,14 @@ public class Block {
*/
void lookForVariablesAndCalls(Node n, boolean liveSet[],
VariableTable theVariables)
OptFunctionNode fn)
{
switch (n.getType()) {
case TokenStream.SETVAR :
{
Node lhs = n.getFirstChild();
Node rhs = lhs.getNext();
lookForVariablesAndCalls(rhs, liveSet, theVariables);
lookForVariablesAndCalls(rhs, liveSet, fn);
Object theVarProp = n.getProp(Node.VARIABLE_PROP);
if (theVarProp != null) {
int theVarIndex = ((OptLocalVariable)theVarProp).getIndex();
@ -211,12 +211,12 @@ public class Block {
case TokenStream.CALL : {
Node child = n.getFirstChild();
while (child != null) {
lookForVariablesAndCalls(child, liveSet, theVariables);
lookForVariablesAndCalls(child, liveSet, fn);
child = child.getNext();
}
for (int i = 0; i < liveSet.length; i++) {
if (liveSet[i])
OptLocalVariable.get(theVariables, i).markLiveAcrossCall();
fn.getVar(i).markLiveAcrossCall();
}
}
break;
@ -234,29 +234,29 @@ public class Block {
default :
Node child = n.getFirstChild();
while (child != null) {
lookForVariablesAndCalls(child, liveSet, theVariables);
lookForVariablesAndCalls(child, liveSet, fn);
child = child.getNext();
}
break;
}
}
void markAnyTypeVariables(VariableTable theVariables)
void markAnyTypeVariables(OptFunctionNode fn)
{
for (int i = 0; i < theVariables.size(); i++)
for (int i = 0; i < fn.getVarCount(); i++)
if (itsLiveOnEntrySet.test(i))
OptLocalVariable.get(theVariables, i).assignType(TypeEvent.AnyType);
fn.getVar(i).assignType(TypeEvent.AnyType);
}
void markVolatileVariables(VariableTable theVariables)
void markVolatileVariables(OptFunctionNode fn)
{
boolean liveSet[] = new boolean[theVariables.size()];
boolean liveSet[] = new boolean[fn.getVarCount()];
for (int i = 0; i < liveSet.length; i++)
liveSet[i] = itsLiveOnEntrySet.test(i);
for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
Node n = itsStatementNodes[i];
lookForVariablesAndCalls(n, liveSet, theVariables);
lookForVariablesAndCalls(n, liveSet, fn);
}
}
@ -327,9 +327,9 @@ public class Block {
Then walk the trees looking for defs/uses of variables
and build the def and useBeforeDef sets.
*/
public void initLiveOnEntrySets(VariableTable theVariables)
void initLiveOnEntrySets(OptFunctionNode fn)
{
int listLength = theVariables.size();
int listLength = fn.getVarCount();
Node lastUse[] = new Node[listLength];
itsUseBeforeDefSet = new DataFlowBitSet(listLength);
itsNotDefSet = new DataFlowBitSet(listLength);
@ -630,7 +630,7 @@ public class Block {
}
}
public boolean doTypeFlow()
boolean doTypeFlow()
{
boolean changed = false;
@ -643,15 +643,15 @@ public class Block {
return changed;
}
public boolean isLiveOnEntry(int index)
boolean isLiveOnEntry(int index)
{
return (itsLiveOnEntrySet != null) && (itsLiveOnEntrySet.test(index));
}
public void printLiveOnEntrySet(PrintWriter pw, VariableTable theVariables)
void printLiveOnEntrySet(PrintWriter pw, OptFunctionNode fn)
{
for (int i = 0; i < theVariables.size(); i++) {
String name = OptLocalVariable.get(theVariables, i).getName();
for (int i = 0; i < fn.getVarCount(); i++) {
String name = fn.getVar(i).getName();
if (itsUseBeforeDefSet.test(i))
pw.println(name + " is used before def'd");
if (itsNotDefSet.test(i))

Просмотреть файл

@ -115,10 +115,9 @@ public class Codegen extends Interpreter {
cursor = cursor.getNext())
{
if (cursor.getType() == TokenStream.FUNCTION) {
OptFunctionNode fnNode
= (OptFunctionNode)cursor.
getProp(Node.FUNCTION_PROP);
obj.put(fnNode.getFunctionName(), obj, fnNode);
FunctionNode fn
= (FunctionNode)cursor.getProp(Node.FUNCTION_PROP);
obj.put(fn.getFunctionName(), obj, fn);
}
}
if (superClass == null) {
@ -186,8 +185,7 @@ public class Codegen extends Interpreter {
throw new RuntimeException
("Unable to instantiate compiled class:"+ex.toString());
}
OptFunctionNode fnNode = (OptFunctionNode)tree;
OptRuntime.initFunction(f, fnNode.getFunctionType(), scope, cx);
OptRuntime.initFunction(f, fnCurrent.getFunctionType(), scope, cx);
return f;
} else {
NativeScript script;
@ -304,7 +302,7 @@ public class Codegen extends Interpreter {
return classFile.acquireLabel();
}
public void emitDirectConstructor(OptFunctionNode fnNode)
public void emitDirectConstructor()
{
/*
we generate ..
@ -322,11 +320,11 @@ public class Codegen extends Interpreter {
short flags = (short)(ClassFileWriter.ACC_PUBLIC
| ClassFileWriter.ACC_FINAL);
classFile.startMethod("constructDirect",
fnNode.getDirectCallParameterSignature()
+ "Ljava/lang/Object;",
flags);
fnCurrent.getDirectCallParameterSignature()
+ "Ljava/lang/Object;",
flags);
int argCount = fnNode.getVariableTable().getParameterCount();
int argCount = fnCurrent.getParameterCount();
int firstLocal = (4 + argCount * 3) + 1;
aload((short)0); // this
@ -350,7 +348,7 @@ public class Codegen extends Interpreter {
aload((short)(4 + argCount * 3));
addVirtualInvoke(this.name,
"callDirect",
fnNode.getDirectCallParameterSignature(),
fnCurrent.getDirectCallParameterSignature(),
"Ljava/lang/Object;");
astore((short)(firstLocal + 1));
@ -403,14 +401,14 @@ public class Codegen extends Interpreter {
Node codegenBase;
if (inFunction) {
OptFunctionNode fnNode = (OptFunctionNode) tree;
inDirectCallFunction = fnNode.isTargetOfDirectCall();
vars = fnNode.getVariableTable();
this.name = fnNode.getClassName();
fnCurrent = (OptFunctionNode)tree;
inDirectCallFunction = fnCurrent.isTargetOfDirectCall();
vars = fnCurrent.getVariableTable();
this.name = fnCurrent.getClassName();
classFile = new ClassFileWriter(name, superClassName, itsSourceFile);
String name = fnNode.getFunctionName();
String name = fnCurrent.getFunctionName();
generateInit(cx, "<init>", tree, name);
if (fnNode.isTargetOfDirectCall()) {
if (fnCurrent.isTargetOfDirectCall()) {
classFile.startMethod("call",
"(Lorg/mozilla/javascript/Context;" +
"Lorg/mozilla/javascript/Scriptable;" +
@ -442,24 +440,24 @@ public class Codegen extends Interpreter {
addByteCode(ByteCode.ALOAD, 4);
addVirtualInvoke(this.name,
"callDirect",
fnNode.getDirectCallParameterSignature(),
fnCurrent.getDirectCallParameterSignature(),
"Ljava/lang/Object;");
addByteCode(ByteCode.ARETURN);
classFile.stopMethod((short)5, null);
// 1 for this, 1 for js this, 1 for args[]
emitDirectConstructor(fnNode);
emitDirectConstructor();
startNewMethod("callDirect",
fnNode.getDirectCallParameterSignature() +
fnCurrent.getDirectCallParameterSignature() +
"Ljava/lang/Object;",
1, false, true);
assignParameterJRegs(vars);
if (!fnNode.getParameterNumberContext()) {
assignParameterJRegs(fnCurrent);
if (!fnCurrent.getParameterNumberContext()) {
// make sure that all parameters are objects
itsForcedObjectParameters = true;
for (int i = 0; i < vars.getParameterCount(); i++) {
OptLocalVariable lVar = OptLocalVariable.get(vars, i);
for (int i = 0; i < fnCurrent.getParameterCount(); i++) {
OptLocalVariable lVar = fnCurrent.getVar(i);
aload(lVar.getJRegister());
classFile.add(ByteCode.GETSTATIC,
"java/lang/Void",
@ -532,15 +530,15 @@ public class Codegen extends Interpreter {
return name;
}
private static void assignParameterJRegs(VariableTable vars) {
private static void assignParameterJRegs(OptFunctionNode fnCurrent) {
// 0 is reserved for function Object 'this'
// 1 is reserved for context
// 2 is reserved for parentScope
// 3 is reserved for script 'this'
short jReg = 4;
int parameterCount = vars.getParameterCount();
int parameterCount = fnCurrent.getParameterCount();
for (int i = 0; i < parameterCount; i++) {
OptLocalVariable lVar = OptLocalVariable.get(vars, i);
OptLocalVariable lVar = fnCurrent.getVar(i);
lVar.assignJRegister(jReg);
jReg += 3; // 3 is 1 for Object parm and 2 for double parm
}
@ -1018,8 +1016,7 @@ public class Codegen extends Interpreter {
classFile.startMethod(methodName, methodDesc, (short) flags);
}
private void finishMethod(Context cx, VariableTable vars) {
OptLocalVariable[] array = OptLocalVariable.toArray(vars);
private void finishMethod(Context cx, OptLocalVariable[] array) {
classFile.stopMethod((short)(localsMax + 1), array);
contextLocal = -1;
}
@ -1155,7 +1152,7 @@ public class Codegen extends Interpreter {
for (int i = 0; i != N; i++) {
addByteCode(ByteCode.DUP);
push(i);
push(OptLocalVariable.get(vars, i).getName());
push(vars.getVariable(i));
addByteCode(ByteCode.AASTORE);
}
addByteCode(ByteCode.ALOAD_0);
@ -1195,10 +1192,9 @@ public class Codegen extends Interpreter {
if (tree instanceof OptFunctionNode) {
OptFunctionNode fnNode = (OptFunctionNode)tree;
if (fnNode.isTargetOfDirectCall()) {
if (fnCurrent.isTargetOfDirectCall()) {
setNonTrivialInit(methodName);
String className = fnNode.getClassName();
String className = fnCurrent.getClassName();
String fieldName = className.replace('.', '_');
String fieldType = 'L'+classFile.fullyQualifiedForm(className)
+';';
@ -1400,8 +1396,8 @@ public class Codegen extends Interpreter {
// REMIND - only need to initialize the vars that don't get a value
// before the next call and are used in the function
short firstUndefVar = -1;
for (int i = 0; i < vars.size(); i++) {
OptLocalVariable lVar = OptLocalVariable.get(vars, i);
for (int i = 0; i < fnCurrent.getVarCount(); i++) {
OptLocalVariable lVar = fnCurrent.getVar(i);
if (lVar.isNumber()) {
lVar.assignJRegister(getNewWordPairLocal());
push(0.0);
@ -1430,7 +1426,7 @@ public class Codegen extends Interpreter {
// Indicate that we should generate debug information for
// the variable table. (If we're generating debug info at
// all.)
debugVars = vars;
debugVars = fnCurrent.getVarsArray();
// Skip creating activation object.
return;
@ -1506,8 +1502,8 @@ public class Codegen extends Interpreter {
lv.assignJRegister(variableObjectLocal);
lv.setStartPC(classFile.getCurrentCodeOffset());
debugVars = new VariableTable();
debugVars.addLocal(debugVariableName, lv);
debugVars = new OptLocalVariable[1];
debugVars[0] = lv;
}
if (!inFunction) {
@ -2399,7 +2395,7 @@ public class Codegen extends Interpreter {
}
String name = node.getString();
if (hasVarsInRegs) {
OptLocalVariable lVar = OptLocalVariable.get(vars, name);
OptLocalVariable lVar = fnCurrent.getVar(name);
if (lVar != null) {
if (lVar.isNumber()) {
push("number");
@ -2437,7 +2433,7 @@ public class Codegen extends Interpreter {
String routine = (isInc) ? "postIncrement" : "postDecrement";
if (hasVarsInRegs && child.getType() == TokenStream.GETVAR) {
if (lVar == null)
lVar = OptLocalVariable.get(vars, child.getString());
lVar = fnCurrent.getVar(child.getString());
if (lVar.getJRegister() == -1)
lVar.assignJRegister(getNewWordLocal());
aload(lVar.getJRegister());
@ -3201,7 +3197,7 @@ public class Codegen extends Interpreter {
{
// TODO: Clean up use of lVar here and in set.
if (hasVarsInRegs && lVar == null)
lVar = OptLocalVariable.get(vars, name);
lVar = fnCurrent.getVar(name);
if (lVar != null) {
if (lVar.getJRegister() == -1)
if (lVar.isNumber())
@ -3272,7 +3268,7 @@ public class Codegen extends Interpreter {
OptLocalVariable lVar = (OptLocalVariable)(node.getProp(Node.VARIABLE_PROP));
// XXX is this right? If so, clean up.
if (hasVarsInRegs && lVar == null)
lVar = OptLocalVariable.get(vars, child.getString());
lVar = fnCurrent.getVar(child.getString());
if (lVar != null) {
generateCodeFromNode(child.getNext(), node, -1, -1);
if (lVar.getJRegister() == -1) {
@ -3768,13 +3764,14 @@ public class Codegen extends Interpreter {
private short itsZeroArgArray;
private short itsOneArgArray;
private OptFunctionNode fnCurrent;
private boolean itsUseDynamicScope;
private boolean hasVarsInRegs;
private boolean itsForcedObjectParameters;
private boolean trivialInit;
private short itsLocalAllocationBase;
private VariableTable vars;
private VariableTable debugVars;
private OptLocalVariable[] debugVars;
private int epilogueLabel;
private int optLevel;
}

Просмотреть файл

@ -39,15 +39,26 @@ package org.mozilla.javascript.optimizer;
import org.mozilla.javascript.*;
import java.util.*;
public class OptFunctionNode extends FunctionNode {
class OptFunctionNode extends FunctionNode {
public OptFunctionNode(String name, Node statements, String className)
OptFunctionNode(String name, Node statements, String className)
{
super(name, statements);
itsClassName = className;
}
public String getDirectCallParameterSignature() {
public void setVariableTable(VariableTable variableTable) {
super.setVariableTable(variableTable);
int N = variableTable.size();
int parameterCount = variableTable.getParameterCount();
optVars = new OptLocalVariable[N];
for (int i = 0; i != N; ++i) {
String name = variableTable.getVariable(i);
optVars[i] = new OptLocalVariable(name, i < parameterCount);
}
}
String getDirectCallParameterSignature() {
int pCount = itsVariableTable.getParameterCount();
switch (pCount) {
case 0: return ZERO_PARAM_SIG;
@ -64,15 +75,15 @@ public class OptFunctionNode extends FunctionNode {
return sb.toString();
}
public String getClassName() {
String getClassName() {
return itsClassName;
}
public boolean isTargetOfDirectCall() {
boolean isTargetOfDirectCall() {
return itsIsTargetOfDirectCall;
}
public void addDirectCallTarget(FunctionNode target) {
void addDirectCallTarget(FunctionNode target) {
if (itsDirectCallTargets == null)
itsDirectCallTargets = new ObjArray();
for (int i = 0; i < itsDirectCallTargets.size(); i++) // OPT !!
@ -81,40 +92,65 @@ public class OptFunctionNode extends FunctionNode {
itsDirectCallTargets.add(target);
}
public ObjArray getDirectCallTargets() {
ObjArray getDirectCallTargets() {
return itsDirectCallTargets;
}
public void setIsTargetOfDirectCall() {
void setIsTargetOfDirectCall() {
itsIsTargetOfDirectCall = true;
}
public void setParameterNumberContext(boolean b) {
void setParameterNumberContext(boolean b) {
itsParameterNumberContext = b;
}
public boolean getParameterNumberContext() {
boolean getParameterNumberContext() {
return itsParameterNumberContext;
}
public boolean containsCalls(int argCount) {
boolean containsCalls(int argCount) {
if ((argCount < itsContainsCallsCount.length) && (argCount >= 0))
return itsContainsCallsCount[argCount];
else
return itsContainsCalls;
}
public void setContainsCalls(int argCount) {
void setContainsCalls(int argCount) {
if (argCount < itsContainsCallsCount.length)
itsContainsCallsCount[argCount] = true;
itsContainsCalls = true;
}
public void incrementLocalCount() {
void incrementLocalCount() {
int localCount = getIntProp(Node.LOCALCOUNT_PROP, 0);
putIntProp(Node.LOCALCOUNT_PROP, localCount + 1);
}
int getVarCount() {
return optVars.length;
}
OptLocalVariable getVar(int index) {
return optVars[index];
}
OptLocalVariable getVar(String name) {
int index = itsVariableTable.getOrdinal(name);
if (index < 0) { return null; }
return optVars[index];
}
void establishVarsIndices() {
int N = optVars.length;
for (int i = 0; i != N; i++) {
optVars[i].setIndex(i);
}
}
OptLocalVariable[] getVarsArray() {
return optVars;
}
private static final String
BEFORE_DIRECT_SIG = "(Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
@ -128,6 +164,7 @@ public class OptFunctionNode extends FunctionNode {
TWO_PARAM_SIG = BEFORE_DIRECT_SIG+DIRECT_ARG_SIG+DIRECT_ARG_SIG
+AFTER_DIRECT_SIG;
private OptLocalVariable[] optVars;
private String itsClassName;
private boolean itsIsTargetOfDirectCall;
private boolean itsContainsCalls;

Просмотреть файл

@ -117,30 +117,6 @@ final class OptLocalVariable implements JavaVariable {
return itsTypeUnion.getEvent();
}
static OptLocalVariable get(VariableTable vars, int index) {
return (OptLocalVariable)(vars.getVariable(index));
}
static OptLocalVariable get(VariableTable vars, String name) {
return (OptLocalVariable)(vars.getVariable(name));
}
static void establishIndices(VariableTable vars) {
int N = vars.size();
for (int i = 0; i != N; i++) {
get(vars, i).itsIndex = i;
}
}
static OptLocalVariable[] toArray(VariableTable vars) {
OptLocalVariable[] array = null;
if (vars != null) {
array = new OptLocalVariable[vars.size()];
vars.getAllVariables(array);
}
return array;
}
private String itsName;
private boolean itsIsParameter;
private int itsIndex = -1;

Просмотреть файл

@ -100,10 +100,6 @@ class OptTransformer extends NodeTransformer {
return argCount;
}
protected Object createVariableObject(String name, boolean isParameter) {
return new OptLocalVariable(name, isParameter);
}
protected void visitNew(Node node, Node tree) {
detectDirectCall(node, tree);
super.visitNew(node, tree);
@ -129,20 +125,20 @@ class OptTransformer extends NodeTransformer {
* else
* ScriptRuntime.Call(fn, tmp, b, c)
*/
void markDirectCall(Node containingTree, Node callNode, int argCount,
String targetName)
private void markDirectCall(Node containingTree, Node callNode,
int argCount, String targetName)
{
OptFunctionNode theFunction
= (OptFunctionNode)theFnClassNameList.get(targetName);
if (theFunction != null) {
VariableTable varTable = theFunction.getVariableTable();
int N = theFunction.getParameterCount();
// Refuse to directCall any function with more
// than 32 parameters - prevent code explosion
// for wacky test cases
if (varTable.getParameterCount() > 32)
if (N > 32)
return;
if (argCount == varTable.getParameterCount()) {
if (argCount == N) {
callNode.putProp(Node.DIRECTCALL_PROP, theFunction);
((OptFunctionNode)containingTree)
.addDirectCallTarget(theFunction);
@ -180,7 +176,6 @@ class OptTransformer extends NodeTransformer {
*/
theFnClassNameList.put(name, fnNode);
}
addParameters(fnNode);
}
}
}

Просмотреть файл

@ -86,48 +86,44 @@ class Optimizer {
pw.println(Block.toString(theBlocks, theStatementNodes));
}
VariableTable vars = theFunction.getVariableTable();
if (vars != null) {
OptLocalVariable.establishIndices(vars);
for (int i = 0; i < theStatementNodes.length; i++)
replaceVariableAccess(theStatementNodes[i], vars);
theFunction.establishVarsIndices();
for (int i = 0; i < theStatementNodes.length; i++)
replaceVariableAccess(theStatementNodes[i], theFunction);
if(DO_CONSTANT_FOLDING){
foldConstants(theFunction, null);
}
if(DO_CONSTANT_FOLDING){
foldConstants(theFunction, null);
}
reachingDefDataFlow(vars, theBlocks);
typeFlow(vars, theBlocks);
findSinglyTypedVars(vars, theBlocks);
localCSE(theBlocks, theFunction);
if (!theFunction.requiresActivation()) {
/*
* Now that we know which local vars are in fact always
* Numbers, we re-write the tree to take advantage of
* that. Any arithmetic or assignment op involving just
* Number typed vars is marked so that the codegen will
* generate non-object code.
*/
parameterUsedInNumberContext = false;
for (int i = 0; i < theStatementNodes.length; i++) {
rewriteForNumberVariables(theStatementNodes[i]);
}
theFunction.setParameterNumberContext(parameterUsedInNumberContext);
//System.out.println("Function " + theFunction.getFunctionName() + " has parameters in number contexts : " + parameterUsedInNumberContext);
reachingDefDataFlow(theFunction, theBlocks);
typeFlow(theFunction, theBlocks);
findSinglyTypedVars(theFunction, theBlocks);
localCSE(theBlocks, theFunction);
if (!theFunction.requiresActivation()) {
/*
* Now that we know which local vars are in fact always
* Numbers, we re-write the tree to take advantage of
* that. Any arithmetic or assignment op involving just
* Number typed vars is marked so that the codegen will
* generate non-object code.
*/
parameterUsedInNumberContext = false;
for (int i = 0; i < theStatementNodes.length; i++) {
rewriteForNumberVariables(theStatementNodes[i]);
}
if (DEBUG_OPTIMIZER) {
for (int i = 0; i < theBlocks.length; i++) {
pw.println("For block " + theBlocks[i].getBlockID());
theBlocks[i].printLiveOnEntrySet(pw, vars);
}
int N = vars.size();
System.out.println("Variable Table, size = " + N);
for (int i = 0; i != N; i++) {
OptLocalVariable lVar = OptLocalVariable.get(vars, i);
pw.println(lVar.toString());
}
theFunction.setParameterNumberContext(parameterUsedInNumberContext);
//System.out.println("Function " + theFunction.getFunctionName() + " has parameters in number contexts : " + parameterUsedInNumberContext);
}
if (DEBUG_OPTIMIZER) {
for (int i = 0; i < theBlocks.length; i++) {
pw.println("For block " + theBlocks[i].getBlockID());
theBlocks[i].printLiveOnEntrySet(pw, theFunction);
}
int N = theFunction.getVarCount();
System.out.println("Variable Table, size = " + N);
for (int i = 0; i != N; i++) {
OptLocalVariable lVar = theFunction.getVar(i);
pw.println(lVar.toString());
}
}
if (DEBUG_OPTIMIZER) pw.close();
}
@ -140,7 +136,7 @@ class Optimizer {
}
private static void
findSinglyTypedVars(VariableTable theVariables, Block theBlocks[])
findSinglyTypedVars(OptFunctionNode fn, Block theBlocks[])
{
/*
discover the type events for each non-volatile variable (not live
@ -158,8 +154,8 @@ class Optimizer {
theBlocks[i].findDefs();
}
}
for (int i = 0; i < theVariables.size(); i++) {
OptLocalVariable lVar = OptLocalVariable.get(theVariables, i);
for (int i = 0; i < fn.getVarCount(); i++) {
OptLocalVariable lVar = fn.getVar(i);
if (!lVar.isParameter()) {
int theType = lVar.getTypeUnion();
if (theType == TypeEvent.NumberType) {
@ -201,7 +197,7 @@ class Optimizer {
}
private static void
typeFlow(VariableTable theVariables, Block theBlocks[])
typeFlow(OptFunctionNode fn, Block theBlocks[])
{
boolean visit[] = new boolean[theBlocks.length];
boolean doneOnce[] = new boolean[theBlocks.length];
@ -237,7 +233,7 @@ class Optimizer {
}
private static void
reachingDefDataFlow(VariableTable theVariables, Block theBlocks[])
reachingDefDataFlow(OptFunctionNode fn, Block theBlocks[])
{
/*
initialize the liveOnEntry and liveOnExit sets, then discover the variables
@ -245,7 +241,7 @@ class Optimizer {
(hence liveOnEntry)
*/
for (int i = 0; i < theBlocks.length; i++) {
theBlocks[i].initLiveOnEntrySets(theVariables);
theBlocks[i].initLiveOnEntrySets(fn);
}
/*
this visits every block starting at the last, re-adding the predecessors of
@ -294,10 +290,10 @@ class Optimizer {
*/
for (int i = 0; i < theBlocks.length; i++) {
theBlocks[i].markVolatileVariables(theVariables);
theBlocks[i].markVolatileVariables(fn);
}
theBlocks[0].markAnyTypeVariables(theVariables);
theBlocks[0].markAnyTypeVariables(fn);
}
/*
@ -989,23 +985,23 @@ class Optimizer {
}
private static void
replaceVariableAccess(Node n, VariableTable theVariables)
replaceVariableAccess(Node n, OptFunctionNode fn)
{
Node child = n.getFirstChild();
while (child != null) {
replaceVariableAccess(child, theVariables);
replaceVariableAccess(child, fn);
child = child.getNext();
}
int type = n.getType();
if (type == TokenStream.SETVAR) {
String name = n.getFirstChild().getString();
OptLocalVariable theVar = OptLocalVariable.get(theVariables, name);
OptLocalVariable theVar = fn.getVar(name);
if (theVar != null) {
n.putProp(Node.VARIABLE_PROP, theVar);
}
} else if (type == TokenStream.GETVAR) {
String name = n.getString();
OptLocalVariable theVar = OptLocalVariable.get(theVariables, name);
OptLocalVariable theVar = fn.getVar(name);
if (theVar != null) {
n.putProp(Node.VARIABLE_PROP, theVar);
}