replace static fields to hold targets of direct call optimization by an instance fields in the class representing the main script object.
This commit is contained in:
igor%mir2.org 2003-03-16 13:53:41 +00:00
parent 85e644cc05
commit 254d313fa4
3 changed files with 102 additions and 29 deletions

View File

@ -56,12 +56,14 @@ public class Codegen extends Interpreter {
public Codegen()
{
mainCodegen = this;
isMainCodegen = true;
}
private Codegen(Codegen mainCodegen)
{
if (mainCodegen == null) Context.codeBug();
this.mainCodegen = mainCodegen;
isMainCodegen = false;
}
public IRFactory createIRFactory(Context cx, TokenStream ts)
@ -110,7 +112,13 @@ public class Codegen extends Interpreter {
}
}
(new OptTransformer(irFactory, possibleDirectCalls)).transform(tree);
if (possibleDirectCalls != null) {
directCallTargets = new ObjArray();
}
OptTransformer ot = new OptTransformer(irFactory, possibleDirectCalls,
directCallTargets);
ot.transform(tree);
if (optLevel > 0) {
(new Optimizer(irFactory)).optimize(tree, optLevel);
@ -280,6 +288,7 @@ public class Codegen extends Interpreter {
generatedClassName = getScriptClassName(null, isPrimary);
superClassName = SCRIPT_SUPER_CLASS_NAME;
}
generatedClassSignature = classNameToSignature(generatedClassName);
itsUseDynamicScope = cx.hasCompileFunctionsWithDynamicScope();
@ -305,7 +314,7 @@ public class Codegen extends Interpreter {
Node codegenBase;
if (inFunction) {
generateInit(cx, superClassName);
if (fnCurrent.isTargetOfDirectCall()) {
if (inDirectCallFunction) {
classFile.startMethod("call",
"(Lorg/mozilla/javascript/Context;" +
"Lorg/mozilla/javascript/Scriptable;" +
@ -407,6 +416,16 @@ public class Codegen extends Interpreter {
emitConstantDudeInitializers();
if (isMainCodegen && mainCodegen.directCallTargets != null) {
int N = mainCodegen.directCallTargets.size();
for (int i = 0; i != N; ++i) {
OptFunctionNode fn = (OptFunctionNode)directCallTargets.get(i);
classFile.addField(getDirectTargetFieldName(i),
classNameToSignature(fn.getClassName()),
(short)0);
}
}
byte[] bytes = classFile.toByteArray();
names.add(generatedClassName);
@ -688,19 +707,16 @@ public class Codegen extends Interpreter {
}
}
if (inFunction) {
if (fnCurrent.isTargetOfDirectCall()) {
String className = fnCurrent.getClassName();
String fieldName = className.replace('.', '_');
String fieldType = 'L'+classFile.fullyQualifiedForm(className)
+';';
classFile.addField(fieldName, fieldType,
(short)(ClassFileWriter.ACC_PUBLIC
| ClassFileWriter.ACC_STATIC));
classFile.addField(MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature,
(short)0);
// For top level script or function init scriptMaster to self
if (isMainCodegen) {
addByteCode(ByteCode.ALOAD_0);
classFile.add(ByteCode.PUTSTATIC, className,
fieldName, fieldType);
}
addByteCode(ByteCode.DUP);
classFile.add(ByteCode.PUTFIELD, generatedClassName,
MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature);
}
addByteCode(ByteCode.RETURN);
@ -1470,6 +1486,29 @@ public class Codegen extends Interpreter {
+"Lorg/mozilla/javascript/Context;)",
"V");
// Init mainScript field;
addByteCode(ByteCode.DUP);
addByteCode(ByteCode.ALOAD_0);
classFile.add(ByteCode.GETFIELD, generatedClassName,
MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature);
classFile.add(ByteCode.PUTFIELD, fnClassName,
MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature);
int directTargetIndex = fn.getDirectTargetIndex();
if (directTargetIndex >= 0) {
addByteCode(ByteCode.DUP);
addByteCode(ByteCode.ALOAD_0);
classFile.add(ByteCode.GETFIELD, generatedClassName,
MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature);
addByteCode(ByteCode.SWAP);
classFile.add(ByteCode.PUTFIELD, mainCodegen.generatedClassName,
getDirectTargetFieldName(directTargetIndex),
classNameToSignature(fn.getClassName()));
}
// Dup function reference for function expressions to have it
// on top of the stack when initFunction returns
if (functionType != FunctionNode.FUNCTION_STATEMENT) {
@ -1625,18 +1664,21 @@ public class Codegen extends Interpreter {
*/
Node chelsea = child; // remember the first child for later
OptFunctionNode target = (OptFunctionNode)node.getProp(Node.DIRECTCALL_PROP);
OptFunctionNode
target = (OptFunctionNode)node.getProp(Node.DIRECTCALL_PROP);
if (target != null) {
generateCodeFromNode(child, node, -1, -1);
int regularCall = acquireLabel();
String className = classFile.fullyQualifiedForm(target.getClassName());
String fieldName = className.replace('/', '_');
int directTargetIndex = target.getDirectTargetIndex();
addByteCode(ByteCode.ALOAD_0);
classFile.add(ByteCode.GETFIELD, generatedClassName,
MAIN_SCRIPT_FIELD,
mainCodegen.generatedClassSignature);
classFile.add(ByteCode.GETFIELD, mainCodegen.generatedClassName,
getDirectTargetFieldName(directTargetIndex),
classNameToSignature(target.getClassName()));
classFile.add(ByteCode.GETSTATIC,
classFile.fullyQualifiedForm(className),
fieldName,
"L" + className + ";");
short stackHeight = classFile.getStackTop();
addByteCode(ByteCode.DUP2);
@ -3782,11 +3824,21 @@ public class Codegen extends Interpreter {
"instance", "Lorg/mozilla/javascript/Scriptable;");
}
private static String classNameToSignature(String className)
{
return 'L'+className.replace('.', '/')+';';
}
private static String getRegexpFieldName(int i)
{
return "_re" + i;
}
private static String getDirectTargetFieldName(int i)
{
return "_dt" + i;
}
private static void badTree()
{
throw new RuntimeException("Bad tree in codegen");
@ -3797,10 +3849,16 @@ public class Codegen extends Interpreter {
private static final String SCRIPT_SUPER_CLASS_NAME =
"org.mozilla.javascript.NativeScript";
private static final String MAIN_SCRIPT_FIELD = "masterScript";
private Codegen mainCodegen;
private boolean isMainCodegen;
private OptClassNameHelper nameHelper;
private ObjToIntMap classNames;
private ObjArray directCallTargets;
private String generatedClassName;
private String generatedClassSignature;
boolean inFunction;
boolean inDirectCallFunction;
private ClassFileWriter classFile;

View File

@ -79,11 +79,18 @@ class OptFunctionNode extends FunctionNode {
}
boolean isTargetOfDirectCall() {
return itsIsTargetOfDirectCall;
return directTargetIndex >= 0;
}
void setIsTargetOfDirectCall() {
itsIsTargetOfDirectCall = true;
int getDirectTargetIndex() {
return directTargetIndex;
}
void setDirectTargetIndex(int directTargetIndex) {
// One time action
if (directTargetIndex < 0 || this.directTargetIndex >= 0)
Context.codeBug();
this.directTargetIndex = directTargetIndex;
}
void setParameterNumberContext(boolean b) {
@ -134,7 +141,7 @@ class OptFunctionNode extends FunctionNode {
private OptLocalVariable[] optVars;
private String itsClassName;
private boolean itsIsTargetOfDirectCall;
private int directTargetIndex = -1;
private boolean itsParameterNumberContext;
boolean itsContainsCalls0;
boolean itsContainsCalls1;

View File

@ -48,14 +48,17 @@ import java.util.Hashtable;
class OptTransformer extends NodeTransformer {
OptTransformer(IRFactory irFactory, Hashtable possibleDirectCalls)
OptTransformer(IRFactory irFactory, Hashtable possibleDirectCalls,
ObjArray directCallTargets)
{
super(irFactory);
this.possibleDirectCalls = possibleDirectCalls;
this.directCallTargets = directCallTargets;
}
protected NodeTransformer newInstance() {
return new OptTransformer(irFactory, possibleDirectCalls);
return new OptTransformer(irFactory, possibleDirectCalls,
directCallTargets);
}
protected void visitNew(Node node, ScriptOrFnNode tree) {
@ -113,7 +116,11 @@ class OptTransformer extends NodeTransformer {
// for wacky test cases
if (argCount <= 32) {
node.putProp(Node.DIRECTCALL_PROP, fn);
fn.setIsTargetOfDirectCall();
if (!fn.isTargetOfDirectCall()) {
int index = directCallTargets.size();
directCallTargets.add(fn);
fn.setDirectTargetIndex(index);
}
}
}
}
@ -122,4 +129,5 @@ class OptTransformer extends NodeTransformer {
}
private Hashtable possibleDirectCalls;
private ObjArray directCallTargets;
}