Search in sources :

Example 26 with BytecodeExpression

use of io.airlift.bytecode.expression.BytecodeExpression in project trino by trinodb.

the class OrderingCompiler method generatePageIndexCompareTo.

private 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(LongArrayList.class, "valueAddresses");
    compareToMethod.getBody().comment("LongArrayList valueAddresses = pagesIndex.valueAddresses").append(valueAddresses.set(pagesIndex.invoke("getValueAddresses", LongArrayList.class)));
    Variable leftPageAddress = scope.declareVariable(long.class, "leftPageAddress");
    compareToMethod.getBody().comment("long leftPageAddress = valueAddresses.getLong(leftPosition)").append(leftPageAddress.set(valueAddresses.invoke("getLong", 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.getLong(rightPosition);").append(rightPageAddress.set(valueAddresses.invoke("getLong", 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);
        Type sortType = sortTypes.get(i);
        MethodHandle compareBlockValue = getBlockPositionOrderingOperator(sortOrder, sortType);
        BytecodeBlock block = new BytecodeBlock().setDescription("compare channel " + sortChannel + " " + sortOrder);
        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(invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(callSiteBinder.bind(compareBlockValue).getBindingId()), "compareBlockValue", compareBlockValue.type(), 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(io.airlift.bytecode.instruction.LabelNode) Type(io.trino.spi.type.Type) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter) SortOrder(io.trino.spi.connector.SortOrder) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 27 with BytecodeExpression

use of io.airlift.bytecode.expression.BytecodeExpression in project trino by trinodb.

the class JoinCompiler method generateHashPositionMethod.

private void generateHashPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
    Parameter blockIndex = arg("blockIndex", int.class);
    Parameter blockPosition = arg("blockPosition", int.class);
    MethodDefinition hashPositionMethod = classDefinition.declareMethod(a(PUBLIC), "hashPosition", type(long.class), blockIndex, blockPosition);
    Variable thisVariable = hashPositionMethod.getThis();
    BytecodeExpression hashChannel = thisVariable.getField(hashChannelField);
    BytecodeExpression bigintType = constantType(callSiteBinder, BigintType.BIGINT);
    IfStatement ifStatement = new IfStatement();
    ifStatement.condition(notEqual(hashChannel, constantNull(hashChannelField.getType())));
    ifStatement.ifTrue(bigintType.invoke("getLong", long.class, hashChannel.invoke("get", Object.class, blockIndex).cast(Block.class), blockPosition).ret());
    hashPositionMethod.getBody().append(ifStatement);
    Variable resultVariable = hashPositionMethod.getScope().declareVariable(long.class, "result");
    hashPositionMethod.getBody().push(0L).putVariable(resultVariable);
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        Type type = joinChannelTypes.get(index);
        BytecodeExpression block = hashPositionMethod.getThis().getField(joinChannelFields.get(index)).invoke("get", Object.class, blockIndex).cast(Block.class);
        hashPositionMethod.getBody().getVariable(resultVariable).push(31L).append(OpCode.LMUL).append(typeHashCode(callSiteBinder, type, block, blockPosition)).append(OpCode.LADD).putVariable(resultVariable);
    }
    hashPositionMethod.getBody().getVariable(resultVariable).retLong();
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) SqlTypeBytecodeExpression.constantType(io.trino.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.trino.spi.type.Type) BigintType(io.trino.spi.type.BigintType) Variable(io.airlift.bytecode.Variable) MethodDefinition(io.airlift.bytecode.MethodDefinition) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 28 with BytecodeExpression

use of io.airlift.bytecode.expression.BytecodeExpression in project trino by trinodb.

the class VarArgsToArrayAdapterGenerator method generateVarArgsToArrayAdapter.

public static MethodHandleAndConstructor generateVarArgsToArrayAdapter(Class<?> returnType, Class<?> javaType, int argsLength, MethodHandle function, MethodHandle userStateFactory) {
    requireNonNull(returnType, "returnType is null");
    requireNonNull(javaType, "javaType is null");
    requireNonNull(function, "function is null");
    requireNonNull(userStateFactory, "userStateFactory is null");
    checkCondition(argsLength <= 253, NOT_SUPPORTED, "Too many arguments for vararg function");
    MethodType methodType = function.type();
    Class<?> javaArrayType = toArrayClass(javaType);
    checkArgument(methodType.returnType() == returnType, "returnType does not match");
    checkArgument(methodType.parameterList().equals(ImmutableList.of(Object.class, javaArrayType)), "parameter types do not match");
    CallSiteBinder callSiteBinder = new CallSiteBinder();
    ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("VarArgsToListAdapter"), type(Object.class));
    classDefinition.declareDefaultConstructor(a(PRIVATE));
    // generate userState constructor
    MethodDefinition stateFactoryDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "createState", type(VarArgsToArrayAdapterState.class));
    stateFactoryDefinition.getBody().comment("create userState for current instance").append(newInstance(VarArgsToArrayAdapterState.class, loadConstant(callSiteBinder, userStateFactory, MethodHandle.class).invoke("invokeExact", Object.class), newArray(type(javaArrayType), argsLength).cast(Object.class)).ret());
    // generate adapter method
    ImmutableList.Builder<Parameter> parameterListBuilder = ImmutableList.builder();
    parameterListBuilder.add(arg("userState", VarArgsToArrayAdapterState.class));
    for (int i = 0; i < argsLength; i++) {
        parameterListBuilder.add(arg("input_" + i, javaType));
    }
    ImmutableList<Parameter> parameterList = parameterListBuilder.build();
    MethodDefinition methodDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "varArgsToArray", type(returnType), parameterList);
    BytecodeBlock body = methodDefinition.getBody();
    BytecodeExpression userState = parameterList.get(0).getField("userState", Object.class);
    BytecodeExpression args = parameterList.get(0).getField("args", Object.class).cast(javaArrayType);
    for (int i = 0; i < argsLength; i++) {
        body.append(args.setElement(i, parameterList.get(i + 1)));
    }
    body.append(loadConstant(callSiteBinder, function, MethodHandle.class).invoke("invokeExact", returnType, userState, args).ret());
    // define class
    Class<?> generatedClass = defineClass(classDefinition, Object.class, callSiteBinder.getBindings(), VarArgsToArrayAdapterGenerator.class.getClassLoader());
    return new MethodHandleAndConstructor(Reflection.methodHandle(generatedClass, "varArgsToArray", ImmutableList.builder().add(VarArgsToArrayAdapterState.class).addAll(nCopies(argsLength, javaType)).build().toArray(new Class<?>[argsLength])), Reflection.methodHandle(generatedClass, "createState"));
}
Also used : MethodType(java.lang.invoke.MethodType) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) MethodDefinition(io.airlift.bytecode.MethodDefinition) Parameter(io.airlift.bytecode.Parameter) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 29 with BytecodeExpression

