X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=blobdiff_plain;f=src%2Fedu%2Fuci%2Feecs%2FspecCompiler%2FcodeGenerator%2FCodeGenerator.java;h=08b8ee76b17f5032c36223f8dfd234b50ea9a009;hp=e685bc6c76aa092e60e1e72835ec444129a0e6d5;hb=574370fb84b50f462162260fda11eff80e90b867;hpb=e8466e30b587947c60bbba7df22b8b0908c75f26 diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java index e685bc6..08b8ee7 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java @@ -6,17 +6,24 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct; import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; import edu.uci.eecs.specCompiler.specExtraction.Construct; +import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; +import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.IDExtractor; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ParserUtils; import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct; import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo; @@ -40,19 +47,16 @@ public class CodeGenerator { private HashMap srcFilesInfo; private HashMap> codeAdditions; - - private ArrayList globalContent; + private String homeDir; public CodeGenerator(File[] srcFiles) { this.srcFiles = srcFiles; _extractor = new SpecExtractor(); _extractor.extract(srcFiles); - + this.srcFilesInfo = _extractor.srcFilesInfo; - - this.globalContent = null; - this.codeAdditions = new HashMap>(); + this.codeAdditions = new HashMap>(); _semantics = new SemanticsChecker(_extractor); try { @@ -72,33 +76,84 @@ public class CodeGenerator { private void globalConstruct2Code(GlobalConstruct construct) { ArrayList newCode = CodeVariables.generateGlobalVarDeclaration( _semantics, construct); - // Record the global content array to generate the new file - globalContent = newCode; + // Add it to the codeAdditions + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); + } + CodeAddition addition = new CodeAddition(construct.beginLineNum, + newCode); + codeAdditions.get(construct.file).add(addition); + newCode = CodeVariables.generateStaticVarDefine(_semantics, construct); + if (newCode.size() > 0) { + addition = new CodeAddition( + _semantics.getClassEndConstruct().beginLineNum, newCode); + codeAdditions.get(construct.file).add(addition); + } } - // Mainly rename and wrap the interface - private void interface2Code(InterfaceConstruct construct) - throws InterfaceWrongFormatException { - int lineNum = construct.beginLineNum; - String funcName = ""; - - // Rename the interface name - - // Rename the function declaration - - // Also rename the function definition if it's separated from the - // declaration - InterfaceDefineConstruct definition = (InterfaceDefineConstruct) _semantics.interfaceName2DefineConstruct + // Wrap the interface and then renaem it + private void interface2Code(InterfaceConstruct construct) { + // If there's no define construct for it, we generate the wrapper just + // in place without declaration + InterfaceDefineConstruct defineConstruct = _semantics.interfaceName2DefineConstruct .get(construct.name); - if (definition != null) { - String funcDefintionName = renameInterface(definition); - assert (funcDefintionName.equals(funcName)); + ArrayList newCode; + int lineNum; + CodeAddition addition; + // Then generate the wrapper if necessary + if (defineConstruct != null) { // Need to have a wrapper declaration + newCode = CodeVariables.generateInterfaceWrapperDeclaration( + _semantics, construct); + lineNum = construct.beginLineNum; + // Add the wrapper declaration + addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions + .put(construct.file, new ArrayList()); + } + codeAdditions.get(construct.file).add(addition); + + // Add the wrapper definition + newCode = CodeVariables.generateInterfaceWrapperDefinition( + _semantics, construct); + lineNum = defineConstruct.beginLineNum; + // Add the wrapper declaration + addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(defineConstruct.file)) { + codeAdditions.put(defineConstruct.file, + new ArrayList()); + } + codeAdditions.get(defineConstruct.file).add(addition); + } else { // No declaration needed but should add forward declaration in + // Class + // Last generate the definition + newCode = new ArrayList(); + if (_semantics.getOption("CLASS") == null) { + newCode.addAll(CodeVariables + .generateInterfaceWrapperDeclaration(_semantics, + construct)); + } + newCode.addAll(CodeVariables.generateInterfaceWrapperDefinition( + _semantics, construct)); + lineNum = construct.beginLineNum; + // Add the wrapper declaration + addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions + .put(construct.file, new ArrayList()); + } + codeAdditions.get(construct.file).add(addition); } - // Generate new wrapper - ArrayList newCode = CodeVariables.generateInterfaceWrapper( + // Don't forget to rename the interface + CodeVariables.renameInterface(_semantics, construct); + } + + private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generatePotentialCPDefine( _semantics, construct); - // Add it to the codeAdditions + CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { codeAdditions.put(construct.file, new ArrayList()); @@ -106,37 +161,22 @@ public class CodeGenerator { codeAdditions.get(construct.file).add(addition); } - // Returns the function name that has been renamed and replace the old line - private String renameInterface(Construct construct) - throws InterfaceWrongFormatException { - String funcDecl = ""; - ArrayList content = srcFilesInfo.get(construct.file).content; - - // Depending on "(" to find the function name, so it doesn't matter if - // there's any template - int beginIdx = funcDecl.indexOf('('); - if (beginIdx == -1) { - throw new InterfaceWrongFormatException(funcDecl - + "\n has wrong format!"); + private void CPDefine2Code(CPDefineConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generateCPDefine(_semantics, + construct); + + CodeAddition addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } - IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx); - String funcName = idExtractor.getPrevID(); - int idBeginIdx = idExtractor.getIDBeginIdx(), idEndIdx = idExtractor - .getIDEndIdx(), idLineBeginIdx = idExtractor.lineBeginIdxOfID(), idLineEndIdx = idExtractor - .lineEndIdxOfID(); - String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx) - + CodeVariables.SPEC_INTERFACE_WRAPPER + funcName - + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1); - - int lineNumOfID = idExtractor.lineNumOfID(); - // Be careful: lineNum - 1 -> index of content array - content.set(construct.beginLineNum - 1, newLine); - return funcName; + codeAdditions.get(construct.file).add(addition); } - private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) { + private void CPDefineCheck2Code(CPDefineCheckConstruct construct) { int lineNum = construct.beginLineNum; - ArrayList newCode = new ArrayList(); + ArrayList newCode = CodeVariables.generateCPDefineCheck( + _semantics, construct); CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -144,10 +184,11 @@ public class CodeGenerator { } codeAdditions.get(construct.file).add(addition); } - - private void CPDefine2Code(CPDefineConstruct construct) { + + private void CPClear2Code(CPClearConstruct construct) { int lineNum = construct.beginLineNum; - ArrayList newCode = new ArrayList(); + ArrayList newCode = CodeVariables.generateCPClear( + _semantics, construct); CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -155,10 +196,24 @@ public class CodeGenerator { } codeAdditions.get(construct.file).add(addition); } + - private void CPDefineCheck2Code(CPDefineCheckConstruct construct) { + /** + * private void ClassEnd2Code(ClassEndConstruct construct) { int lineNum = + * construct.beginLineNum; ArrayList newCode = + * CodeVariables.generateStaticVarDefine(_semantics, + * _semantics.getGlobalConstruct()); + * + * CodeAddition addition = new CodeAddition(lineNum, newCode); if + * (!codeAdditions.containsKey(construct.file)) { + * codeAdditions.put(construct.file, new ArrayList()); } + * codeAdditions.get(construct.file).add(addition); } + */ + + private void EntryPoint2Code(EntryPointConstruct construct) { int lineNum = construct.beginLineNum; ArrayList newCode = new ArrayList(); + newCode.addAll(CodeVariables.generateEntryPointInitCall()); CodeAddition addition = new CodeAddition(lineNum, newCode); if (!codeAdditions.containsKey(construct.file)) { @@ -167,36 +222,120 @@ public class CodeGenerator { codeAdditions.get(construct.file).add(addition); } + private ArrayList insertAnnotation2Src( + ArrayList additions, ArrayList content) { + int totalSize = content.size(); + for (int i = 0; i < additions.size(); i++) { + totalSize += additions.size(); + } + ArrayList newContent = new ArrayList(totalSize); + int curSrcLine = 0; + for (int i = 0; i < additions.size(); i++) { + CodeAddition addition = additions.get(i); + if (curSrcLine < addition.lineNum) { + // Be careful, subList is the interval [begin, end) + newContent + .addAll(content.subList(curSrcLine, addition.lineNum)); + curSrcLine = addition.lineNum; + } + newContent.addAll(addition.newCode); + } + newContent.addAll(content.subList(curSrcLine, content.size())); + return newContent; + } + public void generateCode() { for (int i = 0; i < _semantics.constructs.size(); i++) { Construct construct = _semantics.constructs.get(i); if (construct instanceof GlobalConstruct) { globalConstruct2Code((GlobalConstruct) construct); } else if (construct instanceof InterfaceConstruct) { - try { - interface2Code((InterfaceConstruct) construct); - } catch (InterfaceWrongFormatException e) { - e.printStackTrace(); - } + interface2Code((InterfaceConstruct) construct); } else if (construct instanceof PotentialCPDefineConstruct) { - // potentialCP2Code(inst); + potentialCPDefine2Code((PotentialCPDefineConstruct) construct); } else if (construct instanceof CPDefineConstruct) { - // CPDefine2Code(inst); + CPDefine2Code((CPDefineConstruct) construct); } else if (construct instanceof CPDefineCheckConstruct) { - // CPDefineCheck2Code(inst); + CPDefineCheck2Code((CPDefineCheckConstruct) construct); + } else if (construct instanceof CPClearConstruct) { + CPClear2Code((CPClearConstruct) construct); + } else if (construct instanceof EntryPointConstruct) { + EntryPoint2Code((EntryPointConstruct) construct); } } + + // ClassEndConstruct endConstruct = _semantics.getClassEndConstruct(); + // if (endConstruct != null) { + // ClassEnd2Code(endConstruct); + // } + + // Sort code additions + for (File file : codeAdditions.keySet()) { + ArrayList additions = codeAdditions.get(file); + + if (additions.size() == 0) // Simply do nothing + continue; + ArrayList content = _semantics.srcFilesInfo.get(file).content; + Collections.sort(additions, CodeAddition.lineNumComparator); + // Insert generated annotation to the source files + ArrayList newContent = insertAnnotation2Src(additions, + content); + // Write it back to file + ParserUtils.write2File(file, newContent); + } } public static void main(String[] argvs) { String homeDir = Environment.HOME_DIRECTORY; - File[] srcFiles = { - // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"), - new File(homeDir - + "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"), }; - // new File(homeDir + "/benchmark/ms-queue/my_queue.c"), - // new File(homeDir + "/benchmark/ms-queue/my_queue.h") }; - CodeGenerator gen = new CodeGenerator(srcFiles); - gen.generateCode(); + +// File[] srcLinuxRWLocks = { new File(homeDir +// + "/benchmark/linuxrwlocks/linuxrwlocks.c") }; +// +// File[] srcHashtable = { +// new File(homeDir +// + "/benchmark/cliffc-hashtable/cliffc_hashtable.h"), +// new File(homeDir + "/benchmark/cliffc-hashtable/main.cc") }; +// + File[] srcMSQueue = { + new File(homeDir + "/benchmark/ms-queue/my_queue.c"), + new File(homeDir + "/benchmark/ms-queue/testcase1.c"), + new File(homeDir + "/benchmark/ms-queue/testcase2.c"), + new File(homeDir + "/benchmark/ms-queue/main.c"), + new File(homeDir + "/benchmark/ms-queue/my_queue.h") }; + +// File[] srcRCU = { new File(homeDir +// + "/benchmark/read-copy-update/rcu.cc") }; +// +// File[] srcTrylock = { new File(homeDir +// + "/benchmark/trylock/trylock.c") }; + +// File[] srcDeque = { +// new File(homeDir + "/benchmark/chase-lev-deque-bugfix/deque.c"), +// new File(homeDir + "/benchmark/chase-lev-deque-bugfix/main.c"), +// new File(homeDir + "/benchmark/chase-lev-deque-bugfix/testcase.c"), +// new File(homeDir + "/benchmark/chase-lev-deque-bugfix/deque.h") }; +// +// File[] srcMCSLock = { +// new File(homeDir + "/benchmark/mcs-lock/mcs-lock.cc"), +// new File(homeDir + "/benchmark/mcs-lock/mcs-lock.h") }; +// +// File[] srcSPSCQueue = { +// new File(homeDir + "/benchmark/spsc-bugfix/spsc-queue.cc"), +// new File(homeDir + "/benchmark/spsc-bugfix/eventcount.h"), +// new File(homeDir + "/benchmark/spsc-bugfix/queue.h") }; +// +// File[] srcMPMCQueue = { +// new File(homeDir + "/benchmark/mpmc-queue/mpmc-queue.h"), +// new File(homeDir + "/benchmark/mpmc-queue/mpmc-queue.cc") }; +// +// File[][] sources = { srcLinuxRWLocks, srcMSQueue, srcRCU, +// srcDeque, srcMCSLock, srcSPSCQueue, srcMPMCQueue, srcHashtable }; + + File[][] sources = {srcMSQueue }; + // Compile all the benchmarks + for (int i = 0; i < sources.length; i++) { + CodeGenerator gen = new CodeGenerator(sources[i]); + gen.generateCode(); + } } }