From 2420f847edec02c27130709c8b333a72776f69c6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Mon, 29 May 2017 14:53:57 +0300 Subject: [PATCH] (refs #7250) Cleaning up CHR code generation Change-Id: Iad454f1f7cdc0f27e21a2db03680312f49ab1059 --- .../chr/relations/CHRConstraint.java | 3 +- .../codegen/chr/CHRCodeGenerator.java | 604 +----------------- .../codegen/chr/CHRFactCodeGenerator.java | 602 +++++++++++++++++ .../codegen/chr/StoreInitialization.java | 16 + 4 files changed, 635 insertions(+), 590 deletions(-) create mode 100644 bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRFactCodeGenerator.java create mode 100644 bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/StoreInitialization.java diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java index 4a75a5604..868d70a6f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java @@ -18,6 +18,7 @@ import org.simantics.scl.compiler.elaboration.chr.CHRRelation; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan; import org.simantics.scl.compiler.internal.codegen.chr.CHRCodeGenerator; +import org.simantics.scl.compiler.internal.codegen.chr.CHRFactCodeGenerator; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor; @@ -115,7 +116,7 @@ public class CHRConstraint extends Symbol implements CHRRelation { if(typeDesc.equals(TypeDesc.VOID)) continue; this.accessors[i] = new CallJava(TVar.EMPTY_ARRAY, Types.NO_EFFECTS, parameterTypes[i], new Type[] {factType}, - null, new FieldRef(factClassName, CHRCodeGenerator.fieldName(i), jtt.toTypeDesc(parameterTypes[i])), null); + null, new FieldRef(factClassName, CHRFactCodeGenerator.fieldName(i), jtt.toTypeDesc(parameterTypes[i])), null); } this.addProcedure = new CallJava(TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {parentRuleset.storeType, factType}, new StackItem[] {new ParameterStackItem(1, factType), new ParameterStackItem(0, parentRuleset.storeType)}, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java index c4842ea61..3a249c5de 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRCodeGenerator.java @@ -3,59 +3,32 @@ package org.simantics.scl.compiler.internal.codegen.chr; import java.util.ArrayList; import org.cojen.classfile.TypeDesc; -import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; -import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; -import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint.IndexInfo; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; -import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder; -import org.simantics.scl.compiler.internal.codegen.utils.CodeBuilderUtils; import org.simantics.scl.compiler.internal.codegen.utils.Constants; -import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; -import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase; import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder; -import gnu.trove.list.array.TIntArrayList; -import gnu.trove.set.hash.THashSet; - public class CHRCodeGenerator { - + public static final TypeDesc FACT_ID_TYPE = TypeDesc.INT; - public static final String CHRHashIndex_name = "org/simantics/scl/runtime/chr/CHRHashIndex"; - public static final TypeDesc CHRHashIndex = TypeDesc.forClass(CHRHashIndex_name); - public static final String FactActivationQueue_name = "org/simantics/scl/runtime/chr/FactActivationQueue"; - public static final TypeDesc FactActivationQueue = TypeDesc.forClass(FactActivationQueue_name); - public static final String Fact_name = "org/simantics/scl/runtime/chr/Fact"; - public static final TypeDesc Fact = TypeDesc.forClass(Fact_name); - public static final String QUEUE = "queue"; - - private static class StoreInitialization { - final int access; - final String fieldName; - final TypeDesc fieldType; - final String className; - public StoreInitialization(int access, String fieldName, TypeDesc fieldType, String className) { - this.access = access; - this.fieldName = fieldName; - this.fieldType = fieldType; - this.className = className; - } - } - + private static final String FactActivationQueue_name = "org/simantics/scl/runtime/chr/FactActivationQueue"; + private static final TypeDesc FactActivationQueue = TypeDesc.forClass(FactActivationQueue_name); + private static final String QUEUE = "queue"; + public static void generateStore(ModuleBuilder moduleBuilder, CHRRuleset ruleset) { ClassBuilder storeClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, ruleset.storeClassName, "java/lang/Object"); if(ruleset.parameters == null) ruleset.parameters = new BoundVar[0]; ruleset.parameterTypeDescs = moduleBuilder.getJavaTypeTranslator().getTypeDescs(ruleset.parameters); - + ArrayList hashIndexInitializations = new ArrayList<>(); for(CHRConstraint constraint : ruleset.constraints) generateFact(storeClassBuilder, constraint, hashIndexInitializations); - + // Fields for(int i=0;i hashIndexInitializations) { - CHRRuleset ruleset = constraint.parentRuleset; - boolean supportsRemoval = constraint.mayBeRemoved(); - - ModuleBuilder moduleBuilder = storeClassBuilder.getModuleBuilder(); - JavaTypeTranslator jtt = moduleBuilder.getJavaTypeTranslator(); - TypeDesc storeTypeDesc = storeClassBuilder.getType(); - TypeDesc[] storeTypeDescArray = new TypeDesc[] { storeTypeDesc }; - - String factClassName = storeClassBuilder.getClassName() + "$" + constraint.name; - TypeDesc factTypeDesc = TypeDesc.forClass(factClassName); - ClassBuilder factClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, factClassName, "java/lang/Object", Fact_name); - - // Fields - - /* public int id; - public int c0; // key - public int c1; - public ExampleFact bfPrev; - public ExampleFact bfNext; - */ - TypeDesc[] parameterTypeDescs = jtt.toTypeDescs(constraint.parameterTypes); - factClassBuilder.addField(Opcodes.ACC_PUBLIC, "id", FACT_ID_TYPE); - for(int i=0;i getParameterTypeDescs = new ArrayList(constraint.parameterTypes.length); - for(int i=0;i>i)&1)==1) - getParameterTypeDescs.add(parameterTypeDescs[i]); - MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, constraint.name + "$" + indexInfo.indexName, factTypeDesc, - getParameterTypeDescs.toArray(new TypeDesc[getParameterTypeDescs.size()])); - mb.loadThis(); - mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$temp", factTypeDesc); - LocalVariable tempFactVar = mb.createLocalVariable("temp", factTypeDesc); - mb.storeLocal(tempFactVar); - int parameterId=0; - for(int i=0;i>i)&1)==1) { - TypeDesc typeDesc = parameterTypeDescs[i]; - if(!typeDesc.equals(TypeDesc.VOID)) { - mb.loadLocal(tempFactVar); - mb.loadLocal(mb.getParameter(parameterId)); - mb.storeField(factClassName, fieldName(i), typeDesc); - } - ++parameterId; - } - - mb.loadThis(); - mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$" + indexInfo.indexName, CHRHashIndex); - mb.loadLocal(tempFactVar); - mb.invokeVirtual(CHRHashIndex_name, supportsRemoval ? "getEqual" : "getEqualNoRemovals", TypeDesc.OBJECT, Constants.OBJECTS[1]); - mb.checkCast(factTypeDesc); - - mb.returnValue(factTypeDesc); - mb.finish(); - } - } - } - - // Method: add - - { - MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "add", TypeDesc.VOID, storeTypeDescArray); - LocalVariable storeParameter = mb.getParameter(0); - for(IndexInfo indexInfo : constraint.getIndices()) { - String linkedListPrev = indexInfo.indexName + "Prev"; - String linkedListNext = indexInfo.indexName + "Next"; - String storeHashIndexName = constraint.name + "$" + indexInfo.indexName; - - // public void add(ExampleStore store) { - // bfNext = (ExampleFact)store.ExampleFact_bfIndex.addFreshAndReturnOld(this); - // if(bfNext != null) - // bfNext.bfPrev = this; - // } - - if(indexInfo.indexMask == 0) { - mb.loadThis(); - mb.loadLocal(storeParameter); - mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc); - if(supportsRemoval) - mb.dupX1(); - mb.storeField(factClassName, linkedListNext, factTypeDesc); - if(supportsRemoval) { - Label cont = new Label(); - mb.ifNullBranch(cont, true); - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.loadThis(); - mb.storeField(factClassName, linkedListPrev, factTypeDesc); - mb.setLocation(cont); - } - mb.loadLocal(storeParameter); - mb.loadThis(); - mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc); - } - else { - // bfNext = (ExampleFact)store.ExampleFact_bfIndex.addFreshAndReturnOld(this); - mb.loadThis(); - mb.loadLocal(storeParameter); - mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex); - mb.loadThis(); - mb.invokeVirtual(CHRHashIndex_name, supportsRemoval ? "addFreshAndReturnOld" : "addFreshAndReturnOld", TypeDesc.OBJECT, Constants.OBJECTS[1]); - mb.checkCast(factTypeDesc); - if(supportsRemoval) - mb.dupX1(); - mb.storeField(factClassName, linkedListNext, factTypeDesc); - // leaves bfNext on the stack - - //if(bfNext != null) - // bfNext.bfPrev = this; - if(supportsRemoval) { - Label cont = new Label(); - mb.ifNullBranch(cont, true); - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.loadThis(); - mb.storeField(factClassName, linkedListPrev, factTypeDesc); - mb.setLocation(cont); - } - } - } - if(!constraint.isPassive()) { - mb.loadLocal(storeParameter); - mb.loadField(storeClassBuilder.getClassName(), QUEUE, FactActivationQueue); - mb.loadConstant(constraint.getMinimumPriority()); - mb.loadThis(); - mb.invokeVirtual(FactActivationQueue_name, "add", TypeDesc.VOID, new TypeDesc[] {TypeDesc.INT, Fact}); - } - mb.returnVoid(); - mb.finish(); - } - - // Method: remove - - if(supportsRemoval) { - // public void remove(ExampleStore store) { - // if(bfPrev == null) { - // if(bfNext == null) - // store.ExampleFact_bfIndex.removeKnownToExistKey(this); - // else { - // bfNext.bfPrev = null; - // store.ExampleFact_bfIndex.replaceKnownToExistKey(this, bfNext); - // } - // } - // else { - // bfPrev.bfNext = bfNext; - // if(bfNext != null) - // bfNext.bfPrev = bfPrev; - // } - // } - - MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "remove", TypeDesc.VOID, storeTypeDescArray); - LocalVariable storeParameter = mb.getParameter(0); - for(IndexInfo indexInfo : constraint.getIndices()) { - String linkedListPrev = indexInfo.indexName + "Prev"; - String linkedListNext = indexInfo.indexName + "Next"; - String storeHashIndexName = constraint.name + "$" + indexInfo.indexName; - - Label nextIndex = mb.createLabel(); - - // if(bfPrev == null) { - mb.loadThis(); - mb.loadField(factClassName, linkedListPrev, factTypeDesc); - Label else1 = new Label(); - mb.ifNullBranch(else1, false); - - // if(bfNext == null) - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - Label else2 = new Label(); - mb.ifNullBranch(else2, false); - - // store.ExampleFact_bfIndex.removeKnownToExistKey(this); - if(indexInfo.indexMask == 0) { - mb.loadLocal(storeParameter); - mb.loadNull(); - mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc); - } - else { - mb.loadLocal(storeParameter); - mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex); - mb.loadThis(); - mb.invokeVirtual(CHRHashIndex_name, "removeKnownToExistKey", TypeDesc.VOID, Constants.OBJECTS[1]); - } - mb.branch(nextIndex); - - // else { - mb.setLocation(else2); - // bfNext.bfPrev = null; - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.loadNull(); - mb.storeField(factClassName, linkedListPrev, factTypeDesc); - // store.ExampleFact_bfIndex.replaceKnownToExistKey(this, bfNext); - if(indexInfo.indexMask == 0) { - mb.loadLocal(storeParameter); - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.storeField(storeClassBuilder.getClassName(), storeHashIndexName, factTypeDesc); - } - else { - mb.loadLocal(storeParameter); - mb.loadField(storeClassBuilder.getClassName(), storeHashIndexName, CHRHashIndex); - mb.loadThis(); - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.invokeVirtual(CHRHashIndex_name, "replaceKnownToExistKey", TypeDesc.VOID, Constants.OBJECTS[2]); - } - mb.branch(nextIndex); - // } - - // else { - mb.setLocation(else1); - // bfPrev.bfNext = bfNext; - mb.loadThis(); - mb.loadField(factClassName, linkedListPrev, factTypeDesc); - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.storeField(factClassName, linkedListNext, factTypeDesc); - // if(bfNext != null) - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - Label else3 = new Label(); - mb.ifNullBranch(else3, true); - // bfNext.bfPrev = bfPrev; - mb.loadThis(); - mb.loadField(factClassName, linkedListNext, factTypeDesc); - mb.loadThis(); - mb.loadField(factClassName, linkedListPrev, factTypeDesc); - mb.storeField(factClassName, linkedListPrev, factTypeDesc); - mb.setLocation(else3); - mb.branch(nextIndex); - // } - - mb.setLocation(nextIndex); - } - mb.loadThis(); - mb.loadConstant(-1); - mb.storeField(factClassName, "id", FACT_ID_TYPE); - mb.returnVoid(); - mb.finish(); - } - - // Method: isAlive - - { - // @Override - // public boolean isAlive() { - // return id >= 0; - // } - - MethodBuilderBase mb = factClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "isAlive", TypeDesc.BOOLEAN, Constants.EMPTY_TYPEDESC_ARRAY); - if(supportsRemoval) { - mb.loadThis(); - mb.loadField(factClassName, "id", FACT_ID_TYPE); - - Label thenBranch = mb.createLabel(); - mb.ifZeroComparisonBranch(thenBranch, "<"); - mb.loadConstant(true); - mb.returnValue(TypeDesc.BOOLEAN); - - mb.setLocation(thenBranch); - mb.loadConstant(false); - mb.returnValue(TypeDesc.BOOLEAN); - } - else { - mb.loadConstant(true); - mb.returnValue(TypeDesc.BOOLEAN); - } - mb.finish(); - } - - // activate parts - - THashSet usedParameters = new THashSet(); - for(int i=0;i { - if(valRef.getBinding() instanceof BoundVar) - usedParameters.add((BoundVar)valRef.getBinding()); - }); - for(int j=0;j labels = new ArrayList