mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
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:
parent
85e644cc05
commit
254d313fa4
@ -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));
|
||||
addByteCode(ByteCode.ALOAD_0);
|
||||
classFile.add(ByteCode.PUTSTATIC, className,
|
||||
fieldName, fieldType);
|
||||
}
|
||||
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);
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user