jdk.nashorn.internal.codegen.types.Type Java Examples

The following examples show how to use jdk.nashorn.internal.codegen.types.Type. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: UnaryNode.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
@Override
public Type getWidestOperationType() {
    switch (tokenType()) {
    case ADD:
        final Type operandType = getExpression().getType();
        if(operandType == Type.BOOLEAN) {
            return Type.INT;
        } else if(operandType.isObject()) {
            return Type.NUMBER;
        }
        assert operandType.isNumeric();
        return operandType;
    case SUB:
        // This might seems overly conservative until you consider that -0 can only be represented as a double.
        return Type.NUMBER;
    case NOT:
    case DELETE:
        return Type.BOOLEAN;
    case BIT_NOT:
        return Type.INT;
    case VOID:
        return Type.UNDEFINED;
    default:
        return isAssignment() ? Type.NUMBER : Type.OBJECT;
    }
}
 
Example #2
Source File: CompiledFunction.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
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;
}
 
Example #3
Source File: CodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean enterNOT(final UnaryNode unaryNode) {
    final Expression rhs = unaryNode.rhs();

    load(rhs, Type.BOOLEAN);

    final Label trueLabel  = new Label("true");
    final Label afterLabel = new Label("after");

    method.ifne(trueLabel);
    method.load(true);
    method._goto(afterLabel);
    method.label(trueLabel);
    method.load(false);
    method.label(afterLabel);
    method.store(unaryNode.getSymbol());

    return false;
}
 
Example #4
Source File: Label.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Returns a list of local variable slot types, but for those symbols that have multiple values, only the slot
 * holding the widest type is marked as live.
 * @return a list of widest local variable slot types.
 */
List<Type> getWidestLiveLocals(final List<Type> lvarTypes) {
    final List<Type> widestLiveLocals = new ArrayList<>(lvarTypes);
    boolean keepNextValue = true;
    final int size = widestLiveLocals.size();
    for(int i = size - 1; i-- > 0;) {
        if(symbolBoundary.get(i)) {
            keepNextValue = true;
        }
        final Type t = widestLiveLocals.get(i);
        if(t != Type.UNKNOWN) {
            if(keepNextValue) {
                if(t != Type.SLOT_2) {
                    keepNextValue = false;
                }
            } else {
                widestLiveLocals.set(i, Type.UNKNOWN);
            }
        }
    }
    widestLiveLocals.subList(Math.max(getFirstDeadLocal(widestLiveLocals), firstTemp), widestLiveLocals.size()).clear();
    return widestLiveLocals;
}
 
Example #5
Source File: CodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean enterSHR(final BinaryNode binaryNode) {
    new BinaryArith() {
        @Override
        protected void evaluate(final BinaryNode node) {
            loadBinaryOperands(node.lhs(), node.rhs(), Type.INT);
            op();
            method.store(node.getSymbol());
        }
        @Override
        protected void op() {
            method.shr();
            method.convert(Type.LONG).load(JSType.MAX_UINT).and();
        }
    }.evaluate(binaryNode);

    return false;
}
 
Example #6
Source File: CompiledFunction.java    From hottub with GNU General Public License v2.0 6 votes vote down vote up
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;
}
 
Example #7
Source File: CodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
private void enterForIn(final ForNode forNode) {
    final Block body   = forNode.getBody();
    final Expression  modify = forNode.getModify();

    final Symbol iter      = forNode.getIterator();
    final Label  loopLabel = new Label("loop");

    final Expression init = forNode.getInit();

    load(modify, Type.OBJECT);
    method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
    method.store(iter);
    method._goto(forNode.getContinueLabel());
    method.label(loopLabel);

    new Store<Expression>(init) {
        @Override
        protected void storeNonDiscard() {
            return;
        }
        @Override
        protected void evaluate() {
            method.load(iter);
            method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
        }
    }.store();

    body.accept(this);

    method.label(forNode.getContinueLabel());
    method.load(iter);
    method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
    method.ifne(loopLabel);
    method.label(forNode.getBreakLabel());
}
 
Example #8
Source File: MethodEmitter.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Pop element from stack, convert to given type
 *
 * @param to type to convert to
 *
 * @return the method emitter
 */
