Reverting Ref to the original implementation which did not pass an additional

"Scriptable target" argument to Ref.(get|set|has|delete) methods. The idea was
to optimize away in many cases creation of Ref instances, but given that modern
JVM can GC short-lived objects efficiently it does not sound right to have code
complexity now in the hope of slightly more efficient implementation later.
This commit is contained in:
igor%mir2.org 2005-01-22 20:26:08 +00:00
Родитель 6d5f26df27
Коммит 31d9030dd0
9 изменённых файлов: 52 добавлений и 113 удалений

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

@ -2561,7 +2561,4 @@ public class Context
// It can be used to return the second Scriptable result from function
Scriptable scratchScriptable;
// It is used to return the target component for Ref instance
Scriptable scratchRefTarget;
}

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

@ -857,7 +857,6 @@ public class Interpreter
int type = node.getType();
Node child = node.getFirstChild();
int savedStackDepth = itsStackDepth;
int expectedStackDelta = 1;
switch (type) {
case Token.FUNCTION:
@ -902,9 +901,6 @@ public class Interpreter
break;
case Token.REF_CALL:
// account for the reference represented as pair (ref, target)
expectedStackDelta = 2;
// fallthrough
case Token.CALL:
case Token.NEW:
{
@ -1043,7 +1039,6 @@ public class Interpreter
case Token.DEL_REF:
visitExpression(child, 0);
addToken(type);
stackChange(-1);
break;
case Token.SETPROP:
@ -1090,16 +1085,15 @@ public class Interpreter
visitExpression(child, 0);
child = child.getNext();
if (type == Token.SET_REF_OP) {
addIcode(Icode_DUP2);
stackChange(2);
addIcode(Icode_DUP);
stackChange(1);
addToken(Token.GET_REF);
stackChange(-1);
// Compensate for the following USE_STACK
stackChange(-1);
}
visitExpression(child, 0);
addToken(Token.SET_REF);
stackChange(-2);
stackChange(-1);
break;
case Token.SETNAME:
@ -1225,8 +1219,6 @@ public class Interpreter
case Token.REF_SPECIAL:
visitExpression(child, 0);
addStringOp(type, (String)node.getProp(Node.NAME_PROP));
stackChange(1);
expectedStackDelta = 2;
break;
case Token.REF_MEMBER:
@ -1243,8 +1235,7 @@ public class Interpreter
child = child.getNext();
} while (child != null);
addIndexOp(type, memberTypeFlags);
stackChange(2 - childCount);
expectedStackDelta = 2;
stackChange(1 - childCount);
}
break;
@ -1271,7 +1262,7 @@ public class Interpreter
default:
throw badTree(node);
}
if (savedStackDepth + expectedStackDelta != itsStackDepth) {
if (savedStackDepth + 1 != itsStackDepth) {
Kit.codeBug();
}
}
@ -1359,7 +1350,6 @@ public class Interpreter
visitExpression(ref, 0);
addIcode(Icode_REF_INC_DEC);
addUint8(incrDecrMask);
stackChange(-1);
break;
}
default : {
@ -2763,35 +2753,26 @@ switch (op) {
continue Loop;
}
case Token.GET_REF : {
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refGet(ref, target, cx);
stack[stackTop] = ScriptRuntime.refGet(ref, cx);
continue Loop;
}
case Token.SET_REF : {
Object value = stack[stackTop];
if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
--stackTop;
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refSet(ref, target, value, cx);
stack[stackTop] = ScriptRuntime.refSet(ref, value, cx);
continue Loop;
}
case Token.DEL_REF : {
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refDel(ref, target, cx);
stack[stackTop] = ScriptRuntime.refDel(ref, cx);
continue Loop;
}
case Icode_REF_INC_DEC : {
Scriptable target = (Scriptable)stack[stackTop];
--stackTop;
Ref ref = (Ref)stack[stackTop];
stack[stackTop] = ScriptRuntime.refIncrDecr(ref, target, cx,
iCode[frame.pc]);
stack[stackTop] = ScriptRuntime.refIncrDecr(ref, cx, iCode[frame.pc]);
++frame.pc;
continue Loop;
}
@ -2902,8 +2883,6 @@ switch (op) {
indexReg);
stack[stackTop] = ScriptRuntime.callRef(fun, funThisObj, outArgs,
cx, calleeScope);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
@ -3195,8 +3174,6 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.specialRef(obj, stringReg, cx);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_MEMBER: {
@ -3207,8 +3184,6 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.memberRef(obj, elem, cx, indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NS_MEMBER: {
@ -3222,8 +3197,6 @@ switch (op) {
Object obj = stack[stackTop];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.memberRef(obj, ns, elem, cx, indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NAME: {
@ -3232,8 +3205,6 @@ switch (op) {
if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.nameRef(name, cx, frame.scope,
indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Token.REF_NS_NAME: {
@ -3245,8 +3216,6 @@ switch (op) {
if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.nameRef(ns, name, cx, frame.scope,
indexReg);
++stackTop;
stack[stackTop] = Ref.popTarget(cx);
continue Loop;
}
case Icode_SCOPE_LOAD :

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

@ -43,30 +43,16 @@ import java.io.Serializable;
*/
public abstract class Ref implements Serializable
{
public static Ref pushTarget(Context cx, Ref ref, Scriptable target)
{
if (cx.scratchRefTarget != null) throw new IllegalStateException();
cx.scratchRefTarget = target;
return ref;
}
public static Scriptable popTarget(Context cx)
{
Scriptable target = cx.scratchRefTarget;
cx.scratchRefTarget = null;
return target;
}
public boolean has(Context cx, Scriptable target)
public boolean has(Context cx)
{
return true;
}
public abstract Object get(Context cx, Scriptable target);
public abstract Object get(Context cx);
public abstract Object set(Context cx, Scriptable target, Object value);
public abstract Object set(Context cx, Object value);
public boolean delete(Context cx, Scriptable target)
public boolean delete(Context cx)
{
return false;
}

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

@ -1505,20 +1505,19 @@ public class ScriptRuntime {
return result;
}
public static Object refGet(Ref ref, Scriptable target, Context cx)
public static Object refGet(Ref ref, Context cx)
{
return ref.get(cx, target);
return ref.get(cx);
}
public static Object refSet(Ref ref, Scriptable target,
Object value, Context cx)
public static Object refSet(Ref ref, Object value, Context cx)
{
return ref.set(cx, target, value);
return ref.set(cx, value);
}
public static Object refDel(Ref ref, Scriptable target, Context cx)
public static Object refDel(Ref ref, Context cx)
{
return wrapBoolean(ref.delete(cx, target));
return wrapBoolean(ref.delete(cx));
}
static boolean isSpecialProperty(String s)
@ -2035,7 +2034,6 @@ public class ScriptRuntime {
BaseFunction bf = (BaseFunction)function;
Ref ref = bf.callRef(cx, scope, thisObj, args);
if (ref != null) {
storeScriptable(cx, thisObj);
return ref;
}
}
@ -2405,10 +2403,9 @@ public class ScriptRuntime {
}
}
public static Object refIncrDecr(Ref ref, Scriptable target,
Context cx, int incrDecrMask)
public static Object refIncrDecr(Ref ref, Context cx, int incrDecrMask)
{
Object value = ref.get(cx, target);
Object value = ref.get(cx);
boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
double number;
if (value instanceof Number) {
@ -2426,7 +2423,7 @@ public class ScriptRuntime {
--number;
}
Number result = wrapNumber(number);
ref.set(cx, target, result);
ref.set(cx, result);
if (post) {
return value;
} else {

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

@ -41,11 +41,13 @@ class SpecialRef extends Ref
private static final int SPECIAL_PROTO = 1;
private static final int SPECIAL_PARENT = 2;
private Scriptable target;
private int type;
private String name;
private SpecialRef(int type, String name)
private SpecialRef(Scriptable target, int type, String name)
{
this.target = target;
this.type = type;
this.name = name;
}
@ -71,10 +73,10 @@ class SpecialRef extends Ref
type = SPECIAL_NONE;
}
return Ref.pushTarget(cx, new SpecialRef(type, name), target);
return new SpecialRef(target, type, name);
}
public Object get(Context cx, Scriptable target)
public Object get(Context cx)
{
switch (type) {
case SPECIAL_NONE:
@ -88,7 +90,7 @@ class SpecialRef extends Ref
}
}
public Object set(Context cx, Scriptable target, Object value)
public Object set(Context cx, Object value)
{
switch (type) {
case SPECIAL_NONE:
@ -125,7 +127,7 @@ class SpecialRef extends Ref
}
}
public boolean has(Context cx, Scriptable target)
public boolean has(Context cx)
{
if (type == SPECIAL_NONE) {
return ScriptRuntime.hasObjectElem(target, name, cx);
@ -133,7 +135,7 @@ class SpecialRef extends Ref
return true;
}
public boolean delete(Context cx, Scriptable target)
public boolean delete(Context cx)
{
if (type == SPECIAL_NONE) {
return ScriptRuntime.deleteObjectElem(target, name, cx);

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

@ -1785,8 +1785,6 @@ class BodyCodegen
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+")Ljava/lang/Object;");
// Load reference target stored in cx by refCal
refTargetToStack();
break;
case Token.NUMBER:
@ -2101,12 +2099,11 @@ class BodyCodegen
break;
case Token.GET_REF:
generateExpression(child, node); // reference and target
generateExpression(child, node); // reference
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke(
"refGet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
break;
@ -2139,12 +2136,11 @@ class BodyCodegen
generateExpression(child, node);
child = child.getNext();
if (type == Token.SET_REF_OP) {
cfw.add(ByteCode.DUP2);
cfw.add(ByteCode.DUP);
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke(
"refGet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
}
@ -2153,7 +2149,6 @@ class BodyCodegen
addScriptRuntimeInvoke(
"refSet",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
@ -2165,7 +2160,6 @@ class BodyCodegen
cfw.addALoad(contextLocal);
addScriptRuntimeInvoke("refDel",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+")Ljava/lang/Object;");
break;
@ -2217,8 +2211,6 @@ class BodyCodegen
+"Ljava/lang/String;"
+"Lorg/mozilla/javascript/Context;"
+")Lorg/mozilla/javascript/Ref;");
// Load reference target stored in cx by specialRef
refTargetToStack();
}
break;
@ -2277,8 +2269,6 @@ class BodyCodegen
}
cfw.addPush(memberTypeFlags);
addScriptRuntimeInvoke(methodName, signature);
// Load reference target stored in cx by methodName
refTargetToStack();
}
break;
@ -3258,7 +3248,6 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
addScriptRuntimeInvoke(
"refIncrDecr",
"(Lorg/mozilla/javascript/Ref;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Lorg/mozilla/javascript/Context;"
+"I)Ljava/lang/Object;");
break;
@ -3932,16 +3921,6 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
}
}
private void refTargetToStack()
{
cfw.addALoad(contextLocal);
cfw.addInvoke(ByteCode.INVOKESTATIC,
"org.mozilla.javascript.Ref",
"popTarget",
"(Lorg/mozilla/javascript/Context;"
+")Lorg/mozilla/javascript/Scriptable;");
}
private void addScriptRuntimeInvoke(String methodName,
String methodSignature)
{

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

@ -678,7 +678,10 @@ public final class XMLLibImpl extends XMLLib
// xmlObj == null corresponds to undefined as the target of
// the reference
return Ref.pushTarget(cx, xmlName, xmlObj);
if (xmlObj != null) {
xmlName.initXMLObject(xmlObj);
}
return xmlName;
}
/**

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

@ -49,6 +49,7 @@ class XMLName extends Ref
private String localName;
private boolean isAttributeName;
private boolean isDescendants;
private XMLObjectImpl xmlObject;
private XMLName(String uri, String localName)
{
@ -66,6 +67,13 @@ class XMLName extends Ref
return new XMLName(uri, localName);
}
void initXMLObject(XMLObjectImpl xmlObject)
{
if (xmlObject == null) throw new IllegalArgumentException();
if (this.xmlObject != null) throw new IllegalStateException();
this.xmlObject = xmlObject;
}
String uri()
{
return uri;
@ -98,18 +106,16 @@ class XMLName extends Ref
isDescendants = true;
}
public boolean has(Context cx, Scriptable target)
public boolean has(Context cx)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
return false;
}
return xmlObject.hasXMLProperty(this);
}
public Object get(Context cx, Scriptable target)
public Object get(Context cx)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
throw ScriptRuntime.undefReadError(Undefined.instance,
toString());
@ -117,9 +123,8 @@ class XMLName extends Ref
return xmlObject.getXMLProperty(this);
}
public Object set(Context cx, Scriptable target, Object value)
public Object set(Context cx, Object value)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
throw ScriptRuntime.undefWriteError(Undefined.instance,
toString(),
@ -132,9 +137,8 @@ class XMLName extends Ref
return value;
}
public boolean delete(Context cx, Scriptable target)
public boolean delete(Context cx)
{
XMLObjectImpl xmlObject = (XMLObjectImpl)target;
if (xmlObject == null) {
return true;
}

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

@ -267,7 +267,8 @@ abstract class XMLObjectImpl extends XMLObject
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
return Ref.pushTarget(cx, xmlName, this);
xmlName.initXMLObject(this);
return xmlName;
}
/**
@ -285,7 +286,8 @@ abstract class XMLObjectImpl extends XMLObject
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
return Ref.pushTarget(cx, xmlName, this);
xmlName.initXMLObject(this);
return xmlName;
}
public NativeWith enterWith(Scriptable scope)