Program: 37615
Project: 37615
Buggy source:
/** 
 * ��κ����Ѥ�Ԥ������ɤ��������롣<br> ̿������ˤϡ�1������removemem̿�᤬����Ƥ��ƤϤ����ʤ��� ̿����κǸ��proceed̿��Ǥʤ���Фʤ�ʤ���
 * @param head �إå�̿����
 * @param body �ܥǥ�̿����
 */
private static void reuseMem(List<Instruction> head,List<Instruction> body){
  Instruction spec=body.get(0);
  if (spec.getKind() != Instruction.SPEC) {
    return;
  }
  Instruction last=body.get(body.size() - 1);
  if (last.getKind() != Instruction.PROCEED) {
    return;
  }
  for (Iterator<Instruction> itb=body.iterator(); itb.hasNext(); ) {
    int itbKind=itb.next().getKind();
    if (itbKind == Instruction.COPYCELLS || itbKind == Instruction.DROPMEM)     return;
  }
  HashMap<Integer,Integer> reuseMap=new HashMap<Integer,Integer>();
  HashSet<Integer> reuseMems=new HashSet<Integer>();
  HashMap parent=new HashMap();
  HashMap<Integer,List<Integer>> removedChildren=new HashMap<Integer,List<Integer>>();
  HashMap<Integer,List<Integer>> createdChildren=new HashMap<Integer,List<Integer>>();
  HashMap<Integer,List<Integer>> pourMap=new HashMap<Integer,List<Integer>>();
  HashSet pourMems=new HashSet();
  HashMap<Integer,List<Integer>> copyRulesMap=new HashMap<Integer,List<Integer>>();
  for (  Instruction inst : body) {
switch (inst.getKind()) {
case Instruction.REMOVEMEM:
      parent.put(inst.getArg1(),inst.getArg2());
    addToMap(removedChildren,inst.getArg2(),inst.getArg1());
  break;
case Instruction.NEWMEM:
parent.put(inst.getArg1(),inst.getArg2());
addToMap(createdChildren,inst.getArg2(),inst.getArg1());
break;
case Instruction.MOVECELLS:
addToMap(pourMap,inst.getArg1(),inst.getArg2());
pourMems.add(inst.getArg2());
break;
case Instruction.COPYRULES:
addToMap(copyRulesMap,inst.getArg2(),inst.getArg1());
break;
}
}
createReuseMap(reuseMap,reuseMems,parent,removedChildren,createdChildren,pourMap,pourMems,new Integer(0));
HashSet<Integer> set=new HashSet<Integer>();
for (Iterator<Integer> it=reuseMap.keySet().iterator(); it.hasNext(); ) {
Integer i1=it.next();
Integer i2=reuseMap.get(i1);
Integer p1=(Integer)parent.get(i1);
Integer p2=(Integer)parent.get(i2);
if (reuseMap.containsKey(p1)) {
p1=reuseMap.get(p1);
}
if (p1.equals(p2)) {
set.add(i1);
set.add(i2);
}
}
HashMap<Integer,Integer> ruleMem=new HashMap<Integer,Integer>();
HashMap<Integer,Integer> varInBody=new HashMap<Integer,Integer>();
Instruction react=head.get(head.size() - 1);
if (react.getKind() != Instruction.REACT && react.getKind() != Instruction.JUMP) {
return;
}
int i=0;
List args=(List)react.getArg2();
for (Iterator it=args.iterator(); it.hasNext(); ) {
varInBody.put((Integer)it.next(),new Integer(i++));
}
for (Iterator<Instruction> it=head.iterator(); it.hasNext(); ) {
Instruction inst=it.next();
if (inst.getKind() == Instruction.NORULES) {
varInBody.remove(inst.getArg1());
}
}
ArrayList<Instruction> tmpInsts=new ArrayList<Instruction>();
int nextArg=spec.getIntArg2();
for (Iterator<Integer> it=varInBody.keySet().iterator(); it.hasNext(); ) {
Integer memInHead=it.next();
Integer mem=varInBody.get(memInHead);
if (reuseMems.contains(mem)) {
List<Integer> copyRulesTo=copyRulesMap.get(mem);
boolean flg=false;
if (copyRulesTo == null) {
tmpInsts.add(new Instruction(Instruction.CLEARRULES,mem));
}
 else {
for (Integer dstmem : copyRulesTo) {
if (mem.equals(reuseMap.get(dstmem))) {
flg=true;
break;
}
}
if (!flg) {
ruleMem.put(mem,new Integer(nextArg));
tmpInsts.add(new Instruction(Instruction.ALLOCMEM,nextArg));
tmpInsts.add(new Instruction(Instruction.COPYRULES,nextArg,mem));
tmpInsts.add(new Instruction(Instruction.CLEARRULES,mem));
nextArg++;
}
}
}
}
body.addAll(1,tmpInsts);
ListIterator<Instruction> lit=body.listIterator();
while (lit.hasNext()) {
Instruction inst=lit.next();
switch (inst.getKind()) {
case Instruction.REMOVEMEM:
if (set.contains(inst.getArg1())) {
lit.remove();
}
break;
case Instruction.NEWMEM:
Integer arg1=(Integer)inst.getArg1();
if (reuseMap.containsKey(arg1)) {
lit.remove();
int m=((Integer)reuseMap.get(arg1)).intValue();
if (!set.contains(arg1)) {
lit.add(new Instruction(Instruction.ADDMEM,inst.getIntArg2(),m));
}
lit.add(new Instruction(Instruction.ENQUEUEMEM,m));
}
break;
case Instruction.MOVECELLS:
if (reuseMems.contains(inst.getArg2())) {
lit.remove();
}
break;
case Instruction.COPYRULES:
Integer srcmem=(Integer)inst.getArg2();
Integer dstmem=(Integer)inst.getArg1();
if (ruleMem.containsKey(srcmem)) {
if (!ruleMem.get(srcmem).equals(dstmem)) {
lit.remove();
lit.add(new Instruction(Instruction.COPYRULES,dstmem.intValue(),((Integer)ruleMem.get(srcmem)).intValue()));
}
}
 else if (srcmem.equals(reuseMap.get(dstmem))) {
lit.remove();
}
break;
case Instruction.FREEMEM:
if (reuseMems.contains(inst.getArg1())) {
lit.remove();
}
break;
}
}
lit.previous();
addUnlockInst(lit,reuseMap,new Integer(0),createdChildren);
for (Iterator<Integer> it=ruleMem.values().iterator(); it.hasNext(); ) {
lit.add(new Instruction(Instruction.FREEMEM,it.next()));
}
spec.updateSpec(spec.getIntArg1(),nextArg);
Instruction.changeMemVar(body,reuseMap);
}

