Search in sources :

Example 46 with Variable

use of com.facebook.presto.bytecode.Variable in project presto by prestodb.

the class OrderingCompiler method generatePageIndexCompareTo.

private static void generatePageIndexCompareTo(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> sortTypes, List<Integer> sortChannels, List<SortOrder> sortOrders) {
    Parameter pagesIndex = arg("pagesIndex", PagesIndex.class);
    Parameter leftPosition = arg("leftPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    MethodDefinition compareToMethod = classDefinition.declareMethod(a(PUBLIC), "compareTo", type(int.class), pagesIndex, leftPosition, rightPosition);
    Scope scope = compareToMethod.getScope();
    Variable valueAddresses = scope.declareVariable(AdaptiveLongBigArray.class, "valueAddresses");
    compareToMethod.getBody().comment("AdaptiveLongBigArray valueAddresses = pagesIndex.valueAddresses").append(valueAddresses.set(pagesIndex.invoke("getValueAddresses", AdaptiveLongBigArray.class)));
    Variable leftPageAddress = scope.declareVariable(long.class, "leftPageAddress");
    compareToMethod.getBody().comment("long leftPageAddress = valueAddresses.get(leftPosition)").append(leftPageAddress.set(valueAddresses.invoke("get", long.class, leftPosition)));
    Variable leftBlockIndex = scope.declareVariable(int.class, "leftBlockIndex");
    compareToMethod.getBody().comment("int leftBlockIndex = decodeSliceIndex(leftPageAddress)").append(leftBlockIndex.set(invokeStatic(SyntheticAddress.class, "decodeSliceIndex", int.class, leftPageAddress)));
    Variable leftBlockPosition = scope.declareVariable(int.class, "leftBlockPosition");
    compareToMethod.getBody().comment("int leftBlockPosition = decodePosition(leftPageAddress)").append(leftBlockPosition.set(invokeStatic(SyntheticAddress.class, "decodePosition", int.class, leftPageAddress)));
    Variable rightPageAddress = scope.declareVariable(long.class, "rightPageAddress");
    compareToMethod.getBody().comment("long rightPageAddress = valueAddresses.get(rightPosition);").append(rightPageAddress.set(valueAddresses.invoke("get", long.class, rightPosition)));
    Variable rightBlockIndex = scope.declareVariable(int.class, "rightBlockIndex");
    compareToMethod.getBody().comment("int rightBlockIndex = decodeSliceIndex(rightPageAddress)").append(rightBlockIndex.set(invokeStatic(SyntheticAddress.class, "decodeSliceIndex", int.class, rightPageAddress)));
    Variable rightBlockPosition = scope.declareVariable(int.class, "rightBlockPosition");
    compareToMethod.getBody().comment("int rightBlockPosition = decodePosition(rightPageAddress)").append(rightBlockPosition.set(invokeStatic(SyntheticAddress.class, "decodePosition", int.class, rightPageAddress)));
    for (int i = 0; i < sortChannels.size(); i++) {
        int sortChannel = sortChannels.get(i);
        SortOrder sortOrder = sortOrders.get(i);
        BytecodeBlock block = new BytecodeBlock().setDescription("compare channel " + sortChannel + " " + sortOrder);
        Type sortType = sortTypes.get(i);
        BytecodeExpression leftBlock = pagesIndex.invoke("getChannel", ObjectArrayList.class, constantInt(sortChannel)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = pagesIndex.invoke("getChannel", ObjectArrayList.class, constantInt(sortChannel)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
        block.append(getStatic(SortOrder.class, sortOrder.name()).invoke("compareBlockValue", int.class, ImmutableList.of(Type.class, Block.class, int.class, Block.class, int.class), constantType(callSiteBinder, sortType), leftBlock, leftBlockPosition, rightBlock, rightBlockPosition));
        LabelNode equal = new LabelNode("equal");
        block.comment("if (compare != 0) return compare").dup().ifZeroGoto(equal).retInt().visitLabel(equal).pop(int.class);
        compareToMethod.getBody().append(block);
    }
    // values are equal
    compareToMethod.getBody().push(0).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Type(com.facebook.presto.common.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) SortOrder(com.facebook.presto.common.block.SortOrder) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 47 with Variable

use of com.facebook.presto.bytecode.Variable in project presto by prestodb.

the class VarArgsToMapAdapterGenerator method generateVarArgsToMapAdapter.

/**
 * Generate byte code that
 * <p><ul>
 * <li>takes a specified number of variables as arguments (types of the arguments are provided in {@code javaTypes})
 * <li>put the variables in a map (keys of the map are provided in {@code names})
 * <li>invoke the provided {@code function} with the map
 * <li>return with the result of the function call (type must match {@code returnType})
 * </ul></p>
 */
public static MethodHandle generateVarArgsToMapAdapter(Class<?> returnType, List<Class<?>> javaTypes, List<String> names, Function<Map<String, Object>, Object> function) {
    checkCondition(javaTypes.size() <= 254, NOT_SUPPORTED, "Too many arguments for vararg function");
    CallSiteBinder callSiteBinder = new CallSiteBinder();
    ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("VarArgsToMapAdapter"), type(Object.class));
    ImmutableList.Builder<Parameter> parameterListBuilder = ImmutableList.builder();
    for (int i = 0; i < javaTypes.size(); i++) {
        Class<?> javaType = javaTypes.get(i);
        parameterListBuilder.add(arg("input_" + i, javaType));
    }
    ImmutableList<Parameter> parameterList = parameterListBuilder.build();
    MethodDefinition methodDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "varArgsToMap", type(returnType), parameterList);
    BytecodeBlock body = methodDefinition.getBody();
    // ImmutableMap.Builder can not be used here because it doesn't allow nulls.
    Variable map = methodDefinition.getScope().declareVariable("map", methodDefinition.getBody(), invokeStatic(Maps.class, "newHashMapWithExpectedSize", HashMap.class, constantInt(javaTypes.size())));
    for (int i = 0; i < javaTypes.size(); i++) {
        body.append(map.invoke("put", Object.class, constantString(names.get(i)).cast(Object.class), parameterList.get(i).cast(Object.class)));
    }
    body.append(loadConstant(callSiteBinder, function, Function.class).invoke("apply", Object.class, map.cast(Object.class)).cast(returnType).ret());
    Class<?> generatedClass = defineClass(classDefinition, Object.class, callSiteBinder.getBindings(), new DynamicClassLoader(VarArgsToMapAdapterGenerator.class.getClassLoader()));
    return Reflection.methodHandle(generatedClass, "varArgsToMap", javaTypes.toArray(new Class<?>[javaTypes.size()]));
}
Also used : DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) Variable(com.facebook.presto.bytecode.Variable) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) Maps(com.google.common.collect.Maps) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) Parameter(com.facebook.presto.bytecode.Parameter) CompilerUtils.defineClass(com.facebook.presto.util.CompilerUtils.defineClass)

