Java 类java.lang.invoke.SwitchPoint 实例源码

项目:OpenJSharp    文件:ContinuousArrayData.java   
/**
 * Return a fast linked array getter, or null if we have to dispatch to super class
 * @param desc     descriptor
 * @param request  link request
 * @return invocation or null if needs to be sent to slow relink
 */
@Override
public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
    final MethodType callType   = desc.getMethodType();
    final Class<?>   indexType  = callType.parameterType(1);
    final Class<?>   returnType = callType.returnType();

    if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
        final Object[] args  = request.getArguments();
        final int      index = (int)args[args.length - 1];

        if (has(index)) {
            final MethodHandle getArray     = ScriptObject.GET_ARRAY.methodHandle();
            final int          programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT;
            MethodHandle       getElement   = getElementGetter(returnType, programPoint);
            if (getElement != null) {
                getElement = MH.filterArguments(getElement, 0, MH.asType(getArray, getArray.type().changeReturnType(clazz)));
                final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
                return new GuardedInvocation(getElement, guard, (SwitchPoint)null, ClassCastException.class);
            }
        }
    }

    return null;
}
项目:OpenJSharp    文件:ContinuousArrayData.java   
/**
 * Return a fast linked array setter, or null if we have to dispatch to super class
 * @param desc     descriptor
 * @param request  link request
 * @return invocation or null if needs to be sent to slow relink
 */
@Override
public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
    final MethodType callType    = desc.getMethodType();
    final Class<?>   indexType   = callType.parameterType(1);
    final Class<?>   elementType = callType.parameterType(2);

    if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
        final Object[]        args  = request.getArguments();
        final int             index = (int)args[args.length - 2];

        if (hasRoomFor(index)) {
            MethodHandle setElement = getElementSetter(elementType); //Z(continuousarraydata, int, int), return true if successful
            if (setElement != null) {
                //else we are dealing with a wider type than supported by this callsite
                MethodHandle getArray = ScriptObject.GET_ARRAY.methodHandle();
                getArray   = MH.asType(getArray, getArray.type().changeReturnType(getClass()));
                setElement = MH.filterArguments(setElement, 0, getArray);
                final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
                return new GuardedInvocation(setElement, guard, (SwitchPoint)null, ClassCastException.class); //CCE if not a scriptObject anymore
            }
        }
    }

    return null;
}
项目:OpenJSharp    文件:ScriptObject.java   
/**
 * Find the appropriate GETINDEX method for an invoke dynamic call.
 *
 * @param desc    the call site descriptor
 * @param request the link request
 *
 * @return GuardedInvocation to be invoked at call site.
 */
protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
    final MethodType callType                = desc.getMethodType();
    final Class<?>   returnType              = callType.returnType();
    final Class<?>   returnClass             = returnType.isPrimitive() ? returnType : Object.class;
    final Class<?>   keyClass                = callType.parameterType(1);
    final boolean    explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);

    final String name;
    if (returnClass.isPrimitive()) {
        //turn e.g. get with a double into getDouble
        final String returnTypeName = returnClass.getName();
        name = "get" + Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
    } else {
        name = "get";
    }

    final MethodHandle mh = findGetIndexMethodHandle(returnClass, name, keyClass, desc);
    return new GuardedInvocation(mh, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
}
项目:OpenJSharp    文件:CompiledFunction.java   
/**
 * Returns a pair of an invocation created with a passed-in supplier and a non-invalidated switch point for
 * optimistic assumptions (or null for the switch point if the function can not be deoptimized). While the method
 * makes a best effort to return a non-invalidated switch point (compensating for possible deoptimizing
 * recompilation happening on another thread) it is still possible that by the time this method returns the
 * switchpoint has been invalidated by a {@code RewriteException} triggered on another thread for this function.
 * This is not a problem, though, as these switch points are always used to produce call sites that fall back to
 * relinking when they are invalidated, and in this case the execution will end up here again. What this method
 * basically does is minimize such busy-loop relinking while the function is being recompiled on a different thread.
 * @param invocationSupplier the supplier that constructs the actual invocation method handle; should use the
 * {@code CompiledFunction} method itself in some capacity.
 * @return a tuple object containing the method handle as created by the supplier and an optimistic assumptions
 * switch point that is guaranteed to not have been invalidated before the call to this method (or null if the
 * function can't be further deoptimized).
 */
