From 70383eb20a782422fba17f6283cd19bd2ae69263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 26 Jun 2013 15:40:52 +0200 Subject: [PATCH] 8019157: Avoid calling ScriptObject.setProto() if possible Reviewed-by: jlaskey, sundar --- .../internal/tools/nasgen/ClassGenerator.java | 12 +++---- .../tools/nasgen/ScriptClassInstrumentor.java | 14 +++++--- .../internal/codegen/ClassEmitter.java | 3 +- .../internal/codegen/CodeGenerator.java | 2 +- .../nashorn/internal/codegen/Compiler.java | 4 +-- .../codegen/ObjectClassGenerator.java | 4 +-- .../objects/AccessorPropertyDescriptor.java | 6 +++- .../internal/objects/ArrayBufferView.java | 4 +++ .../objects/DataPropertyDescriptor.java | 6 +++- .../objects/GenericPropertyDescriptor.java | 6 +++- .../jdk/nashorn/internal/objects/Global.java | 33 +++++++++++++------ .../internal/objects/NativeArguments.java | 14 ++++---- .../nashorn/internal/objects/NativeArray.java | 7 ++-- .../internal/objects/NativeArrayBuffer.java | 6 +++- .../internal/objects/NativeBoolean.java | 6 +++- .../nashorn/internal/objects/NativeDate.java | 6 +++- .../nashorn/internal/objects/NativeDebug.java | 8 +++-- .../nashorn/internal/objects/NativeError.java | 6 +++- .../internal/objects/NativeEvalError.java | 8 +++-- .../internal/objects/NativeFloat32Array.java | 4 +++ .../internal/objects/NativeFloat64Array.java | 4 +++ .../internal/objects/NativeFunction.java | 5 +++ .../internal/objects/NativeInt16Array.java | 5 +++ .../internal/objects/NativeInt32Array.java | 4 +++ .../internal/objects/NativeInt8Array.java | 4 +++ .../internal/objects/NativeJSAdapter.java | 6 +++- .../nashorn/internal/objects/NativeJSON.java | 5 ++- .../nashorn/internal/objects/NativeJava.java | 4 +++ .../internal/objects/NativeJavaImporter.java | 6 +++- .../nashorn/internal/objects/NativeMath.java | 6 +++- .../internal/objects/NativeNumber.java | 6 +++- .../internal/objects/NativeObject.java | 4 +++ .../internal/objects/NativeRangeError.java | 6 +++- .../objects/NativeReferenceError.java | 6 +++- .../internal/objects/NativeRegExp.java | 4 +++ .../objects/NativeRegExpExecResult.java | 6 +++- .../objects/NativeStrictArguments.java | 10 +++--- .../internal/objects/NativeString.java | 6 +++- .../internal/objects/NativeSyntaxError.java | 6 +++- .../internal/objects/NativeTypeError.java | 6 +++- .../internal/objects/NativeURIError.java | 6 +++- .../internal/objects/NativeUint16Array.java | 4 +++ .../internal/objects/NativeUint32Array.java | 4 +++ .../internal/objects/NativeUint8Array.java | 4 +++ .../objects/NativeUint8ClampedArray.java | 4 +++ .../internal/objects/PrototypeObject.java | 10 +++--- .../internal/objects/ScriptFunctionImpl.java | 12 +++---- .../jdk/nashorn/internal/runtime/Context.java | 8 +---- .../internal/runtime/FunctionScope.java | 6 ++-- .../nashorn/internal/runtime/PropertyMap.java | 4 ++- .../internal/runtime/ScriptObject.java | 25 +++++++++++--- .../src/jdk/nashorn/internal/scripts/JO.java | 14 +++++++- 52 files changed, 275 insertions(+), 94 deletions(-) diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java index 808f2658046..bc6bb4b2db2 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java @@ -166,11 +166,11 @@ public class ClassGenerator { mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); mi.loadClass(className); mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC); - mi.storeLocal(0); + // stack: PropertyMap } static void emitStaticInitSuffix(final MethodGenerator mi, final String className) { - mi.loadLocal(0); + // stack: PropertyMap mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); mi.returnVoid(); mi.computeMaxs(); @@ -278,7 +278,7 @@ public class ClassGenerator { static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) { final String propertyName = memInfo.getName(); - mi.loadLocal(0); + // stack: PropertyMap mi.loadLiteral(propertyName); // setup flags mi.push(memInfo.getAttributes()); @@ -293,12 +293,12 @@ public class ClassGenerator { mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo))); } mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); - mi.storeLocal(0); + // stack: PropertyMap } static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) { final String propertyName = getter.getName(); - mi.loadLocal(0); + // stack: PropertyMap mi.loadLiteral(propertyName); // setup flags mi.push(getter.getAttributes()); @@ -313,7 +313,7 @@ public class ClassGenerator { setter.getJavaName(), setter.getJavaDesc())); } mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); - mi.storeLocal(0); + // stack: PropertyMap } static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException { diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java index d140585f499..ffeb90bea3e 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java @@ -159,10 +159,14 @@ public class ScriptClassInstrumentor extends ClassVisitor { 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)) { - super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), - MAP_FIELD_NAME, MAP_DESC); - super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, - SCRIPTOBJECT_INIT_DESC); + + // 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); + } if (memberCount > 0) { // initialize @Property fields if needed @@ -223,7 +227,7 @@ public class ScriptClassInstrumentor extends ClassVisitor { ClassGenerator.addSetter(cv, className, memInfo); } } - ClassGenerator.addMapField(this); + // omit addMapField() since instance classes already define a static PropertyMap field } void emitGettersSetters() { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java index 2d379183fd5..09c6a0651cb 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java @@ -165,7 +165,8 @@ public class ClassEmitter implements Emitter { /** * Constructor from the compiler * - * @param compiler Compiler + * @param env Script environment + * @param sourceName Source name * @param unitClassName Compile unit class name. * @param strictMode Should we generate this method in strict mode */ diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index e66e288801d..0f96b6d7983 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -244,7 +244,7 @@ final class CodeGenerator extends NodeOperatorVisitor currentGlobal = - new ThreadLocal() { - @Override - protected ScriptObject initialValue() { - return null; - } - }; + private static final ThreadLocal currentGlobal = new ThreadLocal<>(); /** * Get the current global scope diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java index 713aa69d3ce..59a9d5ede03 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java @@ -54,9 +54,8 @@ public class FunctionScope extends ScriptObject implements Scope { * @param arguments arguments */ public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final Object arguments) { - super(map); + super(callerScope, map); this.arguments = arguments; - setProto(callerScope); setIsScope(); } @@ -67,9 +66,8 @@ public class FunctionScope extends ScriptObject implements Scope { * @param callerScope caller scope */ public FunctionScope(final PropertyMap map, final ScriptObject callerScope) { - super(map); + super(callerScope, map); this.arguments = null; - setProto(callerScope); setIsScope(); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java index 3c552daa118..e03a3ef836e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java @@ -25,6 +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; @@ -166,7 +168,7 @@ public final class PropertyMap implements Iterable, PropertyListener { */ public static PropertyMap newMap(final Class structure, final Collection properties, final int fieldCount, final int fieldMaximum) { // Reduce the number of empty maps in the context. - if (structure == jdk.nashorn.internal.scripts.JO.class) { + if (structure == JO.class) { return EMPTY_MAP; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index 3b11ab9d67f..6b51ad525e2 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -170,13 +170,30 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } this.arrayData = ArrayData.EMPTY_ARRAY; + this.setMap(map == null ? PropertyMap.newMap(getClass()) : map); + } - if (map == null) { - this.setMap(PropertyMap.newMap(getClass())); - return; + /** + * Constructor that directly sets the prototype to {@code proto} and property map to + * {@code map} without invalidating the map as calling {@link #setProto(ScriptObject)} + * would do. This should only be used for objects that are always constructed with the + * same combination of prototype and property map. + * + * @param proto the prototype object + * @param map intial {@link PropertyMap} + */ + protected ScriptObject(final ScriptObject proto, final PropertyMap map) { + if (Context.DEBUG) { + ScriptObject.count++; } - this.setMap(map); + this.arrayData = ArrayData.EMPTY_ARRAY; + this.setMap(map == null ? PropertyMap.newMap(getClass()) : map); + this.proto = proto; + + if (proto != null) { + proto.setIsPrototype(); + } } /** diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java index d698a2637ce..b31df1ae6f1 100644 --- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java +++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java @@ -32,11 +32,14 @@ import jdk.nashorn.internal.runtime.ScriptObject; * Empty object class. */ public class JO extends ScriptObject { + + private static final PropertyMap map$ = PropertyMap.newMap(JO.class); + /** * Constructor */ public JO() { - super(PropertyMap.newMap(JO.class)); + super(map$); } /** @@ -48,6 +51,15 @@ public class JO extends ScriptObject { super(map); } + /** + * Constructor given an initial prototype using the default property map + * + * @param proto the prototype object + */ + public JO(final ScriptObject proto) { + super(proto, map$); + } + /** * Used by FunctionObjectCreator. A method handle of this method is passed to the ScriptFunction constructor. *