Example 48 with Variable

use of com.facebook.presto.bytecode.Variable in project presto by prestodb.

the class JoinCompiler method generatePositionEqualsPositionMethod.

private static void generatePositionEqualsPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, boolean ignoreNulls) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightBlockIndex = arg("rightBlockIndex", int.class);
    Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
    MethodDefinition positionEqualsPositionMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsPositionIgnoreNulls" : "positionEqualsPosition", type(boolean.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
    Variable thisVariable = positionEqualsPositionMethod.getThis();
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
        BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
        BytecodeNode equalityCondition;
        if (ignoreNulls) {
            equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
        } else {
            equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
        }
        LabelNode checkNextField = new LabelNode("checkNextField");
        positionEqualsPositionMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
    }
    positionEqualsPositionMethod.getBody().push(true).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 49 with Variable

use of com.facebook.presto.bytecode.Variable in project presto by prestodb.

the class JoinCompiler method generatePositionNotDistinctFromRowWithPageMethod.

private void generatePositionNotDistinctFromRowWithPageMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter page = arg("page", Page.class);
    Parameter rightChannels = arg("rightChannels", int[].class);
    MethodDefinition positionNotDistinctFromRowMethod = classDefinition.declareMethod(a(PUBLIC), "positionNotDistinctFromRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels);
    Variable thisVariable = positionNotDistinctFromRowMethod.getThis();
    Scope scope = positionNotDistinctFromRowMethod.getScope();
    BytecodeBlock body = positionNotDistinctFromRowMethod.getBody();
    if (groupByUsesEqualTo) {
        // positionNotDistinctFromRow delegates to positionEqualsRow when groupByUsesEqualTo is set.
        body.append(thisVariable.invoke("positionEqualsRow", boolean.class, leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels).ret());
        return;
    }
    scope.declareVariable("wasNull", body, constantFalse());
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = page.invoke("getBlock", Block.class, rightChannels.getElement(index));
        Type type = joinChannelTypes.get(index);
        // At that point, we'll be able to fully deprecate Type.equalTo (and friends) and remove this hack.
        if (type.getJavaType().equals(Slice.class)) {
            switch(type.getTypeSignature().getBase()) {
                case StandardTypes.CHAR:
                case StandardTypes.IPADDRESS:
                case StandardTypes.JSON:
                case StandardTypes.DECIMAL:
                case StandardTypes.VARBINARY:
                case StandardTypes.VARCHAR:
                    body.append(new IfStatement().condition(typeEquals(constantType(callSiteBinder, type), leftBlock, leftBlockPosition, rightBlock, rightPosition)).ifFalse(constantFalse().ret()));
                    continue;
            }
        }
        JavaScalarFunctionImplementation operator = functionAndTypeManager.getJavaScalarFunctionImplementation(functionAndTypeManager.resolveOperator(OperatorType.IS_DISTINCT_FROM, fromTypes(type, type)));
        callSiteBinder.bind(operator.getMethodHandle());
        List<BytecodeNode> argumentsBytecode = new ArrayList<>();
        argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, leftBlock, leftBlockPosition));
        argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, rightBlock, rightPosition));
        body.append(new IfStatement().condition(BytecodeUtils.generateInvocation(scope, "isDistinctFrom", operator, Optional.empty(), argumentsBytecode, callSiteBinder)).ifTrue(constantFalse().ret()));
    }
    body.append(constantTrue().ret());
}
Also used : JavaScalarFunctionImplementation(com.facebook.presto.spi.function.JavaScalarFunctionImplementation) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) IfStatement(com.facebook.presto.bytecode.control.IfStatement) BigintType(com.facebook.presto.common.type.BigintType) Type(com.facebook.presto.common.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) OperatorType(com.facebook.presto.common.function.OperatorType) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 50 with Variable