Fixed version (ground truth):
/** 
 * ��κ����Ѥ�Ԥ������ɤ��������롣<br> ̿������ˤϡ�1������removemem̿�᤬����Ƥ��ƤϤ����ʤ��� ̿����κǸ��proceed̿��Ǥʤ���Фʤ�ʤ���
 * @param head �إå�̿����
 * @param body �ܥǥ�̿����
 */
private static void reuseMem(List<Instruction> head,List<Instruction> body){
  Instruction spec=body.get(0);
  if (spec.getKind() != Instruction.SPEC) {
    return;
  }
  Instruction last=body.get(body.size() - 1);
  if (last.getKind() != Instruction.PROCEED) {
    return;
  }
  for (Iterator<Instruction> itb=body.iterator(); itb.hasNext(); ) {
    int itbKind=itb.next().getKind();
    if (itbKind == Instruction.COPYCELLS || itbKind == Instruction.DROPMEM)     return;
  }
  HashMap<Integer,Integer> reuseMap=new HashMap<Integer,Integer>();
  HashSet<Integer> reuseMems=new HashSet<Integer>();
  HashMap parent=new HashMap();
  HashMap<Integer,List<Integer>> removedChildren=new HashMap<Integer,List<Integer>>();
  HashMap<Integer,List<Integer>> createdChildren=new HashMap<Integer,List<Integer>>();
  HashMap<Integer,List<Integer>> pourMap=new HashMap<Integer,List<Integer>>();
  HashSet pourMems=new HashSet();
  HashMap<Integer,List<Integer>> copyRulesMap=new HashMap<Integer,List<Integer>>();
  HashMap<Integer,String> headMemName=new HashMap<Integer,String>();
  HashMap<Integer,String> bodyMemName=new HashMap<Integer,String>();
  for (  Instruction inst : body) {
switch (inst.getKind()) {
case Instruction.REMOVEMEM:
      parent.put(inst.getArg1(),inst.getArg2());
    addToMap(removedChildren,inst.getArg2(),inst.getArg1());
  break;
case Instruction.NEWMEM:
parent.put(inst.getArg1(),inst.getArg2());
addToMap(createdChildren,inst.getArg2(),inst.getArg1());
break;
case Instruction.MOVECELLS:
addToMap(pourMap,inst.getArg1(),inst.getArg2());
pourMems.add(inst.getArg2());
break;
case Instruction.COPYRULES:
addToMap(copyRulesMap,inst.getArg2(),inst.getArg1());
break;
}
}
for (Instruction inst : head) {
switch (inst.getKind()) {
case Instruction.LOCKMEM:
headMemName.put((Integer)inst.getArg1(),(String)inst.getArg3());
break;
case Instruction.ANYMEM:
headMemName.put((Integer)inst.getArg1(),(String)inst.getArg4());
break;
case Instruction.ANYMEM2:
headMemName.put((Integer)inst.getArg1(),(String)inst.getArg5());
break;
case Instruction.GETMEM:
headMemName.put((Integer)inst.getArg1(),(String)inst.getArg4());
break;
}
}
for (Instruction inst : body) {
switch (inst.getKind()) {
case Instruction.SETMEMNAME:
bodyMemName.put((Integer)inst.getArg1(),(String)inst.getArg2());
}
}
createReuseMap(reuseMap,reuseMems,parent,removedChildren,createdChildren,pourMap,pourMems,new Integer(0));
HashSet<Integer> set=new HashSet<Integer>();
for (Iterator<Integer> it=reuseMap.keySet().iterator(); it.hasNext(); ) {
Integer i1=it.next();
Integer i2=reuseMap.get(i1);
Integer p1=(Integer)parent.get(i1);
Integer p2=(Integer)parent.get(i2);
if (reuseMap.containsKey(p1)) {
p1=reuseMap.get(p1);
}
if (p1.equals(p2)) {
set.add(i1);
set.add(i2);
}
}
HashMap<Integer,Integer> ruleMem=new HashMap<Integer,Integer>();
HashMap<Integer,Integer> varInBody=new HashMap<Integer,Integer>();
Instruction react=head.get(head.size() - 1);
if (react.getKind() != Instruction.REACT && react.getKind() != Instruction.JUMP) {
return;
}
int i=0;
List args=(List)react.getArg2();
for (Iterator it=args.iterator(); it.hasNext(); ) {
varInBody.put((Integer)it.next(),new Integer(i++));
}
for (Iterator<Instruction> it=head.iterator(); it.hasNext(); ) {
Instruction inst=it.next();
if (inst.getKind() == Instruction.NORULES) {
varInBody.remove(inst.getArg1());
}
}
ArrayList<Instruction> tmpInsts=new ArrayList<Instruction>();
int nextArg=spec.getIntArg2();
for (Iterator<Integer> it=varInBody.keySet().iterator(); it.hasNext(); ) {
Integer memInHead=it.next();
Integer mem=varInBody.get(memInHead);
if (reuseMems.contains(mem)) {
List<Integer> copyRulesTo=copyRulesMap.get(mem);
boolean flg=false;
if (copyRulesTo == null) {
tmpInsts.add(new Instruction(Instruction.CLEARRULES,mem));
}
 else {
for (Integer dstmem : copyRulesTo) {
if (mem.equals(reuseMap.get(dstmem))) {
flg=true;
break;
}
}
if (!flg) {
ruleMem.put(mem,new Integer(nextArg));
tmpInsts.add(new Instruction(Instruction.ALLOCMEM,nextArg));
tmpInsts.add(new Instruction(Instruction.COPYRULES,nextArg,mem));
tmpInsts.add(new Instruction(Instruction.CLEARRULES,mem));
nextArg++;
}
}
}
}
body.addAll(1,tmpInsts);
ListIterator<Instruction> lit=body.listIterator();
while (lit.hasNext()) {
Instruction inst=lit.next();
switch (inst.getKind()) {
case Instruction.REMOVEMEM:
if (set.contains(inst.getArg1())) {
lit.remove();
}
break;
case Instruction.NEWMEM:
Integer arg1=(Integer)inst.getArg1();
if (reuseMap.containsKey(arg1)) {
lit.remove();
int m=((Integer)reuseMap.get(arg1)).intValue();
if (!set.contains(arg1)) {
lit.add(new Instruction(Instruction.ADDMEM,inst.getIntArg2(),m));
}
lit.add(new Instruction(Instruction.ENQUEUEMEM,m));
if (bodyMemName.get(arg1) == null && headMemName.get(m) != null) {
lit.add(new Instruction(Instruction.SETMEMNAME,m,null));
}
}
break;
case Instruction.MOVECELLS:
if (reuseMems.contains(inst.getArg2())) {
lit.remove();
}
break;
case Instruction.COPYRULES:
Integer srcmem=(Integer)inst.getArg2();
Integer dstmem=(Integer)inst.getArg1();
if (ruleMem.containsKey(srcmem)) {
if (!ruleMem.get(srcmem).equals(dstmem)) {
lit.remove();
lit.add(new Instruction(Instruction.COPYRULES,dstmem.intValue(),((Integer)ruleMem.get(srcmem)).intValue()));
}
}
 else if (srcmem.equals(reuseMap.get(dstmem))) {
lit.remove();
}
break;
case Instruction.FREEMEM:
if (reuseMems.contains(inst.getArg1())) {
lit.remove();
}
break;
}
}
lit.previous();
addUnlockInst(lit,reuseMap,new Integer(0),createdChildren);
for (Iterator<Integer> it=ruleMem.values().iterator(); it.hasNext(); ) {
lit.add(new Instruction(Instruction.FREEMEM,it.next()));
}
spec.updateSpec(spec.getIntArg1(),nextArg);
Instruction.changeMemVar(body,reuseMap);
}