if(inlineArity < Integer.MAX_VALUE)
inlinableDefinition = (SSAFunction)definition.copy();
}
+
+ public void cleanup() {
+ if(definition != null)
+ definition.cleanup();
+ if(inlinableDefinition != null)
+ inlinableDefinition.cleanup();
+ }
}
import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
equation.guard = equation.guard.accept(this);
}
+ @Override
+ public void visit(CHRStatement statement) {
+ for(int i=0;i<statement.body.length;++i)
+ statement.body[i] = statement.body[i].accept(this);
+ for(int i=0;i<statement.head.length;++i)
+ statement.head[i] = statement.head[i].accept(this);
+ }
+
}
import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.StringAccessor;
import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifierVisitor;
import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
public void visit(IncludeStatement statement) {
statement.value.accept(this);
}
+
+ @Override
+ public void visit(CHRStatement statement) {
+ for(ListQualifier q : statement.body)
+ q.accept(this);
+ for(ListQualifier q : statement.head)
+ q.accept(this);
+ }
}
@Override
public void accept(StatementVisitor visitor) {
- throw new UnsupportedOperationException();
+ visitor.visit(this);
}
@Override
void visit(LetStatement statement);
void visit(RuleStatement statement);
void visit(IncludeStatement statement);
+ void visit(CHRStatement statement);
}
statement.forValRefs(visitor);
exit.forValRefs(visitor);
}
+
+ public void cleanup() {
+ for(SSAStatement statement = firstStatement;
+ statement != null; statement = statement.next)
+ statement.cleanup();
+ exit.cleanup();
+ }
}
}
public abstract void forValRefs(ValRefVisitor visitor);
+
+ public abstract void cleanup();
}
}
public abstract void forValRefs(ValRefVisitor visitor);
+
+ public abstract void cleanup();
}
\ No newline at end of file
// Add valid variables and continuations
context.validContinuations.add(returnCont);
- for(SSABlock block = firstBlock; block != null; block = block.next) {
+ for(SSABlock block = firstBlock; block != null; block = block.next) {
context.validContinuations.add(block);
for(BoundVar parameter : block.parameters)
context.validBoundVariables.add(parameter);
block.forValRefs(visitor);
}
+ @Override
+ public void cleanup() {
+ for(SSABlock block = firstBlock; block != null; block = block.next)
+ block.cleanup();
+ }
}
for(SCLConstant function : functions.values())
function.saveInlinableDefinition();
}
+
+ public void cleanup() {
+ for(SSAClosure closure : closuresToGenerate)
+ closure.cleanup();
+ for(SCLConstant constant : functions.values())
+ constant.cleanup();
+ }
}
closure.forValRefs(visitor);
}
+ @Override
+ public void cleanup() {
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())
+ closure.cleanup();
+ }
+
}
}
public abstract void forValRefs(ValRefVisitor visitor);
+
+ public abstract void cleanup();
}
public void forValRefs(ValRefVisitor visitor) {
visitor.visit(condition);
}
+
+ @Override
+ public void cleanup() {
+ condition.remove();
+ }
}
for(ValRef parameter : parameters)
visitor.visit(parameter);
}
+
+ @Override
+ public void cleanup() {
+ for(ValRef parameter : parameters)
+ parameter.remove();
+ }
}
public void forValRefs(ValRefVisitor visitor) {
visitor.visit(scrutinee);
}
+
+ @Override
+ public void cleanup() {
+ scrutinee.remove();
+ }
}
@Override
public void forValRefs(ValRefVisitor visitor) {
}
+
+ @Override
+ public void cleanup() {
+ }
}
for(ValRef parameter : parameters)
visitor.visit(parameter);
}
+
+ @Override
+ public void cleanup() {
+ function.remove();
+ for(ValRef parameter : parameters)
+ parameter.remove();
+ }
}
for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())
closure.forValRefs(visitor);
}
+
+ @Override
+ public void cleanup() {
+ for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext())
+ closure.cleanup();
+ }
}
throw new SCLExpressionCompilationException(errorLog.getErrors());
}
Map<String, byte[]> classes = moduleBuilder.getClasses();
+ ssaModule.cleanup();
// Load generated code and execute
try {
--- /dev/null
+package org.simantics.scl.compiler.tests;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
+import org.simantics.scl.compiler.errors.CompilationErrorFormatter;
+import org.simantics.scl.compiler.module.repository.ImportFailure;
+import org.simantics.scl.compiler.module.repository.ImportFailureException;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.compiler.top.ExpressionEvaluator;
+import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class MemoryLeakTest {
+ ModuleRepository moduleRepository;
+
+ EnvironmentSpecification environmentSpecification;
+
+ @Before
+ public void initialize() throws Exception {
+ moduleRepository = InitialRepository.getInitialRepository();
+
+ // Environment for compiling expressions
+ environmentSpecification = new EnvironmentSpecification();
+ environmentSpecification.importModule("Builtin", "");
+ environmentSpecification.importModule("Prelude", "");
+ }
+
+ private void testExpression0(String expressionText,
+ Object expectedValue,
+ Type expectedType) throws Exception {
+
+ RuntimeEnvironment runtimeEnvironment;
+ try {
+ runtimeEnvironment = moduleRepository.createRuntimeEnvironment(environmentSpecification,
+ getClass().getClassLoader());
+ } catch(ImportFailureException e) {
+ for(ImportFailure failure : e.failures)
+ System.err.println("Failed to import " + failure.moduleName);
+ throw e;
+ }
+
+ // Compiling and running expression
+ try {
+ Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
+ .expectedType(expectedType)
+ .interpretIfPossible(false)
+ .eval();
+ if(expectedValue != null)
+ Assert.assertEquals(expectedValue, result);
+ } catch(SCLExpressionCompilationException e) {
+ System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
+ throw e;
+ }
+ }
+
+ @Test
+ public void testIt() throws Exception {
+ for(int i=0;i<1000000;++i) {
+ testExpression0("fst (\"a\", \"b\")", "a", Types.STRING);
+ if(i % 10000 == 0 && i > 0) {
+ System.gc();
+ System.runFinalization();
+ System.gc();
+ Thread.sleep(100L);
+ double used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
+ System.out.println(i + " " + used*1e-6 + " Mb, " + (used / i) + " b / expression");
+ }
+ }
+ }
+}