Search in sources :

Example 96 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class JoinCompiler method generateConstructor.

private static void generateConstructor(ClassDefinition classDefinition, List<Integer> joinChannels, FieldDefinition sizeField, FieldDefinition instanceSizeField, List<FieldDefinition> channelFields, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
    Parameter channels = arg("channels", type(List.class, type(List.class, Block.class)));
    Parameter hashChannel = arg("hashChannel", type(OptionalInt.class));
    MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), channels, hashChannel);
    Variable thisVariable = constructorDefinition.getThis();
    Variable blockIndex = constructorDefinition.getScope().declareVariable(int.class, "blockIndex");
    BytecodeBlock constructor = constructorDefinition.getBody().comment("super();").append(thisVariable).invokeConstructor(Object.class);
    constructor.comment("this.size = INSTANCE_SIZE").append(thisVariable.setField(sizeField, getStatic(instanceSizeField)));
    constructor.comment("Set channel fields");
    for (int index = 0; index < channelFields.size(); index++) {
        BytecodeExpression channel = channels.invoke("get", Object.class, constantInt(index)).cast(type(List.class, Block.class));
        constructor.append(thisVariable.setField(channelFields.get(index), channel));
        BytecodeBlock loopBody = new BytecodeBlock();
        constructor.comment("for(blockIndex = 0; blockIndex < channel.size(); blockIndex++) { size += channel.get(i).getRetainedSizeInBytes() }").append(new ForLoop().initialize(blockIndex.set(constantInt(0))).condition(new BytecodeBlock().append(blockIndex).append(channel.invoke("size", int.class)).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(blockIndex, (byte) 1)).body(loopBody));
        loopBody.append(thisVariable).append(thisVariable).getField(sizeField).append(channel.invoke("get", Object.class, blockIndex).cast(type(Block.class)).invoke("getRetainedSizeInBytes", long.class)).longAdd().putField(sizeField);
    }
    constructor.comment("Set join channel fields");
    for (int index = 0; index < joinChannelFields.size(); index++) {
        BytecodeExpression joinChannel = channels.invoke("get", Object.class, constantInt(joinChannels.get(index))).cast(type(List.class, Block.class));
        constructor.append(thisVariable.setField(joinChannelFields.get(index), joinChannel));
    }
    constructor.comment("Set hashChannel");
    constructor.append(new IfStatement().condition(hashChannel.invoke("isPresent", boolean.class)).ifTrue(thisVariable.setField(hashChannelField, channels.invoke("get", Object.class, hashChannel.invoke("getAsInt", int.class)))).ifFalse(thisVariable.setField(hashChannelField, constantNull(hashChannelField.getType()))));
    constructor.ret();
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) ForLoop(io.airlift.bytecode.control.ForLoop) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.prestosql.spi.block.Block) LongArrayList(it.unimi.dsi.fastutil.longs.LongArrayList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) OptionalInt(java.util.OptionalInt) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 97 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class CursorProcessorCompiler method generateFilterMethod.