MethodEmitter convert(final Type to) {
    final Type from = peekType();
    final Type type = from.convert(method, to);
    if (type != null) {
        if (!from.isEquivalentTo(to)) {
            debug("convert", from, "->", to);
        }
        if (type != from) {
            final int l0 = stack.getTopLocalLoad();
            popType();
            pushType(type);
            // NOTE: conversions from a primitive type are considered to preserve the "load" property of the value
            // on the stack. Otherwise we could introduce temporary locals in a deoptimized rest-of (e.g. doing an
            // "i < x.length" where "i" is int and ".length" gets deoptimized to long would end up converting i to
            // long with "ILOAD i; I2L; LSTORE tmp; LLOAD tmp;"). Such additional temporary would cause an error
            // when restoring the state of the function for rest-of execution, as the not-yet deoptimized variant
            // would have the (now invalidated) assumption that "x.length" is an int, so it wouldn't have the I2L,
            // and therefore neither the subsequent LSTORE tmp; LLOAD tmp;. By making sure conversions from a
            // primitive type don't erase the "load" information, we don't introduce temporaries in the deoptimized
            // rest-of that didn't exist in the more optimistic version that triggered the deoptimization.
            // NOTE: as a more general observation, we could theoretically track the operations required to
            // reproduce any stack value as long as they are all local loads, constant loads, and stack operations.
            // We won't go there in the current system
            if(!from.isObject()) {
                stack.markLocalLoad(l0);
            }
        }
    }
    return this;
}
 
Example #9
Source File: Symbol.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Marks this symbol as having a local variable slot for storing a value of specific type.
 * @param type the type
 */
public void setHasSlotFor(final Type type) {
    if(type.isBoolean() || type.isInteger()) {
        setFlag(HAS_INT_VALUE);
    } else if(type.isNumber()) {
        setFlag(HAS_DOUBLE_VALUE);
    } else {
        assert type.isObject();
        setFlag(HAS_OBJECT_VALUE);
    }
}
 
Example #10
Source File: CallNode.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Type getType() {
    if (hasCallSiteType()) {
        return type;
    }
    return function instanceof FunctionNode ? ((FunctionNode)function).getReturnType() : Type.OBJECT;
}
 
Example #11
Source File: FunctionSignature.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
private static Type[] objectArgs(final int nArgs) {
    final Type[] array = new Type[nArgs];
    for (int i = 0; i < nArgs; i++) {
        array[i] = Type.OBJECT;
    }
    return array;
}
 
Example #12
Source File: MethodEmitter.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Pops two integer types from the stack, performs a bitwise shift left and and pushes
 * the result. The shift count, the first element, must be INT.
 *
 * @return the method emitter
 */
MethodEmitter shl() {
    debug("shl");
    popType(Type.INT);
    pushType(popInteger().shl(method));
    return this;
}
 
Example #13
Source File: ObjectClassGenerator.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Add an empty <init> method to the JavaScript class.
 *
 * @param classEmitter Open class emitter.
 * @param className    Name of JavaScript class.
 */
private static void newEmptyInit(final ClassEmitter classEmitter, final String className) {
    final MethodEmitter emptyInit = classEmitter.init();
    emptyInit.begin();
    emptyInit.load(Type.OBJECT, JAVA_THIS.slot());
    emptyInit.loadNull();
    emptyInit.invoke(constructorNoLookup(className, PropertyMap.class));
    emptyInit.returnVoid();
    emptyInit.end();
}
 
Example #14
Source File: CodeGenerator.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterNEW(final UnaryNode unaryNode) {
    final CallNode callNode = (CallNode)unaryNode.rhs();
    final List<Expression> args   = callNode.getArgs();

    // Load function reference.
    load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error

    method.dynamicNew(1 + loadArgs(args), getCallSiteFlags());
    method.store(unaryNode.getSymbol());

    return false;
}
 
Example #15
Source File: FunctionInitializer.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Constructor.
 *
 * @param functionNode the function node
 * @param invalidatedProgramPoints invalidated program points
 */
public FunctionInitializer(final FunctionNode functionNode, final Map<Integer, Type> invalidatedProgramPoints) {
    this.className  = functionNode.getCompileUnit().getUnitClassName();
    this.methodType = new FunctionSignature(functionNode).getMethodType();
    this.flags = functionNode.getFlags();
    this.invalidatedProgramPoints = invalidatedProgramPoints;

    final CompileUnit cu = functionNode.getCompileUnit();
    if (cu != null) {
        this.code = cu.getCode();
    }

    assert className != null;
}
 
