提交 8a2e14fa 编写于 作者: S sundar

8044760: Avoid PropertyMap duplicate for global instances

Reviewed-by: attila, hannesw
上级 73c1f91e
......@@ -447,12 +447,7 @@ public final class Global extends ScriptObject implements Scope {
// null check on context
context.getClass();
/*
* Duplicate global's map and use it. This way the initial Map filled
* by nasgen (referenced from static field in this class) is retained
* 'as is' (as that one is process wide singleton.
*/
return $nasgenmap$.duplicate();
return $nasgenmap$;
}
/**
......
......@@ -222,7 +222,6 @@ public final class NativeDebug extends ScriptObject {
out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
out.println("PropertyMap count " + PropertyMap.getCount());
out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit());
......
......@@ -145,21 +145,6 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
this(propertyMap, propertyMap.properties);
}
/**
* Duplicates this PropertyMap instance. This is used to duplicate 'shared'
* maps {@link PropertyMap} used as process wide singletons. Shared maps are
* duplicated for every global scope object. That way listeners, proto and property
* histories are scoped within a global scope.
*
* @return Duplicated {@link PropertyMap}.
*/
public PropertyMap duplicate() {
if (Context.DEBUG) {
duplicatedCount++;
}
return new PropertyMap(this.properties, this.className, 0, 0, 0, containsArrayKeys());
}
private void writeObject(final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(properties.getProperties());
......@@ -968,7 +953,6 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
// counters updated only in debug mode
private static int count;
private static int clonedCount;
private static int duplicatedCount;
private static int historyHit;
private static int protoInvalidations;
private static int protoHistoryHit;
......@@ -988,13 +972,6 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
return clonedCount;
}
/**
* @return The number of maps that are duplicated.
*/
public static int getDuplicatedCount() {
return duplicatedCount;
}
/**
* @return The number of times history was successfully used.
*/
......
......@@ -160,7 +160,8 @@ public abstract class ScriptObject implements PropertyAccess {
static final MethodHandle GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
private static final MethodHandle TRUNCATINGFILTER = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH_S("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
private static final MethodHandle KNOWNFUNCPROPGUARDPROTO = findOwnMH_S("knownFunctionPropertyGuardProto", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, int.class, ScriptFunction.class);
private static final ArrayList<MethodHandle> PROTO_FILTERS = new ArrayList<>();
......@@ -2271,13 +2272,20 @@ public abstract class ScriptObject implements PropertyAccess {
if (scopeAccess && func.isStrict()) {
mh = bindTo(mh, UNDEFINED);
}
return new GuardedInvocation(
mh,
//TODO this always does a scriptobject check
getKnownFunctionPropertyGuard(
find.isSelf()?
getKnownFunctionPropertyGuardSelf(
getMap(),
find.getGetter(Object.class, INVALID_PROGRAM_POINT),
func)
:
//TODO this always does a scriptobject check
getKnownFunctionPropertyGuardProto(
getMap(),
find.getGetter(Object.class, INVALID_PROGRAM_POINT),
find.getOwner(),
find.getProtoChainLength(),
func),
getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
//TODO this doesn't need a ClassCastException as guard always checks script object
......@@ -3595,15 +3603,51 @@ public abstract class ScriptObject implements PropertyAccess {
return MH.findStatic(MethodHandles.lookup(), ScriptObject.class, name, MH.type(rtype, types));
}
private static MethodHandle getKnownFunctionPropertyGuard(final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
return MH.insertArguments(KNOWNFUNCPROPGUARD, 1, map, getter, where, func);
private static MethodHandle getKnownFunctionPropertyGuardSelf(final PropertyMap map, final MethodHandle getter, final ScriptFunction func) {
return MH.insertArguments(KNOWNFUNCPROPGUARDSELF, 1, map, getter, func);
}
@SuppressWarnings("unused")
private static boolean knownFunctionPropertyGuard(final Object self, final PropertyMap map, final MethodHandle getter, final Object where, final ScriptFunction func) {
private static boolean knownFunctionPropertyGuardSelf(final Object self, final PropertyMap map, final MethodHandle getter, final ScriptFunction func) {
if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) {
try {
return getter.invokeExact(where) == func;
return getter.invokeExact(self) == func;
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
throw new RuntimeException(t);
}
}
return false;
}
private static MethodHandle getKnownFunctionPropertyGuardProto(final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) {
return MH.insertArguments(KNOWNFUNCPROPGUARDPROTO, 1, map, getter, depth, func);
}
@SuppressWarnings("unused")
private static ScriptObject getProto(final ScriptObject self, final int depth) {
ScriptObject proto = self;
for (int d = 0; d < depth; d++) {
proto = proto.getProto();
if (proto == null) {
return null;
}
}
return proto;
}
@SuppressWarnings("unused")
private static boolean knownFunctionPropertyGuardProto(final Object self, final PropertyMap map, final MethodHandle getter, final int depth, final ScriptFunction func) {
if (self instanceof ScriptObject && ((ScriptObject)self).getMap() == map) {
final ScriptObject proto = getProto((ScriptObject)self, depth);
if (proto == null) {
return false;
}
try {
return getter.invokeExact((Object)proto) == func;
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册