1 package edu.uci.eecs.codeGenerator;
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8 import java.io.BufferedWriter;
10 import java.io.FileWriter;
11 import java.io.IOException;
13 import edu.uci.eecs.specExtraction.Code;
14 import edu.uci.eecs.specExtraction.CommutativityRule;
15 import edu.uci.eecs.specExtraction.DefineConstruct;
16 import edu.uci.eecs.specExtraction.EntryConstruct;
17 import edu.uci.eecs.specExtraction.FunctionHeader;
18 import edu.uci.eecs.specExtraction.GlobalConstruct;
19 import edu.uci.eecs.specExtraction.InterfaceConstruct;
20 import edu.uci.eecs.specExtraction.OPConstruct;
21 import edu.uci.eecs.specExtraction.SpecExtractor;
22 import edu.uci.eecs.specExtraction.SpecNaming;
23 import edu.uci.eecs.specExtraction.VariableDeclaration;
27 * Some utility functions for generating specification checking code.
33 public class CodeGeneratorUtils {
35 public static void PrintCode(ArrayList<String> code) {
36 for (int i = 0; i < code.size(); i++) {
37 System.out.println(code.get(i));
41 public static String Comment(String comment) {
42 return "/** " + comment + " */";
45 public static String ShortComment(String comment) {
46 return "// " + comment;
49 public static String IncludeHeader(String header) {
50 return "#include " + header;
53 public static String Brace(String val) {
54 return "(" + val + ")";
57 public static String Quote(String val) {
58 return "\"" + val + "\"";
61 public static String Assign(String varName, String val) {
62 return varName + " = " + val + ";";
65 public static String AssignToPtr(String structName, String field, String val) {
66 return structName + "->" + field + " = " + val + ";";
69 public static String Declare(String type, String name) {
70 return type + " " + name + ";";
73 public static String Declare(VariableDeclaration varDecl) {
74 return Declare(varDecl.type, varDecl.name);
77 public static String DeclareDefine(String type, String var, String val) {
78 return type + " " + var + " = " + val + ";";
83 * Insert a number of tabs at the beginning of the line.
89 * The number of tabs to be inserted
90 * @return A line that starts with the specific inserted tabs
92 public static String TabbedLine(String line, int tabCnt) {
94 for (int i = 0; i < tabCnt; i++)
102 * Insert a tab at the beginning of the line.
107 * @return A line that starts with one inserted tab
109 public static String TabbedLine(String line) {
115 * This function generates the code for the header file that our
116 * specification generates automatically --- cdsspec-generated.h.
120 * The SpecExtractor that contains the extracted information
121 * @return The generated code
123 public static Code GenerateCDSSpecHeaderFile(SpecExtractor extractor) {
124 HashSet<String> headerFiles = extractor.headerFiles;
125 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
126 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
127 HashSet<String> OPLabelSet = extractor.OPLabelSet;
129 Code code = new Code();
131 // Add auto-generated comments
133 code.addLine(TabbedLine("This is a header file auto-generated by CDSSpec compiler; together, CDSSpec"));
134 code.addLine(TabbedLine("compiler should have generated the accompanying implementation file that"));
135 code.addLine(TabbedLine("implements the some functions declared in this file. In order to instrument"));
136 code.addLine(TabbedLine("your benchmark for CDSSpec checker to check, you should include this header"));
137 code.addLine(TabbedLine("file in every file you use an CDSSpec annotation. Note that it should be"));
138 code.addLine(TabbedLine("placed in the end of all other header files. Currently we require a C++"));
139 code.addLine(TabbedLine("compiler that supports C++11."));
143 code.addLine("#ifndef _"
144 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
146 code.addLine("#define _"
147 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
151 // FIXME: We have included ad-hoc header files here
152 // System included headers
153 code.addLine(ShortComment("System included headers go here"));
154 code.addLine(IncludeHeader(SpecNaming.SPECANNOTATION_API));
155 code.addLine(IncludeHeader(SpecNaming.STDLIB));
159 // Users included headers
160 code.addLine(ShortComment("User included headers go here"));
161 for (String header : headerFiles) {
162 code.addLine(IncludeHeader(header));
166 // Decalre extern "C" --- begin
167 code.addLine("#ifdef __cplusplus");
168 code.addLine("extern \"C\" {");
169 code.addLine("#endif");
172 // Declare _createOPDefineUnattached
173 code.addLine(ShortComment("Declare _createOPDefineUnattached"));
174 // void _createOPDefineUnattached();
175 code.addLine("void _createOPDefineUnattached();");
178 // Declare _createOPClearDefineUnattached
179 code.addLine(ShortComment("Declare _createOPClearDefineUnattached"));
180 // void _createOPClearDefineUnattached();
181 code.addLine("void _createOPClearDefineUnattached();");
184 code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
186 // Interface name strings
187 code.addLine(ShortComment("Interface name strings"));
188 for (File file : interfaceListMap.keySet()) {
189 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
190 for (InterfaceConstruct construct : list) {
191 String name = construct.getName();
192 code.addLine(Declare("extern " + SpecNaming.CString,
193 SpecNaming.AppendStr(name)));
198 // Ordering points label strings
199 code.addLine(ShortComment("Ordering points label strings"));
200 for (String label : OPLabelSet) {
201 code.addLine(Declare("extern " + SpecNaming.CString,
202 SpecNaming.AppendStr(label)));
206 // Declare customized value struct
207 for (File file : interfaceListMap.keySet()) {
208 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
209 for (InterfaceConstruct construct : list) {
210 // Declare custom value struct for the interface
211 String name = construct.getName();
212 String structName = construct.getStructName();
213 code.addLine(ShortComment("Declare custom value struct for "
215 code.addLine("typedef struct " + structName + " {");
216 FunctionHeader funcHeader = construct.getFunctionHeader();
218 if (!funcHeader.returnType.equals("void"))
219 code.addLine(TabbedLine(Declare(funcHeader.returnType,
222 for (VariableDeclaration decl : funcHeader.args) {
223 code.addLine(TabbedLine(Declare(decl)));
225 code.addLine("} " + structName + ";");
230 // Declare INIT annotation instrumentation function
231 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
232 code.addLine("void _createInitAnnotation();");
235 // Decalre extern "C" --- begin
236 code.addLine("#ifdef __cplusplus");
238 code.addLine("#endif");
242 code.addLine("#endif");
249 * This function generates the code for the CPP file that our specification
250 * generates automatically --- cdsspec-generated.cc.
254 * The SpecExtractor that contains the extracted information
255 * @return The generated code
257 public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
258 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
259 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
260 HashSet<String> OPLabelSet = extractor.OPLabelSet;
262 Code code = new Code();
264 Code fieldsInit = null;
266 // Add auto-generated comments
268 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
269 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
270 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
274 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
275 code.addLine("#include " + SpecNaming.CDSANNOTATE);
276 code.addLine("#include " + SpecNaming.SPEC_COMMON);
277 code.addLine("#include " + SpecNaming.METHODCALL);
278 code.addLine("#include " + SpecNaming.CDSSPEC);
279 code.addLine("#include " + SpecNaming.SPECANNOTATION);
283 // Declare customized StateStruct
284 code.addLine(ShortComment("Declare customized StateStruct"));
285 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
286 for (VariableDeclaration decl : globalConstruct.declState) {
287 code.addLine(TabbedLine(Declare(decl)));
290 // Define state destructor
291 code.addLine(TabbedLine(ShortComment("Define state destructor")));
292 code.addLine(TabbedLine("~" + SpecNaming.StateStruct + "() {"));
293 if (!globalConstruct.autoGenClear) {
294 code.addLine(TabbedLine(
295 ShortComment("Execute user-defined state clear code"), 2));
297 code.addLine(TabbedLine(
298 ShortComment("Execute auto-generated state clear code"), 2));
300 globalConstruct.clearState.align(2);
301 code.addLines(globalConstruct.clearState);
302 code.addLine(TabbedLine("}"));
305 code.addLine(TabbedLine("SNAPSHOTALLOC"));
307 code.addLine("} " + SpecNaming.StateStruct + ";");
311 // Define the fake ordering point operation
312 code.addLine(ShortComment("Define the fake ordering point operation"));
313 // atomic_int _FAKE_OP_;
314 code.addLine("atomic_int " + SpecNaming.FakeOP + ";");
317 // Define _createOPDefineUnattached
318 code.addLine(ShortComment("Define _createOPDefineUnattached"));
319 code.addLine("void " + SpecNaming.CreateOPDefineUnattachedFunc + "() {");
320 code.addLine(TabbedLine(ShortComment("A load acting as the fake OP")));
321 code.addLine(TabbedLine(SpecNaming.FakeOP
322 + ".load(memory_order_relaxed);"));
323 code.addLine(TabbedLine(SpecNaming.CreateOPDefineAnnoFunc + "();"));
326 // Define _createOPClearDefineUnattached
327 code.addLine(ShortComment("Define _createOPClearDefineUnattached"));
328 code.addLine("void " + SpecNaming.CreateOPClearDefineUnattachedFunc
330 code.addLine(TabbedLine(ShortComment("A load acting as the fake OP")));
331 code.addLine(TabbedLine(SpecNaming.FakeOP
332 + ".load(memory_order_relaxed);"));
333 code.addLine(TabbedLine(SpecNaming.CreateOPClearDefineAnnoFunc + "();"));
336 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
337 code.addLine(ShortComment("A special empty string"));
338 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
342 // Interface name strings
343 code.addLine(ShortComment("Interface name strings"));
344 for (File file : interfaceListMap.keySet()) {
345 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
346 for (InterfaceConstruct construct : list) {
347 String name = construct.getName();
348 code.addLine(DeclareDefine(SpecNaming.CString,
349 SpecNaming.AppendStr(name), Quote(name)));
354 // Commutativity rule strings
355 code.addLine(ShortComment("Commutativity rule strings"));
356 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
357 CommutativityRule rule = globalConstruct.commutativityRules
359 code.addLine(DeclareDefine(SpecNaming.CString,
360 SpecNaming.AppendStr(SpecNaming.Commutativity + i),
361 Quote(rule.toString())));
365 // Ordering points label strings
366 code.addLine(ShortComment("Ordering points label strings"));
367 for (String label : OPLabelSet) {
368 code.addLine(DeclareDefine(SpecNaming.CString,
369 SpecNaming.AppendStr(label), Quote(label)));
373 // Special function name strings
374 code.addLine(ShortComment("Special function name strings"));
375 code.addLine(DeclareDefine(SpecNaming.CString,
376 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
377 + SpecNaming.InitalState.toLowerCase())));
378 code.addLine(DeclareDefine(SpecNaming.CString,
379 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
380 + SpecNaming.CopyState.toLowerCase())));
381 code.addLine(DeclareDefine(SpecNaming.CString,
382 SpecNaming.AppendStr(SpecNaming.ClearState), Quote("_"
383 + SpecNaming.ClearState.toLowerCase())));
384 code.addLine(DeclareDefine(SpecNaming.CString,
385 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
386 + SpecNaming.FinalState.toLowerCase())));
387 code.addLine(DeclareDefine(SpecNaming.CString,
388 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
389 + SpecNaming.PrintState.toLowerCase())));
392 // Interface name strings
393 for (File file : interfaceListMap.keySet()) {
394 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
395 for (InterfaceConstruct construct : list) {
396 String name = construct.getName();
397 code.addLine(ShortComment(name + " function strings"));
399 String tmpFunc = name + "_" + SpecNaming.Transition;
400 code.addLine(DeclareDefine(SpecNaming.CString,
401 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
403 tmpFunc = name + "_" + SpecNaming.PreCondition;
404 if (!construct.preCondition.isEmpty())
405 code.addLine(DeclareDefine(SpecNaming.CString,
406 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
408 code.addLine(DeclareDefine(SpecNaming.CString,
409 SpecNaming.AppendStr(tmpFunc),
410 SpecNaming.EmptyCString));
412 tmpFunc = name + "_" + SpecNaming.PostCondition;
413 if (!construct.postCondition.isEmpty())
414 code.addLine(DeclareDefine(SpecNaming.CString,
415 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
417 code.addLine(DeclareDefine(SpecNaming.CString,
418 SpecNaming.AppendStr(tmpFunc),
419 SpecNaming.EmptyCString));
421 tmpFunc = name + "_" + SpecNaming.PrintValue;
422 if (!construct.print.isEmpty())
423 code.addLine(DeclareDefine(SpecNaming.CString,
424 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
426 code.addLine(DeclareDefine(SpecNaming.CString,
427 SpecNaming.AppendStr(tmpFunc),
428 SpecNaming.EmptyCString));
434 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
435 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
436 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
437 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
438 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
440 for (VariableDeclaration decl : globalConstruct.declState) {
441 code.addLine(TabbedLine("#define " + decl.name + " "
442 + SpecNaming.StateInst + "->" + decl.name));
444 if (!globalConstruct.autoGenInitial)
445 code.addLine(TabbedLine(ShortComment("User-defined state intialization code")));
447 // Auto-generated the initialization function
448 code.addLine(TabbedLine(ShortComment("Auto-generated state intialization code")));
449 // Align the code with one tab
450 globalConstruct.initState.align(1);
451 code.addLines(globalConstruct.initState);
453 for (VariableDeclaration decl : globalConstruct.declState) {
454 code.addLine(TabbedLine("#undef " + decl.name));
457 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
458 SpecNaming.StateInst, SpecNaming.StateInst)));
463 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
464 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
465 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
467 // StateStruct *OLD = (StateStruct*) src->state;
468 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
469 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
470 + " src->" + SpecNaming.StateInst)));
471 // StateStruct *NEW = new StateStruct;
472 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
473 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
474 if (!globalConstruct.autoGenCopy)
475 code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
477 // Auto-generated the copy function
478 code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
479 globalConstruct.copyState.align(1);
480 code.addLines(globalConstruct.copyState);
482 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
483 SpecNaming.NewStateInst)));
488 code.addLine(ShortComment("Define @" + SpecNaming.ClearState));
489 code.addLine("void _" + SpecNaming.ClearState.toLowerCase() + "("
490 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
491 // Retrieve the state
492 code.addLine(TabbedLine(ShortComment("Retrieve the state")));
493 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
494 + SpecNaming.StateInst, "(" + SpecNaming.StateStruct + "*) "
495 + SpecNaming.Method1 + "->state")));
496 // Explicitly call the state destructor
497 code.addLine(TabbedLine(ShortComment("Explicitly call the state destructor")));
498 code.addLine(TabbedLine("delete " + SpecNaming.StateInst + ";"));
503 code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
504 code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
505 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
507 // Initialize state struct fields
508 fieldsInit = GenerateStateFieldsInitialization(SpecNaming.Method1,
509 SpecNaming.StateInst, globalConstruct);
511 code.addLines(fieldsInit);
513 if (!globalConstruct.autoGenPrint)
514 code.addLine(TabbedLine(ShortComment("Execute user-defined state printing code")));
516 // Auto-generated the copy function
517 code.addLine(TabbedLine(ShortComment("Execute auto-generated state printing code")));
519 // Align the code with one tab
520 globalConstruct.printState.align(1);
521 code.addLines(globalConstruct.printState);
525 // Define @Commutativity
526 code.addLine(ShortComment("Define commutativity checking functions"));
527 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
528 CommutativityRule rule = globalConstruct.commutativityRules
530 code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
531 + SpecNaming.Method + " m1, " + SpecNaming.Method
533 // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
534 code.addLine(TabbedLine("if (m1->name == "
535 + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
536 + SpecNaming.AppendStr(rule.method2) + ") {"));
537 // Initialize M1 & M2 in commutativity rule
538 // e.g. ENQ *M1 = (ENQ*) m1->value;
539 String structName1 = InterfaceConstruct
540 .createStructName(rule.method1);
541 String structName2 = InterfaceConstruct
542 .createStructName(rule.method2);
543 code.addLine(TabbedLine(
544 DeclareDefine(structName1, "*M1", "(" + structName1
545 + "*) m1->value"), 2));
546 code.addLine(TabbedLine(
547 DeclareDefine(structName2, "*M2", "(" + structName2
548 + "*) m2->value"), 2));
549 code.addLine(TabbedLine("return " + rule.condition + ";", 2));
550 code.addLine(TabbedLine("}"));
551 code.addLine(TabbedLine("return false;"));
557 // Define customized interface functions
558 for (File file : interfaceListMap.keySet()) {
559 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
560 for (InterfaceConstruct construct : list) {
563 // Define interface functions
564 String name = construct.getName();
565 String structName = construct.getStructName();
566 code.addLine("/********** " + name
567 + " functions **********/");
568 // Define @Transition for INTERFACE
569 code.addLine(ShortComment("Define @" + SpecNaming.Transition
571 code.addLine("bool _" + name + "_" + SpecNaming.Transition
572 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
573 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
576 // Initialize value struct fields
577 fieldsInit = GenerateInterfaceFieldsInitialization(
578 SpecNaming.Method2, SpecNaming.InterfaceValueInst,
581 code.addLines(fieldsInit);
583 construct.transition.align(1);
584 code.addLine(TabbedLine(ShortComment("Execute Transition")));
585 code.addLines(construct.transition);
587 // By default, we will return true for state transition
588 code.addLine(TabbedLine(ShortComment("By default @Transition returns true")));
589 code.addLine(TabbedLine("return true;"));
593 // Define @PreCondition
594 if (!construct.preCondition.isEmpty()) {
595 code.addLine(ShortComment("Define @"
596 + SpecNaming.PreCondition + " for " + name));
597 code.addLine("bool _" + name + "_"
598 + SpecNaming.PreCondition + "(" + SpecNaming.Method
599 + " " + SpecNaming.Method1 + ") {");
601 // Initialize value struct fields
602 fieldsInit = GenerateInterfaceFieldsInitialization(
603 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
606 code.addLines(fieldsInit);
608 construct.preCondition.align(1);
609 code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
610 code.addLines(construct.preCondition);
612 // By default, we will return true for @PreCondition
613 code.addLine(TabbedLine(ShortComment("By default @PreCondition returns true")));
614 code.addLine(TabbedLine("return true;"));
620 // Define @PostCondition
621 if (!construct.postCondition.isEmpty()) {
622 code.addLine(ShortComment("Define @"
623 + SpecNaming.PostCondition + " for " + name));
624 code.addLine("bool _" + name + "_"
625 + SpecNaming.PostCondition + "("
626 + SpecNaming.Method + " " + SpecNaming.Method1
629 // Initialize value struct fields
630 fieldsInit = GenerateInterfaceFieldsInitialization(
631 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
634 code.addLines(fieldsInit);
636 construct.postCondition.align(1);
637 code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
638 code.addLines(construct.postCondition);
640 // By default, we will return true for @PostCondition
641 code.addLine(TabbedLine(ShortComment("By default @PostCondition returns true")));
642 code.addLine(TabbedLine("return true;"));
648 if (!construct.print.isEmpty()) {
649 code.addLine(ShortComment("Define @"
650 + SpecNaming.PrintValue + " for " + name));
651 code.addLine("void _" + name + "_" + SpecNaming.PrintValue
652 + "(" + SpecNaming.Method + " "
653 + SpecNaming.Method1 + ") {");
654 // Initialize value struct fields
655 fieldsInit = GenerateInterfaceFieldsInitialization(
656 SpecNaming.Method1, SpecNaming.InterfaceValueInst,
659 code.addLines(fieldsInit);
661 construct.print.align(1);
662 if (!construct.autoGenPrint)
663 code.addLine(TabbedLine(ShortComment("Execute user-defined value printing code")));
665 // Auto-generated the value printing function
666 code.addLine(TabbedLine(ShortComment("Execute auto-generated value printing code")));
667 code.addLines(construct.print);
675 // Define INIT annotation instrumentation function
676 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
677 code.addLine("void _createInitAnnotation() {");
679 // Init the fake ordering point place holder
680 code.addLine(TabbedLine(ShortComment("Init the fake ordering point place holder")));
681 code.addLine(TabbedLine(SpecNaming.FakeOP
682 + ".store(1, memory_order_relaxed);"));
684 // Init commutativity rules
685 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
686 code.addLine(TabbedLine(DeclareDefine("int",
687 SpecNaming.CommutativityRuleSizeInst,
688 Integer.toString(globalConstruct.commutativityRules.size()))));
689 String tmp = SpecNaming.NewSize
690 + Brace(SpecNaming.CommutativityRule + ", sizeof"
691 + Brace(SpecNaming.CommutativityRule) + " * "
692 + SpecNaming.CommutativityRuleSizeInst);
693 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
694 + SpecNaming.CommutativityRuleInst, tmp)));
695 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
696 CommutativityRule rule = globalConstruct.commutativityRules
698 code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
700 // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
701 // _Commutativity1_str, _checkCommutativity1)
703 + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
704 + (i - 1) + "] ") + SpecNaming.CommutativityRule
705 + "(" + SpecNaming.AppendStr(rule.method1) + ", "
706 + SpecNaming.AppendStr(rule.method2) + ", "
707 + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
708 + "_check" + SpecNaming.Commutativity + i + ");";
709 code.addLine(TabbedLine(line));
712 // Initialize AnnoInit
713 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
714 // AnnoInit *init = new AnnoInit(
715 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
716 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
718 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
719 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
720 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
721 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
722 + SpecNaming.InitalState.toLowerCase() + "),", 2));
723 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
724 line = "new " + SpecNaming.NamedFunction + "("
725 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
726 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
727 if (globalConstruct.finalState.isEmpty()) {
728 line = line + SpecNaming.NullFunc + "),";
730 line = line + "_" + SpecNaming.FinalState.toUpperCase();
732 code.addLine(TabbedLine(line, 2));
733 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
734 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
735 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
736 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
737 + SpecNaming.CopyState.toLowerCase() + "),", 2));
738 // new NamedFunction(_Clear_str, CLEAR, (void*) _clear),
739 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
740 + SpecNaming.AppendStr(SpecNaming.ClearState) + ", "
741 + SpecNaming.ClearState.toUpperCase() + ", " + "(void*) _"
742 + SpecNaming.ClearState.toLowerCase() + "),", 2));
743 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
744 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
745 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
746 + SpecNaming.PrintStateType + ", " + "(void*) _"
747 + SpecNaming.PrintState.toLowerCase() + "),", 2));
748 // commuteRules, CommuteRuleSize);
749 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
750 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
753 // Declare StateFunctions map
754 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
755 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
756 + SpecNaming.StateFunctionsInst)));
759 // StateFunction for interface
760 for (File file : interfaceListMap.keySet()) {
761 ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
762 for (InterfaceConstruct construct : list) {
763 String name = construct.getName();
764 code.addLine(TabbedLine(ShortComment("StateFunction for "
766 // stateFuncs = new StateFunctions(
767 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
768 + " = new " + SpecNaming.StateFunctions + "("));
769 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
772 code.addLine(TabbedLine(
774 + SpecNaming.NamedFunction
776 + SpecNaming.AppendStr(name + "_"
777 + SpecNaming.Transition) + ", "
778 + SpecNaming.TransitionType + ", (void*) _"
779 + name + "_" + SpecNaming.Transition + "),", 2));
782 + SpecNaming.NamedFunction
784 + SpecNaming.AppendStr(name + "_"
785 + SpecNaming.PreCondition) + ", "
786 + SpecNaming.PreConditionType + ", (void*) ";
787 if (construct.preCondition.isEmpty()) {
788 line = line + SpecNaming.NullFunc + "),";
790 line = line + "_" + name + "_" + SpecNaming.PreCondition
793 code.addLine(TabbedLine(line, 2));
796 + SpecNaming.NamedFunction
798 + SpecNaming.AppendStr(name + "_"
799 + SpecNaming.PostCondition) + ", "
800 + SpecNaming.PostConditionType + ", (void*) ";
801 if (construct.postCondition.isEmpty()) {
802 line = line + SpecNaming.NullFunc + "),";
804 line = line + "_" + name + "_" + SpecNaming.PostCondition
807 code.addLine(TabbedLine(line, 2));
810 + SpecNaming.NamedFunction
812 + SpecNaming.AppendStr(name + "_"
813 + SpecNaming.PrintValue) + ", "
814 + SpecNaming.PrintValueType + ", (void*) ";
815 if (construct.print.isEmpty()) {
816 line = line + SpecNaming.NullFunc + ")";
818 line = line + "_" + name + "_" + SpecNaming.PrintValue
821 code.addLine(TabbedLine(line, 2));
822 code.addLine(TabbedLine(");"));
824 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
825 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
827 + SpecNaming.AddInterfaceFunctions
828 + Brace(SpecNaming.AppendStr(name) + ", "
829 + SpecNaming.StateFunctionsInst) + ";"));
834 // Create and instrument with the INIT annotation
835 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
836 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
837 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
838 + Brace(SpecNaming.SPEC_ANALYSIS
840 + SpecNaming.SpecAnnotation
841 + Brace(SpecNaming.AnnoTypeInit + ", "
842 + SpecNaming.AnnoInitInst)) + ";"));
852 * This function generates a list of lines that initialize the fields of the
853 * global state struct. See below.
858 * StateStruct *state = (StateStruct*) _M->state;
860 * IntList * q = state->q;
865 * In this example, _M --> methodInst, state --> inst.
873 * The global state construct
874 * @return The generated code
876 public static Code GenerateStateFieldsInitialization(String methodInst,
877 String inst, GlobalConstruct construct) {
878 Code res = new Code();
879 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
881 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
882 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
883 for (VariableDeclaration decl : construct.declState) {
884 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
892 * This function generates a list of lines that initialize the fields of a
893 * specific interface struct. See below.
898 * ENQ *info = (ENQ*) _M->value;
900 * IntList * q = info->q;
905 * In this example, ENQ --> structType, _M --> methodInst, info --> inst
913 * The corresponding interface construct
914 * @return The generated code
916 public static Code GenerateInterfaceFieldsInitialization(String methodInst,
917 String inst, InterfaceConstruct construct) {
918 Code res = new Code();
919 String name = construct.getName();
920 String structName = construct.getStructName();
921 res.addLine(ShortComment("Initialize fields for " + name));
922 // The very first assignment "
923 res.addLine(DeclareDefine(structName, "*" + inst, "(" + structName
924 + "*) " + methodInst + "->" + SpecNaming.MethodValueField));
925 // Don't leave out the RET field
926 if (!construct.getFunctionHeader().isReturnVoid()) {
927 res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
928 SpecNaming.RET, inst + "->" + SpecNaming.RET));
931 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
932 res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
940 * This function generates the code to be inserted right after the ordering
941 * point construct (instrumentation code)
945 * The corresponding ordering point construct
946 * @return The generated code
948 public static Code Generate4OPConstruct(OPConstruct construct) {
949 Code code = new Code();
950 String curLine = construct.annotation;
951 String label = construct.label;
952 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
953 if (!construct.condition.equals("true")) {
954 code.addLine(prefixTabs + "if (" + construct.condition + ")");
955 prefixTabs = prefixTabs + "\t";
958 switch (construct.type) {
960 code.addLine(prefixTabs + SpecNaming.CreateOPDefineAnnoFunc + "();");
962 case OPDefineUnattached:
963 code.addLine(prefixTabs + SpecNaming.CreateOPDefineUnattachedFunc
967 code.addLine(prefixTabs + SpecNaming.CreatePotentialOPAnnoFunc
968 + "(" + SpecNaming.AppendStr(label) + ");");
971 code.addLine(prefixTabs + SpecNaming.CreateOPCheckAnnoFunc + "("
972 + SpecNaming.AppendStr(label) + ");");
975 code.addLine(prefixTabs + SpecNaming.CreateOPClearAnnoFunc + "();");
978 code.addLine(prefixTabs + SpecNaming.CreateOPClearDefineAnnoFunc
981 case OPClearDefineUnattached:
982 code.addLine(prefixTabs
983 + SpecNaming.CreateOPClearDefineUnattachedFunc + "();");
993 * This function generates the code to be inserted right after the entry
994 * construct (instrumentation code)
998 * The corresponding entry construct
1001 public static Code Generate4Entry(EntryConstruct construct) {
1002 Code res = new Code();
1003 String curLine = construct.annotation;
1004 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1005 // _createInitAnnotation();
1006 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
1012 * This function generates the code to be inserted right after the "@Define"
1013 * construct (instrumentation code)
1017 * The corresponding entry construct
1020 public static Code Generate4Define(DefineConstruct construct) {
1021 Code code = new Code();
1023 code.addLine("/********** User-defined code in annotation (BEGIN) **********/");
1024 code.addLines(construct.code);
1025 code.addLine("/********** User-defined code in annotation (END) **********/");
1031 * This function generates the new interface wrapper code to be inserted
1032 * right after the end of the interface definition
1036 * The corresponding interface construct
1037 * @return The generated code
1039 public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
1040 Code code = new Code();
1042 String name = construct.getName();
1043 String structName = construct.getStructName();
1044 String beginLine = construct.getFunctionHeader().getHeaderLine();
1045 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
1046 Matcher matcherSpace = regexpSpace.matcher(beginLine);
1047 String prefixTabs = "";
1048 if (matcherSpace.find())
1049 prefixTabs = matcherSpace.group(1);
1051 // Add one line to separate
1053 code.addLine(prefixTabs
1054 + ShortComment("Generated wrapper interface for " + name));
1055 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
1057 code.addLine(beginLine + " {");
1059 code.addLine(beginLine);
1061 // Instrument with the INTERFACE_BEGIN annotations
1062 code.addLine(prefixTabs
1064 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1065 // CAnnoInterfaceInfo info = _createInterfaceBeginAnnotation(_DEQ_str);
1066 code.addLine(prefixTabs
1068 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1069 + SpecNaming.AnnoInterfaceInfoInst,
1070 SpecNaming.CreateInterfaceBeginAnnoFunc
1071 + Brace(SpecNaming.AppendStr(name))));
1072 // Call the actual function
1073 code.addLine(prefixTabs + "\t"
1074 + ShortComment("Call the actual function"));
1075 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1076 code.addLine(prefixTabs + "\t"
1077 + construct.getFunctionHeader().getRenamedCall() + ";");
1080 // Initialize the value struct
1081 code.addLine(prefixTabs + "\t"
1082 + ShortComment("Initialize the value struct"));
1083 // The very first assignment "
1084 code.addLine(prefixTabs
1086 + DeclareDefine(structName,
1087 "*" + SpecNaming.InterfaceValueInst, SpecNaming.New
1088 + Brace(structName)));
1089 // Don't leave out the RET field
1090 if (!construct.getFunctionHeader().isReturnVoid())
1091 code.addLine(prefixTabs
1093 + AssignToPtr(SpecNaming.InterfaceValueInst,
1094 SpecNaming.RET, SpecNaming.RET));
1096 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1097 code.addLine(prefixTabs
1099 + AssignToPtr(SpecNaming.InterfaceValueInst, decl.name,
1103 // Store the value info into the current MethodCall
1104 // _setInterfaceBeginAnnotationValue(info, value);
1105 code.addLine(prefixTabs
1107 + ShortComment("Store the value info into the current MethodCall"));
1108 code.addLine(prefixTabs
1110 + SpecNaming.SetInterfaceBeginAnnoValueFunc
1111 + Brace(SpecNaming.AnnoInterfaceInfoInst + ", "
1112 + SpecNaming.InterfaceValueInst) + ";");
1115 // Return if necessary
1116 if (!construct.getFunctionHeader().isReturnVoid())
1117 code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1118 code.addLine(prefixTabs + "}");
1125 * Write a list of lines (as the whole of the file) to a file ---
1126 * newFileName. If that file does not exist, we create that file and then
1130 * @param newFileName
1131 * The name of the file to be written
1133 * The list of lines that as a whole become the content of the
1136 public static void write2File(String newFileName, ArrayList<String> content) {
1137 File newFile = new File(newFileName);
1138 newFile.getParentFile().mkdirs();
1139 if (!newFile.exists()) {
1141 newFile.createNewFile();
1142 } catch (IOException e) {
1143 e.printStackTrace();
1146 BufferedWriter bw = null;
1148 bw = new BufferedWriter(new FileWriter(newFile));
1149 for (int i = 0; i < content.size(); i++) {
1150 bw.write(content.get(i) + "\n");
1153 } catch (IOException e) {
1154 e.printStackTrace();
1159 } catch (IOException e) {
1160 e.printStackTrace();