Example #16
Source File: IdentNode.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public IdentNode setType(final Type type) {
    if (this.type == type) {
        return this;
    }
    return new IdentNode(this, name, type, flags, programPoint, conversion);
}
 
Example #17
Source File: MethodEmitter.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
/**
* Emit a System.err.println statement of whatever is on top of the bytecode stack
*/
void println() {
    getField(ERR_STREAM);
    swap();
    convert(Type.OBJECT);
    invoke(PRINTLN);
}
 
Example #18
Source File: MethodEmitter.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Retrieve the top <tt>count</tt> types on the stack without modifying it.
 *
 * @param count number of types to return
 * @return array of Types
 */
protected Type[] getTypesFromStack(final int count) {
    final Type[] types = new Type[count];
    int pos = 0;
    for (int i = count - 1; i >= 0; i--) {
        types[i] = stack.peek(pos++);
    }

    return types;
}
 
Example #19
Source File: UnaryNode.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Type getType() {
    final Type widest = getWidestOperationType();
    if(type == null) {
        return widest;
    }
    return Type.narrowest(widest, Type.widest(type, expression.getType()));
}
 
Example #20
Source File: MethodEmitter.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Load an element from an array, determining type automatically
 * @return the method emitter
 */
MethodEmitter arrayload() {
    debug("Xaload");
    popType(Type.INT);
    pushType(popArray().aload(method));
    return this;
}
 
Example #21
Source File: CodeGenerator.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Quick symbol generates an extra local variable, always using the same
 * slot, one that is available after the end of the frame.
 *
 * @param type the type of the symbol
 * @param prefix the prefix for the variable name for the symbol
 *
 * @return the quick symbol
 */
private Symbol quickSymbol(final Type type, final String prefix) {
    final String name = lc.getCurrentFunction().uniqueName(prefix);
    final Symbol symbol = new Symbol(name, IS_TEMP | IS_INTERNAL);

    symbol.setType(type);

    symbol.setSlot(lc.quickSlot(symbol));

    return symbol;
}
 
Example #22
Source File: MethodEmitter.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Pop element from stack, convert to given type
 *
 * @param to type to convert to
 *
 * @return the method emitter
 */
MethodEmitter convert(final Type to) {
    final Type from = peekType();
    final Type type = from.convert(method, to);
    if (type != null) {
        if (!from.isEquivalentTo(to)) {
            debug("convert", from, "->", to);
        }
        if (type != from) {
            final int l0 = stack.getTopLocalLoad();
            popType();
            pushType(type);
            // NOTE: conversions from a primitive type are considered to preserve the "load" property of the value
            // on the stack. Otherwise we could introduce temporary locals in a deoptimized rest-of (e.g. doing an
            // "i < x.length" where "i" is int and ".length" gets deoptimized to long would end up converting i to
            // long with "ILOAD i; I2L; LSTORE tmp; LLOAD tmp;"). Such additional temporary would cause an error
            // when restoring the state of the function for rest-of execution, as the not-yet deoptimized variant
            // would have the (now invalidated) assumption that "x.length" is an int, so it wouldn't have the I2L,
            // and therefore neither the subsequent LSTORE tmp; LLOAD tmp;. By making sure conversions from a
            // primitive type don't erase the "load" information, we don't introduce temporaries in the deoptimized
            // rest-of that didn't exist in the more optimistic version that triggered the deoptimization.
            // NOTE: as a more general observation, we could theoretically track the operations required to
            // reproduce any stack value as long as they are all local loads, constant loads, and stack operations.
            // We won't go there in the current system
            if(!from.isObject()) {
                stack.markLocalLoad(l0);
            }
        }
    }
    return this;
}
 
Example #23
Source File: MethodEmitter.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Push a String constant to the stack
 *
 * @param s value of the String
 *
 * @return the method emitter
 */
