8020015: shared PropertyMaps should not be used without duplication
Reviewed-by: hannesw, attila
--- a/nashorn/buildtools/nasgen/build.xml Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/build.xml Mon Jul 08 16:33:50 2013 +0530
@@ -42,7 +42,8 @@
destdir="${build.classes.dir}"
classpath="${javac.classpath}"
debug="${javac.debug}"
- includeantruntime="false">
+ includeantruntime="false" fork="true">
+ <compilerarg value="-J-Djava.ext.dirs="/>
<compilerarg value="-Xlint:unchecked"/>
<compilerarg value="-Xlint:deprecation"/>
<compilerarg value="-XDignore.symbol.file"/>
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java Mon Jul 08 16:33:50 2013 +0530
@@ -37,14 +37,24 @@
import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_TYPE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC;
@@ -161,17 +171,30 @@
return new MethodGenerator(mv, access, name, desc);
}
- static void emitStaticInitPrefix(final MethodGenerator mi, final String className) {
+ static void emitStaticInitPrefix(final MethodGenerator mi, final String className, final int memberCount) {
mi.visitCode();
- mi.pushNull();
- mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
- mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC);
- // stack: PropertyMap
+ if (memberCount > 0) {
+ // new ArrayList(int)
+ mi.newObject(ARRAYLIST_TYPE);
+ mi.dup();
+ mi.push(memberCount);
+ mi.invokeSpecial(ARRAYLIST_TYPE, INIT, ARRAYLIST_INIT_DESC);
+ // stack: ArrayList
+ } else {
+ // java.util.Collections.EMPTY_LIST
+ mi.getStatic(COLLECTIONS_TYPE, COLLECTIONS_EMPTY_LIST, LIST_DESC);
+ // stack List
+ }
}
static void emitStaticInitSuffix(final MethodGenerator mi, final String className) {
- // stack: PropertyMap
- mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
+ // stack: Collection
+ // pmap = PropertyMap.newMap(Collection<Property>);
+ mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC);
+ // pmap.setIsShared();
+ mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_SETISSHARED, PROPERTYMAP_SETISSHARED_DESC);
+ // $nasgenmap$ = pmap;
+ mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
mi.returnVoid();
mi.computeMaxs();
mi.visitEnd();
@@ -235,9 +258,9 @@
}
static void addMapField(final ClassVisitor cv) {
- // add a MAP static field
+ // add a PropertyMap static field
final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL,
- MAP_FIELD_NAME, MAP_DESC, null, null);
+ PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC, null, null);
if (fv != null) {
fv.visitEnd();
}
@@ -278,7 +301,11 @@
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
final String propertyName = memInfo.getName();
- // stack: PropertyMap
+ // stack: Collection
+ // dup of Collection instance
+ mi.dup();
+
+ // property = AccessorProperty.create(key, flags, getter, setter);
mi.loadLiteral(propertyName);
// setup flags
mi.push(memInfo.getAttributes());
@@ -292,13 +319,21 @@
javaName = SETTER_PREFIX + memInfo.getJavaName();
mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo)));
}
- mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
- // stack: PropertyMap
+ mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
+ // boolean Collection.add(property)
+ mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC);
+ // pop return value of Collection.add
+ mi.pop();
+ // stack: Collection
}
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) {
final String propertyName = getter.getName();
- // stack: PropertyMap
+ // stack: Collection
+ // dup of Collection instance
+ mi.dup();
+
+ // property = AccessorProperty.create(key, flags, getter, setter);
mi.loadLiteral(propertyName);
// setup flags
mi.push(getter.getAttributes());
@@ -312,8 +347,12 @@
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
setter.getJavaName(), setter.getJavaDesc()));
}
- mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
- // stack: PropertyMap
+ mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
+ // boolean Collection.add(property)
+ mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC);
+ // pop return value of Collection.add
+ mi.pop();
+ // stack: Collection
}
static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException {
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Mon Jul 08 16:33:50 2013 +0530
@@ -32,11 +32,11 @@
import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
@@ -129,7 +129,7 @@
private void emitStaticInitializer() {
final MethodGenerator mi = makeStaticInitializer();
- emitStaticInitPrefix(mi, className);
+ emitStaticInitPrefix(mi, className, memberCount);
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) {
@@ -170,10 +170,10 @@
private void loadMap(final MethodGenerator mi) {
if (memberCount > 0) {
- mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+ mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
// make sure we use duplicated PropertyMap so that original map
- // stays intact and so can be used for many globals in same context
- mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+ // stays intact and so can be used for many globals.
+ mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
}
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java Mon Jul 08 16:33:50 2013 +0530
@@ -57,6 +57,7 @@
import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
@@ -347,6 +348,10 @@
}
// invokes, field get/sets
+ void invokeInterface(final String owner, final String method, final String desc) {
+ super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc);
+ }
+
void invokeVirtual(final String owner, final String method, final String desc) {
super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc);
}
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Mon Jul 08 16:33:50 2013 +0530
@@ -30,11 +30,11 @@
import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
@@ -67,6 +67,7 @@
// add <clinit>
emitStaticInitializer();
}
+
// add <init>
emitConstructor();
@@ -106,7 +107,7 @@
private void emitStaticInitializer() {
final MethodGenerator mi = makeStaticInitializer();
- emitStaticInitPrefix(mi, className);
+ emitStaticInitPrefix(mi, className, memberCount);
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) {
linkerAddGetterSetter(mi, className, memInfo);
@@ -124,10 +125,10 @@
mi.loadThis();
if (memberCount > 0) {
// call "super(map$)"
- mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC);
+ mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
// make sure we use duplicated PropertyMap so that original map
- // stays intact and so can be used for many globals in same context
- mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC);
+ // stays intact and so can be used for many global.
+ mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
// initialize Function type fields
initFunctionFields(mi);
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Mon Jul 08 16:33:50 2013 +0530
@@ -37,10 +37,7 @@
import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
import java.io.BufferedInputStream;
@@ -159,14 +156,7 @@
public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
if (isConstructor && opcode == INVOKESPECIAL &&
INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
-
- // replace call to empty super-constructor with one passing PropertyMap argument
- if (DEFAULT_INIT_DESC.equals(desc)) {
- super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), MAP_FIELD_NAME, MAP_DESC);
- super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
- } else {
- super.visitMethodInsn(opcode, owner, name, desc);
- }
+ super.visitMethodInsn(opcode, owner, name, desc);
if (memberCount > 0) {
// initialize @Property fields if needed
@@ -256,7 +246,7 @@
}
// Now generate $clinit$
final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$);
- ClassGenerator.emitStaticInitPrefix(mi, className);
+ ClassGenerator.emitStaticInitPrefix(mi, className, memberCount);
if (memberCount > 0) {
for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) {
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java Mon Jul 08 16:33:50 2013 +0530
@@ -27,10 +27,14 @@
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import jdk.internal.org.objectweb.asm.Type;
-import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.objects.PrototypeObject;
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
+import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -40,15 +44,41 @@
*/
@SuppressWarnings("javadoc")
public interface StringConstants {
+ // standard jdk types, methods
static final Type TYPE_METHOD = Type.getType(Method.class);
static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class);
static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
static final Type TYPE_OBJECT = Type.getType(Object.class);
static final Type TYPE_CLASS = Type.getType(Class.class);
static final Type TYPE_STRING = Type.getType(String.class);
+ static final Type TYPE_COLLECTION = Type.getType(Collection.class);
+ static final Type TYPE_COLLECTIONS = Type.getType(Collections.class);
+ static final Type TYPE_ARRAYLIST = Type.getType(ArrayList.class);
+ static final Type TYPE_LIST = Type.getType(List.class);
- // Nashorn types
- static final Type TYPE_LOOKUP = Type.getType(Lookup.class);
+ static final String CLINIT = "<clinit>";
+ static final String INIT = "<init>";
+ static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
+
+ static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+ static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
+ static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
+ static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
+ static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName();
+ static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName();
+ static final String COLLECTIONS_TYPE = TYPE_COLLECTIONS.getInternalName();
+
+ // java.util.Collection.add(Object)
+ static final String COLLECTION_ADD = "add";
+ static final String COLLECTION_ADD_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, TYPE_OBJECT);
+ // java.util.ArrayList.<init>(int)
+ static final String ARRAYLIST_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+ // java.util.Collections.EMPTY_LIST
+ static final String COLLECTIONS_EMPTY_LIST = "EMPTY_LIST";
+ static final String LIST_DESC = TYPE_LIST.getDescriptor();
+
+ // Nashorn types, methods
+ static final Type TYPE_ACCESSORPROPERTY = Type.getType(AccessorProperty.class);
static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class);
static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class);
static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class);
@@ -57,52 +87,56 @@
static final String PROTOTYPE_SUFFIX = "$Prototype";
static final String CONSTRUCTOR_SUFFIX = "$Constructor";
+
// This field name is known to Nashorn runtime (Context).
// Synchronize the name change, if needed at all.
- static final String MAP_FIELD_NAME = "$nasgenmap$";
+ static final String PROPERTYMAP_FIELD_NAME = "$nasgenmap$";
static final String $CLINIT$ = "$clinit$";
- static final String CLINIT = "<clinit>";
- static final String INIT = "<init>";
- static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
- static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
+ // AccessorProperty
+ static final String ACCESSORPROPERTY_TYPE = TYPE_ACCESSORPROPERTY.getInternalName();
+ static final String ACCESSORPROPERTY_CREATE = "create";
+ static final String ACCESSORPROPERTY_CREATE_DESC =
+ Type.getMethodDescriptor(TYPE_ACCESSORPROPERTY, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE);
- static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+ // PropertyMap
+ static final String PROPERTYMAP_TYPE = TYPE_PROPERTYMAP.getInternalName();
+ static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
+ static final String PROPERTYMAP_NEWMAP = "newMap";
+ static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION);
+ static final String PROPERTYMAP_DUPLICATE = "duplicate";
+ static final String PROPERTYMAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
+ static final String PROPERTYMAP_SETISSHARED = "setIsShared";
+ static final String PROPERTYMAP_SETISSHARED_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
- static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
- static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
- static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
+ // PrototypeObject
+ static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
+ static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor";
+ static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT);
+ // ScriptFunction
static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName();
+ static final String SCRIPTFUNCTION_SETARITY = "setArity";
+ static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
+ static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
+ static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
+
+ // ScriptFunctionImpl
static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName();
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction";
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
-
static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY);
- static final String SCRIPTFUNCTION_SETARITY = "setArity";
- static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE);
- static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype";
- static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
- static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
- static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor";
- static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT);
+
+ // ScriptObject
static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
- static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName();
- static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
- static final String MAP_NEWMAP = "newMap";
- static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
- static final String MAP_DUPLICATE = "duplicate";
- static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
- static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName();
- static final String LOOKUP_NEWPROPERTY = "newProperty";
- static final String LOOKUP_NEWPROPERTY_DESC =
- Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE);
+ static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
+
static final String GETTER_PREFIX = "G$";
static final String SETTER_PREFIX = "S$";
--- a/nashorn/make/code_coverage.xml Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/make/code_coverage.xml Mon Jul 08 16:33:50 2013 +0530
@@ -60,16 +60,8 @@
<copy todir="${build.dir}/to_be_instrumented">
<fileset dir="${build.classes.dir}">
<include name="**/*.class"/>
- <include name="**/*.clazz"/>
</fileset>
</copy>
-
- <move todir="${build.dir}/to_be_instrumented/jdk/nashorn/internal/objects">
- <fileset dir="${build.dir}/to_be_instrumented/jdk/nashorn/internal/objects">
- <include name="**/*.clazz"/>
- </fileset>
- <mapper type="glob" from="*.clazz" to="*.class"/>
- </move>
</target>
<target name="generate-cc-template" depends="prepare-to-be-instrumented" description="Generates code coverage template for dynamic CC" if="cc.generate.template">
--- a/nashorn/make/project.properties Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/make/project.properties Mon Jul 08 16:33:50 2013 +0530
@@ -200,6 +200,9 @@
# test262 test frameworks
test262-test-sys-prop.test.js.framework=\
+ --class-cache-size=0 \
+ --no-java \
+ --no-typed-arrays \
-timezone=PST \
${test.script.dir}/test262.js \
${test262.dir}/test/harness/framework.js \
--- a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java Mon Jul 08 16:33:50 2013 +0530
@@ -125,44 +125,6 @@
}
/**
- * Create a new {@link Property}
- *
- * @param map property map
- * @param key property key
- * @param flags property flags
- * @param propertyGetter getter for property if available, null otherwise
- * @param propertySetter setter for property if available, null otherwise
- *
- * @return new property map, representing {@code PropertyMap} with the new property added to it
- */
- @SuppressWarnings("fallthrough")
- public static PropertyMap newProperty(final PropertyMap map, final String key, final int flags, final MethodHandle propertyGetter, final MethodHandle propertySetter) {
- MethodHandle getter = propertyGetter;
- MethodHandle setter = propertySetter;
-
- // TODO: this is temporary code. This code exists to support reflective
- // field reader/writer handles generated by "unreflect" lookup.
-
- switch (getter.type().parameterCount()) {
- case 0:
- // A static field reader, so drop the 'self' argument.
- getter = MH.dropArguments(getter, 0, Object.class);
- if (setter != null) {
- setter = MH.dropArguments(setter, 0, Object.class);
- }
- // fall through
- case 1:
- // standard getter that accepts 'self'.
- break;
- default:
- // Huh!! something wrong..
- throw new IllegalArgumentException("getter/setter has wrong arguments");
- }
-
- return map.newProperty(key, flags, -1, getter, setter);
- }
-
- /**
* This method filters primitive return types using JavaScript semantics. For example,
* an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
* If you are returning values to JavaScript that have to be of a specific type, this is
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java Mon Jul 08 16:33:50 2013 +0530
@@ -46,14 +46,17 @@
return $nasgenmap$;
}
- ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+ private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
+ super(global.getArrayBufferViewMap());
checkConstructorArgs(buffer, byteOffset, elementLength);
- final Global global = Global.instance();
- this.setMap(global.getArrayBufferViewMap());
this.setProto(getPrototype(global));
this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
}
+ ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
+ this(buffer, byteOffset, elementLength, Global.instance());
+ }
+
private void checkConstructorArgs(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
if (byteOffset < 0 || elementLength < 0) {
throw new RuntimeException("byteOffset or length must not be negative");
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Mon Jul 08 16:33:50 2013 +0530
@@ -43,7 +43,6 @@
import java.util.Map;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -389,6 +388,7 @@
private PropertyMap prototypeObjectMap;
private PropertyMap objectMap;
private PropertyMap functionMap;
+ private PropertyMap anonymousFunctionMap;
private PropertyMap strictFunctionMap;
private PropertyMap boundFunctionMap;
@@ -409,7 +409,6 @@
private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class);
// initialized by nasgen
- @SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
/**
@@ -418,14 +417,14 @@
* @param context the context
*/
public Global(final Context context) {
- this.setContext(context);
- this.setIsScope();
/*
* Duplicate global's map and use it. This way the initial Map filled
* by nasgen (referenced from static field in this class) is retained
- * 'as is'. This allows multiple globals to be used within a context.
+ * 'as is' (as that one is process wide singleton.
*/
- this.setMap(getMap().duplicate());
+ super($nasgenmap$.duplicate());
+ this.setContext(context);
+ this.setIsScope();
final int cacheSize = context.getEnv()._class_cache_size;
if (cacheSize > 0) {
@@ -1018,6 +1017,10 @@
return functionMap;
}
+ PropertyMap getAnonymousFunctionMap() {
+ return anonymousFunctionMap;
+ }
+
PropertyMap getStrictFunctionMap() {
return strictFunctionMap;
}
@@ -1538,7 +1541,7 @@
final ScriptEnvironment env = getContext().getEnv();
// duplicate PropertyMaps of Native* classes
- copyInitialMaps();
+ copyInitialMaps(env);
// initialize Function and Object constructor
initFunctionAndObject();
@@ -1599,12 +1602,16 @@
initErrorObjects();
// java access
- initJavaAccess();
+ if (! env._no_java) {
+ initJavaAccess();
+ }
- initTypedArray();
+ if (! env._no_typed_arrays) {
+ initTypedArray();
+ }
if (env._scripting) {
- initScripting();
+ initScripting(env);
}
if (Context.DEBUG && System.getSecurityManager() == null) {
@@ -1685,7 +1692,7 @@
this.builtinJavaApi = initConstructor("Java");
}
- private void initScripting() {
+ private void initScripting(final ScriptEnvironment scriptEnv) {
Object value;
value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
@@ -1704,7 +1711,6 @@
// Nashorn extension: global.$OPTIONS (scripting-mode-only)
final ScriptObject options = newObject();
- final ScriptEnvironment scriptEnv = getContext().getEnv();
copyOptions(options, scriptEnv);
addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
@@ -1857,20 +1863,17 @@
}
}
- private void copyInitialMaps() {
+ private void copyInitialMaps(final ScriptEnvironment env) {
this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
- this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
- this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
this.nativeDateMap = NativeDate.getInitialMap().duplicate();
this.nativeErrorMap = NativeError.getInitialMap().duplicate();
this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
- this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
@@ -1883,9 +1886,21 @@
this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
this.objectMap = JO.getInitialMap().duplicate();
- this.functionMap = ScriptFunctionImpl.getInitialMap();
+ this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate();
+ this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
+
+ // java
+ if (! env._no_java) {
+ this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
+ }
+
+ // typed arrays
+ if (! env._no_typed_arrays) {
+ this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
+ this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
+ }
}
// Function and Object constructors are inter-dependent. Also,
@@ -1899,7 +1914,7 @@
this.builtinFunction = (ScriptFunction)initConstructor("Function");
// create global anonymous function
- final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
+ final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this);
// need to copy over members of Function.prototype to anon function
anon.addBoundProperties(getFunctionPrototype());
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Mon Jul 08 16:33:50 2013 +0530
@@ -31,8 +31,10 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyDescriptor;
import jdk.nashorn.internal.runtime.PropertyMap;
@@ -41,8 +43,6 @@
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
/**
* ECMA 10.6 Arguments Object.
@@ -64,10 +64,10 @@
private static final PropertyMap map$;
static {
- PropertyMap map = PropertyMap.newMap();
- map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
- map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE);
- map$ = map;
+ final ArrayList<Property> properties = new ArrayList<>(2);
+ properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
+ properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE));
+ map$ = PropertyMap.newMap(properties).setIsShared();
}
static PropertyMap getInitialMap() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java Mon Jul 08 16:33:50 2013 +0530
@@ -40,7 +40,6 @@
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
/**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Jul 08 16:33:50 2013 +0530
@@ -49,6 +49,7 @@
public final class NativeDebug extends ScriptObject {
// initialized by nasgen
+ @SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
private NativeDebug() {
@@ -144,7 +145,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object equals(final Object self, final Object obj1, final Object obj2) {
- return (obj1 != null) ? obj1.equals(obj2) : false;
+ return Objects.equals(obj1, obj2);
}
/**
@@ -177,6 +178,15 @@
}
/**
+ * Returns the property listener count for a script object
+ * @return listener count
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object getListenerCount(final Object self, final Object obj) {
+ return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0;
+ }
+
+ /**
* Dump all Nashorn debug mode counters. Calling this may be better if
* you want to print all counters. This way you can avoid too many callsites
* due to counter access itself!!
@@ -197,6 +207,8 @@
out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
out.println("PropertyMap count " + PropertyMap.getCount());
out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
+ out.println("PropertyMap shared " + PropertyMap.getSharedCount());
+ out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit());
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java Mon Jul 08 16:33:50 2013 +0530
@@ -31,7 +31,6 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import jdk.nashorn.api.scripting.NashornException;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Jul 08 16:33:50 2013 +0530
@@ -48,7 +48,6 @@
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.scripts.JO;
/**
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java Mon Jul 08 16:33:50 2013 +0530
@@ -60,6 +60,7 @@
ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
// initialized by nasgen
+ @SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
private NativeJSON() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java Mon Jul 08 16:33:50 2013 +0530
@@ -43,6 +43,7 @@
public final class NativeMath extends ScriptObject {
// initialized by nasgen
+ @SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
private NativeMath() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java Mon Jul 08 16:33:50 2013 +0530
@@ -30,14 +30,14 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
import java.util.Arrays;
+import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
/**
* ECMA 10.6 Arguments Object.
@@ -54,14 +54,15 @@
private static final PropertyMap map$;
static {
- PropertyMap map = PropertyMap.newMap();
- map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
+ final ArrayList<Property> properties = new ArrayList<>(1);
+ properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
+ PropertyMap map = PropertyMap.newMap(properties);
// In strict mode, the caller and callee properties should throw TypeError
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
map = map.addProperty(map.newUserAccessors("caller", flags));
map = map.addProperty(map.newUserAccessors("callee", flags));
- map$ = map;
+ map$ = map.setIsShared();
}
static PropertyMap getInitialMap() {
--- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java Mon Jul 08 16:33:50 2013 +0530
@@ -30,12 +30,12 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.lookup.Lookup;
-import jdk.nashorn.internal.lookup.MethodHandleFactory;
/**
* Instances of this class serve as "prototype" object for script functions.
@@ -52,9 +52,9 @@
private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class);
static {
- PropertyMap map = PropertyMap.newMap();
- map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR);
- map$ = map;
+ final ArrayList<Property> properties = new ArrayList<>(1);
+ properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR));
+ map$ = PropertyMap.newMap(properties).setIsShared();
}
static PropertyMap getInitialMap() {
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Mon Jul 08 16:33:50 2013 +0530
@@ -28,6 +28,7 @@
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
import jdk.nashorn.internal.runtime.GlobalFunctions;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
@@ -36,6 +37,7 @@
import jdk.nashorn.internal.runtime.ScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.AccessorProperty;
/**
* Concrete implementation of ScriptFunction. This sets correct map for the
@@ -57,6 +59,10 @@
return map$;
}
+ static PropertyMap getInitialAnonymousMap() {
+ return AnonymousFunction.getInitialMap();
+ }
+
static PropertyMap getInitialStrictMap() {
return strictmodemap$;
}
@@ -149,13 +155,18 @@
}
static {
- PropertyMap map = PropertyMap.newMap();
- map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE);
- map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null);
- map = Lookup.newProperty(map, "name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null);
- map$ = map;
+ final ArrayList<Property> properties = new ArrayList<>(3);
+ properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
+ properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
+ properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
+ map$ = PropertyMap.newMap(properties);
strictmodemap$ = createStrictModeMap(map$);
boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
+ // There are order dependencies between normal map, struct map and bound map
+ // We can make these 'shared' only after initialization of all three.
+ map$.setIsShared();
+ strictmodemap$.setIsShared();
+ boundfunctionmap$.setIsShared();
}
// function object representing TypeErrorThrower
@@ -201,15 +212,19 @@
// Instance of this class is used as global anonymous function which
// serves as Function.prototype object.
private static class AnonymousFunction extends ScriptFunctionImpl {
- private static final PropertyMap nasgenmap$$ = PropertyMap.newMap();
+ private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
- AnonymousFunction() {
- super("", GlobalFunctions.ANONYMOUS, nasgenmap$$, null);
+ static PropertyMap getInitialMap() {
+ return map$;
+ }
+
+ AnonymousFunction(final Global global) {
+ super("", GlobalFunctions.ANONYMOUS, global.getAnonymousFunctionMap(), null);
}
}
- static ScriptFunctionImpl newAnonymousFunction() {
- return new AnonymousFunction();
+ static ScriptFunctionImpl newAnonymousFunction(final Global global) {
+ return new AnonymousFunction(global);
}
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Mon Jul 08 16:33:50 2013 +0530
@@ -107,6 +107,20 @@
SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
}
+ /**
+ * Create a new accessor property. Factory method used by nasgen generated code.
+ *
+ * @param key {@link Property} key.
+ * @param propertyFlags {@link Property} flags.
+ * @param getter {@link Property} get accessor method.
+ * @param setter {@link Property} set accessor method.
+ *
+ * @return New {@link AccessorProperty} created.
+ */
+ public static AccessorProperty create(final String key, final int propertyFlags, final MethodHandle getter, final MethodHandle setter) {
+ return new AccessorProperty(key, propertyFlags, -1, getter, setter);
+ }
+
/** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
private MethodHandle primitiveGetter;
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Mon Jul 08 16:33:50 2013 +0530
@@ -253,13 +253,7 @@
this.env = new ScriptEnvironment(options, out, err);
this._strict = env._strict;
this.appLoader = appLoader;
- this.scriptLoader = (ScriptLoader)AccessController.doPrivileged(
- new PrivilegedAction<ClassLoader>() {
- @Override
- public ClassLoader run() {
- return new ScriptLoader(sharedLoader, Context.this);
- }
- });
+ this.scriptLoader = env._loader_per_compile? null : createNewLoader();
this.errors = errors;
// if user passed -classpath option, make a class loader with that and set it as
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Mon Jul 08 16:33:50 2013 +0530
@@ -41,6 +41,7 @@
private static int listenersRemoved;
/**
+ * Return aggregate listeners added to all PropertyListenerManagers
* @return the listenersAdded
*/
public static int getListenersAdded() {
@@ -48,12 +49,21 @@
}
/**
+ * Return aggregate listeners removed from all PropertyListenerManagers
* @return the listenersRemoved
*/
public static int getListenersRemoved() {
return listenersRemoved;
}
+ /**
+ * Return listeners added to this PropertyListenerManager.
+ * @return the listener count
+ */
+ public final int getListenerCount() {
+ return listeners != null? listeners.size() : 0;
+ }
+
// Property listener management methods
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Mon Jul 08 16:33:50 2013 +0530
@@ -25,11 +25,8 @@
package jdk.nashorn.internal.runtime;
-import jdk.nashorn.internal.scripts.JO;
-
import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
-import java.lang.invoke.MethodHandle;
import java.lang.invoke.SwitchPoint;
import java.lang.ref.WeakReference;
import java.util.Arrays;
@@ -57,9 +54,8 @@
private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111;
/** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
public static final int IS_LISTENER_ADDED = 0b0001_0000;
-
- /** Empty map used for seed map for JO$ objects */
- private static final PropertyMap EMPTY_MAP = new PropertyMap(EMPTY_HASHMAP);
+ /** Is this process wide "shared" map?. This flag is not copied when cloning a map */
+ public static final int IS_SHARED = 0b0010_0000;
/** Map status flags. */
private int flags;
@@ -145,16 +141,17 @@
}
/**
- * Duplicates this PropertyMap instance. This is used by nasgen generated
- * prototype and constructor classes. {@link PropertyMap} used for singletons
- * like these (and global instance) are duplicated using this method and used.
- * The original filled map referenced by static fields of prototype and
- * constructor classes are not touched. This allows multiple independent global
- * instances to be used within a single context instance.
+ * Duplicates this PropertyMap instance. This is used to duplicate 'shared'
+ * maps {@link PropertyMap} used as process wide singletons. Shared maps are
+ * duplicated for every global scope object. That way listeners, proto and property
+ * histories are scoped within a global scope.
*
* @return Duplicated {@link PropertyMap}.
*/
public PropertyMap duplicate() {
+ if (Context.DEBUG) {
+ duplicatedCount++;
+ }
return new PropertyMap(this.properties);
}
@@ -173,6 +170,15 @@
}
/**
+ * Public property map allocator. Used by nasgen generated code.
+ * @param properties Collection of initial properties.
+ * @return New {@link PropertyMap}.
+ */
+ public static PropertyMap newMap(final Collection<Property> properties) {
+ return (properties == null || properties.isEmpty())? newMap() : newMap(properties, 0, 0, 0);
+ }
+
+ /**
* Return a sharable empty map.
*
* @return New empty {@link PropertyMap}.
@@ -199,6 +205,8 @@
* @return A shared {@link SwitchPoint} for the property.
*/
public SwitchPoint getProtoGetSwitchPoint(final ScriptObject proto, final String key) {
+ assert !isShared() : "proto SwitchPoint from a shared PropertyMap";
+
if (proto == null) {
return null;
}
@@ -227,6 +235,8 @@
* @param property {@link Property} to invalidate.
*/
private void invalidateProtoGetSwitchPoint(final Property property) {
+ assert !isShared() : "proto invalidation on a shared PropertyMap";
+
if (protoGetSwitches != null) {
final String key = property.getKey();
final SwitchPoint sp = protoGetSwitches.get(key);
@@ -241,17 +251,6 @@
}
/**
- * Add a property to the map.
- *
- * @param property {@link Property} being added.
- *
- * @return New {@link PropertyMap} with {@link Property} added.
- */
- public PropertyMap newProperty(final Property property) {
- return addProperty(property);
- }
-
- /**
* Add a property to the map, re-binding its getters and setters,
* if available, to a given receiver. This is typically the global scope. See
* {@link ScriptObject#addBoundProperties(ScriptObject)}
@@ -261,23 +260,8 @@
*
* @return New {@link PropertyMap} with {@link Property} added.
*/
- PropertyMap newPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
- return newProperty(new AccessorProperty(property, bindTo));
- }
-
- /**
- * Add a new accessor property to the map.
- *
- * @param key {@link Property} key.
- * @param propertyFlags {@link Property} flags.
- * @param slot {@link Property} slot.
- * @param getter {@link Property} get accessor method.
- * @param setter {@link Property} set accessor method.
- *
- * @return New {@link PropertyMap} with {@link AccessorProperty} added.
- */
- public PropertyMap newProperty(final String key, final int propertyFlags, final int slot, final MethodHandle getter, final MethodHandle setter) {
- return newProperty(new AccessorProperty(key, propertyFlags, slot, getter, setter));
+ PropertyMap addPropertyBind(final AccessorProperty property, final ScriptObject bindTo) {
+ return addProperty(new AccessorProperty(property, bindTo));
}
/**
@@ -479,6 +463,28 @@
}
/**
+ * Make this property map 'shared' one. Shared property map instances are
+ * process wide singleton objects. A shaped map should never be added as a listener
+ * to a proto object. Nor it should have history or proto history. A shared map
+ * is just a template that is meant to be duplicated before use. All nasgen initialized
+ * property maps are shared.
+ *
+ * @return this map after making it as shared
+ */
+ public PropertyMap setIsShared() {
+ assert !isListenerAdded() : "making PropertyMap shared after listener added";
+ assert protoHistory == null : "making PropertyMap shared after associating a proto with it";
+ if (Context.DEBUG) {
+ sharedCount++;
+ }
+
+ flags |= IS_SHARED;
+ // clear any history on this PropertyMap, won't be used.
+ history = null;
+ return this;
+ }
+
+ /**
* Check for any configurable properties.
*
* @return {@code true} if any configurable.
@@ -544,6 +550,8 @@
* @param newMap {@link PropertyMap} associated with prototype.
*/
private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
+ assert !isShared() : "proto history modified on a shared PropertyMap";
+
if (protoHistory == null) {
protoHistory = new WeakHashMap<>();
}
@@ -558,6 +566,8 @@
* @param newMap Modified {@link PropertyMap}.
*/
private void addToHistory(final Property property, final PropertyMap newMap) {
+ assert !isShared() : "history modified on a shared PropertyMap";
+
if (!properties.isEmpty()) {
if (history == null) {
history = new LinkedHashMap<>();
@@ -683,6 +693,15 @@
}
/**
+ * Check if this map shared or not.
+ *
+ * @return true if this map is shared.
+ */
+ public boolean isShared() {
+ return (flags & IS_SHARED) != 0;
+ }
+
+ /**
* Test to see if {@link PropertyMap} is extensible.
*
* @return {@code true} if {@link PropertyMap} can be added to.
@@ -745,6 +764,8 @@
* @return New {@link PropertyMap} with prototype changed.
*/
PropertyMap changeProto(final ScriptObject oldProto, final ScriptObject newProto) {
+ assert !isShared() : "proto associated with a shared PropertyMap";
+
if (oldProto == newProto) {
return this;
}
@@ -860,6 +881,8 @@
// counters updated only in debug mode
private static int count;
private static int clonedCount;
+ private static int sharedCount;
+ private static int duplicatedCount;
private static int historyHit;
private static int protoInvalidations;
private static int protoHistoryHit;
@@ -880,6 +903,20 @@
}
/**
+ * @return The number of maps that are shared.
+ */
+ public static int getSharedCount() {
+ return sharedCount;
+ }
+
+ /**
+ * @return The number of maps that are duplicated.
+ */
+ public static int getDuplicatedCount() {
+ return duplicatedCount;
+ }
+
+ /**
* @return The number of times history was successfully used.
*/
public static int getHistoryHit() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Mon Jul 08 16:33:50 2013 +0530
@@ -119,9 +119,15 @@
/** Create a new class loaded for each compilation */
public final boolean _loader_per_compile;
+ /** Do not support Java support extensions. */
+ public final boolean _no_java;
+
/** Do not support non-standard syntax extensions. */
public final boolean _no_syntax_extensions;
+ /** Do not support typed arrays. */
+ public final boolean _no_typed_arrays;
+
/** Package to which generated class files are added */
public final String _package;
@@ -207,7 +213,9 @@
_fx = options.getBoolean("fx");
_lazy_compilation = options.getBoolean("lazy.compilation");
_loader_per_compile = options.getBoolean("loader.per.compile");
+ _no_java = options.getBoolean("no.java");
_no_syntax_extensions = options.getBoolean("no.syntax.extensions");
+ _no_typed_arrays = options.getBoolean("no.typed.arrays");
_package = options.getString("package");
_parse_only = options.getBoolean("parse.only");
_print_ast = options.getBoolean("print.ast");
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Jul 08 16:33:50 2013 +0530
@@ -213,7 +213,7 @@
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
newMap = newMap.addProperty(prop);
} else {
- newMap = newMap.newPropertyBind((AccessorProperty)property, source);
+ newMap = newMap.addPropertyBind((AccessorProperty)property, source);
}
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Mon Jul 08 16:33:50 2013 +0530
@@ -192,6 +192,14 @@
default=true \
}
+nashorn.option.no.java = { \
+ name="--no-java", \
+ short_name="-nj", \
+ is_undocumented=true, \
+ desc="No Java support", \
+ default=false \
+}
+
nashorn.option.no.syntax.extensions = { \
name="--no-syntax-extensions", \
short_name="-nse", \
@@ -200,6 +208,14 @@
default=false \
}
+nashorn.option.no.typed.arrays = { \
+ name="--no-typed-arrays", \
+ short_name="-nta", \
+ is_undocumented=true, \
+ desc="No Typed arrays support", \
+ default=false \
+}
+
nashorn.option.package = { \
name="--package", \
is_undocumented=true, \
--- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java Mon Jul 08 16:33:50 2013 +0530
@@ -33,7 +33,7 @@
*/
public class JO extends ScriptObject {
- private static final PropertyMap map$ = PropertyMap.newMap();
+ private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
/**
* Returns the initial property map to be used.
--- a/nashorn/src/jdk/nashorn/tools/Shell.java Fri Jul 05 19:35:39 2013 +0200
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java Mon Jul 08 16:33:50 2013 +0530
@@ -435,6 +435,10 @@
break;
}
+ if (source.isEmpty()) {
+ continue;
+ }
+
Object res;
try {
res = context.eval(global, source, global, "<shell>", env._strict);