Program: 150202
Project: 150202
Buggy source:
/** 
 * Emit code to do the C to Java transition:  JNI methods in VM_JNIFunctions.java
 */
public static void generateGlueCodeForJNIMethod(VM_Assembler asm,VM_Method mth){
  int offset;
  asm.emitSTAddrU(FP,-JNI_GLUE_FRAME_SIZE,FP);
  String mthName=mth.getName().toString();
  if ((mthName.startsWith("String_Node_Str") && mthName.endsWith("String_Node_Str")) || mthName.equals("String_Node_Str")) {
    offset=STACKFRAME_HEADER_SIZE + 3 * BYTES_IN_STACKSLOT;
    for (int i=6; i <= 10; i++) {
      asm.emitSTAddr(i,offset,FP);
      offset+=BYTES_IN_ADDRESS;
    }
    for (int i=1; i <= 3; i++) {
      asm.emitSTFD(i,offset,FP);
      offset+=BYTES_IN_DOUBLE;
    }
    offset=STACKFRAME_HEADER_SIZE + 0;
    for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
      asm.emitSTAddr(i,offset,FP);
      offset+=BYTES_IN_ADDRESS;
    }
    for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_PARAMETER_FPR; i++) {
      asm.emitSTFD(i,offset,FP);
      offset+=BYTES_IN_DOUBLE;
    }
  }
 else {
    convertParametersFromSVR4ToJava(asm,mth);
  }
  offset=STACKFRAME_HEADER_SIZE + JNI_GLUE_SAVED_VOL_SIZE;
  for (int i=FIRST_RVM_RESERVED_NV_GPR; i <= LAST_RVM_RESERVED_NV_GPR; i++) {
    asm.emitSTAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  asm.emitLVAL(S0,INVISIBLE_METHOD_ID);
  asm.emitMFLR(REGISTER_ZERO);
  asm.emitSTW(S0,STACKFRAME_METHOD_ID_OFFSET,FP);
  asm.emitSTAddr(REGISTER_ZERO,JNI_GLUE_FRAME_SIZE + STACKFRAME_NEXT_INSTRUCTION_OFFSET,FP);
  asm.emitADDI(T0,-VM_Entrypoints.JNIExternalFunctionsField.getOffset(),T0);
  int retryLoop=asm.getMachineCodeIndex();
  asm.emitLAddr(PROCESSOR_REGISTER,VM_Entrypoints.JNIEnvSavedPRField.getOffset(),T0);
  asm.emitLAddr(JTOC,VM_Entrypoints.JNIEnvSavedJTOCField.getOffset(),T0);
  asm.emitLVAL(S1,VM_Entrypoints.vpStatusField.getOffset());
  asm.emitLWARX(S0,S1,PROCESSOR_REGISTER);
  asm.emitCMPI(S0,VM_Processor.BLOCKED_IN_NATIVE);
  VM_ForwardReference frBlocked=asm.emitForwardBC(EQ);
  asm.emitLVAL(S0,VM_Processor.IN_JAVA);
  asm.emitSTWCXr(S0,S1,PROCESSOR_REGISTER);
  asm.emitBC(NE,retryLoop);
  VM_ForwardReference frInJava=asm.emitForwardB();
  frBlocked.resolve(asm);
  offset=STACKFRAME_HEADER_SIZE;
  for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
    asm.emitSTAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_VARARG_PARAMETER_FPR; i++) {
    asm.emitSTFD(i,offset,FP);
    offset+=BYTES_IN_DOUBLE;
  }
  asm.emitLAddr(S1,VM_Entrypoints.the_boot_recordField.getOffset(),JTOC);
  asm.emitMR(PROCESSOR_REGISTER,JTOC);
  asm.emitLAddr(JTOC,VM_Entrypoints.sysTOCField.getOffset(),S1);
  asm.emitLAddr(KLUDGE_TI_REG,VM_Entrypoints.sysVirtualProcessorYieldIPField.getOffset(),S1);
  asm.emitMTLR(KLUDGE_TI_REG);
  asm.emitBCLRL();
  asm.emitMR(JTOC,PROCESSOR_REGISTER);
  offset=STACKFRAME_HEADER_SIZE;
  for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
    asm.emitLAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_VARARG_PARAMETER_FPR; i++) {
    asm.emitLFD(i,offset,FP);
    offset+=BYTES_IN_DOUBLE;
  }
  asm.emitB(retryLoop);
  frInJava.resolve(asm);
  asm.emitLAddr(S0,VM_Entrypoints.JNITopJavaFPField.getOffset(),T0);
  asm.emitSUBFC(S0,FP,S0);
  asm.emitSTW(S0,JNI_GLUE_FRAME_SIZE + JNI_GLUE_OFFSET_TO_PREV_JFRAME,FP);
  VM_ForwardReference frNormalPrologue=asm.emitForwardBL();
  asm.emitLAddr(T2,VM_Entrypoints.activeThreadField.getOffset(),PROCESSOR_REGISTER);
  asm.emitLAddr(T2,VM_Entrypoints.jniEnvField.getOffset(),T2);
  asm.emitLInt(T3,JNI_GLUE_FRAME_SIZE + JNI_GLUE_OFFSET_TO_PREV_JFRAME,FP);
  asm.emitADD(T3,FP,T3);
  asm.emitSTAddr(T3,VM_Entrypoints.JNITopJavaFPField.getOffset(),T2);
  asm.emitCMPAddrI(T3,VM_Constants.STACKFRAME_SENTINEL_FP.toInt());
  VM_ForwardReference fr4=asm.emitForwardBC(EQ);
  asm.emitLAddr(S0,0,T3);
  fr4.resolve(asm);
  asm.emitSTAddr(PROCESSOR_REGISTER,VM_Entrypoints.JNIEnvSavedPRField.getOffset(),T2);
  asm.emitLVAL(S0,VM_Processor.IN_NATIVE);
  asm.emitSTW(S0,VM_Entrypoints.vpStatusField.getOffset(),PROCESSOR_REGISTER);
  offset=STACKFRAME_HEADER_SIZE + JNI_GLUE_SAVED_VOL_SIZE;
  for (int i=FIRST_RVM_RESERVED_NV_GPR; i <= LAST_RVM_RESERVED_NV_GPR; i++) {
    asm.emitLAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  asm.emitADDI(FP,JNI_GLUE_FRAME_SIZE,FP);
  asm.emitLAddr(T2,STACKFRAME_NEXT_INSTRUCTION_OFFSET,FP);
  asm.emitMTLR(T2);
  asm.emitBCLR();
  frNormalPrologue.resolve(asm);
}