use of com.facebook.presto.bytecode.Variable in project presto by prestodb.

the class IsNullCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    Preconditions.checkArgument(arguments.size() == 1);
    RowExpression argument = arguments.get(0);
    if (argument.getType().equals(UNKNOWN)) {
        return loadBoolean(true);
    }
    BytecodeNode value = generatorContext.generate(argument, Optional.empty());
    // evaluate the expression, pop the produced value, and load the null flag
    Variable wasNull = generatorContext.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("is null").append(value).pop(argument.getType().getJavaType()).append(wasNull);
    // clear the null flag
    block.append(wasNull.set(constantFalse()));
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
    return block;
}
Also used : Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Aggregations

Variable (com.facebook.presto.bytecode.Variable)131 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)104 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)91 Parameter (com.facebook.presto.bytecode.Parameter)75 Scope (com.facebook.presto.bytecode.Scope)68 IfStatement (com.facebook.presto.bytecode.control.IfStatement)68 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)40 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)36 ImmutableList (com.google.common.collect.ImmutableList)30 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)28 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)21 ForLoop (com.facebook.presto.bytecode.control.ForLoop)21 Block (com.facebook.presto.spi.block.Block)19 Block (com.facebook.presto.common.block.Block)18 List (java.util.List)17 CallSiteBinder (com.facebook.presto.bytecode.CallSiteBinder)16 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)15 Type (com.facebook.presto.common.type.Type)15 RowExpression (com.facebook.presto.spi.relation.RowExpression)15 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)14