diff --git a/compiler/cacerts/full/pom.xml b/compiler/cacerts/full/pom.xml index 1fa821b01..4e4c0379c 100755 --- a/compiler/cacerts/full/pom.xml +++ b/compiler/cacerts/full/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-cacerts-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-cacerts-full diff --git a/compiler/cacerts/pom.xml b/compiler/cacerts/pom.xml index 494480108..71ed9c9d5 100755 --- a/compiler/cacerts/pom.xml +++ b/compiler/cacerts/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-cacerts-parent diff --git a/compiler/cocoatouch/pom.xml b/compiler/cocoatouch/pom.xml index 42f294228..de399066f 100755 --- a/compiler/cocoatouch/pom.xml +++ b/compiler/cocoatouch/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-cocoatouch diff --git a/compiler/compiler/pom.xml b/compiler/compiler/pom.xml index fde771b68..324a31b89 100755 --- a/compiler/compiler/pom.xml +++ b/compiler/compiler/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-compiler diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/AppCompiler.java b/compiler/compiler/src/main/java/org/robovm/compiler/AppCompiler.java index 1a2f4546c..1698e9ec9 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/AppCompiler.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/AppCompiler.java @@ -28,10 +28,7 @@ import org.robovm.compiler.config.Config.TreeShakerMode; import org.robovm.compiler.config.StripArchivesConfig.StripArchivesBuilder; import org.robovm.compiler.log.ConsoleLogger; -import org.robovm.compiler.plugin.LaunchPlugin; -import org.robovm.compiler.plugin.Plugin; -import org.robovm.compiler.plugin.PluginArgument; -import org.robovm.compiler.plugin.TargetPlugin; +import org.robovm.compiler.plugin.*; import org.robovm.compiler.target.ConsoleTarget; import org.robovm.compiler.target.LaunchParameters; import org.robovm.compiler.target.ios.*; @@ -439,6 +436,11 @@ public void failure(Clazz clazz, Throwable t) { dependencyGraph.add(clazz, rootClasses.contains(clazz), forceLinkMethods); linkClasses.add(clazz); + // notify plugins + for (CompilerPlugin plugin : config.getCompilerPlugins()) { + plugin.afterClassDependenciesResolved(config, clazz); + } + if (compileDependencies) { addMetaInfImplementations(config.getClazzes(), clazz, linkClasses, compileQueue); } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java b/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java index 2669072b5..0745bc76a 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java @@ -25,7 +25,6 @@ import org.robovm.compiler.clazz.MethodInfo; import org.robovm.compiler.config.Arch; import org.robovm.compiler.config.Config; -import org.robovm.compiler.config.Environment; import org.robovm.compiler.config.OS; import org.robovm.compiler.llvm.Alias; import org.robovm.compiler.llvm.AliasRef; @@ -228,7 +227,7 @@ public class ClassCompiler { private final TrampolineCompiler trampolineResolver; private final ObjCMemberPlugin.MethodCompiler objcMethodCompiler; - private final ByteArrayOutputStream output = new ByteArrayOutputStream(256 * 1024); + private final ByteArrayOutputStream output = new ByteArrayOutputStream(4 * 1024 * 1024); public ClassCompiler(Config config) { this.config = config; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/Linker.java b/compiler/compiler/src/main/java/org/robovm/compiler/Linker.java index 3282edc0e..71bd6d37b 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/Linker.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/Linker.java @@ -446,7 +446,10 @@ public void link(Set classes) throws IOException { } } - config.getTarget().build(objectFiles); + File binaryFile = config.getTarget().build(objectFiles); + for (CompilerPlugin plugin : config.getCompilerPlugins()) { + plugin.afterLinker(config, binaryFile); + } } private void generateMachineCode(final Config config, ModuleBuilder[] mbs, diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/AbstractPath.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/AbstractPath.java index a86991991..37482e371 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/AbstractPath.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/AbstractPath.java @@ -31,9 +31,9 @@ public abstract class AbstractPath implements Path { protected final Clazzes clazzes; protected final int index; protected Set clazzSet = null; - protected Set packageSet = null; - protected boolean inBootclasspath = false; - protected Map generatedClasses = new HashMap(); + protected boolean disposed = false; + protected boolean inBootclasspath; + protected Map generatedClasses = new HashMap<>(); protected final File generatedClassDir; AbstractPath(File file, Clazzes clazzes, int index, boolean inBootclasspath) { @@ -57,6 +57,8 @@ public File getFile() { } public Set listClasses() { + if (disposed) + throw new IllegalStateException("Path was disposed!"); if (clazzSet == null) { clazzSet = doListClasses(); } @@ -119,5 +121,11 @@ public boolean equals(Object obj) { public String toString() { return file.toString(); } - + + @Override + public void disposeBuildData() { + disposed = true; + clazzSet = null; + generatedClasses = null; + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazz.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazz.java index 0064cf258..582791f4e 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazz.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazz.java @@ -18,6 +18,7 @@ import org.apache.commons.io.IOUtils; import soot.SootClass; +import soot.SootMethod; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -205,4 +206,18 @@ public int compareTo(Clazz o) { public String toString() { return className; } + + /** + * Drops Soot object and releases all its resolved bodies + */ + public void shrinkSoot() { + if (sootClass != null) { + // dropping all bodies + for (SootMethod m: sootClass.getMethods()) { + if (m.hasActiveBody()) + m.releaseActiveBody(); + } + sootClass = null; + } + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/ClazzInfo.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/ClazzInfo.java index 761136952..bf106fc39 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/ClazzInfo.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/ClazzInfo.java @@ -43,13 +43,13 @@ public class ClazzInfo implements Serializable { private String name; private String internalName; private String superclassName; - private final List interfaceNames = new ArrayList(); - private final List methods = new ArrayList(); - private final Set catchNames = new HashSet(); - private Map dependencies = new HashMap(); - private final Set checkcasts = new HashSet(); - private final Set instanceofs = new HashSet(); - private final Set invokes = new HashSet(); + private final List interfaceNames = new ArrayList<>(); + private final List methods = new ArrayList<>(); + private final Set catchNames = new HashSet<>(); + private Map dependencies = new HashMap<>(); + private final Set checkcasts = new HashSet<>(); + private final Set instanceofs = new HashSet<>(); + private final Set invokes = new HashSet<>(); private boolean isStruct; private boolean isEnum; @@ -190,7 +190,7 @@ public void setInterfaceNames(List interfaceNames) { } public List getInterfaces() { - List result = new ArrayList(); + List result = new ArrayList<>(); for (String ifname : interfaceNames) { result.add(loadClazzInfo(ifname)); } @@ -207,7 +207,7 @@ public void setCatchNames(Set catchNames) { } public List getCatches() { - List result = new ArrayList(); + List result = new ArrayList<>(); for (String n : catchNames) { result.add(loadClazzInfo(n)); } @@ -268,11 +268,11 @@ public void addSuperMethodDependency(String owner, String name, String desc, boo } public void clearDependencies() { - dependencies = new HashMap(); + dependencies = new HashMap<>(); } public Set getDependencies() { - return new HashSet(dependencies.values()); + return new HashSet<>(dependencies.values()); } public Set getAllDependencies() { @@ -360,4 +360,10 @@ public boolean equals(Object obj) { } return true; } + + public void dropDependencyData() { + for (MethodInfo mi : getMethods()) + mi.dropDependencyData(); + dependencies = null; + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazzes.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazzes.java index 135986b3b..04294e285 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazzes.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Clazzes.java @@ -40,17 +40,21 @@ */ public class Clazzes { private final Config config; - private final List bootclasspathPaths = new ArrayList(); - private final List classpathPaths = new ArrayList(); - private final List paths = new ArrayList(); - private final Map cache = new HashMap(); - private final List allClasses = new ArrayList(); + private final List bootclasspathPaths = new ArrayList<>(); + private final List classpathPaths = new ArrayList<>(); + private final List paths = new ArrayList<>(); + private final Map cache = new HashMap<>(); + private final List allClasses = new ArrayList<>(); private boolean sootInitialized = false; + // disposed state + private boolean sootDisposed = false; + private boolean contentDisposed = false; + public Clazzes(Config config, List bootclasspath, List classpath) throws IOException { this.config = config; - Set seen = new HashSet(); + Set seen = new HashSet<>(); addPaths(bootclasspath, bootclasspathPaths, seen, true); addPaths(classpath, classpathPaths, seen, false); paths.addAll(bootclasspathPaths); @@ -123,6 +127,7 @@ private boolean isEmpty(File dir) { } private void populateCache() { + requiresContent(); for (Path p : paths) { for (Clazz clazz : p.listClasses()) { if (!cache.containsKey(clazz.getInternalName())) { @@ -134,6 +139,7 @@ private void populateCache() { } public Clazz load(String internalName) { + requiresContent(); Clazz clazz = cache.get(internalName); if (clazz == null) { // Could be a generated class @@ -175,10 +181,12 @@ public List getPaths() { } public List listClasses() { + requiresContent(); return Collections.unmodifiableList(allClasses); } SootClass getSootClass(Clazz clazz) { + requiresSoot(); if (!sootInitialized) { initializeSoot(this); sootInitialized = true; @@ -210,6 +218,42 @@ private static String getSootClasspath(Clazzes clazzes) { return sb.toString(); } + /** + * sanity: checks if soot was disposed + */ + private void requiresSoot() { + if (sootDisposed) + throw new IllegalStateException("Soot has been disposed !"); + } + + /** + * releases soot resources, singletons once these are not required anymore to reduce memory pressure + * after this point soot is not usable anymore + */ + public void disposeSoot() { + requiresSoot(); + soot.G.reset(); + sootDisposed = true; + } + + + private void requiresContent() { + if (contentDisposed) + throw new IllegalStateException("Content has been disposed !"); + } + + /** + * drops caches and all classes data. after this point this data is not accessible + */ + public void disposeData() { + requiresContent(); + cache.clear(); + allClasses.clear(); + for (Path p : paths) + p.disposeBuildData(); + contentDisposed = true; + } + private static void initializeSoot(Clazzes clazzes) { soot.G.reset(); Options.v().set_output_format(Options.output_format_jimple); diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/MethodInfo.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/MethodInfo.java index 78e367f7b..6476556f9 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/MethodInfo.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/MethodInfo.java @@ -204,6 +204,10 @@ public boolean equals(Object obj) { return true; } + public void dropDependencyData() { + dependencies = null; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Path.java b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Path.java index 0145a2980..b22ed2da7 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Path.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/clazz/Path.java @@ -58,4 +58,9 @@ public interface Path { boolean contains(String file); InputStream open(String file) throws IOException; + + /** + * Dispose any cached data to reduce memory footprint + */ + void disposeBuildData(); } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/config/Config.java b/compiler/compiler/src/main/java/org/robovm/compiler/config/Config.java index 06b40df68..76dbf3633 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/config/Config.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/config/Config.java @@ -32,11 +32,7 @@ import org.robovm.compiler.config.tools.Tools; import org.robovm.compiler.llvm.DataLayout; import org.robovm.compiler.log.Logger; -import org.robovm.compiler.plugin.CompilerPlugin; -import org.robovm.compiler.plugin.LaunchPlugin; -import org.robovm.compiler.plugin.Plugin; -import org.robovm.compiler.plugin.PluginArgument; -import org.robovm.compiler.plugin.TargetPlugin; +import org.robovm.compiler.plugin.*; import org.robovm.compiler.plugin.annotation.AnnotationImplPlugin; import org.robovm.compiler.plugin.debug.DebugInformationPlugin; import org.robovm.compiler.plugin.debug.DebuggerLaunchPlugin; @@ -259,7 +255,8 @@ protected Config(UUID uuid) { new ByteBufferJava9ApiPlugin(), new LambdaPlugin(), new DebugInformationPlugin(), - new DebuggerLaunchPlugin() + new DebuggerLaunchPlugin(), + new BuildGarbageCollectorPlugin() )); this.loadPluginsFromClassPath(); } @@ -404,6 +401,8 @@ public StripArchivesConfig getStripArchivesConfig() { } public DependencyGraph getDependencyGraph() { + if (dependencyGraph == null) + throw new IllegalStateException(".dependencyGraph has been disposed!"); return dependencyGraph; } @@ -504,14 +503,29 @@ public File getOsArchDepLibDir() { } public Clazzes getClazzes() { + if (clazzes == null) + throw new IllegalStateException(".clazzes has been disposed!"); return clazzes; } + public void disposeBuildData() { + // not null clazzes as some data like allPath is required post-build (e.g. to stripArchives) + clazzes.disposeData(); + dependencyGraph = null; + vtableCache = null; + itableCache = null; + marshalerLookup = null; + } + public VTable.Cache getVTableCache() { + if (vtableCache == null) + throw new IllegalStateException(".vtableCache has been disposed!"); return vtableCache; } public ITable.Cache getITableCache() { + if (itableCache == null) + throw new IllegalStateException(".itableCache has been disposed!"); return itableCache; } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alias.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alias.java index 7ef42a061..ee72ae6cc 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alias.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alias.java @@ -17,11 +17,14 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public class Alias { +public class Alias implements Writable{ private final String name; private final Linkage linkage; private final Constant value; @@ -48,22 +51,29 @@ public Type getType() { return value.getType(); } - public String getDefinition() { - StringBuilder sb = new StringBuilder(); - sb.append("@\""); - sb.append(name); - sb.append("\" = "); + public void writeDefinition(Writer writer) throws IOException { + writer.write("@\""); + writer.write(name); + writer.write("\" = "); if (linkage != null) { - sb.append(linkage); - sb.append(' '); + writer.write(linkage.toString()); + writer.write(' '); } - sb.append("alias "); - sb.append(value.getType()); - sb.append(' '); - sb.append(value); - return sb.toString(); + writer.write("alias "); + value.getType().write(writer); + writer.write(' '); + value.write(writer); } - + + public String getDefinition() { + return toString(this::writeDefinition); + } + + @Override + public void write(Writer writer) throws IOException { + throw new IllegalStateException("writeDefinition to be used"); + } + @Override public String toString() { return name; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/AliasRef.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/AliasRef.java index 0abe8509b..312dd8361 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/AliasRef.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/AliasRef.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -84,4 +87,9 @@ public boolean equals(Object obj) { public String toString() { return "@\"" + name + "\""; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alloca.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alloca.java index ac82b3fe5..57df62366 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alloca.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Alloca.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Collections; import java.util.Set; @@ -45,8 +47,14 @@ public Type getType() { return type; } + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = alloca "); + type.write(writer); + } + @Override public String toString() { - return result + " = alloca " + type; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Argument.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Argument.java index 28d04f463..f02442482 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Argument.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Argument.java @@ -16,13 +16,15 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; /** * * @version $Id$ */ -public class Argument { +public class Argument implements Writable { private final Value value; private final ParameterAttribute[] attributes; @@ -78,13 +80,16 @@ public boolean equals(Object obj) { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); + public void write(Writer writer) throws IOException { for (ParameterAttribute attribute : attributes) { - sb.append(attribute); - sb.append(' '); + writer.write(attribute.toString()); + writer.write(' '); } - sb.append(value); - return sb.toString(); + value.write(writer); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayConstant.java index bac7a2750..4dce5bc1d 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -35,18 +38,22 @@ public Type getType() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('['); + public void write(Writer writer) throws IOException { + writer.write('['); for (int i = 0; i < values.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(values[i].getType()); - sb.append(' '); - sb.append(values[i]); + values[i].getType().write(writer); + writer.write(' '); + values[i].write(writer); } - sb.append(']'); - return sb.toString(); + writer.write(']'); + + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayType.java index 2d36c8c92..1f09755fe 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ArrayType.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -53,10 +56,17 @@ public Type getTypeAt(int index) { public int getTypeCount() { return (int) size; } - + + @Override + public void writeDefinition(Writer writer) throws IOException { + writer.append('[').append(Long.toString(size)).append(" x "); + elementType.write(writer); + writer.write("]"); + } + @Override public String getDefinition() { - return "[" + size + " x " + elementType + "]"; + return toString(this::writeDefinition); } @Override diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BasicBlock.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BasicBlock.java index f798e4221..422dff94c 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BasicBlock.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BasicBlock.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -25,7 +27,7 @@ * * @version $Id$ */ -public class BasicBlock { +public class BasicBlock implements Writable { private final Function function; private final Label label; private final List instructions = new ArrayList(); @@ -99,24 +101,27 @@ public Instruction last() { } return instructions.get(instructions.size() - 1); } - + @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getName()); - sb.append(":\n"); + public void write(Writer writer) throws IOException { + writer.write(getName()); + writer.write(":\n"); for (Instruction instruction : instructions) { - sb.append(" "); - sb.append(instruction.toString()); + writer.write(" "); + instruction.write(writer); List metadata = instruction.getMetadata(); if (!metadata.isEmpty()) { for (Metadata md : metadata) { - sb.append(", "); - sb.append(md.toString()); + writer.write(", "); + md.write(writer); } } - sb.append('\n'); + writer.write('\n'); } - return sb.toString(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BooleanConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BooleanConstant.java index 9251b45b7..6deeab2e9 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BooleanConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/BooleanConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -40,4 +43,9 @@ public Type getType() { public String toString() { return String.valueOf(value); } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Br.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Br.java index 6bd746049..3040cab8a 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Br.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Br.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -61,12 +63,20 @@ public Set getBranchTargets() { } return result; } - + @Override - public String toString() { + public void write(Writer writer) throws IOException { if (cond != null) { - return "br i1 " + cond + ", label %" + destTrue.getName() + ", label %" + destFalse.getName(); + writer.write("br i1 "); + cond.write(writer); + writer.append(", label %").append(destTrue.getName()).append(", label %").append(destFalse.getName()); + } else { + writer.append("br label %").append(destTrue.getName()); } - return "br label %" + destTrue.getName(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ByteArrayConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ByteArrayConstant.java index 066f682d9..3e15dcae8 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ByteArrayConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ByteArrayConstant.java @@ -15,6 +15,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * Straight forward implementation of byte array constant to reduce amount of memory * required to do same foe ArrayConstant @@ -35,17 +38,20 @@ public Type getType() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('['); + public void write(Writer writer) throws IOException { + writer.write('['); for (int i = 0; i < values.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append("i8 "); - sb.append(values[i]); + writer.write("i8 "); + writer.write(Byte.toString(values[i])); } - sb.append(']'); - return sb.toString(); + writer.write(']'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConstantGetelementptr.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConstantGetelementptr.java index e4c465c60..744fe05e0 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConstantGetelementptr.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConstantGetelementptr.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -48,17 +51,20 @@ public Type getType() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("getelementptr ("); - sb.append(cst.getType()); - sb.append(' '); - sb.append(cst); - for (int i = 0; i < idx.length; i++) { - sb.append(", i32 "); - sb.append(idx[i]); + public void write(Writer writer) throws IOException { + writer.write("getelementptr ("); + cst.getType().write(writer); + writer.write(' '); + cst.write(writer); + for (int j : idx) { + writer.write(", i32 "); + writer.write(Integer.toString(j)); } - sb.append(")"); - return sb.toString(); + writer.write(')'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionConstant.java index 42efb3d5d..6b8a503d2 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -36,8 +39,20 @@ public Type getType() { return type; } + @Override + public void write(Writer writer) throws IOException { + writer.write(name); + writer.write(" ("); + cst.getType().write(writer); + writer.write(' '); + cst.write(writer); + writer.write(" to "); + type.write(writer); + writer.write(')'); + } + @Override public String toString() { - return name + " (" + cst.getType() + " " + cst + " to " + type + ")"; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionInstruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionInstruction.java index b8f00d294..de21ebfd5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionInstruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ConversionInstruction.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -29,9 +32,19 @@ protected ConversionInstruction(String name, Variable result, Value op, Type typ this.name = name; this.type = type; } - + + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = ").append(name).append(' '); + op.getType().write(writer); + writer.write(' '); + op.write(writer); + writer.write(" to "); + type.write(writer); + } + @Override public String toString() { - return result + " = " + name + " " + op.getType() + " " + op + " to " + type; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/DebugMetadata.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/DebugMetadata.java index 6544eeec2..e8b8b0802 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/DebugMetadata.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/DebugMetadata.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * {@link Metadata} used to attach debug info to instructions. */ @@ -26,9 +29,14 @@ public DebugMetadata(MetadataNode value) { this.value = value; } + @Override + public void write(Writer writer) throws IOException { + writer.write( "!dbg "); + value.write(writer); + } + @Override public String toString() { - return "!dbg " + value; + return toString(this::write); } - } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fcmp.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fcmp.java index 3b3d76d0c..5f0e972ae 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fcmp.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fcmp.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -40,9 +43,19 @@ public Fcmp(Variable result, Condition cond, Value op1, Value op2) { } this.cond = cond; } - + + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = fcmp ").append(cond.toString()).append(' '); + op1.getType().write(writer); + writer.write(' '); + op1.write(writer); + writer.write(", "); + op2.write(writer); + } + @Override public String toString() { - return result + " = fcmp " + cond + " " + op1.getType() + " " + op1 + ", " + op2; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fence.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fence.java index f24248813..d33a2be56 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fence.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Fence.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * @author niklas * @@ -32,4 +35,8 @@ public String toString() { return "fence " + ordering; } + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointBinaryInstruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointBinaryInstruction.java index 43ed448cb..f18abe710 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointBinaryInstruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointBinaryInstruction.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -34,9 +37,19 @@ protected FloatingPointBinaryInstruction(String name, Variable result, Value op1 } this.name = name; } - + + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = ").append(name).append(' '); + op1.getType().write(writer); + writer.write(' '); + op1.write(writer); + writer.write(", "); + op2.write(writer); + } + @Override public String toString() { - return result + " = " + name + " " + op1.getType() + " " + op1 + ", " + op2; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointConstant.java index 22b0d03ac..d1372f714 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FloatingPointConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -25,15 +28,15 @@ public class FloatingPointConstant extends Constant { private final Object value; public FloatingPointConstant(float value) { - this(new Float(value), Type.FLOAT); + this(value, Type.FLOAT); } public FloatingPointConstant(double value) { - this(new Double(value), Type.DOUBLE); + this(value, Type.DOUBLE); } public FloatingPointConstant(double value, FloatingPointType type) { - this.value = new Double(value); + this.value = value; this.type = type; } @@ -90,4 +93,9 @@ public String toString() { return "bitcast (i64 " + Double.doubleToLongBits(d) + " to double)"; } } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Function.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Function.java index 0cf9e89dc..f870370e8 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Function.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Function.java @@ -28,7 +28,7 @@ * * @version $Id$ */ -public class Function { +public class Function implements Writable { private final String name; private final Linkage linkage; private final FunctionAttribute[] attributes; @@ -178,6 +178,7 @@ public String getSignature() { return sig; } + @Override public void write(Writer writer) throws IOException { Type returnType = type.getReturnType(); Type[] parameterTypes = type.getParameterTypes(); @@ -186,7 +187,7 @@ public void write(Writer writer) throws IOException { writer.write(linkage.toString()); writer.write(' '); } - writer.write(returnType.toString()); + returnType.write(writer); writer.write(" @\""); writer.write(name); writer.write("\"("); @@ -194,7 +195,7 @@ public void write(Writer writer) throws IOException { if (i > 0) { writer.write(", "); } - writer.write(parameterTypes[i].toString()); + parameterTypes[i].write(writer); if (parameterAttributes[i] != null) { for (ParameterAttribute attrib : parameterAttributes[i]) { writer.write(' '); @@ -221,19 +222,13 @@ public void write(Writer writer) throws IOException { } writer.write(" {\n"); for (BasicBlock bb : basicBlockList) { - writer.write(bb.toString()); + bb.write(writer); } writer.write("}\n"); } @Override public String toString() { - StringWriter sw = new StringWriter(); - try { - write(sw); - } catch (IOException e) { - throw new RuntimeException(e); - } - return sw.toString(); + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionCallInstruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionCallInstruction.java index 72c385a6e..d989732e0 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionCallInstruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionCallInstruction.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -134,28 +136,34 @@ public boolean equals(Object obj) { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); + public void write(Writer writer) throws IOException { if (result != null) { - sb.append(result.toString()); - sb.append(" = "); + writer.write(result.toString()); + writer.write(" = "); } - sb.append(name); - sb.append(' '); + writer.write(name); + writer.write(' '); FunctionType ftype = (FunctionType) function.getType(); - sb.append(ftype.isVarargs() ? ftype.getDefinition() : ftype.getReturnType().toString()); - sb.append(" "); - sb.append(function.toString()); - sb.append('('); + if (ftype.isVarargs()) + ftype.writeDefinition(writer); + else + ftype.getReturnType().write(writer); + writer.write(' '); + function.write(writer); + writer.write('('); for (int i = 0; i < args.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(args[i].getType()); - sb.append(' '); - sb.append(args[i]); + args[i].getType().write(writer); + writer.write(' '); + args[i].write(writer); } - sb.append(')'); - return sb.toString(); + writer.write(')'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionDeclaration.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionDeclaration.java index 706e49faf..6889c1fbf 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionDeclaration.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionDeclaration.java @@ -17,11 +17,14 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public class FunctionDeclaration { +public class FunctionDeclaration implements Writable{ private final String name; private final FunctionType type; @@ -45,27 +48,30 @@ public FunctionType getType() { public FunctionRef ref() { return new FunctionRef(name, type); } - + @Override - public String toString() { + public void write(Writer writer) throws IOException { Type returnType = type.getReturnType(); Type[] parameterTypes = type.getParameterTypes(); - StringBuilder sb = new StringBuilder(); - sb.append("declare "); - sb.append(returnType.toString()); - sb.append(" @\""); - sb.append(name); - sb.append("\"("); + writer.write("declare "); + returnType.write(writer); + writer.write(" @\""); + writer.write(name); + writer.write("\"("); for (int i = 0; i < parameterTypes.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(parameterTypes[i].toString()); + parameterTypes[i].write(writer); } if (type.isVarargs()) { - sb.append(", ..."); + writer.write(", ..."); } - sb.append(")"); - return sb.toString(); + writer.write(')'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionRef.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionRef.java index dfdd47854..49c2f54a7 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionRef.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionRef.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -46,4 +49,9 @@ public FunctionType getType() { public String toString() { return "@\"" + name + "\""; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionType.java index 97ef75e31..e353b0e9f 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/FunctionType.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; @@ -66,26 +68,29 @@ public boolean isVarargs() { public Type[] getParameterTypes() { return parameterTypes; } - + @Override - public String getDefinition() { - StringBuilder sb = new StringBuilder(); - sb.append(returnType.toString()); - sb.append(" ("); + public void writeDefinition(Writer writer) throws IOException { + returnType.write(writer); + writer.write(" ("); for (int i = 0; i < parameterTypes.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(parameterTypes[i].toString()); + parameterTypes[i].write(writer); } if (varargs) { if (parameterTypes.length > 0) { - sb.append(", "); + writer.write(", "); } - sb.append("..."); + writer.write("..."); } - sb.append(")*"); - return sb.toString(); + writer.write(")*"); + } + + @Override + public String getDefinition() { + return toString(this::writeDefinition); } @Override diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Getelementptr.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Getelementptr.java index ef6aa50f1..2e08d94e8 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Getelementptr.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Getelementptr.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Collections; import java.util.Set; @@ -73,21 +75,24 @@ public Set getReadsFrom() { } return super.getReadsFrom(); } - + @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(result); - sb.append(" = getelementptr "); - sb.append(ptr.getType()); - sb.append(' '); - sb.append(ptr); - for (int i = 0; i < idx.length; i++) { - sb.append(", "); - sb.append(idx[i].getType()); - sb.append(" "); - sb.append(idx[i]); + public void write(Writer writer) throws IOException { + writer.write(result.toString()); + writer.write(" = getelementptr "); + ptr.getType().write(writer); + writer.write(' '); + ptr.write(writer); + for (Value value : idx) { + writer.write(", "); + value.getType().write(writer); + writer.write(" "); + value.write(writer); } - return sb.toString(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Global.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Global.java index baf06285f..4a33bf614 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Global.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Global.java @@ -17,11 +17,14 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public class Global { +public class Global implements Writable { private final String name; private final Linkage linkage; private final Constant value; @@ -86,34 +89,41 @@ public String getName() { public PointerType getType() { return new PointerType(type); } - - public String getDefinition() { - StringBuilder sb = new StringBuilder(); - sb.append("@\""); - sb.append(name); - sb.append("\" = "); + + public void writeDefinition(Writer writer) throws IOException { + writer.write("@\""); + writer.write(name); + writer.write("\" = "); if (linkage != null) { - sb.append(linkage); - sb.append(' '); + writer.write(linkage.toString()); + writer.write(' '); } if (constant) { - sb.append("constant "); + writer.write("constant "); } else { - sb.append("global "); + writer.write("global "); } - sb.append(type); + type.write(writer); if (value != null) { - sb.append(' '); - sb.append(value); + writer.write(' '); + value.write(writer); } if (section != null) { - sb.append(", section \""); - sb.append(section); - sb.append('"'); + writer.write(", section \""); + writer.write(section); + writer.write('"'); } - return sb.toString(); } - + + public String getDefinition() { + return toString(this::writeDefinition); + } + + @Override + public void write(Writer writer) throws IOException { + throw new IllegalStateException("writeDefinition to be called!"); + } + @Override public String toString() { return "@\"" + name + "\""; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/GlobalRef.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/GlobalRef.java index 1b6b4c41c..e0d76a933 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/GlobalRef.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/GlobalRef.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -84,4 +87,9 @@ public boolean equals(Object obj) { public String toString() { return "@\"" + name + "\""; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Icmp.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Icmp.java index da5ce83c6..f6e3fc01d 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Icmp.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Icmp.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -40,8 +43,18 @@ public Icmp(Variable result, Condition cond, Value op1, Value op2) { this.cond = cond; } + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = icmp ").append(cond.toString()).append(' '); + op1.getType().write(writer); + writer.write(' '); + op1.write(writer); + writer.write(", "); + op2.write(writer); + } + @Override public String toString() { - return result + " = icmp " + cond + " " + op1.getType() + " " + op1 + ", " + op2; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Instruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Instruction.java index f5574fa4e..425ab5908 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Instruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Instruction.java @@ -25,7 +25,7 @@ * * @version $Id$ */ -public abstract class Instruction { +public abstract class Instruction implements Writable{ BasicBlock basicBlock; private List metadata; private List attachments; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryConstant.java index eecb4f71c..e97709545 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryConstant.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -39,9 +42,23 @@ protected IntegerBinaryConstant(String name, Constant op1, Constant op2) { public Type getType() { return op1.getType(); } - + + @Override + public void write(Writer writer) throws IOException { + writer.write(name); + writer.write(" ("); + op1.getType().write(writer); + writer.write(' '); + op1.write(writer); + writer.write(", "); + op2.getType().write(writer); + writer.write(' '); + op2.write(writer); + writer.write(')'); + } + @Override public String toString() { - return name + " (" + op1.getType() + " " + op1 + ", " + op2.getType() + " " + op2 + ")"; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryInstruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryInstruction.java index b6727cc86..ce12276f5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryInstruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerBinaryInstruction.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -35,8 +38,18 @@ protected IntegerBinaryInstruction(String name, Variable result, Value op1, Valu this.name = name; } + @Override + public void write(Writer writer) throws IOException { + writer.append(result.toString()).append(" = ").append(name).append(' '); + op1.getType().write(writer); + writer.write(' '); + op1.write(writer); + writer.write(", "); + op2.write(writer); + } + @Override public String toString() { - return result + " = " + name + " " + op1.getType() + " " + op1 + ", " + op2; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerConstant.java index 0fc50bff5..7726887fc 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/IntegerConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -30,27 +33,27 @@ private IntegerConstant(Object value, IntegerType type) { } public IntegerConstant(long value, IntegerType type) { - this(new Long(value), type); + this(Long.valueOf(value), type); } public IntegerConstant(byte value) { - this(new Byte(value), Type.I8); + this(Byte.valueOf(value), Type.I8); } public IntegerConstant(short value) { - this(new Short(value), Type.I16); + this(Short.valueOf(value), Type.I16); } public IntegerConstant(char value) { - this(new Integer(value), Type.I16); + this(Integer.valueOf(value), Type.I16); } public IntegerConstant(int value) { - this(new Integer(value), Type.I32); + this(Integer.valueOf(value), Type.I32); } public IntegerConstant(long value) { - this(new Long(value), Type.I64); + this(Long.valueOf(value), Type.I64); } @Override @@ -105,4 +108,9 @@ public int compareTo(IntegerConstant o) { public String toString() { return String.valueOf(value); } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Invoke.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Invoke.java index 7dcd95319..41f0e8041 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Invoke.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Invoke.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -88,9 +91,14 @@ public boolean equals(Object obj) { return true; } + @Override + public void write(Writer writer) throws IOException { + super.write(writer); + writer.append(" to label %").append(to.toString()).append(" unwind label %").append(unwind.toString()); + } + @Override public String toString() { - String s = super.toString(); - return s + " to label %" + to + " unwind label %" + unwind; + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Landingpad.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Landingpad.java index fbbf9aba8..58ee753bf 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Landingpad.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Landingpad.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * @author niklas * @@ -41,35 +44,47 @@ public Landingpad(Variable result, Constant personalityFn, } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(result); - sb.append(" = landingpad "); - sb.append(result.getType()); - sb.append(" personality "); - sb.append(personalityFn.getType()); - sb.append(' '); - sb.append(personalityFn); + public void write(Writer writer) throws IOException { + writer.write(result.toString()); + writer.write(" = landingpad "); + result.getType().write(writer); + writer.write(" personality "); + personalityFn.getType().write(writer); + writer.write(' '); + personalityFn.write(writer); if (cleanup) { - sb.append(" cleanup"); + writer.write(" cleanup"); } for (Clause clause : clauses) { - sb.append(' '); - sb.append(clause); + writer.write(' '); + clause.write(writer); } - return sb.toString(); } - - public interface Clause {} + + @Override + public String toString() { + return toString(this::write); + } + + public interface Clause extends Writable {} public static class Catch implements Clause { private final Value value; public Catch(Value value) { this.value = value; } + + @Override + public void write(Writer writer) throws IOException { + writer.write("catch "); + value.getType().write(writer); + writer.write(' '); + value.write(writer); + } + @Override public String toString() { - return "catch " + value.getType() + " " + value; + return toString(this::write); } } @@ -78,9 +93,18 @@ public static class Filter implements Clause { public Filter(ArrayConstant value) { this.value = value; } + + @Override + public void write(Writer writer) throws IOException { + writer.write("filter "); + value.getType().write(writer); + writer.write(' '); + value.write(writer); + } + @Override public String toString() { - return "filter " + value.getType() + " " + value; + return toString(this::write); } } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Load.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Load.java index 778f5b62f..16c48fe9f 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Load.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Load.java @@ -17,6 +17,8 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; /** * @@ -43,27 +45,30 @@ public Load(Variable result, Value op, boolean _volatile, Ordering ordering, int } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(result); - sb.append(" = load "); + public void write(Writer writer) throws IOException { + writer.write(result.toString()); + writer.write(" = load "); if (_volatile) { - sb.append("volatile "); + writer.write("volatile "); } if (ordering != null) { - sb.append("atomic "); + writer.write("atomic "); } - sb.append(op.getType()); - sb.append(" "); - sb.append(op); + op.getType().write(writer); + writer.write(" "); + op.write(writer); if (ordering != null) { - sb.append(" "); - sb.append(ordering); + writer.write(" "); + writer.write(ordering.toString()); } if (alignment > 0) { - sb.append(", align "); - sb.append(alignment); + writer.write(", align "); + writer.write(Integer.toString(alignment)); } - return sb.toString(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataNode.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataNode.java index 808db4519..6cdc6d13d 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataNode.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataNode.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.List; /** @@ -34,24 +36,27 @@ public MetadataNode(List values) { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("!{"); + public void write(Writer writer) throws IOException { + writer.write("!{"); for (int i = 0; i < values.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } if (values[i] == null) { - sb.append("null"); + writer.write("null"); } else { if (values[i].getType() != Type.METADATA) { - sb.append(values[i].getType()); - sb.append(' '); + values[i].getType().write(writer); + writer.write(' '); } - sb.append(values[i]); + values[i].write(writer); } } - sb.append('}'); - return sb.toString(); + writer.write('}'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataString.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataString.java index 51e1ce417..a58c1591c 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataString.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataString.java @@ -16,7 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.io.Writer; /** * @@ -37,12 +39,15 @@ public MetadataString(String s) { } } + @Override + public void write(Writer writer) throws IOException { + writer.write("!\""); + StringConstant.escape(writer, bytes); + writer.write('"'); + } + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("!\""); - StringConstant.escape(sb, bytes); - sb.append('"'); - return sb.toString(); + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataType.java index e05b49b1d..f4b3a141d 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataType.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -29,4 +32,9 @@ public class MetadataType extends Type { public String toString() { return "metadata"; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataValue.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataValue.java index 21ef4c204..58122e6d9 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataValue.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/MetadataValue.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -29,13 +32,16 @@ public MetadataValue(Value value) { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); + public void write(Writer writer) throws IOException { if (value.getType() != Type.METADATA) { - sb.append(value.getType()); - sb.append(' '); + value.getType().write(writer); + writer.write(' '); } - sb.append(value); - return sb.toString(); + value.write(writer); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Module.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Module.java index 6602d8d12..4a6cb5544 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Module.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Module.java @@ -29,7 +29,7 @@ * * @version $Id$ */ -public class Module { +public class Module implements Writable{ private final Collection includes; private final Collection globals; private final Collection aliases; @@ -57,6 +57,7 @@ public Module(Collection includes, Collection types, this.unnamedMetadata = unnamedMetadata; } + @Override public void write(Writer writer) throws IOException { for (URL g : includes) { InputStream in = null; @@ -80,49 +81,43 @@ public void write(Writer writer) throws IOException { for (UserType type : types) { writer.write(type.getAlias()); writer.write(" = type "); - writer.write(type.getDefinition()); + type.writeDefinition(writer); writer.write("\n"); } writer.write("\n"); for (FunctionDeclaration fd : functionDeclarations) { - writer.write(fd.toString()); + fd.write(writer); writer.write("\n"); } writer.write("\n"); for (Global g : globals) { - writer.write(g.getDefinition()); + g.writeDefinition(writer); writer.write("\n"); } writer.write("\n"); for (Alias a : aliases) { - writer.write(a.getDefinition()); + a.writeDefinition(writer); writer.write("\n"); } writer.write("\n"); for (Function f : functions) { - writer.write(f.toString()); + f.write(writer); writer.write("\n"); } writer.write("\n"); for (NamedMetadata md : namedMetadata) { - writer.write(md.toString()); + md.write(writer); writer.write("\n"); } writer.write("\n"); for (UnnamedMetadata md : unnamedMetadata) { - writer.write(md.getDefinition()); + md.writeDefinition(writer); writer.write("\n"); } } @Override public String toString() { - StringWriter sw = new StringWriter(); - try { - write(sw); - } catch (IOException e) { - throw new RuntimeException(e); - } - return sw.toString(); + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NamedMetadata.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NamedMetadata.java index 514e31d24..3672cf39b 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NamedMetadata.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NamedMetadata.java @@ -16,11 +16,14 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public class NamedMetadata { +public class NamedMetadata implements Writable{ private final String name; private final UnnamedMetadata[] values; @@ -34,19 +37,22 @@ public String getName() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('!'); - sb.append(name); - sb.append(" = "); - sb.append("!{"); + public void write(Writer writer) throws IOException { + writer.write('!'); + writer.write(name); + writer.write(" = "); + writer.write("!{"); for (int i = 0; i < values.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(values[i]); + writer.write(values[i].toString()); } - sb.append('}'); - return sb.toString(); + writer.write('}'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NullConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NullConstant.java index 67c6b338e..49fd52712 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NullConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/NullConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -37,4 +40,9 @@ public Type getType() { public String toString() { return "null"; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/OpaqueType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/OpaqueType.java index 435dc59d9..cc14f64ea 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/OpaqueType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/OpaqueType.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -33,4 +36,9 @@ public OpaqueType(String alias) { public String getDefinition() { return "opaque"; } + + @Override + public void writeDefinition(Writer writer) throws IOException { + writer.write(getDefinition()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PackedStructureType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PackedStructureType.java index 43516f759..5a6471ac5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PackedStructureType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PackedStructureType.java @@ -17,6 +17,8 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; /** * @@ -41,9 +43,16 @@ public PackedStructureType(String alias, Type ... types) { align = 1; } + @Override + public void writeDefinition(Writer writer) throws IOException { + writer.write('<'); + super.writeDefinition(writer); + writer.write('>'); + } + @Override public String getDefinition() { - return "<" + super.getDefinition() + ">"; + return toString(this::writeDefinition); } public int getAlign() { diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Phi.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Phi.java index 7681a0111..4155f6f16 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Phi.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Phi.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -54,23 +56,26 @@ public Set getReadsFrom() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(result.toString()); - sb.append(" = phi "); - sb.append(result.getType().toString()); + public void write(Writer writer) throws IOException { + writer.write(result.toString()); + writer.write(" = phi "); + result.getType().write(writer); for (int i = 0; i < vars.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append("[ "); - sb.append(vars[i].toString()); - sb.append(", "); + writer.write("[ "); + writer.write(vars[i].toString()); + writer.write(", "); BasicBlock bb = basicBlock.getFunction().getDefinedIn(vars[i]); - sb.append('%'); - sb.append(bb.getName()); - sb.append(" ]"); + writer.write('%'); + writer.write(bb.getName()); + writer.write(" ]"); } - return sb.toString(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PlainTextInstruction.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PlainTextInstruction.java index 06b1fc21d..74a48b568 100644 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PlainTextInstruction.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PlainTextInstruction.java @@ -1,5 +1,8 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + public class PlainTextInstruction extends Instruction { private final String plainText; @@ -15,4 +18,9 @@ public String getPlainText() { public String toString() { return plainText; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PointerType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PointerType.java index 3ce92aa0a..07485b8c3 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PointerType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PointerType.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -36,10 +39,16 @@ public PointerType(String alias, Type base) { public Type getBase() { return base; } - + + @Override + public void writeDefinition(Writer writer) throws IOException { + base.write(writer); + writer.write('*'); + } + @Override public String getDefinition() { - return base.toString() + "*"; + return toString(this::writeDefinition); } @Override diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PrimitiveType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PrimitiveType.java index 84463df83..e5e69fc3a 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PrimitiveType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/PrimitiveType.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -65,4 +68,9 @@ public boolean equals(Object obj) { public String toString() { return name; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Ret.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Ret.java index b8773fab6..c058e06c1 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Ret.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Ret.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Collections; import java.util.Set; @@ -43,10 +45,19 @@ public Set getReadsFrom() { } @Override - public String toString() { + public void write(Writer writer) throws IOException { if (value != null) { - return "ret " + value.getType() + " " + value; + writer.write("ret "); + value.getType().write(writer); + writer.write(' '); + value.write(writer); + } else { + writer.write("ret void"); } - return "ret void"; + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Store.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Store.java index 39348810c..6e00e0406 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Store.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Store.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.HashSet; import java.util.Set; @@ -69,30 +71,33 @@ public Set getReadsFrom() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("store "); + public void write(Writer writer) throws IOException { + writer.write("store "); if (_volatile) { - sb.append("volatile "); + writer.write("volatile "); } if (ordering != null) { - sb.append("atomic "); + writer.write("atomic "); } - sb.append(value.getType()); - sb.append(" "); - sb.append(value); - sb.append(", "); - sb.append(pointer.getType()); - sb.append(" "); - sb.append(pointer); + value.getType().write(writer); + writer.write(" "); + value.write(writer); + writer.write(", "); + pointer.getType().write(writer); + writer.write(" "); + pointer.write(writer); if (ordering != null) { - sb.append(" "); - sb.append(ordering); + writer.write(" "); + writer.write(ordering.toString()); } if (alignment > 0) { - sb.append(", align "); - sb.append(alignment); + writer.write(", align "); + writer.write(Integer.toString(alignment)); } - return sb.toString(); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StringConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StringConstant.java index d759e0e69..03b5930d8 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StringConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StringConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -34,22 +37,25 @@ public Type getType() { return type; } + @Override + public void write(Writer writer) throws IOException { + writer.write("c\""); + escape(writer, bytes); + writer.write('"'); + } + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("c\""); - escape(sb, bytes); - sb.append('"'); - return sb.toString(); + return toString(this::write); } - static void escape(StringBuilder sb, byte[] bytes) { + static void escape(Writer writer, byte[] bytes) throws IOException { for (int i = 0; i < bytes.length; i++) { int b = bytes[i] & 0xff; if (b < ' ' || b > '~' || b == '"' || b == '\\') { - sb.append(String.format("\\%02X", b)); + writer.write(String.format("\\%02X", b)); } else { - sb.append((char) b); + writer.write((char) b); } } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java index 20188fe08..814f28cbe 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + import java.util.ArrayList; import java.util.List; @@ -63,18 +66,21 @@ public StructureConstant flatten() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('{'); + public void write(Writer writer) throws IOException { + writer.write('{'); for (int i = 0; i < values.length; i++) { if (i > 0) { - sb.append(", "); + writer.write(", "); } - sb.append(values[i].getType()); - sb.append(' '); - sb.append(values[i]); + values[i].getType().write(writer); + writer.write(' '); + values[i].write(writer); } - sb.append('}'); - return sb.toString(); + writer.write('}'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureType.java index b8e64bf76..531f82b67 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureType.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Arrays; @@ -72,16 +74,19 @@ public int getOwnMembersOffset() { } @Override - public String getDefinition() { - StringBuilder sb = new StringBuilder("{"); + public void writeDefinition(Writer writer) throws IOException { + writer.write('{'); for (int i = 0; i < types.length; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(types[i].toString()); + if (i > 0) + writer.write(", "); + types[i].write(writer); } - sb.append("}"); - return sb.toString(); + writer.write('}'); + } + + @Override + public String getDefinition() { + return toString(this::writeDefinition); } @Override diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Switch.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Switch.java index 1d3c9ed06..377968c8e 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Switch.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Switch.java @@ -16,6 +16,8 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -61,24 +63,27 @@ public Set getBranchTargets() { } @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("switch "); - sb.append(value.getType()); - sb.append(' '); - sb.append(value); - sb.append(", label %"); - sb.append(def.getName()); - sb.append(" [ "); + public void write(Writer writer) throws IOException { + writer.write("switch "); + value.getType().write(writer); + writer.write(' '); + value.write(writer); + writer.write(", label %"); + writer.write(def.getName()); + writer.write(" [ "); for (Entry pair : alt.entrySet()) { - sb.append(pair.getKey().getType()); - sb.append(' '); - sb.append(pair.getKey()); - sb.append(", label %"); - sb.append(pair.getValue().getName()); - sb.append(' '); + pair.getKey().getType().write(writer); + writer.write(' '); + pair.getKey().write(writer); + writer.write(", label %"); + writer.write(pair.getValue().getName()); + writer.write(' '); } - sb.append("]"); - return sb.toString(); + writer.write(']'); + } + + @Override + public String toString() { + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Type.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Type.java index b2e466b4e..dfbe72e8c 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Type.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Type.java @@ -20,7 +20,7 @@ * * @version $Id$ */ -public abstract class Type { +public abstract class Type implements Writable{ public static final IntegerType I1 = new IntegerType(1); public static final IntegerType I8 = new IntegerType(8); public static final IntegerType I16 = new IntegerType(16); diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadata.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadata.java index 10a5e1261..a6bc90961 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadata.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadata.java @@ -16,11 +16,14 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public class UnnamedMetadata { +public class UnnamedMetadata implements Writable { private final int index; private Metadata value; @@ -49,17 +52,24 @@ public int getIndex() { public String toString() { return "!" + index; } - - public String getDefinition() { - StringBuilder sb = new StringBuilder(); - sb.append('!'); - sb.append(index); - sb.append(" = "); + + public void writeDefinition(Writer writer) throws IOException { + writer.write('!'); + writer.write(Integer.toString(index)); + writer.write(" = "); if (value.getType() != Type.METADATA) { - sb.append(value.getType()); - sb.append(' '); + value.getType().write(writer); + writer.write(' '); } - sb.append(value.toString()); - return sb.toString(); + value.write(writer); + } + + public String getDefinition() { + return toString(this::writeDefinition); + } + + @Override + public void write(Writer writer) throws IOException { + throw new IllegalStateException("Use writeDefinition!"); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadataRef.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadataRef.java index 70cb55f16..29f5baae4 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadataRef.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UnnamedMetadataRef.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -62,4 +65,9 @@ public boolean equals(Object obj) { public String toString() { return "!" + index; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Unreachable.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Unreachable.java index 6975c20fe..48bf2002e 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Unreachable.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Unreachable.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -27,4 +30,9 @@ public class Unreachable extends Instruction { public String toString() { return "unreachable"; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UserType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UserType.java index 42f7e72bf..2297cb00c 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UserType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/UserType.java @@ -16,11 +16,14 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ */ -public abstract class UserType extends Type { +public abstract class UserType extends Type implements Writable{ protected final String alias; UserType() { @@ -40,7 +43,9 @@ public boolean hasAlias() { } public abstract String getDefinition(); - + + public abstract void writeDefinition(Writer writer) throws IOException; + @Override public int hashCode() { final int prime = 31; @@ -71,8 +76,13 @@ public boolean equals(Object obj) { return true; } + @Override + public void write(Writer writer) throws IOException { + if (alias != null) writer.write(alias); else writeDefinition(writer); + } + @Override public String toString() { - return alias != null ? alias : getDefinition(); + return toString(this::write); } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Value.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Value.java index b4c2d7b81..82e1c37d5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Value.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Value.java @@ -21,7 +21,7 @@ * * @version $Id$ */ -public abstract class Value { +public abstract class Value implements Writable{ public boolean isInteger() { return getType() instanceof IntegerType; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VariableRef.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VariableRef.java index 712af46f2..2d725cd6f 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VariableRef.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VariableRef.java @@ -17,6 +17,9 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * * @version $Id$ @@ -84,4 +87,9 @@ public boolean equals(Object obj) { public String toString() { return "%" + name; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VectorStructureType.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VectorStructureType.java index 8ca41d00a..68dcc8dfb 100644 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VectorStructureType.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/VectorStructureType.java @@ -17,6 +17,8 @@ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; /** * @@ -47,13 +49,26 @@ public boolean isVectorArray() { @Override - public String getDefinition() { + public void writeDefinition(Writer writer) throws IOException { if (types[0] instanceof StructureType) { // return as struct that contains array StructureType st = (StructureType) types[0]; - return "{ [" + types.length + " x " + st.getDefinition() + "] }"; + writer.write("{ ["); + writer.write(Integer.toString(types.length)); + writer.write(" x "); + st.writeDefinition(writer); + writer.write("] }"); } else { - return "<" + types.length + " x " + types[0].toString() + ">"; + writer.write("<"); + writer.write(Integer.toString(types.length)); + writer.write(" x "); + types[0].write(writer); + writer.write(">"); } } + + @Override + public String getDefinition() { + return toString(this::writeDefinition); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Writable.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Writable.java new file mode 100644 index 000000000..466b2494b --- /dev/null +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/Writable.java @@ -0,0 +1,26 @@ +package org.robovm.compiler.llvm; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +/** + * interface for classes that can write own text presentation using Writer. + * Used as toString() replacement to optimize memory usage + */ +public interface Writable { + interface Provider { + void write(Writer writer) throws IOException; + } + + void write(Writer writer) throws IOException; + + default String toString(Provider provider) { + try (StringWriter sbw = new StringWriter()) { + provider.write(sbw); + return sbw.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ZeroInitializer.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ZeroInitializer.java index 6ba19df24..b2ba53fd5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ZeroInitializer.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/ZeroInitializer.java @@ -15,6 +15,9 @@ */ package org.robovm.compiler.llvm; +import java.io.IOException; +import java.io.Writer; + /** * @author Demyan Kimitsa * returns zeroinitializer to be used as value with arrays structs ect @@ -36,4 +39,9 @@ public Type getType() { public String toString() { return "zeroinitializer"; } + + @Override + public void write(Writer writer) throws IOException { + writer.write(this.toString()); + } } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIBaseItem.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIBaseItem.java index d36df10dd..41a9f4a19 100644 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIBaseItem.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIBaseItem.java @@ -23,6 +23,9 @@ import org.robovm.compiler.llvm.NamedMetadata; import org.robovm.compiler.llvm.UnnamedMetadata; +import java.io.IOException; +import java.io.Writer; + /** * base class for metadata, used as single point of data to be attached to builder and once attached this data * should be used as everywhere as metadata reference @@ -60,7 +63,7 @@ protected DIBaseItem(ModuleBuilder builder, Metadata w) { * @param name to give to metadata */ public DIBaseItem(ModuleBuilder builder, String name) { - this(builder, name, null); + this(builder, name, (Metadata[])null); } protected DIBaseItem(ModuleBuilder builder, String name, Metadata... values) { @@ -98,7 +101,12 @@ private static class NamedMetadataRef extends Metadata { public String toString() { return "!" + name; } - }; + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } + } /** just a wrapper that allows this class to be considered as metadata */ @@ -107,6 +115,11 @@ private class MetadataWrap extends Metadata { public String toString() { return DIBaseItem.this.toString(); } + + @Override + public void write(Writer writer) throws IOException { + writer.write(toString()); + } } protected IntegerConstant v(int i) { diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIHeader.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIHeader.java index 945dba444..e37a93790 100644 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIHeader.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/debug/dwarf/DIHeader.java @@ -15,9 +15,10 @@ */ package org.robovm.compiler.llvm.debug.dwarf; -import org.apache.commons.lang3.StringUtils; import org.robovm.compiler.llvm.Metadata; +import java.io.IOException; +import java.io.Writer; import java.util.ArrayList; import java.util.List; @@ -47,9 +48,20 @@ public DIHeader add(boolean v) { return this; } + @Override + public void write(Writer writer) throws IOException { + writer.write("!\""); + for (int i = 0; i < values.size(); i++) { + if (i > 0) + writer.write("\\00"); + writer.write(values.get(i)); + } + writer.write("\""); + } + @Override public String toString() { - return "!\"" + StringUtils.join(values, "\\00") + "\""; + return toString(this::write); } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/plugin/AbstractCompilerPlugin.java b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/AbstractCompilerPlugin.java index 409479e4b..75006692d 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/plugin/AbstractCompilerPlugin.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/AbstractCompilerPlugin.java @@ -63,9 +63,15 @@ public void afterClass(Config config, Clazz clazz, ModuleBuilder moduleBuilder) public void afterMethod(Config config, Clazz clazz, SootMethod method, ModuleBuilder moduleBuilder, Function function) throws IOException {} + @Override + public void afterClassDependenciesResolved(Config config, Clazz clazz) {} + @Override public void afterObjectFile(Config config, Clazz clazz, File objectFile, ObjectFile objectFileData) throws IOException {} @Override public void beforeLinker(Config config, Linker linker, Set classes) throws IOException {} + + @Override + public void afterLinker(Config config, File executable) throws IOException {} } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/plugin/BuildGarbageCollectorPlugin.java b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/BuildGarbageCollectorPlugin.java new file mode 100644 index 000000000..8dfa9cdbe --- /dev/null +++ b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/BuildGarbageCollectorPlugin.java @@ -0,0 +1,70 @@ +package org.robovm.compiler.plugin; + +import org.robovm.compiler.Linker; +import org.robovm.compiler.clazz.Clazz; +import org.robovm.compiler.config.Config; +import org.robovm.llvm.ObjectFile; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Plugins that release resources/caches once these are not needed + */ +public class BuildGarbageCollectorPlugin extends AbstractCompilerPlugin { + private static final String ARG_KEY_ENABLE_PLUGIN = "enable"; + private Boolean enabled; + + @Override + public PluginArguments getArguments() { + List args = new ArrayList<>(); + args.add(new PluginArgument(ARG_KEY_ENABLE_PLUGIN, "false", "Flag: disables releasing compilation caches as soon as not needed")); + return new PluginArguments("buildGC", args); + } + + private boolean isEnabled(Config config) { + if (enabled == null) { + enabled = argumentValue(parseArguments(config), ARG_KEY_ENABLE_PLUGIN, true); + } + return enabled; + } + + @Override + public void afterClassDependenciesResolved(Config config, Clazz clazz) { + if (isEnabled(config)) { + // at this moment this class is processed and all dependency information not required any more + // can be dropped to reduce memory usage + clazz.getClazzInfo().dropDependencyData(); + } + } + + @Override + public void afterObjectFile(Config config, Clazz clazz, File objectFile, ObjectFile objectFileData) throws IOException { + if (isEnabled(config)) { + // remove all soot structures that are not + // required anymore but consume memory + clazz.shrinkSoot(); + } + } + + @Override + public void beforeLinker(Config config, Linker linker, Set classes) { + if (isEnabled(config)) { + // reset anything that can be retained by Soot library. As it keeps structures that are not required + // any more + // this to be called here as some plugins (like Framework Target) use classes cache during linkage + config.getClazzes().disposeSoot(); + } + } + + @Override + public void afterLinker(Config config, File executable) throws IOException { + if (isEnabled(config)) { + // dispose compilation data that is not required anymore (clazzes, dependency trie etc) + config.disposeBuildData(); + } + } +} diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/plugin/CompilerPlugin.java b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/CompilerPlugin.java index 707f94063..79d9a2560 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/plugin/CompilerPlugin.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/plugin/CompilerPlugin.java @@ -111,6 +111,15 @@ public abstract void afterClass(Config config, Clazz clazz, ModuleBuilder module public abstract void afterMethod(Config config, Clazz clazz, SootMethod method, ModuleBuilder moduleBuilder, Function function) throws IOException; + /** + * Called after dependencies resolved and added to the list. It is the moment when all work with + * clazz is finished (machine code generation pending) and all associated resources might be released + * + * @param config the current {@link Config} + * @param clazz the {@link Clazz} being compiled + */ + public abstract void afterClassDependenciesResolved(Config config, Clazz clazz); + /** * Called after the object file of a class has been compiled to an object * file. @@ -130,4 +139,12 @@ public abstract void afterMethod(Config config, Clazz clazz, SootMethod method, * @param classes the classes that will be linked. */ public abstract void beforeLinker(Config config, Linker linker, Set classes) throws IOException; + + /** + * Called just before {@link Linker} is invoked. + * + * @param config the current {@link Config} + * @param executable the binary + */ + public abstract void afterLinker(Config config, File executable) throws IOException; } diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/target/AbstractTarget.java b/compiler/compiler/src/main/java/org/robovm/compiler/target/AbstractTarget.java index 9b5ce8dd2..212bd4d33 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/target/AbstractTarget.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/target/AbstractTarget.java @@ -25,6 +25,7 @@ import org.robovm.compiler.clazz.Path; import org.robovm.compiler.config.*; import org.robovm.compiler.config.Resource.Walker; +import org.robovm.compiler.target.ios.IOSTarget; import org.robovm.compiler.util.ToolchainUtil; import org.simpleframework.xml.Transient; @@ -90,7 +91,7 @@ protected List getTargetLibs() { return Collections.emptyList(); } - public void build(List objectFiles) throws IOException { + public File build(List objectFiles) throws IOException { File outFile = new File(config.getTmpDir(), config.getExecutableName()); config.getLogger().info("Building %s binary %s", config.getTarget().getType(), outFile); @@ -261,6 +262,7 @@ public void build(List objectFiles) throws IOException { } doBuild(outFile, ccArgs, objectFiles, libs); + return outFile; } protected void doBuild(File outFile, List ccArgs, List objectFiles, @@ -580,7 +582,7 @@ private File[] getSwiftDirs(Config config) throws IOException { private String getSwiftSystemName(Config config) { String system; if (config.getOs() == OS.ios) { - if (config.getArch().isArm()) { + if (IOSTarget.isDeviceArch(config.getArch())) { system = "iphoneos"; } else { system = "iphonesimulator"; diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/target/Target.java b/compiler/compiler/src/main/java/org/robovm/compiler/target/Target.java index 55b93d9f1..0550d4973 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/target/Target.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/target/Target.java @@ -87,7 +87,7 @@ public interface Target { /** * Builds a binary out of the specified object files. */ - void build(List objectFiles) throws IOException; + File build(List objectFiles) throws IOException; /** * Builds a fat binary out of the specified slices. diff --git a/compiler/compiler/src/test/java/org/robovm/compiler/AppCompilerTest.java b/compiler/compiler/src/test/java/org/robovm/compiler/AppCompilerTest.java index 23b59be2c..aae4a5664 100755 --- a/compiler/compiler/src/test/java/org/robovm/compiler/AppCompilerTest.java +++ b/compiler/compiler/src/test/java/org/robovm/compiler/AppCompilerTest.java @@ -216,6 +216,9 @@ public void close() throws IOException { } throw new IOException(); } - + + @Override + public void disposeBuildData() { + } } } diff --git a/compiler/libimobiledevice/pom.xml b/compiler/libimobiledevice/pom.xml index fda40d32c..d7bc1714d 100755 --- a/compiler/libimobiledevice/pom.xml +++ b/compiler/libimobiledevice/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-libimobiledevice diff --git a/compiler/llvm/pom.xml b/compiler/llvm/pom.xml index b7c52c273..1d4e46ae5 100755 --- a/compiler/llvm/pom.xml +++ b/compiler/llvm/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-llvm diff --git a/compiler/objc/pom.xml b/compiler/objc/pom.xml index b3938501b..481135a3d 100755 --- a/compiler/objc/pom.xml +++ b/compiler/objc/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-objc diff --git a/compiler/pom.xml b/compiler/pom.xml index 69baaa3e5..782b25ca3 100755 --- a/compiler/pom.xml +++ b/compiler/pom.xml @@ -6,7 +6,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-compiler-parent diff --git a/compiler/rt/pom.xml b/compiler/rt/pom.xml index 14cd4d1d4..97c4b046f 100755 --- a/compiler/rt/pom.xml +++ b/compiler/rt/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-compiler-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-rt diff --git a/compiler/rt/robovm/src/main/java/org/robovm/rt/bro/Runtime.java b/compiler/rt/robovm/src/main/java/org/robovm/rt/bro/Runtime.java index c1d76de33..bddc66b8a 100755 --- a/compiler/rt/robovm/src/main/java/org/robovm/rt/bro/Runtime.java +++ b/compiler/rt/robovm/src/main/java/org/robovm/rt/bro/Runtime.java @@ -89,6 +89,10 @@ private static List setupDyLdPaths() { if (home != null) { paths.add(new File(home, "lib").getAbsolutePath()); } + if (Bro.IS_IOS) { + // support for sideload on m1 + paths.add("/System/iOSSupport/System/Library/Frameworks"); + } } String basePath = System.getProperty("org.robovm.base.path"); if (basePath != null) { diff --git a/compiler/vm/core/src/class.c b/compiler/vm/core/src/class.c index f44ecf008..65df99062 100755 --- a/compiler/vm/core/src/class.c +++ b/compiler/vm/core/src/class.c @@ -792,8 +792,11 @@ Class* rvmFindClassUsingLoader(Env* env, const char* className, Object* classLoa } Class* rvmFindLoadedClass(Env* env, const char* className, Object* classLoader) { + obtainClassLock(); Class* clazz = getLoadedClass(env, className); + releaseClassLock(); if (rvmExceptionOccurred(env)) return NULL; + if (clazz && !CLASS_IS_STATE_INITIALIZED(clazz)) return NULL; return clazz; } diff --git a/dist/compiler/pom.xml b/dist/compiler/pom.xml index 112d07278..9cb4da4d2 100755 --- a/dist/compiler/pom.xml +++ b/dist/compiler/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-dist-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-dist-compiler diff --git a/dist/package/pom.xml b/dist/package/pom.xml index d582cf992..ad67bad01 100755 --- a/dist/package/pom.xml +++ b/dist/package/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-dist-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-dist diff --git a/dist/pom.xml b/dist/pom.xml index 9775f5a32..2e075c3d6 100755 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-dist-parent diff --git a/plugins/debugger/pom.xml b/plugins/debugger/pom.xml index ef62b1990..5a9139e7b 100755 --- a/plugins/debugger/pom.xml +++ b/plugins/debugger/pom.xml @@ -4,7 +4,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/eclipse/feature/feature.xml b/plugins/eclipse/feature/feature.xml index 0abc16115..b29bdb718 100755 --- a/plugins/eclipse/feature/feature.xml +++ b/plugins/eclipse/feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/plugins/eclipse/feature/pom.xml b/plugins/eclipse/feature/pom.xml index 3b07843c1..e0201c2a1 100755 --- a/plugins/eclipse/feature/pom.xml +++ b/plugins/eclipse/feature/pom.xml @@ -6,7 +6,7 @@ com.mobidevelop.robovm org.robovm.eclipse.parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT org.robovm.eclipse.feature diff --git a/plugins/eclipse/pom.xml b/plugins/eclipse/pom.xml index 0ced0fc78..07e71193a 100644 --- a/plugins/eclipse/pom.xml +++ b/plugins/eclipse/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.mobidevelop.robovm - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT org.robovm.eclipse.parent RoboVM for Eclipse pom @@ -28,7 +28,7 @@ - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT 2.5.0 https://download.eclipse.org/releases/2021-09/ diff --git a/plugins/eclipse/ui/META-INF/MANIFEST.MF b/plugins/eclipse/ui/META-INF/MANIFEST.MF index d55db13a2..468a1eed0 100755 --- a/plugins/eclipse/ui/META-INF/MANIFEST.MF +++ b/plugins/eclipse/ui/META-INF/MANIFEST.MF @@ -17,7 +17,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.jdt.junit, org.eclipse.jdt.junit.runtime, org.eclipse.jdt.junit4.runtime -Bundle-Version: 2.3.17.qualifier +Bundle-Version: 2.3.19.qualifier Bundle-ManifestVersion: 2 Bundle-Activator: org.robovm.eclipse.RoboVMPlugin Bundle-SymbolicName: org.robovm.eclipse.ui;singleton:=true diff --git a/plugins/eclipse/ui/pom.xml b/plugins/eclipse/ui/pom.xml index df397ec94..cedd034b0 100644 --- a/plugins/eclipse/ui/pom.xml +++ b/plugins/eclipse/ui/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm org.robovm.eclipse.parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT org.robovm.eclipse.ui diff --git a/plugins/eclipse/update-site/pom.xml b/plugins/eclipse/update-site/pom.xml index 77fd527a1..a6bd3128d 100755 --- a/plugins/eclipse/update-site/pom.xml +++ b/plugins/eclipse/update-site/pom.xml @@ -6,7 +6,7 @@ com.mobidevelop.robovm org.robovm.eclipse.parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT org.robovm.eclipse.update-site diff --git a/plugins/eclipse/update-site/site.xml b/plugins/eclipse/update-site/site.xml index fbf12843a..463cc93f8 100755 --- a/plugins/eclipse/update-site/site.xml +++ b/plugins/eclipse/update-site/site.xml @@ -1,6 +1,6 @@ - + diff --git a/plugins/gradle/build.gradle b/plugins/gradle/build.gradle index 54d2bd589..2b4885eab 100644 --- a/plugins/gradle/build.gradle +++ b/plugins/gradle/build.gradle @@ -10,7 +10,7 @@ plugins { group = 'com.mobidevelop.robovm' archivesBaseName = 'robovm-gradle-plugin' -version = '2.3.17-SNAPSHOT' +version = '2.3.19-SNAPSHOT' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -20,7 +20,7 @@ compileJava { } ext { - roboVMVersion = '2.3.17-SNAPSHOT' + roboVMVersion = '2.3.19-SNAPSHOT' nexusUsername = System.getenv('MAVEN_USERNAME') nexusPassword = System.getenv('MAVEN_PASSWORD') } diff --git a/plugins/ibxcode/pom.xml b/plugins/ibxcode/pom.xml index 34eb05ecc..9e62b780c 100755 --- a/plugins/ibxcode/pom.xml +++ b/plugins/ibxcode/pom.xml @@ -4,7 +4,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/idea/build.gradle b/plugins/idea/build.gradle index 26a57c460..d6823e40e 100644 --- a/plugins/idea/build.gradle +++ b/plugins/idea/build.gradle @@ -4,7 +4,7 @@ plugins { } ext { - roboVMVersion = '2.3.17-SNAPSHOT' + roboVMVersion = '2.3.19-SNAPSHOT' } group 'com.mobidevelop.robovm' diff --git a/plugins/idea/pom.xml b/plugins/idea/pom.xml index 003849ccd..7ed0dbc6e 100644 --- a/plugins/idea/pom.xml +++ b/plugins/idea/pom.xml @@ -4,13 +4,13 @@ com.mobidevelop.robovm org.robovm.idea RoboVM plugin for Intellij IDEA - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT jar true src/main/resources/META-INF/plugin.xml - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT diff --git a/plugins/idea/src/main/java/org/robovm/idea/actions/CreateFrameworkDialog.java b/plugins/idea/src/main/java/org/robovm/idea/actions/CreateFrameworkDialog.java index 186f84b2c..c81450318 100755 --- a/plugins/idea/src/main/java/org/robovm/idea/actions/CreateFrameworkDialog.java +++ b/plugins/idea/src/main/java/org/robovm/idea/actions/CreateFrameworkDialog.java @@ -73,7 +73,7 @@ private void populateControls() { @Override public void actionPerformed(ActionEvent e) { FileChooserDialog fileChooser = FileChooserFactory.getInstance() - .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) { + .createFileChooser(new FileChooserDescriptor(false, true, false, false, false, false) { @Override public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { return file.isDirectory(); diff --git a/plugins/idea/src/main/java/org/robovm/idea/actions/CreateIpaDialog.java b/plugins/idea/src/main/java/org/robovm/idea/actions/CreateIpaDialog.java index 3604e5f5a..259e23914 100755 --- a/plugins/idea/src/main/java/org/robovm/idea/actions/CreateIpaDialog.java +++ b/plugins/idea/src/main/java/org/robovm/idea/actions/CreateIpaDialog.java @@ -111,7 +111,7 @@ private void populateControls() { browseButton.addActionListener(e -> { FileChooserDialog fileChooser = FileChooserFactory.getInstance() - .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) { + .createFileChooser(new FileChooserDescriptor(false, true, false, false, false, false) { @Override public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { return file.isDirectory(); diff --git a/plugins/idea/src/main/java/org/robovm/idea/components/setupwizard/JdkSetupDialog.java b/plugins/idea/src/main/java/org/robovm/idea/components/setupwizard/JdkSetupDialog.java index 88476fef9..07d93ba76 100755 --- a/plugins/idea/src/main/java/org/robovm/idea/components/setupwizard/JdkSetupDialog.java +++ b/plugins/idea/src/main/java/org/robovm/idea/components/setupwizard/JdkSetupDialog.java @@ -47,7 +47,7 @@ public JdkSetupDialog() { browseButton.addActionListener(e -> { FileChooserDialog fileChooser = FileChooserFactory.getInstance() - .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) { + .createFileChooser(new FileChooserDescriptor(false, true, false, false, false, false) { @Override public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { return file.isDirectory(); diff --git a/plugins/idea/src/main/java/org/robovm/idea/running/RoboVmConsoleRunConfigurationSettingsEditor.java b/plugins/idea/src/main/java/org/robovm/idea/running/RoboVmConsoleRunConfigurationSettingsEditor.java index 9510818a2..67bc62f3d 100755 --- a/plugins/idea/src/main/java/org/robovm/idea/running/RoboVmConsoleRunConfigurationSettingsEditor.java +++ b/plugins/idea/src/main/java/org/robovm/idea/running/RoboVmConsoleRunConfigurationSettingsEditor.java @@ -93,7 +93,7 @@ private void populateControls(final RoboVmRunConfiguration config) { this.workingDir.setText(dir); this.browseButton.addActionListener(e -> { FileChooserDialog fileChooser = FileChooserFactory.getInstance() - .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) { + .createFileChooser(new FileChooserDescriptor(false, true, false, false, false, false) { @Override public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { return file.isDirectory(); diff --git a/plugins/idea/src/main/resources/META-INF/plugin.xml b/plugins/idea/src/main/resources/META-INF/plugin.xml index eb02c724e..10636a8ec 100755 --- a/plugins/idea/src/main/resources/META-INF/plugin.xml +++ b/plugins/idea/src/main/resources/META-INF/plugin.xml @@ -18,12 +18,14 @@ 2.3.16 -
  • Improved XCFramework support
  • -
  • Fix iOS touch inputs after SKStoreReview
  • -
  • Eclipse and IDEA maintenance
  • -
  • iOS 15 binding updates
  • -
  • ByteBuffer java 9 api
  • + 2.3.17 +
  • Debugger improvements, thread statuses
  • +
  • IDEA plugin update
  • +
  • Memory optimizations
  • +
  • Fix debugger crashes
  • +
  • iOS 15.4 binding updates
  • +
  • Sideloading app fixes
  • +
  • m1 arm simulator fixes
  • ]]>
    diff --git a/plugins/junit/client/pom.xml b/plugins/junit/client/pom.xml index d1803205e..f132581bc 100755 --- a/plugins/junit/client/pom.xml +++ b/plugins/junit/client/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-junit-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-junit-client diff --git a/plugins/junit/pom.xml b/plugins/junit/pom.xml index a9d8dd6c0..684b36667 100644 --- a/plugins/junit/pom.xml +++ b/plugins/junit/pom.xml @@ -6,7 +6,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/junit/protocol/pom.xml b/plugins/junit/protocol/pom.xml index f9fe977ba..ecd4b6a08 100755 --- a/plugins/junit/protocol/pom.xml +++ b/plugins/junit/protocol/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-junit-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-junit-protocol diff --git a/plugins/junit/server/pom.xml b/plugins/junit/server/pom.xml index d3907d029..f6c885e92 100755 --- a/plugins/junit/server/pom.xml +++ b/plugins/junit/server/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-junit-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-junit-server diff --git a/plugins/maven/plugin/pom.xml b/plugins/maven/plugin/pom.xml index 0c392f1a3..c795c8b17 100644 --- a/plugins/maven/plugin/pom.xml +++ b/plugins/maven/plugin/pom.xml @@ -7,7 +7,7 @@ com.mobidevelop.robovm robovm-maven-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-maven-plugin diff --git a/plugins/maven/pom.xml b/plugins/maven/pom.xml index 76a61e894..33cf25842 100644 --- a/plugins/maven/pom.xml +++ b/plugins/maven/pom.xml @@ -7,7 +7,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/maven/surefire/pom.xml b/plugins/maven/surefire/pom.xml index c20efa5d4..9da17b713 100755 --- a/plugins/maven/surefire/pom.xml +++ b/plugins/maven/surefire/pom.xml @@ -6,7 +6,7 @@ com.mobidevelop.robovm robovm-maven-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-surefire-provider diff --git a/plugins/resolver/pom.xml b/plugins/resolver/pom.xml index 6d832e441..2d3f8ce79 100644 --- a/plugins/resolver/pom.xml +++ b/plugins/resolver/pom.xml @@ -7,7 +7,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/templates/console/pom.xml b/plugins/templates/console/pom.xml index ee64dd572..29d78da73 100755 --- a/plugins/templates/console/pom.xml +++ b/plugins/templates/console/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-templates-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-templates-console diff --git a/plugins/templates/ios-framework/pom.xml b/plugins/templates/ios-framework/pom.xml index 84f6878f7..b1bb2e2d4 100755 --- a/plugins/templates/ios-framework/pom.xml +++ b/plugins/templates/ios-framework/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-templates-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-templates-ios-framework diff --git a/plugins/templates/ios-single-view-no-ib/pom.xml b/plugins/templates/ios-single-view-no-ib/pom.xml index 05f9e583b..0da2c120d 100755 --- a/plugins/templates/ios-single-view-no-ib/pom.xml +++ b/plugins/templates/ios-single-view-no-ib/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-templates-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-templates-ios-single-view-no-ib diff --git a/plugins/templates/pom.xml b/plugins/templates/pom.xml index 4d6937204..e567abcf1 100755 --- a/plugins/templates/pom.xml +++ b/plugins/templates/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT ../../ diff --git a/plugins/templates/templater/pom.xml b/plugins/templates/templater/pom.xml index 7295b53c0..6382600d3 100755 --- a/plugins/templates/templater/pom.xml +++ b/plugins/templates/templater/pom.xml @@ -5,7 +5,7 @@ com.mobidevelop.robovm robovm-templates-parent - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-templater diff --git a/pom.xml b/pom.xml index e14ecc7af..cd2fcc62a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.mobidevelop.robovm - 2.3.17-SNAPSHOT + 2.3.19-SNAPSHOT robovm-parent com.mobidevelop.robovm @@ -173,7 +173,7 @@ org.simpleframework simple-xml - 2.7 + 2.7.1 org.bouncycastle