private synchronized HandleAndAssumptions getValidOptimisticInvocation(final Supplier<MethodHandle> invocationSupplier) {
    for(;;) {
        final MethodHandle handle = invocationSupplier.get();
        final SwitchPoint assumptions = canBeDeoptimized() ? optimismInfo.optimisticAssumptions : null;
        if(assumptions != null && assumptions.hasBeenInvalidated()) {
            // We can be in a situation where one thread is in the middle of a deoptimizing compilation when we hit
            // this and thus, it has invalidated the old switch point, but hasn't created the new one yet. Note that
            // the behavior of invalidating the old switch point before recompilation, and only creating the new one
            // after recompilation is by design. If we didn't wait here for the recompilation to complete, we would
            // be busy looping through the fallback path of the invalidated switch point, relinking the call site
            // again with the same invalidated switch point, invoking the fallback, etc. stealing CPU cycles from
            // the recompilation task we're dependent on. This can still happen if the switch point gets invalidated
            // after we grabbed it here, in which case we'll indeed do one busy relink immediately.
            try {
                wait();
            } catch (final InterruptedException e) {
                // Intentionally ignored. There's nothing meaningful we can do if we're interrupted
            }
        } else {
            return new HandleAndAssumptions(handle, assumptions);
        }
    }
}
项目:OpenJSharp    文件:CompiledFunction.java   
private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
    final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() {
        @Override
        public MethodHandle get() {
            return inv.getInvokerOrConstructor(constructor);
        }
    });
    final MethodHandle handle = handleAndAssumptions.handle;
    final SwitchPoint assumptions = handleAndAssumptions.assumptions;
    final MethodHandle target;
    if(assumptions == null) {
        target = handle;
    } else {
        final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
        target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
    }
    cs.setTarget(target.asType(cs.type()));
}
项目:OpenJSharp    文件:CompiledFunction.java   
boolean requestRecompile(final RewriteException e) {
    final Type retType            = e.getReturnType();
    final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);

    if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
        final StackTraceElement[] stack      = e.getStackTrace();
        final String              functionId = stack.length == 0 ?
                data.getName() :
                stack[0].getClassName() + "." + stack[0].getMethodName();

        log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");

        return false;
    }

    SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });

    return true;
}
项目:OpenJSharp    文件:GuardedInvocation.java   
/**
 * Add a switchpoint to this guarded invocation
 * @param newSwitchPoint new switchpoint, or null for nop
 * @return new guarded invocation with the extra switchpoint
 */
public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) {
    if (newSwitchPoint == null) {
        return this;
    }

    final SwitchPoint[] newSwitchPoints;
    if (switchPoints != null) {
        newSwitchPoints = new SwitchPoint[switchPoints.length + 1];
        System.arraycopy(switchPoints, 0, newSwitchPoints, 0, switchPoints.length);
        newSwitchPoints[switchPoints.length] = newSwitchPoint;
    } else {
        newSwitchPoints = new SwitchPoint[] { newSwitchPoint };
    }

    return new GuardedInvocation(invocation, guard, newSwitchPoints, exception);
}
项目:openjdk-jdk10    文件:ContinuousArrayData.java   
/**
 * Return a fast linked array getter, or null if we have to dispatch to super class
 * @param desc     descriptor
 * @param request  link request
 * @return invocation or null if needs to be sent to slow relink
 */
