diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Block.java b/js/rhino/src/org/mozilla/javascript/optimizer/Block.java index fdf6744c145d..eb982e2aef2a 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Block.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Block.java @@ -125,7 +125,7 @@ class Block for (int i = paramCount; i != varCount; i++) { if (varTypes[i] == Optimizer.NumberType) { - fn.getVar(i).setIsNumber(); + fn.setIsNumberVar(i); } } diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index 1a1a41e70ed0..47cc728bf6f2 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -1116,9 +1116,16 @@ class BodyCodegen { isTopLevel = (scriptOrFn == codegen.scriptOrFnNodes[0]); + varRegisters = null; if (scriptOrFn.getType() == Token.FUNCTION) { fnCurrent = OptFunctionNode.get(scriptOrFn); hasVarsInRegs = !fnCurrent.fnode.requiresActivation(); + if (hasVarsInRegs) { + int n = fnCurrent.fnode.getParamAndVarCount(); + if (n != 0) { + varRegisters = new short[n]; + } + } inDirectCallFunction = fnCurrent.isTargetOfDirectCall(); if (inDirectCallFunction && !hasVarsInRegs) Codegen.badTree(); } else { @@ -1158,8 +1165,7 @@ class BodyCodegen // 3 is reserved for script 'this' if (firstFreeLocal != 4) Kit.codeBug(); for (int i = 0; i != directParameterCount; ++i) { - OptLocalVariable lVar = fnCurrent.getVar(i); - lVar.assignJRegister(firstFreeLocal); + varRegisters[i] = firstFreeLocal; // 3 is 1 for Object parm and 2 for double parm firstFreeLocal += 3; } @@ -1167,8 +1173,7 @@ class BodyCodegen // make sure that all parameters are objects itsForcedObjectParameters = true; for (int i = 0; i != directParameterCount; ++i) { - OptLocalVariable lVar = fnCurrent.getVar(i); - short reg = lVar.getJRegister(); + short reg = varRegisters[i]; cfw.addALoad(reg); cfw.add(ByteCode.GETSTATIC, "java/lang/Void", @@ -1239,7 +1244,6 @@ class BodyCodegen // before the next call and are used in the function short firstUndefVar = -1; for (int i = 0; i != varCount; ++i) { - OptLocalVariable lVar = fnCurrent.getVar(i); short reg = -1; if (i < paramCount) { if (!inDirectCallFunction) { @@ -1249,7 +1253,7 @@ class BodyCodegen cfw.add(ByteCode.AALOAD); cfw.addAStore(reg); } - } else if (lVar.isNumber()) { + } else if (fnCurrent.isNumberVar(i)) { reg = getNewWordPairLocal(); cfw.addPush(0.0); cfw.addDStore(reg); @@ -1264,16 +1268,17 @@ class BodyCodegen cfw.addAStore(reg); } if (reg >= 0) { - lVar.assignJRegister(reg); + varRegisters[i] = reg; } // Add debug table enry if we're generating debug info if (compilerEnv.isGenerateDebugInfo()) { String name = fnCurrent.fnode.getParamOrVarName(i); - String type = lVar.isNumber() ? "D" : "Ljava/lang/Object;"; + String type = fnCurrent.isNumberVar(i) + ? "D" : "Ljava/lang/Object;"; int startPC = cfw.getCurrentCodeOffset(); if (reg < 0) { - reg = lVar.getJRegister(); + reg = varRegisters[i]; } cfw.addVariableDescriptor(name, type, startPC, reg); } @@ -3025,12 +3030,12 @@ Else pass the JS object in the aReg and 0.0 in the dReg. { String name = node.getString(); if (hasVarsInRegs) { - OptLocalVariable lVar = fnCurrent.getVar(name); - if (lVar != null) { - if (lVar.isNumber()) { + int varIndex = fnCurrent.fnode.getParamOrVarIndex(name); + if (varIndex >= 0) { + if (fnCurrent.isNumberVar(varIndex)) { cfw.addPush("number"); - } else if (varIsDirectCallParameter(lVar)) { - int dcp_register = lVar.getJRegister(); + } else if (varIsDirectCallParameter(varIndex)) { + int dcp_register = varRegisters[varIndex]; cfw.addALoad(dcp_register); cfw.add(ByteCode.GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;"); @@ -3047,7 +3052,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. cfw.addPush("number"); cfw.markLabel(beyond); } else { - cfw.addALoad(lVar.getJRegister()); + cfw.addALoad(varRegisters[varIndex]); addScriptRuntimeInvoke("typeof", "(Ljava/lang/Object;" +")Ljava/lang/String;"); @@ -3071,8 +3076,8 @@ Else pass the JS object in the aReg and 0.0 in the dReg. case Token.GETVAR: if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); - OptLocalVariable lVar = fnCurrent.getVar(child); - short reg = lVar.getJRegister(); + int varIndex = fnCurrent.getVarIndex(child); + short reg = varRegisters[varIndex]; cfw.addDLoad(reg); if (post) { cfw.add(ByteCode.DUP2); @@ -3090,8 +3095,8 @@ Else pass the JS object in the aReg and 0.0 in the dReg. break; } else if (hasVarsInRegs) { boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); - OptLocalVariable lVar = fnCurrent.getVar(child); - short reg = lVar.getJRegister(); + int varIndex = fnCurrent.getVarIndex(child); + short reg = varRegisters[varIndex]; cfw.addALoad(reg); if (post) { cfw.add(ByteCode.DUP); @@ -3255,17 +3260,17 @@ Else pass the JS object in the aReg and 0.0 in the dReg. if (node.getType() == Token.GETVAR && inDirectCallFunction && !itsForcedObjectParameters) { - OptLocalVariable lVar = fnCurrent.getVar(node); - if (lVar.isParameter()) { - return lVar.getJRegister(); + int varIndex = fnCurrent.getVarIndex(node); + if (fnCurrent.isParameter(varIndex)) { + return varRegisters[varIndex]; } } return -1; } - private boolean varIsDirectCallParameter(OptLocalVariable lVar) + private boolean varIsDirectCallParameter(int varIndex) { - return lVar.isParameter() + return fnCurrent.isParameter(varIndex) && inDirectCallFunction && !itsForcedObjectParameters; } @@ -3527,9 +3532,9 @@ Else pass the JS object in the aReg and 0.0 in the dReg. private void visitGetVar(Node node) { if (hasVarsInRegs) { - OptLocalVariable lVar = fnCurrent.getVar(node); - short reg = lVar.getJRegister(); - if (varIsDirectCallParameter(lVar)) { + int varIndex = fnCurrent.getVarIndex(node); + short reg = varRegisters[varIndex]; + if (varIsDirectCallParameter(varIndex)) { // Remember that here the isNumber flag means that we // want to use the incoming parameter in a Number // context, so test the object type and convert the @@ -3539,7 +3544,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. } else { dcpLoadAsObject(reg); } - } else if (lVar.isNumber()) { + } else if (fnCurrent.isNumberVar(varIndex)) { cfw.addDLoad(reg); } else { cfw.addALoad(reg); @@ -3560,11 +3565,11 @@ Else pass the JS object in the aReg and 0.0 in the dReg. private void visitSetVar(Node node, Node child, boolean needValue) { if (hasVarsInRegs) { - OptLocalVariable lVar = fnCurrent.getVar(node); + int varIndex = fnCurrent.getVarIndex(node); generateExpression(child.getNext(), node); boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1); - short reg = lVar.getJRegister(); - if (varIsDirectCallParameter(lVar)) { + short reg = varRegisters[varIndex]; + if (varIsDirectCallParameter(varIndex)) { if (isNumber) { if (needValue) cfw.add(ByteCode.DUP2); cfw.addALoad(reg); @@ -3976,6 +3981,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. private int itsLineNumber; private boolean hasVarsInRegs; + private short[] varRegisters; private boolean inDirectCallFunction; private boolean itsForcedObjectParameters; private int enterAreaStartLabel; diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java b/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java index be47e3c9b58e..f7cb6670ea92 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java @@ -44,12 +44,6 @@ final class OptFunctionNode OptFunctionNode(FunctionNode fnode) { this.fnode = fnode; - int N = fnode.getParamAndVarCount(); - int parameterCount = fnode.getParamCount(); - optVars = new OptLocalVariable[N]; - for (int i = 0; i != N; ++i) { - optVars[i] = new OptLocalVariable(i < parameterCount); - } fnode.setCompilerData(this); } @@ -94,19 +88,33 @@ final class OptFunctionNode int getVarCount() { - return optVars.length; + return fnode.getParamAndVarCount(); } - OptLocalVariable getVar(int index) + boolean isParameter(int varIndex) { - return optVars[index]; + return varIndex < fnode.getParamCount(); } - OptLocalVariable getVar(String name) + boolean isNumberVar(int varIndex) { - int index = fnode.getParamOrVarIndex(name); - if (index < 0) { return null; } - return optVars[index]; + varIndex -= fnode.getParamCount(); + if (varIndex >= 0 && numberVarFlags != null) { + return numberVarFlags[varIndex]; + } + return false; + } + + void setIsNumberVar(int varIndex) + { + varIndex -= fnode.getParamCount(); + // Can only be used with non-parameters + if (varIndex < 0) Kit.codeBug(); + if (numberVarFlags == null) { + int size = fnode.getParamAndVarCount() - fnode.getParamCount(); + numberVarFlags = new boolean[size]; + } + numberVarFlags[varIndex] = true; } int getVarIndex(Node n) @@ -129,19 +137,8 @@ final class OptFunctionNode return index; } - OptLocalVariable getVar(Node n) - { - int index = getVarIndex(n); - return optVars[index]; - } - - OptLocalVariable[] getVarsArray() - { - return optVars; - } - FunctionNode fnode; - private OptLocalVariable[] optVars; + private boolean[] numberVarFlags; private int directTargetIndex = -1; private boolean itsParameterNumberContext; boolean itsContainsCalls0; diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/OptLocalVariable.java b/js/rhino/src/org/mozilla/javascript/optimizer/OptLocalVariable.java deleted file mode 100644 index b5fe32ea38ca..000000000000 --- a/js/rhino/src/org/mozilla/javascript/optimizer/OptLocalVariable.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Rhino code, released - * May 6, 1999. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1997-1999 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Norris Boyd - * Roger Lawrence - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU Public License (the "GPL"), in which case the - * provisions of the GPL are applicable instead of those above. - * If you wish to allow use of your version of this file only - * under the terms of the GPL and not to allow others to use your - * version of this file under the NPL, indicate your decision by - * deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete - * the provisions above, a recipient may use your version of this - * file under either the NPL or the GPL. - */ - - -package org.mozilla.javascript.optimizer; - -import org.mozilla.javascript.*; - -final class OptLocalVariable -{ - - OptLocalVariable(boolean isParameter) - { - itsIsParameter = isParameter; - } - - short getJRegister() { - return itsJRegister; - } - - void assignJRegister(short aJReg) { - itsJRegister = aJReg; - } - - void setIsNumber() { itsIsNumber = true; } - boolean isNumber() { return itsIsNumber; } - - boolean isParameter() { return itsIsParameter; } - - private boolean itsIsParameter; - private boolean itsIsNumber; - - private short itsJRegister = -1; // unassigned - -} diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java b/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java index 6dba9d4c4a83..654f859d4ea4 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java @@ -130,7 +130,8 @@ class Optimizer private void markDCPNumberContext(Node n) { if (inDirectCallFunction && n.getType() == Token.GETVAR) { - if (theFunction.getVar(n).isParameter()) { + int varIndex = theFunction.getVarIndex(n); + if (theFunction.isParameter(varIndex)) { parameterUsedInNumberContext = true; } } @@ -139,7 +140,8 @@ class Optimizer private boolean convertParameter(Node n) { if (inDirectCallFunction && n.getType() == Token.GETVAR) { - if (theFunction.getVar(n).isParameter()) { + int varIndex = theFunction.getVarIndex(n); + if (theFunction.isParameter(varIndex)) { n.removeProp(Node.ISNUMBER_PROP); return true; } @@ -161,13 +163,16 @@ class Optimizer n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH); return NumberType; - case Token.GETVAR : { - OptLocalVariable theVar = theFunction.getVar(n); - if (inDirectCallFunction && theVar.isParameter()) { + case Token.GETVAR : + { + int varIndex = theFunction.getVarIndex(n); + if (inDirectCallFunction + && theFunction.isParameter(varIndex)) + { n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH); return NumberType; } - else if (theVar.isNumber()) { + else if (theFunction.isNumberVar(varIndex)) { n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH); return NumberType; } @@ -178,8 +183,8 @@ class Optimizer case Token.DEC : { Node child = n.getFirstChild(); // will be a GETVAR or GETPROP if (child.getType() == Token.GETVAR) { - OptLocalVariable theVar = theFunction.getVar(child); - if (theVar.isNumber()) { + int varIndex = theFunction.getVarIndex(child); + if (theFunction.isNumberVar(varIndex)) { n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH); markDCPNumberContext(child); return NumberType; @@ -194,8 +199,10 @@ class Optimizer Node lChild = n.getFirstChild(); Node rChild = lChild.getNext(); int rType = rewriteForNumberVariables(rChild); - OptLocalVariable theVar = theFunction.getVar(n); - if (inDirectCallFunction && theVar.isParameter()) { + int varIndex = theFunction.getVarIndex(n); + if (inDirectCallFunction + && theFunction.isParameter(varIndex)) + { if (rType == NumberType) { if (!convertParameter(rChild)) { n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH); @@ -207,7 +214,7 @@ class Optimizer else return rType; } - else if (theVar.isNumber()) { + else if (theFunction.isNumberVar(varIndex)) { if (rType != NumberType) { n.removeChild(rChild); n.addChildToBack(new Node(TO_DOUBLE, rChild));