8068784: Halve the function object creation code size

Mon, 12 Jan 2015 14:32:32 +0100

author
attila
date
Mon, 12 Jan 2015 14:32:32 +0100
changeset 1215
b49d4cf4a8a9
parent 1214
f98201c9d76a
child 1216
34291d7ca37d

8068784: Halve the function object creation code size
Reviewed-by: hannesw, sundar

src/jdk/nashorn/internal/codegen/CodeGenerator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Jan 12 11:29:42 2015 +0100
     1.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Jan 12 14:32:32 2015 +0100
     1.3 @@ -38,7 +38,6 @@
     1.4  import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
     1.5  import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
     1.6  import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
     1.7 -import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
     1.8  import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
     1.9  import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
    1.10  import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
    1.11 @@ -186,9 +185,6 @@
    1.12  
    1.13      private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
    1.14  
    1.15 -    private static final String SCRIPTFUNCTION_IMPL_NAME = Type.getInternalName(ScriptFunctionImpl.class);
    1.16 -    private static final Type   SCRIPTFUNCTION_IMPL_TYPE   = Type.typeFor(ScriptFunction.class);
    1.17 -
    1.18      private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class,
    1.19              "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class);
    1.20      private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class,
    1.21 @@ -201,6 +197,11 @@
    1.22      private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
    1.23              "ensureNumber", double.class, Object.class, int.class);
    1.24  
    1.25 +    private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
    1.26 +            "create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
    1.27 +    private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
    1.28 +            "create", ScriptFunction.class, Object[].class, int.class);
    1.29 +
    1.30      private static final Class<?> ITERATOR_CLASS = Iterator.class;
    1.31      static {
    1.32          assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
    1.33 @@ -2242,7 +2243,6 @@
    1.34          } else {
    1.35              methodEmitter.loadConstants().load(index).arrayload();
    1.36              if (object instanceof ArrayData) {
    1.37 -                // avoid cast to non-public ArrayData subclass
    1.38                  methodEmitter.checkcast(ArrayData.class);
    1.39                  methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
    1.40              } else if (cls != Object.class) {
    1.41 @@ -2251,6 +2251,10 @@
    1.42          }
    1.43      }
    1.44  
    1.45 +    private void loadConstantsAndIndex(final Object object, final MethodEmitter methodEmitter) {
    1.46 +        methodEmitter.loadConstants().load(compiler.getConstantData().add(object));
    1.47 +    }
    1.48 +
    1.49      // literal values
    1.50      private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) {
    1.51          final Object value = node.getValue();
    1.52 @@ -4322,15 +4326,13 @@
    1.53          final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(functionNode.getId());
    1.54  
    1.55          if (functionNode.isProgram() && !compiler.isOnDemandCompilation()) {
    1.56 -            final CompileUnit fnUnit = functionNode.getCompileUnit();
    1.57 -            final MethodEmitter createFunction = fnUnit.getClassEmitter().method(
    1.58 +            final MethodEmitter createFunction = functionNode.getCompileUnit().getClassEmitter().method(
    1.59                      EnumSet.of(Flag.PUBLIC, Flag.STATIC), CREATE_PROGRAM_FUNCTION.symbolName(),
    1.60                      ScriptFunction.class, ScriptObject.class);
    1.61              createFunction.begin();
    1.62 -            createFunction._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
    1.63 -            loadConstant(data, fnUnit, createFunction);
    1.64 +            loadConstantsAndIndex(data, createFunction);
    1.65              createFunction.load(SCOPE_TYPE, 0);
    1.66 -            createFunction.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
    1.67 +            createFunction.invoke(CREATE_FUNCTION_OBJECT);
    1.68              createFunction._return();
    1.69              createFunction.end();
    1.70          }
    1.71 @@ -4345,15 +4347,14 @@
    1.72              return;
    1.73          }
    1.74  
    1.75 -        method._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
    1.76 -        loadConstant(data);
    1.77 +        loadConstantsAndIndex(data, method);
    1.78  
    1.79          if (functionNode.needsParentScope()) {
    1.80              method.loadCompilerConstant(SCOPE);
    1.81 +            method.invoke(CREATE_FUNCTION_OBJECT);
    1.82          } else {
    1.83 -            method.loadNull();
    1.84 -        }
    1.85 -        method.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
    1.86 +            method.invoke(CREATE_FUNCTION_OBJECT_NO_SCOPE);
    1.87 +        }
    1.88      }
    1.89  
    1.90      // calls on Global class.
     2.1 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Jan 12 11:29:42 2015 +0100
     2.2 +++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Jan 12 14:32:32 2015 +0100
     2.3 @@ -118,13 +118,26 @@
     2.4      }
     2.5  
     2.6      /**
     2.7 -     * Constructor called by (compiler) generated code for {@link ScriptObject}s.
     2.8 +     * Factory method called by compiler generated code for functions that need parent scope.
     2.9       *
    2.10 -     * @param data static function data
    2.11 -     * @param scope scope object
    2.12 +     * @param constants the generated class' constant array
    2.13 +     * @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
    2.14 +     * @param scope the parent scope object
    2.15 +     * @return a newly created function object
    2.16       */
    2.17 -    public ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope) {
    2.18 -        this(data, scope, Global.instance());
    2.19 +    public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
    2.20 +        return new ScriptFunctionImpl((RecompilableScriptFunctionData)constants[index], scope, Global.instance());
    2.21 +    }
    2.22 +
    2.23 +    /**
    2.24 +     * Factory method called by compiler generated code for functions that don't need parent scope.
    2.25 +     *
    2.26 +     * @param constants the generated class' constant array
    2.27 +     * @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
    2.28 +     * @return a newly created function object
    2.29 +     */
    2.30 +    public static ScriptFunction create(final Object[] constants, final int index) {
    2.31 +        return create(constants, index, null);
    2.32      }
    2.33  
    2.34      /**

mercurial