Search in sources :

Example 21 with IntegerConstant

use of org.robovm.compiler.llvm.IntegerConstant in project robovm by robovm.

the class HashTableGeneratorTest method testNoRehashCollisions.

@Test
public void testNoRehashCollisions() {
    HashTableGenerator<Integer, Constant> gen = new HashTableGenerator<Integer, Constant>(new IntegerHash(), 2);
    gen.put(0, new IntegerConstant(0));
    gen.put(4, new IntegerConstant(4));
    gen.put(8, new IntegerConstant(8));
    StructureConstant result = gen.generate();
    assertEquals("{i32 3, i32 4, i32 0, i32 3, i32 3, i32 3, i32 3, i32 0, i32 4, i32 8}", result.toString());
}
Also used : StructureConstant(org.robovm.compiler.llvm.StructureConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StructureConstant(org.robovm.compiler.llvm.StructureConstant) Constant(org.robovm.compiler.llvm.Constant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Test(org.junit.Test)

Example 22 with IntegerConstant

use of org.robovm.compiler.llvm.IntegerConstant in project robovm by robovm.

the class HashTableGeneratorTest method testNoRehashNoCollisions.

@Test
public void testNoRehashNoCollisions() {
    HashTableGenerator<Integer, Constant> gen = new HashTableGenerator<Integer, Constant>(new IntegerHash(), 2);
    gen.put(0, new IntegerConstant(0));
    gen.put(1, new IntegerConstant(1));
    gen.put(2, new IntegerConstant(2));
    StructureConstant result = gen.generate();
    assertEquals("{i32 3, i32 4, i32 0, i32 1, i32 2, i32 3, i32 3, i32 0, i32 1, i32 2}", result.toString());
}
Also used : StructureConstant(org.robovm.compiler.llvm.StructureConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StructureConstant(org.robovm.compiler.llvm.StructureConstant) Constant(org.robovm.compiler.llvm.Constant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Test(org.junit.Test)

Example 23 with IntegerConstant

use of org.robovm.compiler.llvm.IntegerConstant in project robovm by robovm.

the class HashTableGeneratorTest method testRehashCollisions.

@Test
public void testRehashCollisions() {
    HashTableGenerator<Integer, Constant> gen = new HashTableGenerator<Integer, Constant>(new IntegerHash(), 2);
    gen.put(0, new IntegerConstant(0));
    gen.put(4, new IntegerConstant(4));
    gen.put(8, new IntegerConstant(8));
    gen.put(3, new IntegerConstant(3));
    StructureConstant result = gen.generate();
    assertEquals("{i32 4, i32 8, i32 0, i32 2, i32 2, i32 2, i32 3, i32 4, i32 4, i32 4, i32 4, i32 0, i32 8, i32 3, i32 4}", result.toString());
}
Also used : StructureConstant(org.robovm.compiler.llvm.StructureConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StructureConstant(org.robovm.compiler.llvm.StructureConstant) Constant(org.robovm.compiler.llvm.Constant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Test(org.junit.Test)

Example 24 with IntegerConstant

use of org.robovm.compiler.llvm.IntegerConstant in project robovm by robovm.

the class ClassCompiler method generateMachineCode.

private static void generateMachineCode(Config config, Clazz clazz, byte[] llData, List<String> cCode) throws IOException {
    if (config.isDumpIntermediates()) {
        File llFile = config.getLlFile(clazz);
        llFile.getParentFile().mkdirs();
        FileUtils.writeByteArrayToFile(llFile, llData);
        File cFile = config.getCFile(clazz);
        if (cCode.isEmpty()) {
            cFile.delete();
        } else {
            FileUtils.writeLines(cFile, "ascii", cCode);
        }
    }
    File oFile = config.getOFile(clazz);
    try (Context context = new Context()) {
        try (Module module = Module.parseIR(context, llData, clazz.getClassName())) {
            if (!cCode.isEmpty()) {
                int size = 0;
                for (String s : cCode) {
                    size += s.length();
                }
                StringBuilder sb = new StringBuilder(size);
                for (String s : cCode) {
                    sb.append(s);
                }
                try (Module m2 = Module.parseClangString(context, sb.toString(), clazz.getClassName() + ".c", config.getClangTriple())) {
                    module.link(m2);
                    for (org.robovm.llvm.Function f1 : m2.getFunctions()) {
                        String name = f1.getName();
                        org.robovm.llvm.Function f2 = module.getFunctionByName(name);
                        if (Symbols.isBridgeCSymbol(name) || Symbols.isCallbackCSymbol(name) || Symbols.isCallbackInnerCSymbol(name)) {
                            f2.setLinkage(org.robovm.llvm.binding.Linkage.PrivateLinkage);
                            if (Symbols.isCallbackInnerCSymbol(name)) {
                                // TODO: We should also always inline the bridge functions but for some reason
                                // that makes the RoboVM tests hang indefinitely.
                                f2.removeAttribute(Attribute.NoInlineAttribute);
                                f2.addAttribute(Attribute.AlwaysInlineAttribute);
                            }
                        }
                    }
                }
            }
            try (PassManager passManager = createPassManager(config)) {
                passManager.run(module);
            }
            if (config.isDumpIntermediates()) {
                File bcFile = config.getBcFile(clazz);
                bcFile.getParentFile().mkdirs();
                module.writeBitcode(bcFile);
            }
            String triple = config.getTriple();
            Target target = Target.lookupTarget(triple);
            try (TargetMachine targetMachine = target.createTargetMachine(triple, config.getArch().getLlvmCpu(), null, config.isDebug() ? CodeGenOptLevel.CodeGenLevelNone : null, RelocMode.RelocPIC, null)) {
                targetMachine.setAsmVerbosityDefault(true);
                targetMachine.setFunctionSections(true);
                targetMachine.setDataSections(true);
                targetMachine.getOptions().setNoFramePointerElim(true);
                // NOTE: Doesn't have any effect on x86. See #503.
                targetMachine.getOptions().setPositionIndependentExecutable(!config.isDebug());
                ByteArrayOutputStream output = new ByteArrayOutputStream(256 * 1024);
                targetMachine.emit(module, output, CodeGenFileType.AssemblyFile);
                byte[] asm = output.toByteArray();
                output.reset();
                patchAsmWithFunctionSizes(config, clazz, new ByteArrayInputStream(asm), output);
                asm = output.toByteArray();
                if (config.isDumpIntermediates()) {
                    File sFile = config.getSFile(clazz);
                    sFile.getParentFile().mkdirs();
                    FileUtils.writeByteArrayToFile(sFile, asm);
                }
                oFile.getParentFile().mkdirs();
                ByteArrayOutputStream oFileBytes = new ByteArrayOutputStream();
                targetMachine.assemble(asm, clazz.getClassName(), oFileBytes);
                new HfsCompressor().compress(oFile, oFileBytes.toByteArray(), config);
                for (CompilerPlugin plugin : config.getCompilerPlugins()) {
                    plugin.afterObjectFile(config, clazz, oFile);
                }
                /*
                     * Read out line number info from the .o file if any and
                     * assemble into a separate .o file.
                     */
                String symbolPrefix = config.getOs().getFamily() == OS.Family.darwin ? "_" : "";
                symbolPrefix += Symbols.EXTERNAL_SYMBOL_PREFIX;
                ModuleBuilder linesMb = null;
                try (ObjectFile objectFile = ObjectFile.load(oFile)) {
                    for (Symbol symbol : objectFile.getSymbols()) {
                        if (symbol.getSize() > 0 && symbol.getName().startsWith(symbolPrefix)) {
                            List<LineInfo> lineInfos = objectFile.getLineInfos(symbol);
                            if (!lineInfos.isEmpty()) {
                                Collections.sort(lineInfos, new Comparator<LineInfo>() {

                                    public int compare(LineInfo o1, LineInfo o2) {
                                        return Long.compare(o1.getAddress(), o2.getAddress());
                                    }
                                });
                                // The base address of the method which will be used to calculate offsets into the method
                                long baseAddress = symbol.getAddress();
                                // The first line number in the method. All other line numbers in the table will be deltas against this.
                                int firstLineNumber = lineInfos.get(0).getLineNumber();
                                // Calculate the max address and line number offsets
                                long maxAddressOffset = 0;
                                long maxLineOffset = 0;
                                for (LineInfo lineInfo : lineInfos) {
                                    maxAddressOffset = Math.max(maxAddressOffset, lineInfo.getAddress() - baseAddress);
                                    maxLineOffset = Math.max(maxLineOffset, lineInfo.getLineNumber() - firstLineNumber);
                                }
                                // Calculate the number of bytes needed to represent the highest offsets.
                                // Either 1, 2 or 4 bytes will be used.
                                int addressOffsetSize = (maxAddressOffset & ~0xff) == 0 ? 1 : ((maxAddressOffset & ~0xffff) == 0 ? 2 : 4);
                                int lineOffsetSize = (maxLineOffset & ~0xff) == 0 ? 1 : ((maxLineOffset & ~0xffff) == 0 ? 2 : 4);
                                // The size of the address offsets table. We skip the first LineInfo as its offset is always 0.
                                int addressOffsetTableSize = addressOffsetSize * (lineInfos.size() - 1);
                                // Pad size of address offset table to make sure line offsets are aligned properly 
                                int addressOffsetPadding = (lineOffsetSize - (addressOffsetTableSize & (lineOffsetSize - 1))) & (lineOffsetSize - 1);
                                addressOffsetTableSize += addressOffsetPadding;
                                // The first 32 bits of the line number info contains the number of line numbers
                                // minus the first. The 4 most significant bits are used to store the number of
                                // bytes needed by each entry in each table.
                                int flags = 0;
                                flags = addressOffsetSize - 1;
                                flags <<= 2;
                                flags |= lineOffsetSize - 1;
                                flags <<= 28;
                                flags |= (lineInfos.size() - 1) & 0x0fffffff;
                                StructureConstantBuilder builder = new StructureConstantBuilder();
                                builder.add(new IntegerConstant(flags)).add(new IntegerConstant(firstLineNumber));
                                for (LineInfo lineInfo : lineInfos.subList(1, lineInfos.size())) {
                                    if (addressOffsetSize == 1) {
                                        builder.add(new IntegerConstant((byte) (lineInfo.getAddress() - baseAddress)));
                                    } else if (addressOffsetSize == 2) {
                                        builder.add(new IntegerConstant((short) (lineInfo.getAddress() - baseAddress)));
                                    } else {
                                        builder.add(new IntegerConstant((int) (lineInfo.getAddress() - baseAddress)));
                                    }
                                }
                                // Padding
                                for (int i = 0; i < addressOffsetPadding; i++) {
                                    builder.add(new IntegerConstant((byte) 0));
                                }
                                for (LineInfo lineInfo : lineInfos.subList(1, lineInfos.size())) {
                                    if (lineOffsetSize == 1) {
                                        builder.add(new IntegerConstant((byte) (lineInfo.getLineNumber() - firstLineNumber)));
                                    } else if (lineOffsetSize == 2) {
                                        builder.add(new IntegerConstant((short) (lineInfo.getLineNumber() - firstLineNumber)));
                                    } else {
                                        builder.add(new IntegerConstant((int) (lineInfo.getLineNumber() - firstLineNumber)));
                                    }
                                }
                                // Extract the method's name and descriptor from the symbol and
                                // build the linetable symbol name.
                                String methodName = symbol.getName().substring(symbol.getName().lastIndexOf('.') + 1);
                                methodName = methodName.substring(0, methodName.indexOf('('));
                                String methodDesc = symbol.getName().substring(symbol.getName().lastIndexOf('('));
                                String linetableSymbol = Symbols.linetableSymbol(clazz.getInternalName(), methodName, methodDesc);
                                if (linesMb == null) {
                                    linesMb = new ModuleBuilder();
                                }
                                linesMb.addGlobal(new Global(linetableSymbol, builder.build(), true));
                            }
                        }
                    }
                }
                if (linesMb != null) {
                    byte[] linesData = linesMb.build().toString().getBytes("UTF-8");
                    if (config.isDumpIntermediates()) {
                        File linesLlFile = config.getLinesLlFile(clazz);
                        linesLlFile.getParentFile().mkdirs();
                        FileUtils.writeByteArrayToFile(linesLlFile, linesData);
                    }
                    try (Module linesModule = Module.parseIR(context, linesData, clazz.getClassName() + ".lines")) {
                        File linesOFile = config.getLinesOFile(clazz);
                        ByteArrayOutputStream linesOBytes = new ByteArrayOutputStream();
                        targetMachine.emit(linesModule, linesOBytes, CodeGenFileType.ObjectFile);
                        new HfsCompressor().compress(linesOFile, linesOBytes.toByteArray(), config);
                    }
                } else {
                    // Make sure there's no stale lines.o file lingering
                    File linesOFile = config.getLinesOFile(clazz);
                    if (linesOFile.exists()) {
                        linesOFile.delete();
                    }
                }
            }
        }
    } catch (Throwable t) {
        if (oFile.exists()) {
            oFile.delete();
        }
        if (t instanceof IOException) {
            throw (IOException) t;
        }
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        }
        if (t instanceof Error) {
            throw (Error) t;
        }
        throw new CompilerException(t);
    }
}
Also used : CompilerPlugin(org.robovm.compiler.plugin.CompilerPlugin) Symbol(org.robovm.llvm.Symbol) LineInfo(org.robovm.llvm.LineInfo) PassManager(org.robovm.llvm.PassManager) Global(org.robovm.compiler.llvm.Global) HfsCompressor(org.robovm.compiler.util.io.HfsCompressor) Target(org.robovm.llvm.Target) ObjectFile(org.robovm.llvm.ObjectFile) Context(org.robovm.llvm.Context) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) StructureConstantBuilder(org.robovm.compiler.llvm.StructureConstantBuilder) PackedStructureConstantBuilder(org.robovm.compiler.llvm.PackedStructureConstantBuilder) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) TargetMachine(org.robovm.llvm.TargetMachine) ByteArrayInputStream(java.io.ByteArrayInputStream) Module(org.robovm.llvm.Module) ObjectFile(org.robovm.llvm.ObjectFile) File(java.io.File)

Example 25 with IntegerConstant

use of org.robovm.compiler.llvm.IntegerConstant in project robovm by robovm.

the class Functions method trycatchAllEnter.

public static void trycatchAllEnter(Function fn, Value env, BasicBlockRef onNoException, BasicBlockRef onException) {
    Variable ctx = fn.newVariable(TRYCATCH_CONTEXT_PTR);
    fn.add(new Alloca(ctx, TRYCATCH_CONTEXT));
    Variable selPtr = fn.newVariable(new PointerType(I32));
    fn.add(new Getelementptr(selPtr, ctx.ref(), 0, 1));
    fn.add(new Store(new IntegerConstant(-1), selPtr.ref()));
    Value result = call(fn, RVM_TRYCATCH_ENTER, env, ctx.ref());
    fn.add(new Switch(result, onException, new IntegerConstant(0), onNoException));
}
Also used : Variable(org.robovm.compiler.llvm.Variable) Alloca(org.robovm.compiler.llvm.Alloca) Switch(org.robovm.compiler.llvm.Switch) Value(org.robovm.compiler.llvm.Value) Store(org.robovm.compiler.llvm.Store) PointerType(org.robovm.compiler.llvm.PointerType) Getelementptr(org.robovm.compiler.llvm.Getelementptr) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Aggregations

IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)39 Value (org.robovm.compiler.llvm.Value)24 Variable (org.robovm.compiler.llvm.Variable)14 NullConstant (org.robovm.compiler.llvm.NullConstant)11 ConstantBitcast (org.robovm.compiler.llvm.ConstantBitcast)10 FunctionRef (org.robovm.compiler.llvm.FunctionRef)10 ArrayList (java.util.ArrayList)9 Function (org.robovm.compiler.llvm.Function)9 Ret (org.robovm.compiler.llvm.Ret)9 Constant (org.robovm.compiler.llvm.Constant)8 FunctionType (org.robovm.compiler.llvm.FunctionType)8 Global (org.robovm.compiler.llvm.Global)8 PointerType (org.robovm.compiler.llvm.PointerType)8 StructureConstant (org.robovm.compiler.llvm.StructureConstant)8 StructureConstantBuilder (org.robovm.compiler.llvm.StructureConstantBuilder)8 Invokestatic (org.robovm.compiler.trampoline.Invokestatic)8 Bitcast (org.robovm.compiler.llvm.Bitcast)6 Label (org.robovm.compiler.llvm.Label)6 Load (org.robovm.compiler.llvm.Load)6 Type (org.robovm.compiler.llvm.Type)6