@Override
public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
    final MethodType callType   = desc.getMethodType();
    final Class<?>   indexType  = callType.parameterType(1);
    final Class<?>   returnType = callType.returnType();

    if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
        final Object[] args  = request.getArguments();
        final int      index = (int)args[args.length - 1];

        if (has(index)) {
            final MethodHandle getArray     = ScriptObject.GET_ARRAY.methodHandle();
            final int          programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT;
            MethodHandle       getElement   = getElementGetter(returnType, programPoint);
            if (getElement != null) {
                getElement = MH.filterArguments(getElement, 0, MH.asType(getArray, getArray.type().changeReturnType(clazz)));
                final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
                return new GuardedInvocation(getElement, guard, (SwitchPoint)null, ClassCastException.class);
            }
        }
    }

    return null;
}
项目:openjdk-jdk10    文件:ContinuousArrayData.java   
/**
 * Return a fast linked array setter, or null if we have to dispatch to super class
 * @param desc     descriptor
 * @param request  link request
 * @return invocation or null if needs to be sent to slow relink
 */
@Override
public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
    final MethodType callType    = desc.getMethodType();
    final Class<?>   indexType   = callType.parameterType(1);
    final Class<?>   elementType = callType.parameterType(2);

    if (ContinuousArrayData.class.isAssignableFrom(clazz) && indexType == int.class) {
        final Object[]        args  = request.getArguments();
        final int             index = (int)args[args.length - 2];

        if (hasRoomFor(index)) {
            MethodHandle setElement = getElementSetter(elementType); //Z(continuousarraydata, int, int), return true if successful
            if (setElement != null) {
                //else we are dealing with a wider type than supported by this callsite
                MethodHandle getArray = ScriptObject.GET_ARRAY.methodHandle();
                getArray   = MH.asType(getArray, getArray.type().changeReturnType(getClass()));
                setElement = MH.filterArguments(setElement, 0, getArray);
                final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
                return new GuardedInvocation(setElement, guard, (SwitchPoint)null, ClassCastException.class); //CCE if not a scriptObject anymore
            }
        }
    }

    return null;
}
项目:openjdk-jdk10    文件:ScriptObject.java   
/**
 * Find the appropriate GETINDEX method for an invoke dynamic call.
 *
 * @param desc    the call site descriptor
 * @param request the link request
 *
 * @return GuardedInvocation to be invoked at call site.
 */
protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) {
    final MethodType callType                = desc.getMethodType();
    final Class<?>   returnType              = callType.returnType();
    final Class<?>   returnClass             = returnType.isPrimitive() ? returnType : Object.class;
    final Class<?>   keyClass                = callType.parameterType(1);
    final boolean    explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);

    final String name;
    if (returnClass.isPrimitive()) {
        //turn e.g. get with a double into getDouble
        final String returnTypeName = returnClass.getName();
        name = "get" + Character.toUpperCase(returnTypeName.charAt(0)) + returnTypeName.substring(1, returnTypeName.length());
    } else {
        name = "get";
    }

    final MethodHandle mh = findGetIndexMethodHandle(returnClass, name, keyClass, desc);
    return new GuardedInvocation(mh, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
}
项目:openjdk-jdk10    文件:ScriptObject.java   
/**
 * Get a switch point for a property with the given {@code name} that will be invalidated when
 * the property definition is changed in this object's prototype chain. Returns {@code null} if
 * the property is defined in this object itself.
 *
 * @param name the property name
 * @param owner the property owner, null if property is not defined
 * @return a SwitchPoint or null
 */
