8068784: Halve the function object creation code size
Reviewed-by: hannesw, sundar
This commit is contained in:
parent
faf445e144
commit
fb821c2f75
@ -38,7 +38,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
|
||||
@ -186,9 +185,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
|
||||
private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
|
||||
|
||||
private static final String SCRIPTFUNCTION_IMPL_NAME = Type.getInternalName(ScriptFunctionImpl.class);
|
||||
private static final Type SCRIPTFUNCTION_IMPL_TYPE = Type.typeFor(ScriptFunction.class);
|
||||
|
||||
private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class,
|
||||
"create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class);
|
||||
private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class,
|
||||
@ -201,6 +197,11 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
|
||||
"ensureNumber", double.class, Object.class, int.class);
|
||||
|
||||
private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
|
||||
"create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
|
||||
private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
|
||||
"create", ScriptFunction.class, Object[].class, int.class);
|
||||
|
||||
private static final Class<?> ITERATOR_CLASS = Iterator.class;
|
||||
static {
|
||||
assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
|
||||
@ -2242,7 +2243,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
} else {
|
||||
methodEmitter.loadConstants().load(index).arrayload();
|
||||
if (object instanceof ArrayData) {
|
||||
// avoid cast to non-public ArrayData subclass
|
||||
methodEmitter.checkcast(ArrayData.class);
|
||||
methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
|
||||
} else if (cls != Object.class) {
|
||||
@ -2251,6 +2251,10 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
}
|
||||
}
|
||||
|
||||
private void loadConstantsAndIndex(final Object object, final MethodEmitter methodEmitter) {
|
||||
methodEmitter.loadConstants().load(compiler.getConstantData().add(object));
|
||||
}
|
||||
|
||||
// literal values
|
||||
private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) {
|
||||
final Object value = node.getValue();
|
||||
@ -4323,15 +4327,13 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(functionNode.getId());
|
||||
|
||||
if (functionNode.isProgram() && !compiler.isOnDemandCompilation()) {
|
||||
final CompileUnit fnUnit = functionNode.getCompileUnit();
|
||||
final MethodEmitter createFunction = fnUnit.getClassEmitter().method(
|
||||
final MethodEmitter createFunction = functionNode.getCompileUnit().getClassEmitter().method(
|
||||
EnumSet.of(Flag.PUBLIC, Flag.STATIC), CREATE_PROGRAM_FUNCTION.symbolName(),
|
||||
ScriptFunction.class, ScriptObject.class);
|
||||
createFunction.begin();
|
||||
createFunction._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
|
||||
loadConstant(data, fnUnit, createFunction);
|
||||
loadConstantsAndIndex(data, createFunction);
|
||||
createFunction.load(SCOPE_TYPE, 0);
|
||||
createFunction.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
|
||||
createFunction.invoke(CREATE_FUNCTION_OBJECT);
|
||||
createFunction._return();
|
||||
createFunction.end();
|
||||
}
|
||||
@ -4346,15 +4348,14 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
return;
|
||||
}
|
||||
|
||||
method._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
|
||||
loadConstant(data);
|
||||
loadConstantsAndIndex(data, method);
|
||||
|
||||
if (functionNode.needsParentScope()) {
|
||||
method.loadCompilerConstant(SCOPE);
|
||||
method.invoke(CREATE_FUNCTION_OBJECT);
|
||||
} else {
|
||||
method.loadNull();
|
||||
method.invoke(CREATE_FUNCTION_OBJECT_NO_SCOPE);
|
||||
}
|
||||
method.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
|
||||
}
|
||||
|
||||
// calls on Global class.
|
||||
|
@ -118,13 +118,26 @@ public class ScriptFunctionImpl extends ScriptFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor called by (compiler) generated code for {@link ScriptObject}s.
|
||||
* Factory method called by compiler generated code for functions that need parent scope.
|
||||
*
|
||||
* @param data static function data
|
||||
* @param scope scope object
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
|
||||
* @param scope the parent scope object
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope) {
|
||||
this(data, scope, Global.instance());
|
||||
public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
|
||||
return new ScriptFunctionImpl((RecompilableScriptFunctionData)constants[index], scope, Global.instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called by compiler generated code for functions that don't need parent scope.
|
||||
*
|
||||
* @param constants the generated class' constant array
|
||||
* @param index the index of the {@code RecompilableScriptFunctionData} object in the constants array.
|
||||
* @return a newly created function object
|
||||
*/
|
||||
public static ScriptFunction create(final Object[] constants, final int index) {
|
||||
return create(constants, index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user