private void generateFilterMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, RowExpression filter) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter cursor = arg("cursor", RecordCursor.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), session, cursor);
    method.comment("Filter: %s", filter);
    Scope scope = method.getScope();
    Variable wasNullVariable = scope.declareVariable(type(boolean.class), "wasNull");
    RowExpressionCompiler compiler = new RowExpressionCompiler(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cursor), metadata, compiledLambdaMap, new ClassContext(classDefinition, scope, (newFilterName, rowExpressionCompiler, generator, subFilter, callerScope) -> {
        MethodDefinition newFilterMethod = classDefinition.declareMethod(a(PUBLIC), newFilterName, type(boolean.class), ImmutableList.<Parameter>builder().add(session).add(cursor).build());
        newFilterMethod.comment("Filter: %s", subFilter.toString());
        Scope innerScope = newFilterMethod.getScope();
        Variable wasNullVariable1 = innerScope.declareVariable(type(boolean.class), "wasNull");
        LabelNode end1 = new LabelNode("end");
        BytecodeGeneratorContext generatorContext = new BytecodeGeneratorContext(rowExpressionCompiler, innerScope, callSiteBinder, cachedInstanceBinder, metadata.getFunctionAndTypeManager());
        newFilterMethod.getBody().comment("boolean wasNull = false;").putVariable(wasNullVariable1, false).comment("evaluate filter: " + subFilter).append(generator.generateExpression(null, generatorContext, subFilter.getType(), subFilter.getArguments())).comment("if (wasNull) return false;").getVariable(wasNullVariable1).ifFalseGoto(end1).pop(boolean.class).push(false).visitLabel(end1).retBoolean();
        /* Call the sub-method: Important use caller scope to pass parameters to new function */
        BytecodeBlock block = new BytecodeBlock().setDescription("INVOKE " + newFilterName);
        LabelNode endCall = new LabelNode("end");
        block.append(callerScope.getThis()).getVariable(session).getVariable(cursor).invokeVirtual(classDefinition.getType(), newFilterName, type(boolean.class), type(ConnectorSession.class), type(RecordCursor.class));
        block.visitLabel(endCall);
        return block;
    }));
    LabelNode end = new LabelNode("end");
    method.getBody().comment("boolean wasNull = false;").putVariable(wasNullVariable, false).comment("evaluate filter: " + filter).append(compiler.compile(filter, scope)).comment("if (wasNull) return false;").getVariable(wasNullVariable).ifFalseGoto(end).pop(boolean.class).push(false).visitLabel(end).retBoolean();
}
Also used : ParameterizedType.type(io.airlift.bytecode.ParameterizedType.type) Variable(io.airlift.bytecode.Variable) Slice(io.airlift.slice.Slice) ConstantExpression(io.prestosql.spi.relation.ConstantExpression) JumpInstruction.jump(io.airlift.bytecode.instruction.JumpInstruction.jump) RowExpressionVisitor(io.prestosql.spi.relation.RowExpressionVisitor) DriverYieldSignal(io.prestosql.operator.DriverYieldSignal) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeNode(io.airlift.bytecode.BytecodeNode) Scope(io.airlift.bytecode.Scope) CursorProcessorOutput(io.prestosql.operator.project.CursorProcessorOutput) Parameter(io.airlift.bytecode.Parameter) WhileLoop(io.airlift.bytecode.control.WhileLoop) Access.a(io.airlift.bytecode.Access.a) CallExpression(io.prestosql.spi.relation.CallExpression) Parameter.arg(io.airlift.bytecode.Parameter.arg) ImmutableList(com.google.common.collect.ImmutableList) ConnectorSession(io.prestosql.spi.connector.ConnectorSession) BytecodeExpressions.constantTrue(io.airlift.bytecode.expression.BytecodeExpressions.constantTrue) LabelNode(io.airlift.bytecode.instruction.LabelNode) Locale(java.util.Locale) Map(java.util.Map) RecordCursor(io.prestosql.spi.connector.RecordCursor) Type(io.prestosql.spi.type.Type) SpecialForm(io.prestosql.spi.relation.SpecialForm) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeExpressions.newInstance(io.airlift.bytecode.expression.BytecodeExpressions.newInstance) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) BytecodeUtils.generateWrite(io.prestosql.sql.gen.BytecodeUtils.generateWrite) BlockBuilder(io.prestosql.spi.block.BlockBuilder) CompiledLambda(io.prestosql.sql.gen.LambdaBytecodeGenerator.CompiledLambda) Set(java.util.Set) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) PageBuilder(io.prestosql.spi.PageBuilder) Metadata(io.prestosql.metadata.Metadata) Primitives(com.google.common.primitives.Primitives) IfStatement(io.airlift.bytecode.control.IfStatement) List(java.util.List) PUBLIC(io.airlift.bytecode.Access.PUBLIC) BytecodeExpressions.or(io.airlift.bytecode.expression.BytecodeExpressions.or) LambdaDefinitionExpression(io.prestosql.spi.relation.LambdaDefinitionExpression) InputReferenceExpression(io.prestosql.spi.relation.InputReferenceExpression) RowExpression(io.prestosql.spi.relation.RowExpression) LambdaExpressionExtractor.extractLambdaExpressions(io.prestosql.sql.gen.LambdaExpressionExtractor.extractLambdaExpressions) ClassDefinition(io.airlift.bytecode.ClassDefinition) LabelNode(io.airlift.bytecode.instruction.LabelNode) 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)

Example 98 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class IfCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext context, Type returnType, List<RowExpression> arguments) {
    Preconditions.checkArgument(arguments.size() == 3);
    Variable wasNull = context.wasNull();
    BytecodeBlock condition = new BytecodeBlock().append(context.generate(arguments.get(0))).comment("... and condition value was not null").append(wasNull).invokeStatic(CompilerOperations.class, "not", boolean.class, boolean.class).invokeStatic(CompilerOperations.class, "and", boolean.class, boolean.class, boolean.class).append(wasNull.set(constantFalse()));
    return new IfStatement().condition(condition).ifTrue(context.generate(arguments.get(1))).ifFalse(context.generate(arguments.get(2)));
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock)