public final SwitchPoint[] getProtoSwitchPoints(final String name, final ScriptObject owner) {
    if (owner == this || getProto() == null) {
        return null;
    }

    final List<SwitchPoint> switchPoints = new ArrayList<>();
    for (ScriptObject obj = this; obj != owner && obj.getProto() != null; obj = obj.getProto()) {
        final ScriptObject parent = obj.getProto();
        parent.getMap().addListener(name, obj.getMap());
        final SwitchPoint sp = parent.getMap().getSharedProtoSwitchPoint();
        if (sp != null && !sp.hasBeenInvalidated()) {
            switchPoints.add(sp);
        }
    }

    switchPoints.add(getMap().getSwitchPoint(name));
    return switchPoints.toArray(new SwitchPoint[0]);
}
项目:openjdk-jdk10    文件:CompiledFunction.java   
/**
 * Returns a pair of an invocation created with a passed-in supplier and a non-invalidated switch point for
 * optimistic assumptions (or null for the switch point if the function can not be deoptimized). While the method
 * makes a best effort to return a non-invalidated switch point (compensating for possible deoptimizing
 * recompilation happening on another thread) it is still possible that by the time this method returns the
 * switchpoint has been invalidated by a {@code RewriteException} triggered on another thread for this function.
 * This is not a problem, though, as these switch points are always used to produce call sites that fall back to
 * relinking when they are invalidated, and in this case the execution will end up here again. What this method
 * basically does is minimize such busy-loop relinking while the function is being recompiled on a different thread.
 * @param invocationSupplier the supplier that constructs the actual invocation method handle; should use the
 * {@code CompiledFunction} method itself in some capacity.
 * @return a tuple object containing the method handle as created by the supplier and an optimistic assumptions
 * switch point that is guaranteed to not have been invalidated before the call to this method (or null if the
 * function can't be further deoptimized).
 */
private synchronized HandleAndAssumptions getValidOptimisticInvocation(final Supplier<MethodHandle> invocationSupplier) {
    for(;;) {
        final MethodHandle handle = invocationSupplier.get();
        final SwitchPoint assumptions = canBeDeoptimized() ? optimismInfo.optimisticAssumptions : null;
        if(assumptions != null && assumptions.hasBeenInvalidated()) {
            // We can be in a situation where one thread is in the middle of a deoptimizing compilation when we hit
            // this and thus, it has invalidated the old switch point, but hasn't created the new one yet. Note that
            // the behavior of invalidating the old switch point before recompilation, and only creating the new one
            // after recompilation is by design. If we didn't wait here for the recompilation to complete, we would
            // be busy looping through the fallback path of the invalidated switch point, relinking the call site
            // again with the same invalidated switch point, invoking the fallback, etc. stealing CPU cycles from
            // the recompilation task we're dependent on. This can still happen if the switch point gets invalidated
            // after we grabbed it here, in which case we'll indeed do one busy relink immediately.
            try {
                wait();
            } catch (final InterruptedException e) {
                // Intentionally ignored. There's nothing meaningful we can do if we're interrupted
            }
        } else {
            return new HandleAndAssumptions(handle, assumptions);
        }
    }
}
项目:openjdk-jdk10    文件:CompiledFunction.java   
private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) {
    final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() {
        @Override
        public MethodHandle get() {
            return inv.getInvokerOrConstructor(constructor);
        }
    });
    final MethodHandle handle = handleAndAssumptions.handle;
    final SwitchPoint assumptions = handleAndAssumptions.assumptions;
    final MethodHandle target;
    if(assumptions == null) {
        target = handle;
    } else {
        final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor);
        target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink));
    }
    cs.setTarget(target.asType(cs.type()));
}
项目:openjdk-jdk10    文件:CompiledFunction.java   
boolean requestRecompile(final RewriteException e) {
    final Type retType            = e.getReturnType();
    final Type previousFailedType = invalidatedProgramPoints.put(e.getProgramPoint(), retType);

    if (previousFailedType != null && !previousFailedType.narrowerThan(retType)) {
        final StackTraceElement[] stack      = e.getStackTrace();
        final String              functionId = stack.length == 0 ?
                data.getName() :
                stack[0].getClassName() + "." + stack[0].getMethodName();

        log.info("RewriteException for an already invalidated program point ", e.getProgramPoint(), " in ", functionId, ". This is okay for a recursive function invocation, but a bug otherwise.");

        return false;
    }

    SwitchPoint.invalidateAll(new SwitchPoint[] { optimisticAssumptions });

    return true;
}
项目:openjdk-jdk10    文件:GuardedInvocation.java   
/**
 * Create a new guarded invocation with an added switch point.
 * @param newSwitchPoint new switch point. Can be null in which case this
 * method return the current guarded invocation with no changes.
 * @return a guarded invocation with the added switch point.
 */
