提交 86732dac 编写于 作者: S sundar

8027137: Merge ScriptFunction and ScriptFunctionImpl

Reviewed-by: attila, hannesw, mhaupt
上级 9c50ad1c
...@@ -54,10 +54,9 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL ...@@ -54,10 +54,9 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP; 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_NEWMAP_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE;
...@@ -282,9 +281,9 @@ public class ClassGenerator { ...@@ -282,9 +281,9 @@ public class ClassGenerator {
assert specs != null; assert specs != null;
if (!specs.isEmpty()) { if (!specs.isEmpty()) {
mi.memberInfoArray(className, specs); mi.memberInfoArray(className, specs);
mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC); mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC);
} else { } else {
mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC); mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_DESC);
} }
if (arityFound) { if (arityFound) {
......
...@@ -38,9 +38,8 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL ...@@ -38,9 +38,8 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIEL
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC3; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC3;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC4; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE;
...@@ -76,7 +75,7 @@ public class ConstructorGenerator extends ClassGenerator { ...@@ -76,7 +75,7 @@ public class ConstructorGenerator extends ClassGenerator {
byte[] getClassBytes() { byte[] getClassBytes() {
// new class extending from ScriptObject // new class extending from ScriptObject
final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE; final String superClass = (constructor != null)? SCRIPTFUNCTION_TYPE : SCRIPTOBJECT_TYPE;
cw.visit(V1_7, ACC_FINAL, className, null, superClass, null); cw.visit(V1_7, ACC_FINAL, className, null, superClass, null);
if (memberCount > 0) { if (memberCount > 0) {
// add fields // add fields
...@@ -182,8 +181,8 @@ public class ConstructorGenerator extends ClassGenerator { ...@@ -182,8 +181,8 @@ public class ConstructorGenerator extends ClassGenerator {
loadMap(mi); loadMap(mi);
} else { } else {
// call Function.<init> // call Function.<init>
superClass = SCRIPTFUNCTIONIMPL_TYPE; superClass = SCRIPTFUNCTION_TYPE;
superDesc = (memberCount > 0) ? SCRIPTFUNCTIONIMPL_INIT_DESC4 : SCRIPTFUNCTIONIMPL_INIT_DESC3; superDesc = (memberCount > 0) ? SCRIPTFUNCTION_INIT_DESC4 : SCRIPTFUNCTION_INIT_DESC3;
mi.loadLiteral(constructor.getName()); mi.loadLiteral(constructor.getName());
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc())); mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc()));
loadMap(mi); loadMap(mi);
......
...@@ -31,10 +31,9 @@ import java.util.Collection; ...@@ -31,10 +31,9 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.Type;
import jdk.nashorn.internal.objects.PrototypeObject;
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.PrototypeObject;
import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Specialization; import jdk.nashorn.internal.runtime.Specialization;
...@@ -88,7 +87,6 @@ public interface StringConstants { ...@@ -88,7 +87,6 @@ public interface StringConstants {
static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class); static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class);
static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class); static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class);
static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class); static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class);
static final Type TYPE_SCRIPTFUNCTIONIMPL = Type.getType(ScriptFunctionImpl.class);
static final Type TYPE_SCRIPTOBJECT = Type.getType(ScriptObject.class); static final Type TYPE_SCRIPTOBJECT = Type.getType(ScriptObject.class);
static final String PROTOTYPE_SUFFIX = "$Prototype"; static final String PROTOTYPE_SUFFIX = "$Prototype";
...@@ -122,17 +120,14 @@ public interface StringConstants { ...@@ -122,17 +120,14 @@ public interface StringConstants {
static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); 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 = "setPrototype";
static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT); static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT);
static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin";
// ScriptFunctionImpl static final String SCRIPTFUNCTION_CREATEBUILTIN_DESC =
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); Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC = static final String SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC =
Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY); Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 = static final String SCRIPTFUNCTION_INIT_DESC3 =
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY); Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 = static final String SCRIPTFUNCTION_INIT_DESC4 =
Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY); Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY);
// ScriptObject // ScriptObject
......
...@@ -77,7 +77,7 @@ public final class ScriptUtils { ...@@ -77,7 +77,7 @@ public final class ScriptUtils {
* @return a synchronizing wrapper function * @return a synchronizing wrapper function
*/ */
public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) { public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
return func.makeSynchronizedFunction(unwrap(sync)); return func.createSynchronized(unwrap(sync));
} }
/** /**
......
...@@ -132,7 +132,6 @@ import jdk.nashorn.internal.ir.WithNode; ...@@ -132,7 +132,6 @@ import jdk.nashorn.internal.ir.WithNode;
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
import jdk.nashorn.internal.parser.Lexer.RegexToken; import jdk.nashorn.internal.parser.Lexer.RegexToken;
import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
...@@ -195,9 +194,9 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex ...@@ -195,9 +194,9 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
"ensureNumber", double.class, Object.class, int.class); "ensureNumber", double.class, Object.class, int.class);
private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class, private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
"create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class); "create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class, private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunction.class,
"create", ScriptFunction.class, Object[].class, int.class); "create", ScriptFunction.class, Object[].class, int.class);
private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class, private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class,
......
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
* A {@code ScriptFunctionImpl} subclass for functions created using {@code Function.prototype.bind}. Such functions
* must track their {@code [[TargetFunction]]} property for purposes of correctly implementing {@code [[HasInstance]]};
* see {@link ScriptFunction#isInstance(ScriptObject)}.
*/
final class BoundScriptFunctionImpl extends ScriptFunctionImpl {
private final ScriptFunction targetFunction;
BoundScriptFunctionImpl(final ScriptFunctionData data, final ScriptFunction targetFunction) {
super(data, Global.instance());
setPrototype(ScriptRuntime.UNDEFINED);
this.targetFunction = targetFunction;
}
@Override
protected ScriptFunction getTargetFunction() {
return targetFunction;
}
}
...@@ -1583,7 +1583,11 @@ public final class Global extends Scope { ...@@ -1583,7 +1583,11 @@ public final class Global extends Scope {
return ScriptFunction.getPrototype(builtinObject); return ScriptFunction.getPrototype(builtinObject);
} }
ScriptObject getFunctionPrototype() { /**
* Get the builtin Function prototype.
* @return the Function.prototype.
*/
public ScriptObject getFunctionPrototype() {
return ScriptFunction.getPrototype(builtinFunction); return ScriptFunction.getPrototype(builtinFunction);
} }
...@@ -1768,7 +1772,12 @@ public final class Global extends Scope { ...@@ -1768,7 +1772,12 @@ public final class Global extends Scope {
return ScriptFunction.getPrototype(getBuiltinFloat64Array()); return ScriptFunction.getPrototype(getBuiltinFloat64Array());
} }
ScriptFunction getTypeErrorThrower() { /**
* Return the function that throws TypeError unconditionally. Used as "poison" methods for certain Function properties.
*
* @return the TypeError throwing function
*/
public ScriptFunction getTypeErrorThrower() {
return typeErrorThrower; return typeErrorThrower;
} }
...@@ -2202,10 +2211,10 @@ public final class Global extends Scope { ...@@ -2202,10 +2211,10 @@ public final class Global extends Scope {
* Adds jjs shell interactive mode builtin functions to global scope. * Adds jjs shell interactive mode builtin functions to global scope.
*/ */
public void addShellBuiltins() { public void addShellBuiltins() {
Object value = ScriptFunctionImpl.makeFunction("input", ShellFunctions.INPUT); Object value = ScriptFunction.createBuiltin("input", ShellFunctions.INPUT);
addOwnProperty("input", Attribute.NOT_ENUMERABLE, value); addOwnProperty("input", Attribute.NOT_ENUMERABLE, value);
value = ScriptFunctionImpl.makeFunction("evalinput", ShellFunctions.EVALINPUT); value = ScriptFunction.createBuiltin("evalinput", ShellFunctions.EVALINPUT);
addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value); addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value);
} }
...@@ -2251,35 +2260,35 @@ public final class Global extends Scope { ...@@ -2251,35 +2260,35 @@ public final class Global extends Scope {
this.setInitialProto(getObjectPrototype()); this.setInitialProto(getObjectPrototype());
// initialize global function properties // initialize global function properties
this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL); this.eval = this.builtinEval = ScriptFunction.createBuiltin("eval", EVAL);
this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT, this.parseInt = ScriptFunction.createBuiltin("parseInt", GlobalFunctions.PARSEINT,
new Specialization[] { new Specialization[] {
new Specialization(GlobalFunctions.PARSEINT_Z), new Specialization(GlobalFunctions.PARSEINT_Z),
new Specialization(GlobalFunctions.PARSEINT_I), new Specialization(GlobalFunctions.PARSEINT_I),
new Specialization(GlobalFunctions.PARSEINT_J), new Specialization(GlobalFunctions.PARSEINT_J),
new Specialization(GlobalFunctions.PARSEINT_OI), new Specialization(GlobalFunctions.PARSEINT_OI),
new Specialization(GlobalFunctions.PARSEINT_O) }); new Specialization(GlobalFunctions.PARSEINT_O) });
this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT); this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN, this.isNaN = ScriptFunction.createBuiltin("isNaN", GlobalFunctions.IS_NAN,
new Specialization[] { new Specialization[] {
new Specialization(GlobalFunctions.IS_NAN_I), new Specialization(GlobalFunctions.IS_NAN_I),
new Specialization(GlobalFunctions.IS_NAN_J), new Specialization(GlobalFunctions.IS_NAN_J),
new Specialization(GlobalFunctions.IS_NAN_D) }); new Specialization(GlobalFunctions.IS_NAN_D) });
this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT); this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);
this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN); this.isNaN = ScriptFunction.createBuiltin("isNaN", GlobalFunctions.IS_NAN);
this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE); this.isFinite = ScriptFunction.createBuiltin("isFinite", GlobalFunctions.IS_FINITE);
this.encodeURI = ScriptFunctionImpl.makeFunction("encodeURI", GlobalFunctions.ENCODE_URI); this.encodeURI = ScriptFunction.createBuiltin("encodeURI", GlobalFunctions.ENCODE_URI);
this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT); this.encodeURIComponent = ScriptFunction.createBuiltin("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
this.decodeURI = ScriptFunctionImpl.makeFunction("decodeURI", GlobalFunctions.DECODE_URI); this.decodeURI = ScriptFunction.createBuiltin("decodeURI", GlobalFunctions.DECODE_URI);
this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT); this.decodeURIComponent = ScriptFunction.createBuiltin("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
this.escape = ScriptFunctionImpl.makeFunction("escape", GlobalFunctions.ESCAPE); this.escape = ScriptFunction.createBuiltin("escape", GlobalFunctions.ESCAPE);
this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE); this.unescape = ScriptFunction.createBuiltin("unescape", GlobalFunctions.UNESCAPE);
this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN); this.print = ScriptFunction.createBuiltin("print", env._print_no_newline ? PRINT : PRINTLN);
this.load = ScriptFunctionImpl.makeFunction("load", LOAD); this.load = ScriptFunction.createBuiltin("load", LOAD);
this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL); this.loadWithNewGlobal = ScriptFunction.createBuiltin("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT); this.exit = ScriptFunction.createBuiltin("exit", EXIT);
this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT); this.quit = ScriptFunction.createBuiltin("quit", EXIT);
// built-in constructors // built-in constructors
this.builtinArray = initConstructorAndSwitchPoint("Array", ScriptFunction.class); this.builtinArray = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
...@@ -2359,7 +2368,7 @@ public final class Global extends Scope { ...@@ -2359,7 +2368,7 @@ public final class Global extends Scope {
// default file name // default file name
addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null); addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
// __noSuchProperty__ hook for ScriptContext search of missing variables // __noSuchProperty__ hook for ScriptContext search of missing variables
final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY); final ScriptFunction noSuchProp = ScriptFunction.createStrictBuiltin(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp); addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
} }
} }
...@@ -2370,17 +2379,17 @@ public final class Global extends Scope { ...@@ -2370,17 +2379,17 @@ public final class Global extends Scope {
final ScriptObject errorProto = getErrorPrototype(); final ScriptObject errorProto = getErrorPrototype();
// Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK); final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", NativeError.GET_STACK);
final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK); final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", NativeError.SET_STACK);
errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack); errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER); final ScriptFunction getLineNumber = ScriptFunction.createBuiltin("getLineNumber", NativeError.GET_LINENUMBER);
final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER); final ScriptFunction setLineNumber = ScriptFunction.createBuiltin("setLineNumber", NativeError.SET_LINENUMBER);
errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber); errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER); final ScriptFunction getColumnNumber = ScriptFunction.createBuiltin("getColumnNumber", NativeError.GET_COLUMNNUMBER);
final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER); final ScriptFunction setColumnNumber = ScriptFunction.createBuiltin("setColumnNumber", NativeError.SET_COLUMNNUMBER);
errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber); errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME); final ScriptFunction getFileName = ScriptFunction.createBuiltin("getFileName", NativeError.GET_FILENAME);
final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME); final ScriptFunction setFileName = ScriptFunction.createBuiltin("setFileName", NativeError.SET_FILENAME);
errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName); errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
// ECMA 15.11.4.2 Error.prototype.name // ECMA 15.11.4.2 Error.prototype.name
...@@ -2420,14 +2429,14 @@ public final class Global extends Scope { ...@@ -2420,14 +2429,14 @@ public final class Global extends Scope {
private void initScripting(final ScriptEnvironment scriptEnv) { private void initScripting(final ScriptEnvironment scriptEnv) {
ScriptObject value; ScriptObject value;
value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE); value = ScriptFunction.createBuiltin("readLine", ScriptingFunctions.READLINE);
addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value); addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY); value = ScriptFunction.createBuiltin("readFully", ScriptingFunctions.READFULLY);
addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value); addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
final String execName = ScriptingFunctions.EXEC_NAME; final String execName = ScriptingFunctions.EXEC_NAME;
value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC); value = ScriptFunction.createBuiltin(execName, ScriptingFunctions.EXEC);
value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false); value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false);
addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value); addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
...@@ -2610,7 +2619,7 @@ public final class Global extends Scope { ...@@ -2610,7 +2619,7 @@ public final class Global extends Scope {
this.builtinFunction = initConstructor("Function", ScriptFunction.class); this.builtinFunction = initConstructor("Function", ScriptFunction.class);
// create global anonymous function // create global anonymous function
final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(); final ScriptFunction anon = ScriptFunction.createAnonymous();
// need to copy over members of Function.prototype to anon function // need to copy over members of Function.prototype to anon function
anon.addBoundProperties(getFunctionPrototype()); anon.addBoundProperties(getFunctionPrototype());
...@@ -2622,10 +2631,7 @@ public final class Global extends Scope { ...@@ -2622,10 +2631,7 @@ public final class Global extends Scope {
anon.deleteOwnProperty(anon.getMap().findProperty("prototype")); anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
// use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3 // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0); this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER);
typeErrorThrower.setPrototype(UNDEFINED);
// Non-constructor built-in functions do not have "prototype" property
typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
typeErrorThrower.preventExtensions(); typeErrorThrower.preventExtensions();
// now initialize Object // now initialize Object
...@@ -2636,8 +2642,8 @@ public final class Global extends Scope { ...@@ -2636,8 +2642,8 @@ public final class Global extends Scope {
// ES6 draft compliant __proto__ property of Object.prototype // ES6 draft compliant __proto__ property of Object.prototype
// accessors on Object.prototype for "__proto__" // accessors on Object.prototype for "__proto__"
final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", NativeObject.GET__PROTO__); final ScriptFunction getProto = ScriptFunction.createBuiltin("getProto", NativeObject.GET__PROTO__);
final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__); final ScriptFunction setProto = ScriptFunction.createBuiltin("setProto", NativeObject.SET__PROTO__);
ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto); ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
// Function valued properties of Function.prototype were not properly // Function valued properties of Function.prototype were not properly
......
...@@ -148,8 +148,8 @@ public final class NativeError extends ScriptObject { ...@@ -148,8 +148,8 @@ public final class NativeError extends ScriptObject {
initException(sobj); initException(sobj);
sobj.delete(STACK, false); sobj.delete(STACK, false);
if (! sobj.has("stack")) { if (! sobj.has("stack")) {
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK); final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", GET_STACK);
final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK); final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", SET_STACK);
sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack); sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
} }
return UNDEFINED; return UNDEFINED;
......
...@@ -621,11 +621,11 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -621,11 +621,11 @@ public final class NativeJSAdapter extends ScriptObject {
if (find != null) { if (find != null) {
final Object value = find.getObjectValue(); final Object value = find.getObjectValue();
if (value instanceof ScriptFunction) { if (value instanceof ScriptFunction) {
final ScriptFunctionImpl func = (ScriptFunctionImpl)value; final ScriptFunction func = (ScriptFunction)value;
// TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
// to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), func.createBound(this, new Object[] { name })), 0, Object.class),
testJSAdaptor(adaptee, null, null, null), testJSAdaptor(adaptee, null, null, null),
adaptee.getProtoSwitchPoint(__call__, find.getOwner())); adaptee.getProtoSwitchPoint(__call__, find.getOwner()));
} }
......
...@@ -96,7 +96,7 @@ public final class NativeJava { ...@@ -96,7 +96,7 @@ public final class NativeJava {
@Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(name="synchronized", attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object synchronizedFunc(final Object self, final Object func, final Object obj) { public static Object synchronizedFunc(final Object self, final Object func, final Object obj) {
if (func instanceof ScriptFunction) { if (func instanceof ScriptFunction) {
return ((ScriptFunction)func).makeSynchronizedFunction(obj); return ((ScriptFunction)func).createSynchronized(obj);
} }
throw typeError("not.a.function", ScriptRuntime.safeToString(func)); throw typeError("not.a.function", ScriptRuntime.safeToString(func));
......
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
import java.util.ArrayList;
import jdk.nashorn.internal.runtime.AccessorProperty;
import jdk.nashorn.internal.runtime.GlobalFunctions;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptFunctionData;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Specialization;
/**
* Concrete implementation of ScriptFunction. This sets correct map for the
* function objects -- to expose properties like "prototype", "length" etc.
*/
public class ScriptFunctionImpl extends ScriptFunction {
/** Reference to constructor prototype. */
private Object prototype;
// property map for strict mode functions
private static final PropertyMap strictmodemap$;
// property map for bound functions
private static final PropertyMap boundfunctionmap$;
// property map for non-strict, non-bound functions.
private static final PropertyMap map$;
// Marker object for lazily initialized prototype object
private static final Object LAZY_PROTOTYPE = new Object();
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs, final Global global) {
super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
init(global);
}
/**
* Constructor called by Nasgen generated code, no membercount, use the default map.
* Creates builtin functions only.
*
* @param name name of function
* @param invokeHandle handle for invocation
* @param specs specialized versions of this method, if available, null otherwise
*/
ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
this(name, invokeHandle, specs, Global.instance());
}
private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs, final Global global) {
super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
init(global);
}
/**
* Constructor called by Nasgen generated code, no membercount, use the map passed as argument.
* Creates builtin functions only.
*
* @param name name of function
* @param invokeHandle handle for invocation
* @param map initial property map
* @param specs specialized versions of this method, if available, null otherwise
*/
ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
this(name, invokeHandle, map, specs, Global.instance());
}
private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags, final Global global) {
super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
init(global);
}
/**
* Constructor called by Global.newScriptFunction (runtime).
*
* @param name name of function
* @param methodHandle handle for invocation
* @param scope scope object
* @param specs specialized versions of this method, if available, null otherwise
* @param flags {@link ScriptFunctionData} flags
*/
ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags) {
this(name, methodHandle, scope, specs, flags, Global.instance());
}
private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
super(data, getMap(data.isStrict()), scope);
init(global);
}
/**
* Factory method called by compiler generated code for functions that need parent scope.
*
* @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 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);
}
/**
* Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
* @param data the script function data for the bound function.
* @param global the global object
*/
ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
super(data, boundfunctionmap$, null);
init(global);
}
static {
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$);
}
private static PropertyMap createStrictModeMap(final PropertyMap map) {
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
PropertyMap newMap = map;
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
return newMap;
}
private static boolean isStrict(final int flags) {
return (flags & ScriptFunctionData.IS_STRICT) != 0;
}
// Choose the map based on strict mode!
private static PropertyMap getMap(final boolean strict) {
return strict ? strictmodemap$ : map$;
}
private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
// Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
// ECMAScript 5.1 section 15.3.4.5
return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
}
// 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 anonmap$ = PropertyMap.newMap();
AnonymousFunction() {
super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
}
}
static ScriptFunctionImpl newAnonymousFunction() {
return new AnonymousFunction();
}
private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
func.setPrototype(UNDEFINED);
// Non-constructor built-in functions do not have "prototype" property
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
return func;
}
/**
* Factory method for non-constructor built-in functions
*
* @param name function name
* @param methodHandle handle for invocation
* @param specs specialized versions of function if available, null otherwise
* @return new ScriptFunction
*/
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
}
/**
* Factory method for non-constructor built-in, strict functions
*
* @param name function name
* @param methodHandle handle for invocation
* @return new ScriptFunction
*/
static ScriptFunction makeStrictFunction(final String name, final MethodHandle methodHandle) {
return makeFunction(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT );
}
/**
* Factory method for non-constructor built-in functions
*
* @param name function name
* @param methodHandle handle for invocation
* @return new ScriptFunction
*/
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle) {
return makeFunction(name, methodHandle, null);
}
@Override
public ScriptFunction makeSynchronizedFunction(final Object sync) {
final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
return makeFunction(getName(), mh);
}
/**
* Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
* can expose it.
* @param self the self to bind to this function. Can be null (in which case, null is bound as this).
* @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
* @return a function with the specified self and parameters bound.
*/
@Override
public ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
return super.makeBoundFunction(self, args);
}
/**
* This method is used to create a bound function based on this function.
*
* @param data the {@code ScriptFunctionData} specifying the functions immutable portion.
* @return a function initialized from the specified data. Its parent scope will be set to null, therefore the
* passed in data should not expect a callee.
*/
@Override
protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) {
return new BoundScriptFunctionImpl(data, getTargetFunction());
}
// return Object.prototype - used by "allocate"
@Override
protected final ScriptObject getObjectPrototype() {
return Global.objectPrototype();
}
@Override
public final Object getPrototype() {
if (prototype == LAZY_PROTOTYPE) {
prototype = new PrototypeObject(this);
}
return prototype;
}
@Override
public final void setPrototype(final Object newProto) {
if (newProto instanceof ScriptObject && newProto != this.prototype && allocatorMap != null) {
// Replace our current allocator map with one that is associated with the new prototype.
allocatorMap = allocatorMap.changeProto((ScriptObject)newProto);
}
this.prototype = newProto;
}
// Internals below..
private void init(final Global global) {
this.setInitialProto(global.getFunctionPrototype());
this.prototype = LAZY_PROTOTYPE;
// We have to fill user accessor functions late as these are stored
// in this object rather than in the PropertyMap of this object.
assert objectSpill == null;
final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
if (findProperty("arguments", true) != null) {
initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
}
if (findProperty("caller", true) != null) {
initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
}
}
}
...@@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime; ...@@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.atomic.LongAdder;
/** /**
* Helper class to manage property listeners and notification. * Helper class to manage property listeners and notification.
...@@ -37,8 +38,15 @@ public class PropertyListeners { ...@@ -37,8 +38,15 @@ public class PropertyListeners {
private Map<String, WeakPropertyMapSet> listeners; private Map<String, WeakPropertyMapSet> listeners;
// These counters are updated in debug mode // These counters are updated in debug mode
private static int listenersAdded; private static LongAdder listenersAdded;
private static int listenersRemoved; private static LongAdder listenersRemoved;
static {
if (Context.DEBUG) {
listenersAdded = new LongAdder();
listenersRemoved = new LongAdder();
}
}
/** /**
* Copy constructor * Copy constructor
...@@ -54,16 +62,16 @@ public class PropertyListeners { ...@@ -54,16 +62,16 @@ public class PropertyListeners {
* Return aggregate listeners added to all PropertyListenerManagers * Return aggregate listeners added to all PropertyListenerManagers
* @return the listenersAdded * @return the listenersAdded
*/ */
public static int getListenersAdded() { public static long getListenersAdded() {
return listenersAdded; return listenersAdded.longValue();
} }
/** /**
* Return aggregate listeners removed from all PropertyListenerManagers * Return aggregate listeners removed from all PropertyListenerManagers
* @return the listenersRemoved * @return the listenersRemoved
*/ */
public static int getListenersRemoved() { public static long getListenersRemoved() {
return listenersRemoved; return listenersRemoved.longValue();
} }
/** /**
...@@ -122,7 +130,7 @@ public class PropertyListeners { ...@@ -122,7 +130,7 @@ public class PropertyListeners {
*/ */
synchronized final void addListener(final String key, final PropertyMap propertyMap) { synchronized final void addListener(final String key, final PropertyMap propertyMap) {
if (Context.DEBUG) { if (Context.DEBUG) {
listenersAdded++; listenersAdded.increment();
} }
if (listeners == null) { if (listeners == null) {
listeners = new WeakHashMap<>(); listeners = new WeakHashMap<>();
...@@ -151,6 +159,9 @@ public class PropertyListeners { ...@@ -151,6 +159,9 @@ public class PropertyListeners {
propertyMap.propertyAdded(prop); propertyMap.propertyAdded(prop);
} }
listeners.remove(prop.getKey()); listeners.remove(prop.getKey());
if (Context.DEBUG) {
listenersRemoved.increment();
}
} }
} }
} }
...@@ -168,6 +179,9 @@ public class PropertyListeners { ...@@ -168,6 +179,9 @@ public class PropertyListeners {
propertyMap.propertyDeleted(prop); propertyMap.propertyDeleted(prop);
} }
listeners.remove(prop.getKey()); listeners.remove(prop.getKey());
if (Context.DEBUG) {
listenersRemoved.increment();
}
} }
} }
} }
...@@ -187,6 +201,9 @@ public class PropertyListeners { ...@@ -187,6 +201,9 @@ public class PropertyListeners {
propertyMap.propertyModified(oldProp, newProp); propertyMap.propertyModified(oldProp, newProp);
} }
listeners.remove(oldProp.getKey()); listeners.remove(oldProp.getKey());
if (Context.DEBUG) {
listenersRemoved.increment();
}
} }
} }
} }
......
...@@ -42,6 +42,7 @@ import java.util.HashMap; ...@@ -42,6 +42,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.atomic.LongAdder;
import jdk.nashorn.internal.scripts.JO; import jdk.nashorn.internal.scripts.JO;
/** /**
...@@ -114,7 +115,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -114,7 +115,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
} }
if (Context.DEBUG) { if (Context.DEBUG) {
count++; count.increment();
} }
} }
...@@ -135,8 +136,8 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -135,8 +136,8 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
this.freeSlots = propertyMap.freeSlots; this.freeSlots = propertyMap.freeSlots;
if (Context.DEBUG) { if (Context.DEBUG) {
count++; count.increment();
clonedCount++; clonedCount.increment();
} }
} }
...@@ -328,7 +329,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -328,7 +329,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
if (sp != null) { if (sp != null) {
protoGetSwitches.remove(key); protoGetSwitches.remove(key);
if (Context.DEBUG) { if (Context.DEBUG) {
protoInvalidations++; protoInvalidations.increment();
} }
SwitchPoint.invalidateAll(new SwitchPoint[] { sp }); SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
} }
...@@ -343,7 +344,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -343,7 +344,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
final int size = protoGetSwitches.size(); final int size = protoGetSwitches.size();
if (size > 0) { if (size > 0) {
if (Context.DEBUG) { if (Context.DEBUG) {
protoInvalidations += size; protoInvalidations.add(size);
} }
SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[size])); SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[size]));
protoGetSwitches.clear(); protoGetSwitches.clear();
...@@ -713,7 +714,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -713,7 +714,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
} }
if (Context.DEBUG && cachedMap != null) { if (Context.DEBUG && cachedMap != null) {
protoHistoryHit++; protoHistoryHit.increment();
} }
return cachedMap; return cachedMap;
...@@ -762,7 +763,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -762,7 +763,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
if (historicMap != null) { if (historicMap != null) {
if (Context.DEBUG) { if (Context.DEBUG) {
historyHit++; historyHit.increment();
} }
return historicMap; return historicMap;
...@@ -910,7 +911,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -910,7 +911,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
} }
if (Context.DEBUG) { if (Context.DEBUG) {
setProtoNewMapCount++; setProtoNewMapCount.increment();
} }
final PropertyMap newMap = new PropertyMap(this); final PropertyMap newMap = new PropertyMap(this);
...@@ -1030,52 +1031,62 @@ public final class PropertyMap implements Iterable<Object>, Serializable { ...@@ -1030,52 +1031,62 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
} }
// counters updated only in debug mode // counters updated only in debug mode
private static int count; private static LongAdder count;
private static int clonedCount; private static LongAdder clonedCount;
private static int historyHit; private static LongAdder historyHit;
private static int protoInvalidations; private static LongAdder protoInvalidations;
private static int protoHistoryHit; private static LongAdder protoHistoryHit;
private static int setProtoNewMapCount; private static LongAdder setProtoNewMapCount;
static {
if (Context.DEBUG) {
count = new LongAdder();
clonedCount = new LongAdder();
historyHit = new LongAdder();
protoInvalidations = new LongAdder();
protoHistoryHit = new LongAdder();
setProtoNewMapCount = new LongAdder();
}
}
/** /**
* @return Total number of maps. * @return Total number of maps.
*/ */
public static int getCount() { public static long getCount() {
return count; return count.longValue();
} }
/** /**
* @return The number of maps that were cloned. * @return The number of maps that were cloned.
*/ */
public static int getClonedCount() { public static long getClonedCount() {
return clonedCount; return clonedCount.longValue();
} }
/** /**
* @return The number of times history was successfully used. * @return The number of times history was successfully used.
*/ */
public static int getHistoryHit() { public static long getHistoryHit() {
return historyHit; return historyHit.longValue();
} }
/** /**
* @return The number of times prototype changes caused invalidation. * @return The number of times prototype changes caused invalidation.
*/ */
public static int getProtoInvalidations() { public static long getProtoInvalidations() {
return protoInvalidations; return protoInvalidations.longValue();
} }
/** /**
* @return The number of times proto history was successfully used. * @return The number of times proto history was successfully used.
*/ */
public static int getProtoHistoryHit() { public static long getProtoHistoryHit() {
return protoHistoryHit; return protoHistoryHit.longValue();
} }
/** /**
* @return The number of times prototypes were modified. * @return The number of times prototypes were modified.
*/ */
public static int getSetProtoNewMapCount() { public static long getSetProtoNewMapCount() {
return setProtoNewMapCount; return setProtoNewMapCount.longValue();
} }
} }
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* questions. * questions.
*/ */
package jdk.nashorn.internal.objects; package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
...@@ -31,17 +31,12 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; ...@@ -31,17 +31,12 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.util.ArrayList; import java.util.ArrayList;
import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
/** /**
* Instances of this class serve as "prototype" object for script functions. * Instances of this class serve as "prototype" object for script functions.
* The purpose is to expose "constructor" property from "prototype". Also, nasgen * The purpose is to expose "constructor" property from "prototype". Also, nasgen
* generated prototype classes extend from this class. * generated prototype classes extend from this class.
*
*/ */
public class PrototypeObject extends ScriptObject { public class PrototypeObject extends ScriptObject {
private static final PropertyMap map$; private static final PropertyMap map$;
...@@ -61,7 +56,10 @@ public class PrototypeObject extends ScriptObject { ...@@ -61,7 +56,10 @@ public class PrototypeObject extends ScriptObject {
super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$); super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
} }
PrototypeObject() { /**
* Prototype constructor
*/
protected PrototypeObject() {
this(Global.instance(), map$); this(Global.instance(), map$);
} }
...@@ -70,11 +68,16 @@ public class PrototypeObject extends ScriptObject { ...@@ -70,11 +68,16 @@ public class PrototypeObject extends ScriptObject {
* *
* @param map property map * @param map property map
*/ */
PrototypeObject(final PropertyMap map) { protected PrototypeObject(final PropertyMap map) {
this(Global.instance(), map); this(Global.instance(), map);
} }
PrototypeObject(final ScriptFunction func) { /**
* PropertyObject constructor
*
* @param func constructor function
*/
protected PrototypeObject(final ScriptFunction func) {
this(Global.instance(), map$); this(Global.instance(), map$);
this.constructor = func; this.constructor = func;
} }
...@@ -84,7 +87,7 @@ public class PrototypeObject extends ScriptObject { ...@@ -84,7 +87,7 @@ public class PrototypeObject extends ScriptObject {
* @param self self reference * @param self self reference
* @return constructor, probably, but not necessarily, a {@link ScriptFunction} * @return constructor, probably, but not necessarily, a {@link ScriptFunction}
*/ */
static Object getConstructor(final Object self) { public static Object getConstructor(final Object self) {
return (self instanceof PrototypeObject) ? return (self instanceof PrototypeObject) ?
((PrototypeObject)self).getConstructor() : ((PrototypeObject)self).getConstructor() :
UNDEFINED; UNDEFINED;
...@@ -95,7 +98,7 @@ public class PrototypeObject extends ScriptObject { ...@@ -95,7 +98,7 @@ public class PrototypeObject extends ScriptObject {
* @param self self reference * @param self self reference
* @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction} * @param constructor constructor, probably, but not necessarily, a {@link ScriptFunction}
*/ */
static void setConstructor(final Object self, final Object constructor) { public static void setConstructor(final Object self, final Object constructor) {
if (self instanceof PrototypeObject) { if (self instanceof PrototypeObject) {
((PrototypeObject)self).setConstructor(constructor); ((PrototypeObject)self).setConstructor(constructor);
} }
......
...@@ -397,7 +397,7 @@ public abstract class ScriptFunctionData implements Serializable { ...@@ -397,7 +397,7 @@ public abstract class ScriptFunctionData implements Serializable {
/** /**
* This method is used to create the immutable portion of a bound function. * This method is used to create the immutable portion of a bound function.
* See {@link ScriptFunction#makeBoundFunction(Object, Object[])} * See {@link ScriptFunction#createBound(Object, Object[])}
* *
* @param fn the original function being bound * @param fn the original function being bound
* @param self this reference to bind. Can be null. * @param self this reference to bind. Can be null.
......
...@@ -64,6 +64,7 @@ import java.util.LinkedHashSet; ...@@ -64,6 +64,7 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.LongAdder;
import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
...@@ -211,7 +212,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable { ...@@ -211,7 +212,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
*/ */
public ScriptObject(final PropertyMap map) { public ScriptObject(final PropertyMap map) {
if (Context.DEBUG) { if (Context.DEBUG) {
ScriptObject.count++; ScriptObject.count.increment();
} }
this.arrayData = ArrayData.EMPTY_ARRAY; this.arrayData = ArrayData.EMPTY_ARRAY;
this.setMap(map == null ? PropertyMap.newMap() : map); this.setMap(map == null ? PropertyMap.newMap() : map);
...@@ -2316,7 +2317,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable { ...@@ -2316,7 +2317,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
MH.dropArguments( MH.dropArguments(
MH.constant( MH.constant(
ScriptFunction.class, ScriptFunction.class,
func.makeBoundFunction(thiz, new Object[] { name })), func.createBound(thiz, new Object[] { name })),
0, 0,
Object.class), Object.class),
NashornGuards.combineGuards( NashornGuards.combineGuards(
...@@ -2422,7 +2423,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable { ...@@ -2422,7 +2423,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return UNDEFINED; return UNDEFINED;
} }
return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name}); return ((ScriptFunction)value).createBound(this, new Object[] {name});
} }
private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) { private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
...@@ -3811,15 +3812,20 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable { ...@@ -3811,15 +3812,20 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
} }
/** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */ /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
private static int count; private static LongAdder count;
static {
if (Context.DEBUG) {
count = new LongAdder();
}
}
/** /**
* Get number of {@code ScriptObject} instances created. If not running in debug * Get number of {@code ScriptObject} instances created. If not running in debug
* mode this is always 0 * mode this is always 0
* *
* @return number of ScriptObjects created * @return number of ScriptObjects created
*/ */
public static int getCount() { public static long getCount() {
return count; return count.longValue();
} }
} }
...@@ -352,7 +352,7 @@ public final class WithObject extends Scope { ...@@ -352,7 +352,7 @@ public final class WithObject extends Scope {
} }
private static Object bindToExpression(final ScriptFunction fn, final Object receiver) { private static Object bindToExpression(final ScriptFunction fn, final Object receiver) {
return fn.makeBoundFunction(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY); return fn.createBound(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
} }
private MethodHandle expressionGuard(final String name, final ScriptObject owner) { private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
......
...@@ -49,7 +49,6 @@ import jdk.nashorn.api.scripting.JSObject; ...@@ -49,7 +49,6 @@ import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.lookup.MethodHandleFunctionality; import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.OptimisticReturnFilters; import jdk.nashorn.internal.runtime.OptimisticReturnFilters;
...@@ -396,8 +395,8 @@ public final class Bootstrap { ...@@ -396,8 +395,8 @@ public final class Bootstrap {
* @throws ECMAException with {@code TypeError} if the object is not a callable. * @throws ECMAException with {@code TypeError} if the object is not a callable.
*/ */
public static Object bindCallable(final Object callable, final Object boundThis, final Object[] boundArgs) { public static Object bindCallable(final Object callable, final Object boundThis, final Object[] boundArgs) {
if (callable instanceof ScriptFunctionImpl) { if (callable instanceof ScriptFunction) {
return ((ScriptFunctionImpl)callable).makeBoundFunction(boundThis, boundArgs); return ((ScriptFunction)callable).createBound(boundThis, boundArgs);
} else if (callable instanceof BoundCallable) { } else if (callable instanceof BoundCallable) {
return ((BoundCallable)callable).bind(boundArgs); return ((BoundCallable)callable).bind(boundArgs);
} else if (isCallable(callable)) { } else if (isCallable(callable)) {
......
...@@ -43,6 +43,7 @@ import java.util.Map.Entry; ...@@ -43,6 +43,7 @@ import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;
import jdk.internal.dynalink.ChainedCallSite; import jdk.internal.dynalink.ChainedCallSite;
import jdk.internal.dynalink.DynamicLinker; import jdk.internal.dynalink.DynamicLinker;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
...@@ -70,7 +71,7 @@ public class LinkerCallSite extends ChainedCallSite { ...@@ -70,7 +71,7 @@ public class LinkerCallSite extends ChainedCallSite {
LinkerCallSite(final NashornCallSiteDescriptor descriptor) { LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
super(descriptor); super(descriptor);
if (Context.DEBUG) { if (Context.DEBUG) {
LinkerCallSite.count++; LinkerCallSite.count.increment();
} }
} }
...@@ -173,7 +174,7 @@ public class LinkerCallSite extends ChainedCallSite { ...@@ -173,7 +174,7 @@ public class LinkerCallSite extends ChainedCallSite {
* @return self reference * @return self reference
*/ */
public static Object increaseMissCount(final String desc, final Object self) { public static Object increaseMissCount(final String desc, final Object self) {
++missCount; missCount.increment();
if (r.nextInt(100) < missSamplingPercentage) { if (r.nextInt(100) < missSamplingPercentage) {
final AtomicInteger i = missCounts.get(desc); final AtomicInteger i = missCounts.get(desc);
if (i == null) { if (i == null) {
...@@ -509,12 +510,19 @@ public class LinkerCallSite extends ChainedCallSite { ...@@ -509,12 +510,19 @@ public class LinkerCallSite extends ChainedCallSite {
} }
// counters updated in debug mode // counters updated in debug mode
private static int count; private static LongAdder count;
private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>(); private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>();
private static int missCount; private static LongAdder missCount;
private static final Random r = new Random(); private static final Random r = new Random();
private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1); private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
static {
if (Context.DEBUG) {
count = new LongAdder();
missCount = new LongAdder();
}
}
@Override @Override
protected int getMaxChainLength() { protected int getMaxChainLength() {
return 8; return 8;
...@@ -524,16 +532,16 @@ public class LinkerCallSite extends ChainedCallSite { ...@@ -524,16 +532,16 @@ public class LinkerCallSite extends ChainedCallSite {
* Get the callsite count * Get the callsite count
* @return the count * @return the count
*/ */
public static int getCount() { public static long getCount() {
return count; return count.longValue();
} }
/** /**
* Get the callsite miss count * Get the callsite miss count
* @return the missCount * @return the missCount
*/ */
public static int getMissCount() { public static long getMissCount() {
return missCount; return missCount.longValue();
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册