Example 99 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class RowConstructorCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext context, Type rowType, List<RowExpression> arguments) {
    BytecodeBlock block = new BytecodeBlock().setDescription("Constructor for " + rowType.toString());
    CallSiteBinder binder = context.getCallSiteBinder();
    Scope scope = context.getScope();
    List<Type> types = rowType.getTypeParameters();
    block.comment("Create new RowBlockBuilder; beginBlockEntry;");
    Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
    Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
    block.append(blockBuilder.set(constantType(binder, rowType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
    block.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    for (int i = 0; i < arguments.size(); ++i) {
        Type fieldType = types.get(i);
        Variable field = scope.createTempVariable(fieldType.getJavaType());
        block.comment("Clean wasNull and Generate + " + i + "-th field of row");
        block.append(context.wasNull().set(constantFalse()));
        block.append(context.generate(arguments.get(i)));
        block.putVariable(field);
        block.append(new IfStatement().condition(context.wasNull()).ifTrue(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, fieldType).writeValue(singleRowBlockWriter, field).pop()));
    }
    block.comment("closeEntry; slice the SingleRowBlock; wasNull = false;");
    block.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    block.append(constantType(binder, rowType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class));
    block.append(context.wasNull().set(constantFalse()));
    return block;
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) SqlTypeBytecodeExpression.constantType(io.prestosql.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.prestosql.spi.type.Type) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.prestosql.spi.block.Block) BlockBuilderStatus(io.prestosql.spi.block.BlockBuilderStatus)

Example 100 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class BytecodeUtils method generateWrite.

public static BytecodeNode generateWrite(CallSiteBinder callSiteBinder, Scope scope, Variable wasNullVariable, Type type) {
    Class<?> valueJavaType = type.getJavaType();
    if (!valueJavaType.isPrimitive() && valueJavaType != Slice.class) {
        valueJavaType = Object.class;
    }
    String methodName = "write" + Primitives.wrap(valueJavaType).getSimpleName();
    // the stack contains [output, value]
    // We should be able to insert the code to get the output variable and compute the value
    // at the right place instead of assuming they are in the stack. We should also not need to
    // use temp variables to re-shuffle the stack to the right shape before Type.writeXXX is called
    // Unfortunately, because of the assumptions made by try_cast, we can't get around it yet.
    // TODO: clean up once try_cast is fixed
    Variable tempValue = scope.createTempVariable(valueJavaType);
    Variable tempOutput = scope.createTempVariable(BlockBuilder.class);
    return new BytecodeBlock().comment("if (wasNull)").append(new IfStatement().condition(wasNullVariable).ifTrue(new BytecodeBlock().comment("output.appendNull();").pop(valueJavaType).invokeInterface(BlockBuilder.class, "appendNull", BlockBuilder.class).pop()).ifFalse(new BytecodeBlock().comment("%s.%s(output, %s)", type.getTypeSignature(), methodName, valueJavaType.getSimpleName()).putVariable(tempValue).putVariable(tempOutput).append(loadConstant(callSiteBinder.bind(type, Type.class))).getVariable(tempOutput).getVariable(tempValue).invokeInterface(Type.class, methodName, void.class, BlockBuilder.class, valueJavaType)));
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Type(io.prestosql.spi.type.Type) MethodType(java.lang.invoke.MethodType) Variable(io.airlift.bytecode.Variable) Slice(io.airlift.slice.Slice) BytecodeBlock(io.airlift.bytecode.BytecodeBlock)

Aggregations

BytecodeBlock (io.airlift.bytecode.BytecodeBlock)129 Variable (io.airlift.bytecode.Variable)112 MethodDefinition (io.airlift.bytecode.MethodDefinition)81 Parameter (io.airlift.bytecode.Parameter)73 IfStatement (io.airlift.bytecode.control.IfStatement)69 Scope (io.airlift.bytecode.Scope)56 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)36 BytecodeNode (io.airlift.bytecode.BytecodeNode)31 ClassDefinition (io.airlift.bytecode.ClassDefinition)29 LabelNode (io.airlift.bytecode.instruction.LabelNode)29 ImmutableList (com.google.common.collect.ImmutableList)25 ArrayList (java.util.ArrayList)23 ForLoop (io.airlift.bytecode.control.ForLoop)19 FieldDefinition (io.airlift.bytecode.FieldDefinition)18 Type (io.prestosql.spi.type.Type)15 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)14 Block (io.prestosql.spi.block.Block)14 List (java.util.List)13 BlockBuilder (io.prestosql.spi.block.BlockBuilder)12 Block (io.trino.spi.block.Block)12