public GuardedInvocation addSwitchPoint(final SwitchPoint newSwitchPoint) {
    if (newSwitchPoint == null) {
        return this;
    }

    final SwitchPoint[] newSwitchPoints;
    if (switchPoints != null) {
        newSwitchPoints = new SwitchPoint[switchPoints.length + 1];
        System.arraycopy(switchPoints, 0, newSwitchPoints, 0, switchPoints.length);
        newSwitchPoints[switchPoints.length] = newSwitchPoint;
    } else {
        newSwitchPoints = new SwitchPoint[] { newSwitchPoint };
    }

    return new GuardedInvocation(invocation, guard, newSwitchPoints, exception);
}
项目:OpenJSharp    文件:Global.java   
private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
    SwitchPoint switchPoint = lexicalScopeSwitchPoint;
    if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
        switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
    }
    return switchPoint;
}
项目:OpenJSharp    文件:Global.java   
/**
 * Given a builtin object, traverse its properties recursively and associate them with a name that
 * will be a key to their invalidation switchpoint.
 * @param name name for key
 * @param func builtin script object
 */
private void tagBuiltinProperties(final String name, final ScriptObject func) {
    SwitchPoint sp = context.getBuiltinSwitchPoint(name);
    if (sp == null) {
        sp = context.newBuiltinSwitchPoint(name);
    }

    //get all builtin properties in this builtin object and register switchpoints keyed on the propery name,
    //one overwrite destroys all for now, e.g. Function.prototype.apply = 17; also destroys Function.prototype.call etc
    for (final jdk.nashorn.internal.runtime.Property prop : extractBuiltinProperties(name, func)) {
        prop.setBuiltinSwitchPoint(sp);
    }
}
项目:OpenJSharp    文件:GlobalConstants.java   
private Access getOrCreateSwitchPoint(final String name) {
    Access acc = map.get(name);
    if (acc != null) {
        return acc;
    }
    final SwitchPoint sp = new SwitchPoint();
    map.put(name, acc = new Access(name, sp));
    return acc;
}
项目:OpenJSharp    文件:AccessorProperty.java   
@SuppressWarnings("unused")
private static Object invalidateSwitchPoint(final AccessorProperty property, final Object obj) {
     if (!property.builtinSwitchPoint.hasBeenInvalidated()) {
        SwitchPoint.invalidateAll(new SwitchPoint[] { property.builtinSwitchPoint });
    }
    return obj;
}
项目:OpenJSharp    文件:Context.java   
/**
 * Create a new builtin switchpoint and return it
 * @param name key name
 * @return new builtin switchpoint
 */
public SwitchPoint newBuiltinSwitchPoint(final String name) {
    assert builtinSwitchPoints.get(name) == null;
    final SwitchPoint sp = new BuiltinSwitchPoint();
    builtinSwitchPoints.put(name, sp);
    return sp;
}
项目:OpenJSharp    文件:ScriptObject.java   
private SwitchPoint findBuiltinSwitchPoint(final String key) {
    for (ScriptObject myProto = getProto(); myProto != null; myProto = myProto.getProto()) {
        final Property prop = myProto.getMap().findProperty(key);
        if (prop != null) {
            final SwitchPoint sp = prop.getBuiltinSwitchPoint();
            if (sp != null && !sp.hasBeenInvalidated()) {
                return sp;
            }
        }
    }
    return null;
}
项目:OpenJSharp    文件:ScriptObject.java   
/**
 * Get a switch point for a property with the given {@code name} that will be invalidated when
 * the property definition is changed in this object's prototype chain. Returns {@code null} if
 * the property is defined in this object itself.
 *
 * @param name the property name
 * @param owner the property owner, null if property is not defined
 * @return a SwitchPoint or null
 */
