Make it possible to debug SCL compiler in production builds 64/3864/1
authorjsimomaa <jani.simomaa@gmail.com>
Wed, 12 Feb 2020 11:52:18 +0000 (13:52 +0200)
committerjsimomaa <jani.simomaa@gmail.com>
Wed, 12 Feb 2020 11:52:18 +0000 (13:52 +0200)
gitlab #465

Change-Id: Ie032c198f9e9aa9d21a41c0b223c6534a2b070f5

14 files changed:
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/Constant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/FunctionValue.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/LoggingOutputStream.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ModuleBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSASimplificationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java

index 082fa2f6dc553d1b36e2b64c6152329f46b87725..f0b9f735e68b7b6522b46423e188f7a0ca95feba 100644 (file)
@@ -53,12 +53,16 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.procedure.TObjectObjectProcedure;
 import gnu.trove.procedure.TObjectProcedure;
 
 public class CodeGeneration {
-    
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CodeGeneration.class);
+
     public static final int OPTIMIZATION_PHASES = 2;
     
     CompilationContext compilationContext;
@@ -85,11 +89,11 @@ public class CodeGeneration {
     }
     
     public void simplifyValues() {
-        //System.out.println("===== Simplify values =====");
+        //LOGGER.info("===== Simplify values =====");
         
         Collection<SCLValue> values = module.getValues();
         SimplificationContext simplificationContext = new SimplificationContext(compilationContext, validator);
-        //System.out.println("-----------------------------------------------");
+        //LOGGER.info("-----------------------------------------------");
         SCLValue[] valueArray = values.toArray(new SCLValue[values.size()]);
         
         for(SCLValue value : valueArray) {
@@ -101,16 +105,16 @@ public class CodeGeneration {
         
         // Simplify
         for(SCLValue value : valueArray) {
-            //System.out.println("BEFORE " + value.getName() + " = " + value.getExpression());
+            //LOGGER.info("BEFORE " + value.getName() + " = " + value.getExpression());
             value.getSimplifiedExpression(simplificationContext);
-            //System.out.println("AFTER " + value.getName() + " = " + value.getExpression());
+            //LOGGER.info("AFTER " + value.getName() + " = " + value.getExpression());
         }
     }
     
     public void convertToSSA() {
         ModuleWriter mw = new ModuleWriter(compilationContext.namingPolicy.getModuleClassName(), compilationContext.lineLocator);
         for(SCLValue value : module.getValues()) {
-            //System.out.println(value.getName().name + " :: " + value.getType());
+            //LOGGER.info(value.getName().name + " :: " + value.getType());
             Expression expression = value.getExpression();
             if(expression == null)
                 continue;
@@ -149,7 +153,7 @@ public class CodeGeneration {
             if(constant.getTypeParameters().length > 0)
                 continue;
             
-            //System.out.println(value.getName() + " <- " + constant.getValue().getName());
+            //LOGGER.info(value.getName() + " <- " + constant.getValue().getName());
             value.setValue(constant.getValue().getValue());
             value.setExpression(null); // HMM??
         }*/
@@ -190,24 +194,24 @@ public class CodeGeneration {
     
     public void optimizeSSA() {
         if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION && SCLCompilerConfiguration.debugFilter(module.getName())) {
-            System.out.println("=== SSA before optimization ====================================");
-            System.out.println(ssaModule);            
+            LOGGER.info("=== SSA before optimization ====================================");
+            LOGGER.info("{}", ssaModule);            
         }
         if(SCLCompilerConfiguration.DEBUG)
         ssaModule.validate();
         int optCount = 0;
         for(int phase=0;phase<OPTIMIZATION_PHASES;++phase) {
             while(optCount++ < 100 && ssaModule.simplify(compilationContext.environment, phase)) {
-                //System.out.println("simplify " + optCount);
-                //System.out.println("================================================================");
-                //System.out.println(ssaModule);        
+                //LOGGER.info("simplify " + optCount);
+                //LOGGER.info("================================================================");
+                //LOGGER.info(ssaModule);        
             }
             if(phase == 0)
                 ssaModule.saveInlinableDefinitions();
         }
         if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING && SCLCompilerConfiguration.debugFilter(module.getName())) {
-            System.out.println("=== SSA before lambda lifting ==================================");
-            System.out.println(ssaModule);            
+            LOGGER.info("=== SSA before lambda lifting ==================================");
+            LOGGER.info("{}", ssaModule);            
         }
         ssaModule.lambdaLift(errorLog);
         //ssaModule.validate();
@@ -218,8 +222,8 @@ public class CodeGeneration {
     
     public void generateCode() {
         if(SCLCompilerConfiguration.SHOW_FINAL_SSA && SCLCompilerConfiguration.debugFilter(module.getName())) {
-            System.out.println("=== Final SSA ==================================================");
-            System.out.println(ssaModule);
+            LOGGER.info("=== Final SSA ==================================================");
+            LOGGER.info("{}", ssaModule);
         }
         try {
             ssaModule.generateCode(moduleBuilder);
@@ -227,7 +231,7 @@ public class CodeGeneration {
             errorLog.log(e.getMessage());
         }
         if(SCLCompilerConfiguration.TRACE_MAX_METHOD_SIZE && moduleBuilder.getMethodSizeCounter() != null)
-            System.out.println("[Max method size] " + module.getName() + ": " + moduleBuilder.getMethodSizeCounter());
+            LOGGER.info("[Max method size] " + module.getName() + ": " + moduleBuilder.getMethodSizeCounter());
         classes = moduleBuilder.getClasses();
     }
     
@@ -240,7 +244,7 @@ public class CodeGeneration {
                 if(constructor.parameterTypes.length != 1) {                    
                     String javaName = MethodBuilderBase.getClassName(dataType.getTypeDesc());
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + javaName);
+                        LOGGER.info("Create class " + javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, javaName, "java/lang/Object");
                     cf.setSourceFile("_SCL_DataType");
                     CodeBuilderUtils.makeRecord(cf, constructor.name.name,
@@ -255,7 +259,7 @@ public class CodeGeneration {
                 // Create supertype
                 {
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + javaName);
+                        LOGGER.info("Create class " + javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder,
                             Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC,
                             javaName, "java/lang/Object");
@@ -267,7 +271,7 @@ public class CodeGeneration {
                 // Create constructors
                 for(Constructor constructor : dataType.constructors) {
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + constructor.javaName);
+                        LOGGER.info("Create class " + constructor.javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, constructor.javaName, javaName);
                     cf.setSourceFile("_SCL_DataType");
                     CodeBuilderUtils.makeRecord(cf, constructor.name.name,
@@ -285,7 +289,7 @@ public class CodeGeneration {
             final JavaTypeTranslator javaTypeTranslator = moduleBuilder.getJavaTypeTranslator();
             
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + typeClass.javaName);
+                LOGGER.info("Create class " + typeClass.javaName);
             final ClassBuilder cf = new ClassBuilder(moduleBuilder,
                     Opcodes.ACC_INTERFACE | Opcodes.ACC_PUBLIC,
                     typeClass.javaName, "java/lang/Object");
@@ -336,7 +340,7 @@ public class CodeGeneration {
         final JavaTypeTranslator javaTypeTranslator = moduleBuilder.getJavaTypeTranslator();
         
         if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-            System.out.println("Create class " + instance.javaName);
+            LOGGER.info("Create class " + instance.javaName);
         final ClassBuilder cb = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, instance.javaName, "java/lang/Object",
                 instance.typeClass.javaName);
         cb.setSourceFile("_SCL_TypeClassInstance");
@@ -367,7 +371,7 @@ public class CodeGeneration {
                 } catch (MatchException e) {
                     throw new InternalCompilerError("Method " + method.getName() + " has too high arity.");
                 }
-                //System.out.println("Interface types: " + Arrays.toString(types));
+                //LOGGER.info("Interface types: " + Arrays.toString(types));
                 TypeDesc[] parameterTypeDescs = javaTypeTranslator.toTypeDescs(mfun.parameterTypes);
                 TypeDesc returnTypeDesc = javaTypeTranslator.toTypeDesc(mfun.returnType); 
                 MethodBuilder mb = cb.addMethod(Opcodes.ACC_PUBLIC, method.getJavaName(), 
@@ -404,7 +408,7 @@ public class CodeGeneration {
                     MultiFunction mfun2;
                     try {
                         mfun2 = Types.matchFunction(Types.removeForAll(function.getType()), parameters.length);
-                        //System.out.println("Implementation types: " + Arrays.toString(functionTypes));
+                        //LOGGER.info("Implementation types: " + Arrays.toString(functionTypes));
                     } catch (MatchException e) {
                         throw new InternalCompilerError(e);
                     }
index b019c74705bc9c1a668496f49a4012cc5f444594..6f6d3daf3af28d4d74597c40c2ce7554ff6faa0d 100644 (file)
@@ -18,6 +18,8 @@ import org.simantics.scl.compiler.runtime.MutableClassLoader;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 
@@ -29,6 +31,8 @@ import gnu.trove.map.hash.THashMap;
  */
 public abstract class Constant extends Val {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(Constant.class);
+
     public static boolean TRACE_REALIZATION = false;
     
     protected Type type;
@@ -102,7 +106,7 @@ public abstract class Constant extends Val {
         ModuleBuilder moduleBuilder = new ModuleBuilder(policy, builder.javaTypeTranslator);
         
         if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-            System.out.println("Create class " + policy.getModuleClassName());
+            LOGGER.info("Create class " + policy.getModuleClassName());
         ClassBuilder classFile = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, policy.getModuleClassName(), "java/lang/Object");
         classFile.setSourceFile("_SCL_RealizedValue");
         
@@ -124,7 +128,7 @@ public abstract class Constant extends Val {
             if(valueCache != null) {
                 valueCache.put(this, result);
                 if(TRACE_REALIZATION)
-                    System.out.println("/REALIZED/ " + this + " " + getClass().getSimpleName());
+                    LOGGER.info("/REALIZED/ " + this + " " + getClass().getSimpleName());
             }
             return result;
         } catch (IllegalAccessException e) {
index dcef289f02763d9521532f30bc02bd7242714e52..60f54ea3c2b440fa06dd705e9682262de090c6e9 100644 (file)
@@ -21,11 +21,15 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 
 public abstract class FunctionValue extends Constant {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(FunctionValue.class);
+
     TVar[] typeParameters;
     Type returnType;
     protected Type[] parameterTypes;
@@ -66,10 +70,10 @@ public abstract class FunctionValue extends Constant {
     public Type apply(MethodBuilder mb, Type[] typeParameters, Val... parameters) {
         int arity = getArity();
         
-        /*System.out.println("MONADIC APPLICATION " + this);
-        System.out.println("    call arity: " + parameters.length);
-        System.out.println("    func arity: " + arity);
-        System.out.println("    func monadic: " + isMonadic());
+        /*LOGGER.info("MONADIC APPLICATION " + this);
+        LOGGER.info("    call arity: " + parameters.length);
+        LOGGER.info("    func arity: " + arity);
+        LOGGER.info("    func monadic: " + isMonadic());
         */
         if(parameters.length < arity) {
             ModuleBuilder moduleBuilder = mb.getModuleBuilder();            
@@ -127,7 +131,7 @@ public abstract class FunctionValue extends Constant {
         ClassBuilder classFile;
         if(arity <= Constants.MAX_FUNCTION_PARAMETER_COUNT) {
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + policy.getModuleClassName());
+                LOGGER.info("Create class " + policy.getModuleClassName());
             classFile = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, policy.getModuleClassName(), 
                     MethodBuilderBase.getClassName(Constants.FUNCTION_IMPL[arity]));
             classFile.setSourceFile("_SCL_FunctionValue");
@@ -144,7 +148,7 @@ public abstract class FunctionValue extends Constant {
         }
         else {
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + policy.getModuleClassName());
+                LOGGER.info("Create class " + policy.getModuleClassName());
             classFile = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, policy.getModuleClassName(), 
                     MethodBuilderBase.getClassName(Constants.FUNCTION_N_IMPL));
             classFile.setSourceFile("_SCL_FunctionValue");
@@ -187,7 +191,7 @@ public abstract class FunctionValue extends Constant {
             if(valueCache != null) {
                 valueCache.put(this, result);
                 if(TRACE_REALIZATION)
-                    System.out.println("/REALIZED/ " + this + " " + getClass().getSimpleName());
+                    LOGGER.info("/REALIZED/ " + this + " " + getClass().getSimpleName());
             }
             return result;
         } catch (InstantiationException e) {
index b96907ea3b9e4b3b69907f0cd53b766e6d8d07e2..c23c05886065672d9ff24ba95d3ef8ee10e8284e 100644 (file)
@@ -13,8 +13,13 @@ import org.simantics.scl.compiler.internal.elaboration.transformations.Transform
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ETransformation extends SimplifiableExpression {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ETransformation.class);
+
     public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object();
     
     public final String name;
@@ -56,7 +61,7 @@ public class ETransformation extends SimplifiableExpression {
         Expression expression = tb.compileRules();
         
         if(SCLCompilerConfiguration.SHOW_COMPILED_RULES)
-            System.out.println(expression);
+            LOGGER.info("{}", expression);
         return expression;
     }
 
index d25038117131d3376a094b3815134d9f268708b0..7370a58c29d1b2d7428de1f51a89cac94b25a586 100644 (file)
@@ -23,12 +23,17 @@ import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext
 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
 import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.procedure.TObjectObjectProcedure;
 import gnu.trove.procedure.TObjectProcedure;
 
 public class SSAModule {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SSAModule.class);
+
     THashMap<Name, SCLConstant> functions = new THashMap<Name, SCLConstant>();
     ArrayList<StaticField> staticFields = new ArrayList<StaticField>();
     public ArrayList<SSAClosure> closuresToGenerate = new ArrayList<SSAClosure>(); 
@@ -70,11 +75,11 @@ public class SSAModule {
             try {            
                 function.getDefinition().validate(context);
             } catch(RuntimeException e) {
-                System.out.println("-- VALIDATE " + function.getName() + " ----------------");
+                LOGGER.info("-- VALIDATE " + function.getName() + " ----------------");
                 PrintingContext printingContext = new PrintingContext();
                 printingContext.setErrorMarker(context.errorMarker);
                 function.getDefinition().toString(printingContext);
-                System.out.println(printingContext.toString());
+                LOGGER.info(printingContext.toString());
                 throw e;
             }
         }
@@ -104,7 +109,7 @@ public class SSAModule {
     public void generateCode(final ModuleBuilder moduleBuilder) throws CodeBuildingException {
         final String moduleClassName = moduleBuilder.getNamingPolicy().getModuleClassName();
         if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-            System.out.println("Create class " + moduleClassName);
+            LOGGER.info("Create class " + moduleClassName);
         final ClassBuilder classFile = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, moduleClassName,
                 "java/lang/Object");        
         classFile.setSourceFile(moduleBuilder.getNamingPolicy().getModuleName());
index 5316b861dc52e3e7a2e9b6424e0debf29ce96a13..e0571dbd321bf46f63f822d3ebcb0fbccc8ace9e 100644 (file)
@@ -11,9 +11,15 @@ import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.commons.CodeSizeEvaluator;
 import org.objectweb.asm.util.TraceClassVisitor;
+import org.simantics.scl.compiler.internal.codegen.utils.LoggingOutputStream.LogLevel;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ClassBuilder {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClassBuilder.class);
+
     ModuleBuilder moduleBuilder;
     String className;
     String superClassName;
@@ -30,7 +36,7 @@ public class ClassBuilder {
         this.classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
         this.classVisitor = SCLCompilerConfiguration.SHOW_COMPILED_BYTECODE
                   && SCLCompilerConfiguration.debugFilter(moduleBuilder.namingPolicy.getModuleName())
-                ? new TraceClassVisitor(classWriter, new PrintWriter(System.out))
+                ? new TraceClassVisitor(classWriter, new PrintWriter(new LoggingOutputStream(LOGGER, LogLevel.INFO)))
                 : classWriter; 
         classVisitor.visit(Opcodes.V1_5, access, className, null, superClassName, interfaces);
     }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/LoggingOutputStream.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/LoggingOutputStream.java
new file mode 100644 (file)
index 0000000..cc87e84
--- /dev/null
@@ -0,0 +1,50 @@
+package org.simantics.scl.compiler.internal.codegen.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.slf4j.Logger;
+
+public class LoggingOutputStream extends OutputStream {
+
+    private final ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
+    private final Logger logger;
+    private final LogLevel level;
+
+    public enum LogLevel {
+        TRACE, DEBUG, INFO, WARN, ERROR,
+    }
+
+    public LoggingOutputStream(Logger logger, LogLevel level) {
+        this.logger = logger;
+        this.level = level;
+    }
+
+    @Override
+    public void write(int b) {
+        if (b == '\n') {
+            String line = baos.toString();
+            baos.reset();
+
+            switch (level) {
+            case TRACE:
+                logger.trace(line);
+                break;
+            case DEBUG:
+                logger.debug(line);
+                break;
+            case ERROR:
+                logger.error(line);
+                break;
+            case INFO:
+                logger.info(line);
+                break;
+            case WARN:
+                logger.warn(line);
+                break;
+            }
+        } else {
+            baos.write(b);
+        }
+    }
+}
index 32d4283392bc093b9b083735488284bb73b71e95..3008cac78e58740a1b2d308ff9b5ca8ac4bd3690 100644 (file)
@@ -13,10 +13,15 @@ import org.simantics.scl.compiler.internal.codegen.references.Val;
 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 
 public class ModuleBuilder {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ModuleBuilder.class);
+
     JavaNamingPolicy namingPolicy;
     JavaTypeTranslator javaTypeTranslator;
     
@@ -29,7 +34,7 @@ public class ModuleBuilder {
     public void addClass(ClassBuilder cb) {
         byte[] bytecode = cb.finishClass();
         classes.put(cb.getClassName(), bytecode);
-        //System.out.println("Added " + cb.getClassName());
+        //LOGGER.info("Added " + cb.getClassName());
     }
     
     public JavaTypeTranslator getJavaTypeTranslator() {
@@ -86,7 +91,7 @@ public class ModuleBuilder {
         ClassBuilder classBuilder;
         if(remainingArity <= Constants.MAX_FUNCTION_PARAMETER_COUNT) {
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + className);
+                LOGGER.info("Create class " + className);
             classBuilder = new ClassBuilder(this, Opcodes.ACC_PUBLIC, className, MethodBuilderBase.getClassName(Constants.FUNCTION_IMPL[remainingArity]));
             classBuilder.setSourceFile("_SCL_Closure");
             
@@ -114,7 +119,7 @@ public class ModuleBuilder {
         }
         else {
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + className);
+                LOGGER.info("Create class " + className);
             classBuilder = new ClassBuilder(this, Opcodes.ACC_PUBLIC, className, MethodBuilderBase.getClassName(Constants.FUNCTION_N_IMPL));
             classBuilder.setSourceFile("_SCL_Closure");
             
index aea1c033b8f71e73866d6c3eb00230ac18ea461b..f7c6d309705c02b68f555f692074bfc0c8438d02 100644 (file)
@@ -25,7 +25,7 @@ public class SSASimplificationContext {
 
     public void markModified(String description) {
         if(SCLCompilerConfiguration.PRINT_OPTIMIZATION_TRANSFORMATIONS)
-            System.out.println("(" + modiId + ") DID " + description);
+            LOGGER.info("(" + modiId + ") DID " + description);
         modified = true;
         if(SCLCompilerConfiguration.VALIDATE_AFTER_OPTIMIZATIONS)
             module.validate();
@@ -55,8 +55,8 @@ public class SSASimplificationContext {
     }
     
     public void printConstant(Name name) {
-        System.out.println("--- " + name + " ---------------------------");
-        System.out.println(module.get(name));
+        LOGGER.info("--- " + name + " ---------------------------");
+        LOGGER.info("{}", module.get(name));
     }
 
     public void validate() {
index 69b8e7e647f2a393e988204d4092fa7306d4aa51..1cdeea71dab5e551a1f9bce723f738c55226b9dc 100644 (file)
@@ -16,12 +16,16 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.util.TConComparator;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.set.hash.THashSet;
 
 public class ConstraintSolver {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ConstraintSolver.class);
+    
     public static THashSet<TCon> DEFAULTS_IGNORE = new THashSet<TCon>(); 
     public static THashMap<List<TCon>, Type> DEFAULTS = new THashMap<List<TCon>, Type>();
     
@@ -60,14 +64,14 @@ public class ConstraintSolver {
         TypeUnparsingContext tuc = SCLCompilerConfiguration.TRACE_CONSTRAINT_SOLVER ? 
                 new TypeUnparsingContext() : null;
         if(SCLCompilerConfiguration.TRACE_CONSTRAINT_SOLVER) {
-            System.out.println();
-            System.out.println("GIVEN:");
+            LOGGER.info("");
+            LOGGER.info("GIVEN:");
             for(TPred g : given)
-                System.out.println("    " + g.toString(tuc));
-            System.out.println("DEMANDS:");
+                LOGGER.info("    " + g.toString(tuc));
+            LOGGER.info("DEMANDS:");
             for(EVariable demand : demands)
-                System.out.println("    " + demand.getType().toString(tuc));
-            System.out.println("==>");
+                LOGGER.info("    " + demand.getType().toString(tuc));
+            LOGGER.info("==>");
         }
         
         ConstraintSet cs = new ConstraintSet(environment);
@@ -91,11 +95,11 @@ public class ConstraintSolver {
             ArrayList<ArrayList<Constraint>> groups = 
                     groupConstraintsByCommonMetavars(unsolvedConstraints);
             if(SCLCompilerConfiguration.TRACE_CONSTRAINT_SOLVER) {
-                System.out.println("DEFAULT GROUPS:");
+                LOGGER.info("DEFAULT GROUPS:");
                 for(ArrayList<Constraint> group : groups) {
                     for(Constraint c : group)
-                        System.out.println("    " + c.constraint.toString(tuc));
-                    System.out.println("    --");
+                        LOGGER.info("    " + c.constraint.toString(tuc));
+                    LOGGER.info("    --");
                 }
             }
             
@@ -173,13 +177,13 @@ public class ConstraintSolver {
         }
 
         if(SCLCompilerConfiguration.TRACE_CONSTRAINT_SOLVER) {
-            System.out.println("UNSOLVED:");
+            LOGGER.info("UNSOLVED:");
             for(Constraint c : unsolvedConstraints)
-                System.out.println("    " + c.constraint.toString(tuc));  
-            System.out.println("SOLVED:");
+                LOGGER.info("    " + c.constraint.toString(tuc));  
+            LOGGER.info("SOLVED:");
             for(Constraint c : solvedConstraints)
-                System.out.println("    " + c.constraint.toString(tuc) + " <= " + c.generator);
-            //System.out.println("APPLY DEFAULTS: " + applyDefaults);
+                LOGGER.info("    " + c.constraint.toString(tuc) + " <= " + c.generator);
+            //LOGGER.info("APPLY DEFAULTS: " + applyDefaults);
         }
         
         return new ReducedConstraints(givenConstraints, 
index a6650e9a44faa5627b41b0cf260ee6ecf6baaadb..79b596908962b2f4d8fbc4b8c09e74c9266bd213 100644 (file)
@@ -37,6 +37,8 @@ import org.simantics.scl.compiler.top.ModuleInitializer;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.top.ValueNotFound;
 import org.simantics.scl.compiler.types.Types;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TObjectLongHashMap;
@@ -49,6 +51,9 @@ import gnu.trove.set.hash.THashSet;
  * @author Hannu Niemist&ouml;
  */
 public class ModuleRepository {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(ModuleRepository.class);
+
     private final ModuleRepository parentRepository;
     private final ModuleSourceRepository sourceRepository;
     private ConcurrentHashMap<String, ModuleEntry> moduleCache = new ConcurrentHashMap<String, ModuleEntry>();
@@ -120,9 +125,9 @@ public class ModuleRepository {
             if(moduleCache.get(moduleName) == this) {
                 moduleCache.remove(moduleName);
                 if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE) {
-                    System.out.println("Invalidate " + moduleName);
+                    LOGGER.info("Invalidate " + moduleName);
                     for(UpdateListener l : listenersCopy)
-                        System.out.println("    " + l);
+                        LOGGER.info("    " + l);
                 }
                 for(UpdateListener l : listenersCopy)
                     if(!l.stopListening())
@@ -141,7 +146,7 @@ public class ModuleRepository {
                 compilationResult = DoesNotExist.getInstance();
             else {
                 if(SCLCompilerConfiguration.TRACE_MODULE_UPDATE)
-                    System.out.println("Compile " + source);
+                    LOGGER.info("Compile " + source);
                 beginModuleCompilation(moduleName);
                 compilationResult = source.compileModule(ModuleRepository.this, this, advisor == null ? null : advisor.getOptions(moduleName));
                 finishModuleCompilation(moduleName);
index 5ae73c41240700f44662e1b70f6851487752b290..4893f684084a0479d48f241c35ddd21a3a9bbdc5 100644 (file)
@@ -13,6 +13,8 @@ import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.environment.GlobalOnlyEnvironment;
 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
 import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
+import org.simantics.scl.compiler.internal.codegen.utils.LoggingOutputStream;
+import org.simantics.scl.compiler.internal.codegen.utils.LoggingOutputStream.LogLevel;
 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.internal.decompilation.DecompilerFactory;
 import org.simantics.scl.compiler.internal.decompilation.IDecompiler;
@@ -50,7 +52,7 @@ public class RuntimeModule {
         
         public synchronized void addClass(String name, byte[] class_) {
             if(TRACE_CLASS_CREATION)
-                System.out.println("addClass " + name + " (" + class_.length + " bytes)");
+                LOGGER.info("addClass " + name + " (" + class_.length + " bytes)");
             if(VALIDATE_CLASS_NAMES)
                 validateClassName(name);
             localClasses.put(name, class_);
@@ -59,7 +61,7 @@ public class RuntimeModule {
         public synchronized void addClasses(Map<String, byte[]> classes) {
             if(TRACE_CLASS_CREATION)
                 for(String name : classes.keySet())
-                    System.out.println("addClass " + name + " (" + classes.get(name).length + " bytes)");
+                    LOGGER.info("addClass " + name + " (" + classes.get(name).length + " bytes)");
             if(VALIDATE_CLASS_NAMES)
                 for(String name : classes.keySet())
                     validateClassName(name);
@@ -67,7 +69,7 @@ public class RuntimeModule {
         }
         
         private void validateClassName(String name) {
-            //System.out.println(name);
+            //LOGGER.info(name);
             /*if(!name.startsWith(SCL_PACKAGE_PREFIX) || !extractClassLoaderId(name).equals(moduleName))
                 throw new IllegalArgumentException("Class name " + name + " does not start with '" +
                         SCL_PACKAGE_PREFIX + moduleName + "$'.");
@@ -123,7 +125,7 @@ public class RuntimeModule {
         }
         
         private Class<?> getClass(String name) throws ClassNotFoundException {
-            //System.out.println("getClass " + name);
+            //LOGGER.info("getClass " + name);
             
             // If the class is not generated from SCL, use parent class loader
             if(!name.startsWith(SCL_PACKAGE_PREFIX)) {
@@ -169,7 +171,7 @@ public class RuntimeModule {
         }
         
         public Module getModule(String moduleName) {
-            //System.out.println("ModuleClassLoader.getModule(" + moduleName + ")");
+            //LOGGER.info("ModuleClassLoader.getModule(" + moduleName + ")");
             if(moduleName.equals(this.moduleName))
                 return module;
             else {
@@ -203,7 +205,7 @@ public class RuntimeModule {
             IDecompiler decompiler = DecompilerFactory.getDecompiler();
             if(decompiler == null)
                 return;
-            decompiler.decompile(this, className, new OutputStreamWriter(System.out));
+            decompiler.decompile(this, className, new OutputStreamWriter(new LoggingOutputStream(LOGGER, LogLevel.INFO)));
         }
     }
 
index b51b188cda117823c4d8b0308f13eb607615aa91..f14a3be967438af2e93d134e9e1024513e5eb193 100644 (file)
@@ -58,11 +58,15 @@ import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.ProcedureType;
 import org.simantics.scl.runtime.function.FunctionImpl1;
 import org.simantics.scl.runtime.tuple.Tuple0;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
 
 import gnu.trove.set.hash.THashSet;
 
 public class ExpressionEvaluator {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionEvaluator.class);
+
     public static final boolean TRACE_INTERPRETATION_VS_COMPILATION = false;
     private static final String COMPUTATION_METHOD_NAME = "main";
     
@@ -225,7 +229,7 @@ public class ExpressionEvaluator {
                 }
             } catch(SCLSyntaxErrorException e) {
                 errorLog.log(e.location, e.getMessage());
-                //System.out.println(errorLog.getErrorsAsString());
+                //LOGGER.info(errorLog.getErrorsAsString());
                 throw new SCLExpressionCompilationException(errorLog.getErrors());
             } catch(Exception e) {
                 errorLog.log(e);
@@ -348,7 +352,7 @@ public class ExpressionEvaluator {
             throw new SCLExpressionCompilationException(errorLog.getErrors());
         
         if(SCLCompilerConfiguration.SHOW_EXPRESSION_BEFORE_EVALUATION)
-            System.out.println(expression);
+            LOGGER.info("{}", expression);
         
         if(interpretIfPossible) {
         // Try to interpret
@@ -358,9 +362,9 @@ public class ExpressionEvaluator {
                             new TransientClassBuilder(classLoader, javaTypeTranslator));
             IExpression iexp = expression.toIExpression(expressionInterpretationContext);
                 if(TRACE_INTERPRETATION_VS_COMPILATION)
-                System.out.println("INTERPRETED " + expressionText);
+                LOGGER.info("INTERPRETED " + expressionText);
                 if(SCLCompilerConfiguration.SHOW_INTERPRETED_EXPRESSION)
-                    System.out.println("INTERPRETED AS: " + iexp);
+                    LOGGER.info("INTERPRETED AS: " + iexp);
             return iexp.execute(new Object[expressionInterpretationContext.getMaxVariableId()]);
         } catch(UnsupportedOperationException e) {
             // This is normal when expression cannot be interpreted. We compile it instead.
@@ -400,8 +404,8 @@ public class ExpressionEvaluator {
 
         SSAModule ssaModule = mw.getModule();
         if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION) {
-            System.out.println("=== SSA before optimization ==================================");
-            System.out.println(ssaModule);            
+            LOGGER.info("=== SSA before optimization ==================================");
+            LOGGER.info("{}", ssaModule);
         }
         if(SCLCompilerConfiguration.DEBUG)
             ssaModule.validate();
@@ -412,12 +416,12 @@ public class ExpressionEvaluator {
         for(int phase=0;phase<CodeGeneration.OPTIMIZATION_PHASES;++phase) {
             int optCount = 0;
             while(optCount++ < 4 && ssaModule.simplify(environment, phase)) {
-                //System.out.println("simplify " + optCount);
+                //LOGGER.info("simplify " + optCount);
             }
         }
         if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING) {
-            System.out.println("=== SSA before lambda lifting ==================================");
-            System.out.println(ssaModule);            
+            LOGGER.info("=== SSA before lambda lifting ==================================");
+            LOGGER.info("{}", ssaModule);
         }
         //ssaModule.saveInlinableDefinitions();
         ssaModule.lambdaLift(errorLog);
@@ -426,7 +430,7 @@ public class ExpressionEvaluator {
         
         // Generate code
         if(SCLCompilerConfiguration.SHOW_FINAL_SSA)
-            System.out.println(ssaModule);
+            LOGGER.info("{}", ssaModule);
         try {
             ssaModule.generateCode(moduleBuilder);
         } catch (CodeBuildingException e) {
index 1331530dda6dfe5249fda811387f850d8022e6c4..5f45852e36c4e269df060017d72e153fc1204780 100644 (file)
@@ -3,39 +3,44 @@ package org.simantics.scl.compiler.top;
 
 public interface SCLCompilerConfiguration {
 
-    public static final boolean DEBUG = false;
-    public static final boolean ENABLE_TIMING = false;
+    static final String KEY_PREFIX = "org.simantics.scl.compiler.";
     
-    public static final boolean SHOW_SSA_BEFORE_OPTIMIZATION = false;
-    public static final boolean SHOW_SSA_BEFORE_LAMBDA_LIFTING = false;
-    public static final boolean SHOW_FINAL_SSA = false;
-    public static final boolean SHOW_COMPILED_BYTECODE = false;
-    public static final boolean SHOW_DECOMPILED_BYTECODE = false;
+    public static final boolean DEBUG = parseBoolean("debug", false);
+    public static final boolean ENABLE_TIMING = parseBoolean("enableTiming", false);
     
-    public static final boolean SHOW_EXPRESSION_BEFORE_EVALUATION = false;
-    public static final boolean SHOW_INTERPRETED_EXPRESSION = false;
+    public static final boolean SHOW_SSA_BEFORE_OPTIMIZATION        = parseBoolean("showSsaBeforeOptimization", false);
+    public static final boolean SHOW_SSA_BEFORE_LAMBDA_LIFTING      = parseBoolean("showSsaBeforeLambdaLifting", false);
+    public static final boolean SHOW_FINAL_SSA                      = parseBoolean("showFinalSsa", false);
+    public static final boolean SHOW_COMPILED_BYTECODE              = parseBoolean("showCompiledBytecode", false);
+    public static final boolean SHOW_DECOMPILED_BYTECODE            = parseBoolean("showDecompiledBytecode", false);
     
-    public static final boolean SHOW_COMPILED_RULES = false;
+    public static final boolean SHOW_EXPRESSION_BEFORE_EVALUATION   = parseBoolean("showExpressionBeforeEvaluation", false);
+    public static final boolean SHOW_INTERPRETED_EXPRESSION         = parseBoolean("showInterpretedExpression", false);
     
-    public static final boolean VALIDATE_AFTER_OPTIMIZATIONS = false;
-    public static final boolean TRACE_CONSTRAINT_SOLVER = false;
-    public static final boolean PRINT_OPTIMIZATION_TRANSFORMATIONS = false;
+    public static final boolean SHOW_COMPILED_RULES                 = parseBoolean("showCompiledRules", false);
     
-    public static final boolean NULL_CHECK_THREAD_LOCAL_VARIABLES = false;
+    public static final boolean VALIDATE_AFTER_OPTIMIZATIONS        = parseBoolean("validateAfterOptimizations", false);
+    public static final boolean TRACE_CONSTRAINT_SOLVER             = parseBoolean("traceConstraintSolver", false);
+    public static final boolean PRINT_OPTIMIZATION_TRANSFORMATIONS  = parseBoolean("printOptimizationTransformations", false);
     
-    public static final boolean TRACE_METHOD_CREATION = false;
+    public static final boolean NULL_CHECK_THREAD_LOCAL_VARIABLES   = parseBoolean("nullCheckThreadLocalVariables", false);
     
-    public static final boolean TRACE_MODULE_UPDATE = false;
+    public static final boolean TRACE_METHOD_CREATION               = parseBoolean("traceMethodCreation", false);
+    
+    public static final boolean TRACE_MODULE_UPDATE                 = parseBoolean("traceModuleUpdate", false);
     
     // Flags related to too long method sizes
-    public static final boolean TRACE_MAX_METHOD_SIZE = false;
-    public static final boolean EVERY_RULE_ENFORCEMENT_IN_SEPARATE_METHOD = true;
-    public static final boolean EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD = true;
+    public static final boolean TRACE_MAX_METHOD_SIZE               = parseBoolean("traceMaxMethodSize", false);
+    public static final boolean EVERY_RULE_ENFORCEMENT_IN_SEPARATE_METHOD = parseBoolean("everyRuleEnforcementInSeparateMethod", true);
+    public static final boolean EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD = parseBoolean("everyDatalogStratumInSeparateMethod", true);
     
-    public static final boolean ALLOW_OVERLOADING = true;
+    public static final boolean ALLOW_OVERLOADING = parseBoolean("allowOverloading", true);
 
     public static boolean debugFilter(String name) {
         return true;
     }
-    
+
+    static boolean parseBoolean(String property, boolean defaultValue) {
+        return defaultValue || Boolean.parseBoolean(System.getProperty(KEY_PREFIX + property));
+    }
 }