use of io.airlift.bytecode.expression.BytecodeExpression in project trino by trinodb.

the class AccumulatorCompiler method initializeStateFields.

private static void initializeStateFields(MethodDefinition method, List<StateFieldAndDescriptor> stateFieldAndDescriptors, CallSiteBinder callSiteBinder, boolean grouped) {
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    for (StateFieldAndDescriptor fieldAndDescriptor : stateFieldAndDescriptors) {
        AccumulatorStateDescriptor<?> accumulatorStateDescriptor = fieldAndDescriptor.getAccumulatorStateDescriptor();
        body.append(thisVariable.setField(fieldAndDescriptor.getStateSerializerField(), loadConstant(callSiteBinder, accumulatorStateDescriptor.getSerializer(), AccumulatorStateSerializer.class)));
        body.append(generateRequireNotNull(thisVariable, fieldAndDescriptor.getStateSerializerField()));
        body.append(thisVariable.setField(fieldAndDescriptor.getStateFactoryField(), loadConstant(callSiteBinder, accumulatorStateDescriptor.getFactory(), AccumulatorStateFactory.class)));
        body.append(generateRequireNotNull(thisVariable, fieldAndDescriptor.getStateFactoryField()));
        // create the state object
        FieldDefinition stateField = fieldAndDescriptor.getStateField();
        BytecodeExpression stateFactory = thisVariable.getField(fieldAndDescriptor.getStateFactoryField());
        BytecodeExpression createStateInstance = stateFactory.invoke(grouped ? "createGroupedState" : "createSingleState", AccumulatorState.class);
        body.append(thisVariable.setField(stateField, createStateInstance.cast(stateField.getType())));
        body.append(generateRequireNotNull(thisVariable, stateField));
    }
}
Also used : Variable(io.airlift.bytecode.Variable) FieldDefinition(io.airlift.bytecode.FieldDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 30 with BytecodeExpression

use of io.airlift.bytecode.expression.BytecodeExpression in project trino by trinodb.

the class AccumulatorCompiler method generateEvaluateFinal.

private static void generateEvaluateFinal(ClassDefinition definition, List<FieldDefinition> stateFields, MethodHandle outputFunction, CallSiteBinder callSiteBinder) {
    Parameter out = arg("out", BlockBuilder.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC), "evaluateFinal", type(void.class), out);
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    List<BytecodeExpression> states = new ArrayList<>();
    for (FieldDefinition stateField : stateFields) {
        BytecodeExpression state = thisVariable.getField(stateField);
        states.add(state);
    }
    body.comment("output(state_0, state_1, ..., out)");
    states.forEach(body::append);
    body.append(out);
    body.append(invoke(callSiteBinder.bind(outputFunction), "output"));
    body.ret();
}
Also used : Variable(io.airlift.bytecode.Variable) MethodDefinition(io.airlift.bytecode.MethodDefinition) FieldDefinition(io.airlift.bytecode.FieldDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) Parameter(io.airlift.bytecode.Parameter) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Aggregations

BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)66 MethodDefinition (io.airlift.bytecode.MethodDefinition)51 Parameter (io.airlift.bytecode.Parameter)49 Variable (io.airlift.bytecode.Variable)49 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)38 IfStatement (io.airlift.bytecode.control.IfStatement)20 LabelNode (io.airlift.bytecode.instruction.LabelNode)17 FieldDefinition (io.airlift.bytecode.FieldDefinition)14 Type (io.trino.spi.type.Type)14 Scope (io.airlift.bytecode.Scope)13 ArrayList (java.util.ArrayList)13 ImmutableList (com.google.common.collect.ImmutableList)11 SqlTypeBytecodeExpression.constantType (io.trino.sql.gen.SqlTypeBytecodeExpression.constantType)11 BigintType (io.trino.spi.type.BigintType)10 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)9 BytecodeNode (io.airlift.bytecode.BytecodeNode)9 ClassDefinition (io.airlift.bytecode.ClassDefinition)8 MethodHandle (java.lang.invoke.MethodHandle)8 Type (io.prestosql.spi.type.Type)7 SqlTypeBytecodeExpression.constantType (io.prestosql.sql.gen.SqlTypeBytecodeExpression.constantType)7