public final SwitchPoint getProtoSwitchPoint(final String name, final ScriptObject owner) {
    if (owner == this || getProto() == null) {
        return null;
    }

    for (ScriptObject obj = this; obj != owner && obj.getProto() != null; obj = obj.getProto()) {
        final ScriptObject parent = obj.getProto();
        parent.getMap().addListener(name, obj.getMap());
    }

    return getMap().getSwitchPoint(name);
}
项目:OpenJSharp    文件:SetMethodCreator.java   
/**
 * Composes from its components an actual guarded invocation that represents the dynamic setter method for the property.
 * @return the composed guarded invocation that represents the dynamic setter method for the property.
 */
GuardedInvocation createGuardedInvocation() {
    // getGuard() and getException() either both return null, or neither does. The reason for that is that now
    // getGuard returns a map guard that casts its argument to ScriptObject, and if that fails, we need to
    // relink on ClassCastException.
    final boolean explicitInstanceOfCheck = NashornGuards.explicitInstanceOfCheck(desc, request);
    return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc, explicitInstanceOfCheck),
            (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
}
项目:OpenJSharp    文件:SetMethodCreator.java   
private SetMethod createSetMethod(final SwitchPoint builtinSwitchPoint) {
    if (find != null) {
        return createExistingPropertySetter();
    }

    checkStrictCreateNewVariable();

    if (sobj.isScope()) {
        return createGlobalPropertySetter();
    }

    return createNewPropertySetter(builtinSwitchPoint);
}
项目:OpenJSharp    文件:SetMethodCreator.java   
private SetMethod createNewPropertySetter(final SwitchPoint builtinSwitchPoint) {
    final SetMethod sm = map.getFreeFieldSlot() > -1 ? createNewFieldSetter(builtinSwitchPoint) : createNewSpillPropertySetter(builtinSwitchPoint);
    final PropertyListeners listeners = map.getListeners();
    if (listeners != null) {
        listeners.propertyAdded(sm.property);
    }
    return sm;
}
项目:OpenJSharp    文件:SetMethodCreator.java   
private SetMethod createNewSetter(final Property property, final SwitchPoint builtinSwitchPoint) {
    property.setBuiltinSwitchPoint(builtinSwitchPoint);

    final PropertyMap oldMap   = getMap();
    final PropertyMap newMap   = getNewMap(property);
    final boolean     isStrict = NashornCallSiteDescriptor.isStrict(desc);
    final String      name     = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);

    //fast type specific setter
    final MethodHandle fastSetter = property.getSetter(type, newMap); //0 sobj, 1 value, slot folded for spill property already

    //slow setter, that calls ScriptObject.set with appropraite type and key name
    MethodHandle slowSetter = ScriptObject.SET_SLOW[getAccessorTypeIndex(type)];
    slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.getFlags(desc));
    slowSetter = MH.insertArguments(slowSetter, 1, name);
    slowSetter = MH.asType(slowSetter, slowSetter.type().changeParameterType(0, Object.class));

    assert slowSetter.type().equals(fastSetter.type()) : "slow=" + slowSetter + " != fast=" + fastSetter;

    //cas map used as guard, if true that means we can do the set fast
    MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
    casMap = MH.dropArguments(casMap, 1, type);
    casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
    final MethodHandle casGuard = MH.guardWithTest(casMap, fastSetter, slowSetter);

    //outermost level needs an extendable check. if object can be extended, guard is true and
    //we can run the cas setter. The setter goes to "nop" VOID_RETURN if false or throws an
    //exception if we are in strict mode and object is not extensible
    MethodHandle extCheck = MH.insertArguments(ScriptObject.EXTENSION_CHECK, 1, isStrict, name);
    extCheck = MH.asType(extCheck, extCheck.type().changeParameterType(0, Object.class));
    extCheck = MH.dropArguments(extCheck, 1, type);

    MethodHandle nop = JSType.VOID_RETURN.methodHandle();
    nop = MH.dropArguments(nop, 0, Object.class, type);

    return new SetMethod(MH.asType(MH.guardWithTest(extCheck, casGuard, nop), fastSetter.type()), property);
}
项目:OpenJSharp    文件:PropertyMap.java   
/**
 * Indicate that a prototype property has changed.
 *
 * @param property {@link Property} to invalidate.
 */
