From 468e3b4f0570c70b43375b016eef803f66a37fe8 Mon Sep 17 00:00:00 2001 From: jzhou Date: Tue, 19 Oct 2010 00:01:31 +0000 Subject: [PATCH] Add support for 'static' fields in multicore gc version w/o tasks. Now we can have static fields and access static fields/methods with Class name. Static blocks are also supported but with very simple invocation solution. All the static blocks are executed right before executing the main method and are executed in random order. The initialization for the static field is not supported yet. --- Robust/src/IR/ClassDescriptor.java | 10 +++ Robust/src/IR/FieldDescriptor.java | 4 + Robust/src/IR/Flat/BuildCode.java | 88 ++++++++++++++++---- Robust/src/IR/Flat/BuildCodeMGC.java | 59 +++++++++---- Robust/src/IR/Flat/BuildCodeMultiCore.java | 9 +- Robust/src/IR/Flat/BuildFlat.java | 52 +++++++++--- Robust/src/IR/MethodDescriptor.java | 11 +++ Robust/src/IR/State.java | 16 ++++ Robust/src/IR/Tree/BuildIR.java | 25 +++++- Robust/src/IR/Tree/NameNode.java | 26 +++++- Robust/src/IR/Tree/SemanticCheck.java | 35 +++++++- Robust/src/IR/TypeDescriptor.java | 15 ++++ Robust/src/Main/Main.java | 2 +- Robust/src/Parse/java14.cup | 16 ++-- Robust/src/Runtime/bamboo/multicoreruntime.h | 2 + Robust/src/Tests/StaticTest.java | 40 +++++++++ 16 files changed, 355 insertions(+), 55 deletions(-) create mode 100644 Robust/src/Tests/StaticTest.java diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index ffae5094..648173a3 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -16,6 +16,8 @@ public class ClassDescriptor extends Descriptor { Vector fieldvec; SymbolTable flags; SymbolTable methods; + + int numstaticblocks=0; public ClassDescriptor(String classname) { this("", classname); @@ -146,4 +148,12 @@ public class ClassDescriptor extends Descriptor { public String getSuper() { return superclass; } + + public void incStaticBlocks() { + this.numstaticblocks++; + } + + public int getNumStaticBlocks() { + return this.numstaticblocks; + } } diff --git a/Robust/src/IR/FieldDescriptor.java b/Robust/src/IR/FieldDescriptor.java index 324d0c46..42951328 100644 --- a/Robust/src/IR/FieldDescriptor.java +++ b/Robust/src/IR/FieldDescriptor.java @@ -29,6 +29,10 @@ public class FieldDescriptor extends Descriptor { if (en!=null) throw new Error("Field initializers not implemented"); } + public boolean isStatic() { + return modifier.isStatic(); + } + public boolean isGlobal() { return isglobal; } diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 7979db02..c8ad8077 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -159,6 +159,7 @@ public class BuildCode { PrintWriter outtaskdefs=null; PrintWriter outoptionalarrays=null; PrintWriter optionalheaders=null; + PrintWriter outglobaldefs=null; try { if (state.SANDBOX) { @@ -167,6 +168,7 @@ public class BuildCode { outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true); outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true); outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true); + outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true); outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true); outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true); if (state.TASK) { @@ -228,19 +230,29 @@ public class BuildCode { // Output the C class declarations // These could mutually reference each other + outglobaldefs.println("#ifndef __GLOBALDEF_H_"); + outglobaldefs.println("#define __GLOBALDEF_H_"); + outglobaldefs.println(""); + outglobaldefs.println("struct global_defs_t {"); outclassdefs.println("#ifndef __CLASSDEF_H_"); outclassdefs.println("#define __CLASSDEF_H_"); - outputClassDeclarations(outclassdefs); + outputClassDeclarations(outclassdefs, outglobaldefs); // Output function prototypes and structures for parameters Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - generateCallStructs(cn, outclassdefs, outstructs, outmethodheader); + generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); } outclassdefs.println("#endif"); outclassdefs.close(); + outglobaldefs.println("};"); + outglobaldefs.println(""); + outglobaldefs.println("extern struct global_defs_t * global_defs_p;"); + outglobaldefs.println("#endif"); + outglobaldefs.flush(); + outglobaldefs.close(); if (state.TASK) { /* Map flags to integers */ @@ -627,6 +639,7 @@ public class BuildCode { } } + outmethod.println("struct global_defs_t * global_defs_p;"); //Store the sizes of classes & array elements generateSizeArray(outmethod); @@ -734,7 +747,7 @@ public class BuildCode { } } - protected void outputClassDeclarations(PrintWriter outclassdefs) { + protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs) { if (state.THREAD||state.DSM||state.SINGLETM) outclassdefs.println("#include "); outclassdefs.println("#ifndef INTPTR"); @@ -794,7 +807,7 @@ public class BuildCode { outclassdefs.println(" int * fses;"); } } - printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs); + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); if (state.STMARRAY) { outclassdefs.println(" int lowindex;"); @@ -812,6 +825,8 @@ public class BuildCode { outclassdefs.println("extern int hasflags[];"); outclassdefs.println("extern unsigned INTPTR * pointerarray[];"); outclassdefs.println("extern int supertypes[];"); + outclassdefs.println("#include \"globaldefs.h\""); + outclassdefs.println(""); } /** Prints out definitions for generic task structures */ @@ -1441,11 +1456,11 @@ public class BuildCode { /** Force consistent field ordering between inherited classes. */ - private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) { + private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout, PrintWriter globaldefout) { ClassDescriptor sp=cn.getSuperDesc(); if (sp!=null) - printClassStruct(sp, classdefout); + printClassStruct(sp, classdefout, globaldefout); if (!fieldorder.containsKey(cn)) { Vector fields=new Vector(); @@ -1463,7 +1478,11 @@ public class BuildCode { FieldDescriptor fd=(FieldDescriptor)fields.get(i); if (fd.getType().isClass()||fd.getType().isArray()) classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";"); - else + else if(fd.isStatic()) { + // static field + globaldefout.println(" "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";"); + classdefout.println(" "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";"); + } else classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";"); } } @@ -1506,7 +1525,7 @@ public class BuildCode { * passed in (when PRECISE GC is enabled) and (2) function * prototypes for the methods */ - protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) { + protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout) { /* Output class structure */ classdefout.println("struct "+cn.getSafeSymbol()+" {"); classdefout.println(" int type;"); @@ -1547,7 +1566,7 @@ public class BuildCode { classdefout.println(" int * fses;"); } } - printClassStruct(cn, classdefout); + printClassStruct(cn, classdefout, globaldefout); classdefout.println("};\n"); if (state.DSM||state.SINGLETM) { @@ -1991,6 +2010,21 @@ public class BuildCode { } } } + + if(fm.getMethod().isStaticBlock()) { + // a static block + } else if((fm.getMethod().getReturnType() == null) && (cn != null)){ + // is a constructor, check and output initialization of the static fields + Vector fields=(Vector)fieldorder.get(cn); + + for(int i=0; i"+fd.getSafeSymbol()+"=&(global_defs_p->"+cn.getSafeSymbol()+fd.getSafeSymbol()+");"); + } + } + } generateCode(fm.getNext(0), fm, lb, null, output, true); @@ -4634,7 +4668,12 @@ public class BuildCode { if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) { if (fc.getThis()!=null) { - TypeDescriptor ptd=md.getThis().getType(); + TypeDescriptor ptd=null; + if(md.getThis() != null) { + ptd = md.getThis().getType(); + } else { + ptd = fc.getThis().getType(); + } if (needcomma) output.print(","); if (ptd.isClass()&&!ptd.isArray()) @@ -4754,8 +4793,19 @@ public class BuildCode { } else{ // DEBUG if(!ffn.getDst().getType().isPrimitive()){ // DEBUG output.println("within((void*)"+generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+");"); -// DEBUG } - output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); +// DEBUG } + if(ffn.getField().isStatic()) { + // static field, redirect to the global_defs_p structure + if(ffn.getSrc().getType().isStatic()) { + // reference to the static field with Class name + output.println(generateTemp(fm, ffn.getDst(),lb)+"=global_defs_p->"+ ffn.getSrc().getType().getClassDesc().getSafeSymbol()+ffn.getField().getSafeSymbol()+";"); + } else { + output.println(generateTemp(fm, ffn.getDst(),lb)+"=*"+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } + //output.println(generateTemp(fm, ffn.getDst(),lb)+"=global_defs_p->"+ffn.getSrc().getType().getClassDesc().getSafeSymbol()+"->"+ ffn.getField().getSafeSymbol()+";"); + } else { + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } } } @@ -4856,8 +4906,18 @@ public class BuildCode { // DEBUG if(!fsfn.getField().getType().isPrimitive()){ // DEBUG output.println("within((void*)"+generateTemp(fm,fsfn.getSrc(),lb)+");"); -// DEBUG } - output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); +// DEBUG } + if(fsfn.getField().isStatic()) { + // static field, redirect to the global_defs_p structure + if(fsfn.getDst().getType().isStatic()) { + // reference to the static field with Class name + output.println("global_defs_p->" + fsfn.getDst().getType().getClassDesc().getSafeSymbol() + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } else { + output.println("*"+generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } + } else { + output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } } } diff --git a/Robust/src/IR/Flat/BuildCodeMGC.java b/Robust/src/IR/Flat/BuildCodeMGC.java index 85ffe663..dc115aea 100644 --- a/Robust/src/IR/Flat/BuildCodeMGC.java +++ b/Robust/src/IR/Flat/BuildCodeMGC.java @@ -2,28 +2,17 @@ package IR.Flat; import java.io.FileOutputStream; import java.io.PrintWriter; -import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; -import java.util.LinkedList; -import java.util.Queue; -import java.util.Set; -import java.util.Vector; - -import Analysis.Locality.LocalityBinding; -import Analysis.Scheduling.Schedule; -import Analysis.TaskStateAnalysis.FEdge; -import Analysis.TaskStateAnalysis.FlagState; -import Analysis.TaskStateAnalysis.SafetyAnalysis; -import Analysis.OwnershipAnalysis.AllocationSite; -import Analysis.OwnershipAnalysis.OwnershipAnalysis; -import Analysis.OwnershipAnalysis.HeapRegionNode; + import Analysis.Prefetch.*; +import Analysis.TaskStateAnalysis.SafetyAnalysis; import IR.ClassDescriptor; import IR.Descriptor; import IR.FlagDescriptor; import IR.MethodDescriptor; import IR.State; +import IR.SymbolTable; import IR.TagVarDescriptor; import IR.TaskDescriptor; import IR.TypeDescriptor; @@ -59,6 +48,7 @@ public class BuildCodeMGC extends BuildCode { public void buildCode() { /* Create output streams to write to */ PrintWriter outclassdefs=null; + PrintWriter outglobaldefs=null; PrintWriter outstructs=null; PrintWriter outmethodheader=null; PrintWriter outmethod=null; @@ -68,6 +58,7 @@ public class BuildCodeMGC extends BuildCode { outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true); outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true); outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true); + outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true); outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true); outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true); } catch (Exception e) { @@ -86,18 +77,32 @@ public class BuildCodeMGC extends BuildCode { /* Output Structures */ super.outputStructs(outstructs); + outglobaldefs.println("#ifndef __GLOBALDEF_H_"); + outglobaldefs.println("#define __GLOBALDEF_H_"); + outglobaldefs.println(""); + outglobaldefs.println("struct global_defs_t {"); + // Output the C class declarations - // These could mutually reference each other - super.outputClassDeclarations(outclassdefs); + // These could mutually reference each other + outclassdefs.println("#ifndef __CLASSDEF_H_"); + outclassdefs.println("#define __CLASSDEF_H_"); + super.outputClassDeclarations(outclassdefs, outglobaldefs); // Output function prototypes and structures for parameters Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); int numclasses = this.state.numClasses(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader); + super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); } + outclassdefs.println("#endif"); outclassdefs.close(); + outglobaldefs.println("};"); + outglobaldefs.println(""); + outglobaldefs.println("extern struct global_defs_t * global_defs_p;"); + outglobaldefs.println("#endif"); + outglobaldefs.flush(); + outglobaldefs.close(); /* Build the actual methods */ super.outputMethods(outmethod); @@ -135,6 +140,24 @@ public class BuildCodeMGC extends BuildCode { outmethod.println("int mgc_main(int argc, const char *argv[]) {"); outmethod.println(" int i;"); + // execute all the static blocks in random order + // TODO may need more careful about the execution order + SymbolTable sbt = this.state.getStaticBlockSymbolTable(); + Iterator it_staticblocks = state.getStaticBlockSymbolTable().getDescriptorsIterator(); + while(it_staticblocks.hasNext()) { + MethodDescriptor t_md = (MethodDescriptor) it_staticblocks.next(); + ClassDescriptor t_cd = t_md.getClassDesc(); + outmethod.println(" {"); + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { + outmethod.print(" struct "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + outmethod.println("1, NULL};"); + outmethod.println(" "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + outmethod.println(" "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } + outmethod.println(" }"); + } + if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);"); } else { @@ -148,7 +171,7 @@ public class BuildCodeMGC extends BuildCode { outmethod.println(" struct ___String___ *newstring=NewString(argv[i], length);"); } outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;"); - outmethod.println(" }"); + outmethod.println(" }"); MethodDescriptor md=typeutil.getMain(); ClassDescriptor cd=typeutil.getMainClass(); diff --git a/Robust/src/IR/Flat/BuildCodeMultiCore.java b/Robust/src/IR/Flat/BuildCodeMultiCore.java index ba46a7a8..d2d59b45 100644 --- a/Robust/src/IR/Flat/BuildCodeMultiCore.java +++ b/Robust/src/IR/Flat/BuildCodeMultiCore.java @@ -97,6 +97,7 @@ public class BuildCodeMultiCore extends BuildCode { public void buildCode() { /* Create output streams to write to */ PrintWriter outclassdefs=null; + PrintWriter outglobaldefs=null; PrintWriter outstructs=null; PrintWriter outmethodheader=null; PrintWriter outmethod=null; @@ -110,6 +111,7 @@ public class BuildCodeMultiCore extends BuildCode { outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true); outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true); outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true); + outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true); outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true); outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true); if (state.TASK) { @@ -144,15 +146,18 @@ public class BuildCodeMultiCore extends BuildCode { // Output the C class declarations // These could mutually reference each other - super.outputClassDeclarations(outclassdefs); + outclassdefs.println("#ifndef __CLASSDEF_H_"); + outclassdefs.println("#define __CLASSDEF_H_"); + super.outputClassDeclarations(outclassdefs, outglobaldefs); // Output function prototypes and structures for parameters Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); int numclasses = this.state.numClasses(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader); + super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); } + outclassdefs.println("#endif"); outclassdefs.close(); if (state.TASK) { diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index 5c70bf8b..fc42219f 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -480,11 +480,19 @@ public class BuildFlat { } private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) { - TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType()); - NodePair npe=flattenExpressionNode(fan.getExpression(),tmp); - FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp); - npe.getEnd().addNext(fn); - return new NodePair(npe.getBegin(),fn); + TempDescriptor tmp=null; + if(fan.getExpression().getType().isStatic()) { + // static field dereference with class name + tmp = new TempDescriptor(fan.getExpression().getType().getClassDesc().getSymbol(), fan.getExpression().getType()); + FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp); + return new NodePair(fn,fn); + } else { + tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType()); + NodePair npe=flattenExpressionNode(fan.getExpression(),tmp); + FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp); + npe.getEnd().addNext(fn); + return new NodePair(npe.getBegin(),fn); + } } private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) { @@ -541,8 +549,17 @@ public class BuildFlat { FieldAccessNode fan=(FieldAccessNode)an.getDest(); ExpressionNode en=fan.getExpression(); - TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); - NodePair np_baseexp=flattenExpressionNode(en, dst_tmp); + TempDescriptor dst_tmp=null; + NodePair np_baseexp=null; + if(en.getType().isStatic()) { + // static field dereference with class name + dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType()); + FlatNop nop=new FlatNop(); + np_baseexp = new NodePair(nop,nop); + } else { + dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); + np_baseexp=flattenExpressionNode(en, dst_tmp); + } if (first==null) first=np_baseexp.getBegin(); else @@ -661,8 +678,17 @@ public class BuildFlat { //It is a field FieldAccessNode fan=(FieldAccessNode)nn.getExpression(); ExpressionNode en=fan.getExpression(); - TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); - NodePair np_baseexp=flattenExpressionNode(en, dst_tmp); + TempDescriptor dst_tmp=null; + NodePair np_baseexp=null; + if(en.getType().isStatic()) { + // static field dereference with class name + dst_tmp = new TempDescriptor(en.getType().getClassDesc().getSymbol(), en.getType()); + FlatNop nop=new FlatNop(); + np_baseexp = new NodePair(nop,nop); + } else { + dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); + np_baseexp=flattenExpressionNode(en, dst_tmp); + } if (first==null) first=np_baseexp.getBegin(); else @@ -740,7 +766,13 @@ public class BuildFlat { } } - FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp); + FlatSetFieldNode fsfn=null; + if(nn.getClassDesc()!=null) { + // this is a static field access inside of a static block + fsfn=new FlatSetFieldNode(new TempDescriptor("sfsb", nn.getClassType()), nn.getField(), src_tmp); + } else { + fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp); + } if (first==null) { first=fsfn; } else { diff --git a/Robust/src/IR/MethodDescriptor.java b/Robust/src/IR/MethodDescriptor.java index 27423619..5e556cc9 100644 --- a/Robust/src/IR/MethodDescriptor.java +++ b/Robust/src/IR/MethodDescriptor.java @@ -19,6 +19,7 @@ public class MethodDescriptor extends Descriptor { protected ClassDescriptor cd; protected VarDescriptor thisvd; protected boolean isglobal; + protected boolean isstaticblock; public MethodDescriptor(Modifiers m, TypeDescriptor rt, String identifier) { super(identifier); @@ -30,6 +31,7 @@ public class MethodDescriptor extends Descriptor { params=new Vector(); paramtable=new SymbolTable(); thisvd=null; + isstaticblock = false; } public Modifiers getModifiers() { @@ -68,12 +70,21 @@ public class MethodDescriptor extends Descriptor { params=new Vector(); paramtable=new SymbolTable(); thisvd=null; + isstaticblock = false; } public boolean isGlobal() { return isglobal; } + + public boolean isStaticBlock() { + return isstaticblock; + } + + public void setAsStaticBlock() { + isstaticblock = true; + } public void setThis(VarDescriptor vd) { thisvd=vd; diff --git a/Robust/src/IR/State.java b/Robust/src/IR/State.java index 3844d94d..2b849e80 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -11,6 +11,7 @@ public class State { public State() { this.classes=new SymbolTable(); this.tasks=new SymbolTable(); + this.staticblocks=new SymbolTable(); this.treemethodmap=new Hashtable(); this.flatmethodmap=new Hashtable(); this.parsetrees=new HashSet(); @@ -166,6 +167,7 @@ public class State { public Vector classpath; public SymbolTable classes; public SymbolTable tasks; + public SymbolTable staticblocks; public Set parsetrees; public Hashtable treemethodmap; public Hashtable flatmethodmap; @@ -173,6 +175,7 @@ public class State { public Hashtable arraytonumber; private int numclasses=1; // start from 1 instead of 0 for multicore gc private int numtasks=0; + private int numstaticblocks=0; private int arraycount=0; public boolean OPTIMIZE=false; @@ -229,9 +232,18 @@ public class State { numclasses++; } + public void addStaticBlock(MethodDescriptor sbn) { + staticblocks.add(sbn); + numstaticblocks++; + } + public int numClasses() { return numclasses; } + + public int numStaticBlocks() { + return numstaticblocks; + } public BlockNode getMethodBody(MethodDescriptor md) { return (BlockNode)treemethodmap.get(md); @@ -248,6 +260,10 @@ public class State { public SymbolTable getTaskSymbolTable() { return tasks; } + + public SymbolTable getStaticBlockSymbolTable() { + return staticblocks; + } /** Returns Flat IR representation of MethodDescriptor md. */ diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 3d47b148..7e5c1929 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -250,12 +250,14 @@ public class BuildIR { parseClassMember(cn,decl); } else if (isNode(decl,"constructor")) { parseConstructorDecl(cn,decl.getChild("constructor_declaration")); - } else if (isNode(decl,"block")) { + } else if (isNode(decl, "static_block")) { + parseStaticBlockDecl(cn, decl.getChild("static_block_declaration")); + } else if (isNode(decl,"block")) { } else throw new Error(); } } } - + private void parseClassMember(ClassDescriptor cn, ParseNode pn) { ParseNode fieldnode=pn.getChild("field"); @@ -648,6 +650,25 @@ public class BuildIR { } state.addTreeCode(md,bn); } + + private void parseStaticBlockDecl(ClassDescriptor cn, ParseNode pn) { + Modifiers m=new Modifiers(); + m.addModifier(Modifiers.STATIC); + MethodDescriptor md=new MethodDescriptor(m, "staticblock"+cn.getNumStaticBlocks(), false); + //md.setClassDesc(cn); + md.setAsStaticBlock(); + ParseNode bodyn=pn.getChild("body");; + cn.addMethod(md); + cn.incStaticBlocks(); + BlockNode bn=null; + if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null) + bn=parseBlock(bodyn); + else + bn=new BlockNode(); + state.addTreeCode(md,bn); + state.addStaticBlock(md); + } + public BlockNode parseBlock(ParseNode pn) { this.m_taskexitnum = 0; diff --git a/Robust/src/IR/Tree/NameNode.java b/Robust/src/IR/Tree/NameNode.java index 008c3964..e2634647 100644 --- a/Robust/src/IR/Tree/NameNode.java +++ b/Robust/src/IR/Tree/NameNode.java @@ -5,22 +5,33 @@ import IR.VarDescriptor; import IR.TagVarDescriptor; import IR.TypeDescriptor; import IR.FieldDescriptor; +import IR.ClassDescriptor; public class NameNode extends ExpressionNode { NameDescriptor name; Descriptor vd; FieldDescriptor fd; ExpressionNode en; + ClassDescriptor cd; public NameNode(NameDescriptor nd) { this.name=nd; this.vd=null; this.fd=null; + this.cd = null; } public ExpressionNode getExpression() { return en; } + + public ClassDescriptor getClassDesc() { + return this.cd; + } + + public void setClassDesc(ClassDescriptor cd) { + this.cd = cd; + } /* Gross hack */ public void setExpression(ExpressionNode en) { @@ -58,9 +69,22 @@ public class NameNode extends ExpressionNode { return fd.getType(); } else if (isTag()) return new TypeDescriptor(TypeDescriptor.TAG); - else + else if(cd != null) { + TypeDescriptor tp = new TypeDescriptor(cd); + tp.setStatic(); + return tp; + } else return ((VarDescriptor)vd).getType(); } + + public TypeDescriptor getClassType() { + if(cd != null) { + TypeDescriptor tp = new TypeDescriptor(cd); + tp.setStatic(); + return tp; + } else + return null; + } NameDescriptor getName() { return name; diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index e8ddffce..10d68bd3 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -1,6 +1,7 @@ package IR.Tree; import java.util.*; + import IR.*; public class SemanticCheck { @@ -492,8 +493,14 @@ public class SemanticCheck { FieldDescriptor fd=null; if (ltd.isArray()&&fieldname.equals("length")) fd=FieldDescriptor.arrayLength; - else + else fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname); + if(ltd.isStatic()) { + // check if this field is a static field + if(!fd.isStatic()) { + throw new Error("Dereference of the non-static field "+ fieldname + " in "+fan.printNode(0)+" in "+md); + } + } if (fd==null) throw new Error("Unknown field "+fieldname + " in "+fan.printNode(0)+" in "+md); @@ -572,7 +579,31 @@ public class SemanticCheck { String varname=nd.toString(); Descriptor d=(Descriptor)nametable.get(varname); if (d==null) { - throw new Error("Name "+varname+" undefined in: "+md); + ClassDescriptor cd = null; + if(((MethodDescriptor)md).isStaticBlock()) { + // this is a static block, all the accessed fields should be static field + cd = ((MethodDescriptor)md).getClassDesc(); + SymbolTable fieldtbl = cd.getFieldTable(); + FieldDescriptor fd=(FieldDescriptor)fieldtbl.get(varname); + if((fd == null) || (!fd.isStatic())){ + // no such field in the class or it is not a static field + throw new Error("Name "+varname+" should not be used in static block: "+md); + } else { + // this is a static field + nn.setField(fd); + nn.setClassDesc(cd); + return; + } + } else { + cd=getClass(varname); + if(cd != null) { + // this is a class name + nn.setClassDesc(cd); + return; + } else { + throw new Error("Name "+varname+" undefined in: "+md); + } + } } if (d instanceof VarDescriptor) { nn.setVar(d); diff --git a/Robust/src/IR/TypeDescriptor.java b/Robust/src/IR/TypeDescriptor.java index f039f652..c306e4b4 100644 --- a/Robust/src/IR/TypeDescriptor.java +++ b/Robust/src/IR/TypeDescriptor.java @@ -25,6 +25,7 @@ public class TypeDescriptor extends Descriptor { int arraycount; private int type; ClassDescriptor class_desc; + boolean isStatic = false; public boolean equals(Object o) { if (o instanceof TypeDescriptor) { @@ -33,6 +34,8 @@ public class TypeDescriptor extends Descriptor { return false; if ((type==CLASS)&&(!t.getSymbol().equals(getSymbol()))) return false; + if (isStatic != t.isStatic) + return false; if (t.arraycount!=arraycount) return false; return true; @@ -49,6 +52,14 @@ public class TypeDescriptor extends Descriptor { return false; return true; } + + public boolean isStatic() { + return this.isStatic; + } + + public void setStatic() { + this.isStatic = true; + } public int hashCode() { int hashcode=type^arraycount; @@ -258,6 +269,7 @@ public class TypeDescriptor extends Descriptor { this.type=CLASS; this.class_desc=null; this.arraycount=0; + this.isStatic =false; } public TypeDescriptor(String st) { @@ -265,6 +277,7 @@ public class TypeDescriptor extends Descriptor { this.type=CLASS; this.class_desc=null; this.arraycount=0; + this.isStatic =false; } public ClassDescriptor getClassDesc() { @@ -276,12 +289,14 @@ public class TypeDescriptor extends Descriptor { this.type=CLASS; this.class_desc=cd; this.arraycount=0; + this.isStatic =false; } public TypeDescriptor(int t) { super(decodeInt(t)); this.type=t; this.arraycount=0; + this.isStatic =false; } public String toString() { diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index e95f14c9..0874728e 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -415,7 +415,7 @@ public class Main { if (state.TASK) { sc.getClass("TagDescriptor"); } - if (state.THREAD||state.DSM||state.SINGLETM) { + if (state.THREAD||state.DSM||state.SINGLETM||state.MGC) { sc.getClass("Thread"); } diff --git a/Robust/src/Parse/java14.cup b/Robust/src/Parse/java14.cup index 3b03115c..477ea95a 100644 --- a/Robust/src/Parse/java14.cup +++ b/Robust/src/Parse/java14.cup @@ -151,7 +151,7 @@ non terminal ParseNode formal_parameter; //non terminal ParseNode class_type_list; non terminal ParseNode method_body; // 19.8.4) Static Initializers -//non terminal ParseNode static_initializer; +non terminal ParseNode static_initializer; // 19.8.5) Constructor Declarations non terminal ParseNode constructor_declaration, constructor_declarator; non terminal ParseNode constructor_body; @@ -785,7 +785,9 @@ class_body_declaration ::= class_member_declaration:member {: RESULT=(new ParseNode("member")).addChild(member).getRoot(); :} -// | static_initializer + | static_initializer:block{: + RESULT=(new ParseNode("static_block")).addChild(block).getRoot(); + :} | constructor_declaration:constructor {: RESULT=(new ParseNode("constructor")).addChild(constructor).getRoot(); :} @@ -969,9 +971,13 @@ method_body ::= block:block {: ; // 19.8.4) Static Initializers -//static_initializer ::= -// STATIC block -// ; +static_initializer ::= + STATIC block:body {: + ParseNode pn=new ParseNode("static_block_declaration"); + pn.addChild("body").addChild(body); + RESULT=pn; + :} + ; // 19.8.5) Constructor Declarations constructor_declaration ::= diff --git a/Robust/src/Runtime/bamboo/multicoreruntime.h b/Robust/src/Runtime/bamboo/multicoreruntime.h index bcff03a3..e8641920 100644 --- a/Robust/src/Runtime/bamboo/multicoreruntime.h +++ b/Robust/src/Runtime/bamboo/multicoreruntime.h @@ -38,8 +38,10 @@ bool reside; // mutex + thread counter + start pointer + end pointer #ifdef GC_SMALLPAGESIZE #define BAMBOO_THREAD_QUEUE_SIZE (1024 * 1024) +#define BAMBOO_GLOBAL_DEFS_SIZE (1024 * 1024) #else #define BAMBOO_THREAD_QUEUE_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024) +#define BAMBOO_GLOBAL_DEFS_SIZE (BAMBOO_SMEM_SIZE) #endif // data structures for threads INTPTR * bamboo_thread_queue; diff --git a/Robust/src/Tests/StaticTest.java b/Robust/src/Tests/StaticTest.java new file mode 100644 index 00000000..168c2b6f --- /dev/null +++ b/Robust/src/Tests/StaticTest.java @@ -0,0 +1,40 @@ +class StaticTester { + static int i; // = 47; + + static { + i = 47; + } + + public StaticTester() {} +} + +class Incrementable { + static void increment() { StaticTester.i++; } + + public Incrementable() {} +} + +public class StaticTest{ + public StaticTest() { + } + + public static void main(String[] st) { + //StaticTester.i = 47; + StaticTester st1 = new StaticTester(); + StaticTester st2 = new StaticTester(); + System.printString("static i: "+StaticTester.i+"\n"); + System.printString("st1 i: "+st1.i+"\n"); + System.printString("st2 i: "+st2.i+"\n"); + + Incrementable incr = new Incrementable(); + incr.increment(); + System.printString("static i: "+StaticTester.i+"\n"); + System.printString("st1 i: "+st1.i+"\n"); + System.printString("st2 i: "+st2.i+"\n"); + + Incrementable.increment(); + System.printString("static i: "+StaticTester.i+"\n"); + System.printString("st1 i: "+st1.i+"\n"); + System.printString("st2 i: "+st2.i+"\n"); + } +} \ No newline at end of file -- 2.34.1