Fixed version (ground truth):
/** 
 * Emit code to do the C to Java transition:  JNI methods in VM_JNIFunctions.java
 */
public static void generateGlueCodeForJNIMethod(VM_Assembler asm,VM_Method mth){
  int offset;
  boolean usesVarargs;
  int varargAmount=0;
  String mthName=mth.getName().toString();
  if ((mthName.startsWith("String_Node_Str") && mthName.endsWith("String_Node_Str")) || mthName.equals("String_Node_Str"))   usesVarargs=true;
 else   usesVarargs=false;
  if (usesVarargs) {
    VM_TypeReference[] argTypes=mth.getParameterTypes();
    int argCount=argTypes.length;
    for (int i=0; i < argCount; i++) {
      if (argTypes[i].isLongType() || argTypes[i].isDoubleType())       varargAmount+=2 * BYTES_IN_ADDRESS;
 else       varargAmount+=BYTES_IN_ADDRESS;
    }
  }
  int glueFrameSize=JNI_GLUE_FRAME_SIZE + varargAmount;
  asm.emitSTAddrU(FP,-glueFrameSize,FP);
  if (usesVarargs) {
    offset=STACKFRAME_HEADER_SIZE + 3 * BYTES_IN_STACKSLOT;
    for (int i=6; i <= 10; i++) {
      asm.emitSTAddr(i,offset,FP);
      offset+=BYTES_IN_ADDRESS;
    }
    for (int i=1; i <= 3; i++) {
      asm.emitSTFD(i,offset,FP);
      offset+=BYTES_IN_DOUBLE;
    }
    offset=STACKFRAME_HEADER_SIZE + 0;
    for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
      asm.emitSTAddr(i,offset,FP);
      offset+=BYTES_IN_ADDRESS;
    }
    for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_PARAMETER_FPR; i++) {
      asm.emitSTFD(i,offset,FP);
      offset+=BYTES_IN_DOUBLE;
    }
    offset=STACKFRAME_HEADER_SIZE + 0;
    for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
      asm.emitSTAddr(i,offset,FP);
      offset+=BYTES_IN_ADDRESS;
    }
  }
 else {
    convertParametersFromSVR4ToJava(asm,mth);
  }
  offset=STACKFRAME_HEADER_SIZE + JNI_GLUE_SAVED_VOL_SIZE;
  for (int i=FIRST_RVM_RESERVED_NV_GPR; i <= LAST_RVM_RESERVED_NV_GPR; i++) {
    asm.emitSTAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  asm.emitLVAL(S0,INVISIBLE_METHOD_ID);
  asm.emitMFLR(REGISTER_ZERO);
  asm.emitSTW(S0,STACKFRAME_METHOD_ID_OFFSET,FP);
  asm.emitSTAddr(REGISTER_ZERO,glueFrameSize + STACKFRAME_NEXT_INSTRUCTION_OFFSET,FP);
  asm.emitADDI(T0,-VM_Entrypoints.JNIExternalFunctionsField.getOffset(),T0);
  int retryLoop=asm.getMachineCodeIndex();
  asm.emitLAddr(PROCESSOR_REGISTER,VM_Entrypoints.JNIEnvSavedPRField.getOffset(),T0);
  asm.emitLAddr(JTOC,VM_Entrypoints.JNIEnvSavedJTOCField.getOffset(),T0);
  asm.emitLVAL(S1,VM_Entrypoints.vpStatusField.getOffset());
  asm.emitLWARX(S0,S1,PROCESSOR_REGISTER);
  asm.emitCMPI(S0,VM_Processor.BLOCKED_IN_NATIVE);
  VM_ForwardReference frBlocked=asm.emitForwardBC(EQ);
  asm.emitLVAL(S0,VM_Processor.IN_JAVA);
  asm.emitSTWCXr(S0,S1,PROCESSOR_REGISTER);
  asm.emitBC(NE,retryLoop);
  VM_ForwardReference frInJava=asm.emitForwardB();
  frBlocked.resolve(asm);
  offset=STACKFRAME_HEADER_SIZE;
  for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
    asm.emitSTAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_VARARG_PARAMETER_FPR; i++) {
    asm.emitSTFD(i,offset,FP);
    offset+=BYTES_IN_DOUBLE;
  }
  asm.emitLAddr(S1,VM_Entrypoints.the_boot_recordField.getOffset(),JTOC);
  asm.emitMR(PROCESSOR_REGISTER,JTOC);
  asm.emitLAddr(JTOC,VM_Entrypoints.sysTOCField.getOffset(),S1);
  asm.emitLAddr(KLUDGE_TI_REG,VM_Entrypoints.sysVirtualProcessorYieldIPField.getOffset(),S1);
  asm.emitMTLR(KLUDGE_TI_REG);
  asm.emitBCLRL();
  asm.emitMR(JTOC,PROCESSOR_REGISTER);
  offset=STACKFRAME_HEADER_SIZE;
  for (int i=FIRST_OS_PARAMETER_GPR; i <= LAST_OS_PARAMETER_GPR; i++) {
    asm.emitLAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  for (int i=FIRST_OS_PARAMETER_FPR; i <= LAST_OS_VARARG_PARAMETER_FPR; i++) {
    asm.emitLFD(i,offset,FP);
    offset+=BYTES_IN_DOUBLE;
  }
  asm.emitB(retryLoop);
  frInJava.resolve(asm);
  asm.emitLAddr(S0,VM_Entrypoints.JNITopJavaFPField.getOffset(),T0);
  asm.emitSUBFC(S0,FP,S0);
  asm.emitSTW(S0,glueFrameSize + JNI_GLUE_OFFSET_TO_PREV_JFRAME,FP);
  VM_ForwardReference frNormalPrologue=asm.emitForwardBL();
  asm.emitLAddr(T2,VM_Entrypoints.activeThreadField.getOffset(),PROCESSOR_REGISTER);
  asm.emitLAddr(T2,VM_Entrypoints.jniEnvField.getOffset(),T2);
  asm.emitLInt(T3,glueFrameSize + JNI_GLUE_OFFSET_TO_PREV_JFRAME,FP);
  asm.emitADD(T3,FP,T3);
  asm.emitSTAddr(T3,VM_Entrypoints.JNITopJavaFPField.getOffset(),T2);
  asm.emitCMPAddrI(T3,VM_Constants.STACKFRAME_SENTINEL_FP.toInt());
  VM_ForwardReference fr4=asm.emitForwardBC(EQ);
  asm.emitLAddr(S0,0,T3);
  fr4.resolve(asm);
  asm.emitSTAddr(PROCESSOR_REGISTER,VM_Entrypoints.JNIEnvSavedPRField.getOffset(),T2);
  asm.emitLVAL(S0,VM_Processor.IN_NATIVE);
  asm.emitSTW(S0,VM_Entrypoints.vpStatusField.getOffset(),PROCESSOR_REGISTER);
  offset=STACKFRAME_HEADER_SIZE + JNI_GLUE_SAVED_VOL_SIZE;
  for (int i=FIRST_RVM_RESERVED_NV_GPR; i <= LAST_RVM_RESERVED_NV_GPR; i++) {
    asm.emitLAddr(i,offset,FP);
    offset+=BYTES_IN_ADDRESS;
  }
  asm.emitADDI(FP,glueFrameSize,FP);
  asm.emitLAddr(T2,STACKFRAME_NEXT_INSTRUCTION_OFFSET,FP);
  asm.emitMTLR(T2);
  asm.emitBCLR();
  frNormalPrologue.resolve(asm);
}