synchronized void invalidateProtoGetSwitchPoint(final Property property) {
    if (protoGetSwitches != null) {

        final String key = property.getKey();
        final SwitchPoint sp = protoGetSwitches.get(key);
        if (sp != null) {
            protoGetSwitches.remove(key);
            if (Context.DEBUG) {
                protoInvalidations++;
            }
            SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
        }
    }
}
项目:OpenJSharp    文件:PropertyMap.java   
/**
 * Indicate that proto itself has changed in hierarchy somewhere.
 */
synchronized void invalidateAllProtoGetSwitchPoints() {
    if (protoGetSwitches != null && !protoGetSwitches.isEmpty()) {
        if (Context.DEBUG) {
            protoInvalidations += protoGetSwitches.size();
        }
        SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[protoGetSwitches.values().size()]));
        protoGetSwitches.clear();
    }
}
项目:OpenJSharp    文件:GuardedInvocation.java   
/**
 * Returns true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
 * @return true if and only if this guarded invocation has a switchpoint, and that switchpoint has been invalidated.
 */
public boolean hasBeenInvalidated() {
    if (switchPoints == null) {
        return false;
    }
    for (final SwitchPoint sp : switchPoints) {
        if (sp.hasBeenInvalidated()) {
            return true;
        }
    }
    return false;
}
项目:OpenJSharp    文件:GuardedInvocation.java   
/**
 * Composes the invocation, switchpoint, and the guard into a composite method handle that knows how to fall back.
 * @param switchpointFallback the fallback method handle in case switchpoint is invalidated.
 * @param guardFallback the fallback method handle in case guard returns false.
 * @param catchFallback the fallback method in case the exception handler triggers
 * @return a composite method handle.
 */
public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) {
    final MethodHandle guarded =
            guard == null ?
                    invocation :
                    MethodHandles.guardWithTest(
                            guard,
                            invocation,
                            guardFallback);

    final MethodHandle catchGuarded =
            exception == null ?
                    guarded :
                    MH.catchException(
                            guarded,
                            exception,
                            MethodHandles.dropArguments(
                                catchFallback,
                                0,
                                exception));

    if (switchPoints == null) {
        return catchGuarded;
    }

    MethodHandle spGuarded = catchGuarded;
    for (final SwitchPoint sp : switchPoints) {
        spGuarded = sp.guardWithTest(spGuarded, switchpointFallback);
    }

    return spGuarded;
}
项目:openjdk-jdk10    文件:Global.java   
private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
    SwitchPoint switchPoint = lexicalScopeSwitchPoint;
    if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
        switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
    }
    return switchPoint;
}
项目:openjdk-jdk10    文件:Global.java   
/**
 * Given a builtin object, traverse its properties recursively and associate them with a name that
 * will be a key to their invalidation switchpoint.
 * @param name name for key
 * @param func builtin script object
 */
private void tagBuiltinProperties(final String name, final ScriptObject func) {
    SwitchPoint sp = context.getBuiltinSwitchPoint(name);
    if (sp == null) {
        sp = context.newBuiltinSwitchPoint(name);
    }

    //get all builtin properties in this builtin object and register switchpoints keyed on the propery name,
    //one overwrite destroys all for now, e.g. Function.prototype.apply = 17; also destroys Function.prototype.call etc
    for (final jdk.nashorn.internal.runtime.Property prop : extractBuiltinProperties(name, func)) {
        prop.setBuiltinSwitchPoint(sp);
    }
}
项目:openjdk-jdk10    文件:GuardedInvocation.java   
/**
 * Composes the invocation, guard, switch points, and the exception into a
 * composite method handle that knows how to fall back when the guard fails
 * or the invocation is invalidated.
 * @param switchpointFallback the fallback method handle in case a switch
 * point is invalidated.
 * @param guardFallback the fallback method handle in case guard returns
 * false.
 * @param catchFallback the fallback method in case the exception handler
 * triggers.
 * @return a composite method handle.
 */
