+ private void computeReadOnly(LocalityBinding lb, Hashtable<FlatNode, Set<TypeDescriptor>> updatedtypemap, Hashtable<FlatNode, Set<FieldDescriptor>> updatedfieldmap) {
+ //inside of transaction, try to convert rw access to ro access
+ MethodDescriptor md=lb.getMethod();
+ FlatMethod fm=state.getMethodFlat(md);
+ Hashtable<FlatNode, Integer> atomictable=locality.getAtomic(lb);
+
+ HashSet<FlatNode> toanalyze=new HashSet<FlatNode>();
+ toanalyze.addAll(fm.getNodeSet());
+
+ while(!toanalyze.isEmpty()) {
+ FlatNode fn=toanalyze.iterator().next();
+ toanalyze.remove(fn);
+ HashSet<TypeDescriptor> updatetypeset=new HashSet<TypeDescriptor>();
+ HashSet<FieldDescriptor> updatefieldset=new HashSet<FieldDescriptor>();
+
+ //Stop if we aren't in a transaction
+ if (atomictable.get(fn).intValue()==0)
+ continue;
+
+ //Do merge of all exits
+ for(int i=0;i<fn.numNext();i++) {
+ FlatNode fnnext=fn.getNext(i);
+ if (updatedtypemap.containsKey(fnnext)) {
+ updatetypeset.addAll(updatedtypemap.get(fnnext));
+ }
+ if (updatedfieldmap.containsKey(fnnext)) {
+ updatefieldset.addAll(updatedfieldmap.get(fnnext));
+ }
+ }
+
+ //process this node
+ if (cannotdelaymap!=null&&cannotdelaymap.containsKey(lb)&&cannotdelaymap.get(lb).contains(fn)!=inclusive) {
+ switch(fn.kind()) {
+ case FKind.FlatSetFieldNode: {
+ FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
+ updatefieldset.add(fsfn.getField());
+ break;
+ }
+ case FKind.FlatSetElementNode: {
+ FlatSetElementNode fsen=(FlatSetElementNode)fn;
+ updatetypeset.addAll(typeanalysis.expand(fsen.getDst().getType()));
+ break;
+ }
+ case FKind.FlatCall: {
+ FlatCall fcall=(FlatCall)fn;
+ MethodDescriptor mdfc=fcall.getMethod();
+
+ //get modified fields
+ Set<FieldDescriptor> fields=gft.getFieldsAll(mdfc);
+ updatefieldset.addAll(fields);
+
+ //get modified arrays
+ Set<TypeDescriptor> arrays=gft.getArraysAll(mdfc);
+ updatetypeset.addAll(typeanalysis.expandSet(arrays));
+ break;
+ }
+ }
+ }
+
+ if (!updatedtypemap.containsKey(fn)||!updatedfieldmap.containsKey(fn)||
+ !updatedtypemap.get(fn).equals(updatetypeset)||!updatedfieldmap.get(fn).equals(updatefieldset)) {
+ updatedtypemap.put(fn, updatetypeset);
+ updatedfieldmap.put(fn, updatefieldset);
+ for(int i=0;i<fn.numPrev();i++) {
+ toanalyze.add(fn.getPrev(i));
+ }
+ }
+ }
+ }
+