8199443: Nashorn multithread bottleneck with "use strict"
Reviewed-by: jlaskey, sundar
This commit is contained in:
parent
19ea0009a6
commit
2ca067436f
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal
@ -56,11 +56,8 @@ public final class Lookup {
|
||||
/** Method handle to the empty setter */
|
||||
public static final MethodHandle EMPTY_SETTER = findOwnMH("emptySetter", void.class, Object.class, Object.class);
|
||||
|
||||
/** Method handle to a getter that only throws type error */
|
||||
public static final MethodHandle TYPE_ERROR_THROWER_GETTER = findOwnMH("typeErrorThrowerGetter", Object.class, Object.class);
|
||||
|
||||
/** Method handle to a setter that only throws type error */
|
||||
public static final MethodHandle TYPE_ERROR_THROWER_SETTER = findOwnMH("typeErrorThrowerSetter", void.class, Object.class, Object.class);
|
||||
/** Method handle to a getter or setter that only throws type error */
|
||||
public static final MethodHandle TYPE_ERROR_THROWER = findOwnMH("typeErrorThrower", Object.class, Object.class);
|
||||
|
||||
/** Method handle to the most generic of getters, the one that returns an Object */
|
||||
public static final MethodType GET_OBJECT_TYPE = MH.type(Object.class, Object.class);
|
||||
@ -114,17 +111,7 @@ public final class Lookup {
|
||||
* @param self self reference
|
||||
* @return undefined (but throws error before return point)
|
||||
*/
|
||||
public static Object typeErrorThrowerGetter(final Object self) {
|
||||
throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter function that always throws type error
|
||||
*
|
||||
* @param self self reference
|
||||
* @param value (ignored)
|
||||
*/
|
||||
public static void typeErrorThrowerSetter(final Object self, final Object value) {
|
||||
public static Object typeErrorThrower(final Object self) {
|
||||
throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
|
||||
|
@ -2978,7 +2978,7 @@ public final class Global extends Scope {
|
||||
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
|
||||
this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER);
|
||||
this.typeErrorThrower = ScriptFunction.createBuiltin("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER);
|
||||
typeErrorThrower.preventExtensions();
|
||||
|
||||
// now initialize Object
|
||||
|
@ -79,9 +79,8 @@ public final class NativeStrictArguments extends ScriptObject {
|
||||
final ScriptFunction func = Global.instance().getTypeErrorThrower();
|
||||
// We have to fill user accessor functions late as these are stored
|
||||
// in this object rather than in the PropertyMap of this object.
|
||||
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
|
||||
initUserAccessors("caller", flags, func, func);
|
||||
initUserAccessors("callee", flags, func, func);
|
||||
initUserAccessors("caller", func, func);
|
||||
initUserAccessors("callee", func, func);
|
||||
|
||||
setArray(ArrayData.allocate(values));
|
||||
this.length = values.length;
|
||||
|
@ -137,8 +137,8 @@ public class ScriptFunction extends ScriptObject {
|
||||
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));
|
||||
newMap = newMap.addPropertyNoHistory(newMap.newUserAccessors("arguments", flags));
|
||||
newMap = newMap.addPropertyNoHistory(newMap.newUserAccessors("caller", flags));
|
||||
return newMap;
|
||||
}
|
||||
|
||||
@ -215,8 +215,8 @@ public class ScriptFunction extends ScriptObject {
|
||||
assert objectSpill == null;
|
||||
if (isStrict() || isBoundFunction()) {
|
||||
final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
|
||||
initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
|
||||
initUserAccessors("arguments", typeErrorThrower, typeErrorThrower);
|
||||
initUserAccessors("caller", typeErrorThrower, typeErrorThrower);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -962,24 +962,19 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
/**
|
||||
* Fast initialization functions for ScriptFunctions that are strict, to avoid
|
||||
* creating setters that probably aren't used. Inject directly into the spill pool
|
||||
* the defaults for "arguments" and "caller"
|
||||
* the defaults for "arguments" and "caller", asserting the property is already
|
||||
* defined in the map.
|
||||
*
|
||||
* @param key property key
|
||||
* @param propertyFlags flags
|
||||
* @param getter getter for {@link UserAccessorProperty}, null if not present or N/A
|
||||
* @param setter setter for {@link UserAccessorProperty}, null if not present or N/A
|
||||
* @param key property key
|
||||
* @param getter getter for {@link UserAccessorProperty}
|
||||
* @param setter setter for {@link UserAccessorProperty}
|
||||
*/
|
||||
protected final void initUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
|
||||
final PropertyMap oldMap = getMap();
|
||||
final int slot = oldMap.getFreeSpillSlot();
|
||||
ensureSpillSize(slot);
|
||||
objectSpill[slot] = new UserAccessorProperty.Accessors(getter, setter);
|
||||
Property newProperty;
|
||||
PropertyMap newMap;
|
||||
do {
|
||||
newProperty = new UserAccessorProperty(key, propertyFlags, slot);
|
||||
newMap = oldMap.addProperty(newProperty);
|
||||
} while (!compareAndSetMap(oldMap, newMap));
|
||||
protected final void initUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) {
|
||||
final PropertyMap map = getMap();
|
||||
final Property property = map.findProperty(key);
|
||||
assert property instanceof UserAccessorProperty;
|
||||
ensureSpillSize(property.getSlot());
|
||||
objectSpill[property.getSlot()] = new UserAccessorProperty.Accessors(getter, setter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user