public MethodHandle compose(final MethodHandle guardFallback, final MethodHandle switchpointFallback, final MethodHandle catchFallback) {
    final MethodHandle guarded =
            guard == null ?
                    invocation :
                    MethodHandles.guardWithTest(
                            guard,
                            invocation,
                            guardFallback);

    final MethodHandle catchGuarded =
            exception == null ?
                    guarded :
                    MethodHandles.catchException(
                            guarded,
                            exception,
                            MethodHandles.dropArguments(
                                catchFallback,
                                0,
                                exception));

    if (switchPoints == null) {
        return catchGuarded;
    }

    MethodHandle spGuarded = catchGuarded;
    for (final SwitchPoint sp : switchPoints) {
        spGuarded = sp.guardWithTest(spGuarded, switchpointFallback);
    }

    return spGuarded;
}
项目:openjdk-jdk10    文件:AccessorProperty.java   
@SuppressWarnings("unused")
private static Object invalidateSwitchPoint(final AccessorProperty property, final Object obj) {
     if (!property.builtinSwitchPoint.hasBeenInvalidated()) {
        SwitchPoint.invalidateAll(new SwitchPoint[] { property.builtinSwitchPoint });
    }
    return obj;
}
项目:openjdk-jdk10    文件:Context.java   
/**
 * Create a new builtin switchpoint and return it
 * @param name key name
 * @return new builtin switchpoint
 */
public SwitchPoint newBuiltinSwitchPoint(final String name) {
    assert builtinSwitchPoints.get(name) == null;
    final SwitchPoint sp = new BuiltinSwitchPoint();
    builtinSwitchPoints.put(name, sp);
    return sp;
}
项目:openjdk-jdk10    文件:ScriptObject.java   
private SwitchPoint findBuiltinSwitchPoint(final Object key) {
    for (ScriptObject myProto = getProto(); myProto != null; myProto = myProto.getProto()) {
        final Property prop = myProto.getMap().findProperty(key);
        if (prop != null) {
            final SwitchPoint sp = prop.getBuiltinSwitchPoint();
            if (sp != null && !sp.hasBeenInvalidated()) {
                return sp;
            }
        }
    }
    return null;
}
项目:openjdk-jdk10    文件:ScriptObject.java   
private SwitchPoint getProtoSwitchPoint(final String name) {
    if (getProto() == null) {
        return null;
    }

    for (ScriptObject obj = this; obj.getProto() != null; obj = obj.getProto()) {
        final ScriptObject parent = obj.getProto();
        parent.getMap().addListener(name, obj.getMap());
    }

    return getMap().getSwitchPoint(name);
}
项目:openjdk-jdk10    文件:WithObject.java   
private static boolean hasBeenInvalidated(final SwitchPoint[] switchPoints) {
    if (switchPoints != null) {
        for (final SwitchPoint switchPoint : switchPoints) {
            if (switchPoint.hasBeenInvalidated()) {
                return true;
            }
        }
    }
    return false;
}
项目:openjdk-jdk10    文件:SetMethodCreator.java   
/**
 * Composes from its components an actual guarded invocation that represents the dynamic setter method for the property.
 * @return the composed guarded invocation that represents the dynamic setter method for the property.
 */
GuardedInvocation createGuardedInvocation() {
    // getGuard() and getException() either both return null, or neither does. The reason for that is that now
    // getGuard returns a map guard that casts its argument to ScriptObject, and if that fails, we need to
    // relink on ClassCastException.
    final boolean explicitInstanceOfCheck = NashornGuards.explicitInstanceOfCheck(desc, request);
    return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc, explicitInstanceOfCheck),
            (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
}
项目:openjdk-jdk10    文件:SetMethodCreator.java   
private SetMethod createSetMethod(final SwitchPoint builtinSwitchPoint) {
    if (find != null) {
        return createExistingPropertySetter();
    }

    checkStrictCreateNewVariable();

    if (sobj.isScope()) {
        return createGlobalPropertySetter();
    }

    return createNewPropertySetter(builtinSwitchPoint);
}