MethodEmitter load(final String s) {
    debug("load string", s);

    if (s == null) {
        loadNull();
        return this;
    }

    //NASHORN-142 - split too large string
    final int length = s.length();
    if (length > LARGE_STRING_THRESHOLD) {

        _new(StringBuilder.class);
        dup();
        load(length);
        invoke(constructorNoLookup(StringBuilder.class, int.class));

        for (int n = 0; n < length; n += LARGE_STRING_THRESHOLD) {
            final String part = s.substring(n, Math.min(n + LARGE_STRING_THRESHOLD, length));
            load(part);
            stringBuilderAppend();
        }

        invoke(virtualCallNoLookup(StringBuilder.class, "toString", String.class));

        return this;
    }

    pushType(Type.OBJECT.ldc(method, s));
    return this;
}
 
Example #24
Source File: Symbol.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Sets the type of the symbol to the specified type. If the type would be changed, but this symbol is a shared
 * temporary, it will instead return a different temporary symbol of the requested type from the passed temporary
 * symbols. That way, it never mutates the type of a shared temporary.
 * @param type the new type for the symbol
 * @param ts a holder of temporary symbols
 * @return either this symbol, or a different symbol if this symbol is a shared temporary and it type would have to
 * be changed.
 */
public Symbol setTypeOverrideShared(final Type type, final TemporarySymbols ts) {
    if(getSymbolType() != type) {
        if(isShared()) {
            assert !hasSlot();
            return ts.getTypedTemporarySymbol(type);
        }
        setTypeOverride(type);
    }
    return this;
}
 
Example #25
Source File: BinaryNode.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
private Type getTypeUncached() {
    if(type == OPTIMISTIC_UNDECIDED_TYPE) {
        return decideType(lhs.getType(), rhs.getType());
    }
    final Type widest = getWidestOperationType();
    if(type == null) {
        return widest;
    }
    if (tokenType() == TokenType.ASSIGN_SHR || tokenType() == TokenType.SHR) {
        return type;
    }
    return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType())));
}
 
Example #26
Source File: FinalizeTypes.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Node leaveCatchNode(final CatchNode catchNode) {
    final Expression exceptionCondition = catchNode.getExceptionCondition();
    if (exceptionCondition != null) {
        return catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN));
    }
    return catchNode;
}
 
Example #27
Source File: ObjectClassGenerator.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Allocate and initialize a new <init> method for scopes with arguments.
 * @param classEmitter  Open class emitter.
 * @return Open method emitter.
 */
private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) {
    final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, ScriptObject.class);
    init.begin();
    init.load(Type.OBJECT, JAVA_THIS.slot());
    init.load(Type.OBJECT, INIT_MAP.slot());
    init.load(Type.OBJECT, INIT_SCOPE.slot());
    init.load(Type.OBJECT, INIT_ARGUMENTS.slot());
    init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, ScriptObject.class));

    return init;
}
 
Example #28
Source File: MethodEmitter.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
@SuppressWarnings("fallthrough")
private static Type fieldType(final String desc) {
    switch (desc) {
    case "Z":
    case "B":
    case "C":
    case "S":
    case "I":
        return Type.INT;
    case "F":
        assert false;
    case "D":
        return Type.NUMBER;
    case "J":
        return Type.LONG;
    default:
        assert desc.startsWith("[") || desc.startsWith("L") : desc + " is not an object type";
        switch (desc.charAt(0)) {
        case 'L':
            return Type.OBJECT;
        case '[':
            return Type.typeFor(Array.newInstance(fieldType(desc.substring(1)).getTypeClass(), 0).getClass());
        default:
            assert false;
        }
        return Type.OBJECT;
    }
}
 
Example #29
Source File: ClassEmitter.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Add a new method to the class, representing a rest-of version of the
 * function node.
 *
 * @param functionNode the function node to generate a method for
 *
 * @return method emitter to use for weaving this method
 */
MethodEmitter restOfMethod(final FunctionNode functionNode) {
    methodCount++;
    methodNames.add(functionNode.getName());
    final MethodVisitor mv = cw.visitMethod(
        ACC_PUBLIC | ACC_STATIC,
        functionNode.getName(),
        Type.getMethodDescriptor(functionNode.getReturnType().getTypeClass(), RewriteException.class),
        null,
        null);

    return new MethodEmitter(this, mv, functionNode);
}
 
Example #30
Source File: MethodEmitter.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
MethodEmitter loadCompilerConstant(final CompilerConstants cc, final Type type) {
    if (cc == SCOPE && peekType() == Type.SCOPE) {
        dup();
        return this;
    }
    return load(getCompilerConstantSymbol(cc), type != null ? type : getCompilerConstantType(cc));
}