1. In that patch I forgot to remove "import org.mozilla.classfile.*" and
simply catch Exception in newInvokerMaster which is not a good practice.
The attached patch FunctionObject_patch fixes that and removes other
unused imports.
2. In org.mozilla.classfile.DefiningClassLoader defineClass method first
tries to call via ClassManager the defineClass method in a class loader
that loaded DefiningClassLoader itself. But this would define new
classes in that class loader so they would not be subject of the garbage
collection until a classloader that loads DefiningClassLoader would go
away even if a DefiningClassLoader instance is gone. The
DefiningClassLoader_patch removes that and simply calls super.defineClass.
The patch also change the order of class search in loadClass so the
loader first looks for a class among its defined classes and only after
that in parent loaders.
Regards, Igor
> Igor Bukanov wrote:
>
>
>>Norris Boyd wrote:
>>
>>
>>>The intention was to keep classfile and JavaAdapter optional. Those
>>>dependencies crept in. We can use Invoker optionally--perhaps I should do
>>>some performance numbers to see if it's worth it.
>>>
>>I implemented that patch, it splits Invoker.java into Invoker.java and
>>its implementation in optimizer/InvokerImpl.java The reason to put it
>>into optimizer package is that Invoker is very similar in spirit to
>>NativeScript: it generates classes to speed up access and in this way
>>there is no need to have separated option not to use: one can simply
>>remove optimizer all together.
>>
>
> Yes, that sounds great.
>
>
>>
>>I noticed during implementation that JavaAdapter.DefiningClassLoader and
>>optimizer/JavaScriptClassLoader contains the same code, so maybe they
>>can be moved to org.mozilla.classfile package under one name?
>>
>
> Yes, that sounds like a good change too. Thanks for noticing that.
The update is pretty messy: it touches FunctionObject which I changed to
remove the special treatment of NativeWith in the previous patch, and it
also add/removes files.
Here is a description:
DefiningClassLoader.java should go to org/mozilla/classfile. It is the
same code that was in omj/optimizer/JavaScriptClassLoader.java with
class rename and adding public attribute and correspondingly
omj.optimizer/JavaScriptClassLoader.java should be removed. I guess it
would be nice to preserve logs/history in CVS during the move.
InvokerImpl.java should go to omj/optimizer. It is mostly what
omj.Invoker was.
invoker_changes_patch was generated via
cvs diff -u Invoker.java JavaAdapter.java optimizer/Codegen.java
and contains changes against the current CVS
FunctionObject_invoker_patch was generated via
diff -u ../../mozilla.1/javascript/FunctionObject.java FunctionObject.java
and contains changes against that With patch.
Igor
constructor, removes the special treatment of the With object from
IdScriptable and FunctionObject, adds to IdFunction the
initAsConstructor method similar in spirit to
FunctionObject.addAsConstructor (it is called now from IdScriptable and
NativeWith) and replaces in Context.java lazy initialization of
NativeWith by direct call of NativeWith.scopeInit.
The attached patch moves the IdFunction.Master interface to the
separated file IdFunctionMaster and eliminates getParentScope from the
interface: it is simpler to set scope explicitly.
The patch assumes the changes in IdFunction.java from the previous patch
and were produced via:
diff -uP javascript.2000-05-10 javascript
Regards, Igor
The attached patch allows subclasses of IdScriptable to override
hasIdValur/deleteIdValue and uses lazy initialization for idMapData
array to avoid its creation when an IdScriptable descendant does not
have any functions. The patch also touches NativeMath.java to replace in
its scopeInit method
super.scopeInit(cx, scope, sealed);
by
activateIdMap(cx, sealed);
This is the only reason NativeMath needs to call
IdScriptable.scopeInit() which is intended for creation
constructor/prototype pair.
Regards, Igor
Rhino: optimization for NativeFunction.java
Date:
Mon, 07 May 2001 14:19:59 +0200
From:
Igor Bukanov <igor.bukanov@windriver.com>
Organization:
Wind River
To:
Norris Boyd <nboyd@atg.com>
Hi, Norris!
This is the first of 3 patches that are completly independent from each
other.
Currently in NativeFunction its name stored as the first element in the
names array. But this lead to creation of a single element array for
each FunctionObject and for each script function that does not have
arguments or variables. The attached patch splits NativeFunction names
into simple functionName and argNames arrays and adjust code elsewhere
accordingly. This patch can increase memory footprint for anonymous
script functions without arguments because it adds additional field to
each NativeFunction, but I do not think this is a case to worry about.
Regards, Igor
Date: Mon, 07 May 2001 14:25:34 +0200
From: Igor Bukanov <igor.bukanov@windriver.com>
Organization: Wind River
To: Norris Boyd <nboyd@atg.com>
The current code that implements execMethod/methodArity for IdFunction
support returns an arbitrary value for id that is not known. This is not
very good behavior because it may hide bugs in the id support and it
also does not allow to distinguish ids that are used for function from
ids used for properties like String.length.
To fix this I changed semantic of the methodArity method to return -1
for an unknown/non-method id and added code to throw an exception for
bad ids. This change requires to adjust all NativeSomething objects that
use IdScriptabl and after a release all such interface changes would be
no go, but is not a release yet, right?
I also eliminated the "IdFunction f" argument from
IdFunction.Master.methodArity and the tagId field from IdFunction. When
I wrote the initial code for IdFunction.java, I added that just to be
able to use same id number in a class that implements IdFunction.Master
and its descendants via checking idTag. But that does not work in
general because IdScriptable can use id for non-function fields as well
so to avoid id clashes another way should be used. For example, if
someone would like to extend NativeMath to support more functionality,
he can use:
class Math2: extends NativeMath {
private static idBase;
{
if (idBase == 0) idBase = super.getMaximumId();
}
public int methodArity(int methodId) {
switch (methodId - idBase) {
case Id_foo: return 2;
case Id_bar: return 3;
}
return super.methodArity(methodId);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
{
switch (methodId - idBase) {
case Id_foo: return ...;
case Id_bar: return ...;
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
}
protected int getMaximumId() { return idBase + MAX_ID; }
protected String getIdName(int id) {
switch (id - idBase) {
case Id_foo: return "for";
case Id_bar: return "bar";
}
return super.getIdName(id);
}
...
private static final int
Id_foo = 1,
Id_bar = 2,
MAX_ID = 2;
etc.
Note that a simpler solution to make MAX_ID field public in NativeMath
and write in Math2:
private static final int
Id_foo = NativeMath.MAX_ID + 1,
Id_bar = NativeMath.MAX_ID + 2,
MAX_ID = NativeMath.MAX_ID + 2;
does not work because in this way adding any new id to NativeMath would
break binary compatibility with Math2.
Rhino: fix for race conditions in listeners code in Context.java
Date:
Mon, 07 May 2001 14:22:57 +0200
From:
Igor Bukanov <igor.bukanov@windriver.com>
Organization:
Wind River
To:
Norris Boyd <nboyd@atg.com>
The current code for listeners and contextListeners in Context.java is
not race condition free. If contextListeners Vector would be modified
during context event firing loops, the code can produce
index-out-of-bounds exception. The problem with listeners array is more
subbtle and comes from the fact that ListenerCollection.java uses code like:
for(Enumeration enum = getAllListeners();enum.hasMoreElements();) {
Object listener = enum.nextElement();
if(iface.isInstance(listener)) {
array.addElement(listener);
}
}
where getAllListeners() uses Vector.elements to get element enumeration.
But to work with such enumeration in a thread safe way, one has to
synchronized against Vector, otherwise between enum.hasMoreElements()
and enum.nextElement() the last element can be removed.
Initially I thought to fix ListenerCollection and use it for
contextListeners as well, but then I realized that in its current form
ListenerCollection is very inefficient (it produces too many objects
just to get simple array to fire events), so I wrote ListenerArray.java
and use it in Context.java. It makes life simpler and shrinks code as well.
js_SetProtoOrParent should always have used a condvar in addition to a lock.
- Fix bug 79129, assert-botch in js_AllocSlot (r/sr=jband, sr=shaver)
JS_INITIAL_NSLOTS is the minimum number of slots, js_FreeSlot guarantees it.