Program: 149870
Project: 149870
Buggy source:
/** 
 * Process a taken yieldpoint. May result in threadswitch, depending on state of various control flags on the processor object. NOTE: The ThreadSwitchSampling code in the adaptive system depends on (a) knowing how many stack frames there are between here and the code in which the yieldpoint is taken and (b) this number being identical for all possible paths (ie, all compilers) from a yieldpoint in compiled code to the entry of this method. Changing this portion of the call stack is delicate and requires changes in the various AOS listeners that do call stack sampling.
 */
@NoInline public static void yieldpoint(int whereFrom){
  boolean threadSwitch=false;
  VM_GreenProcessor p=VM_GreenProcessor.getCurrentProcessor();
  int takeYieldpointVal=p.takeYieldpoint;
  p.takeYieldpoint=0;
  if (VM.BuildForPowerPC && p.codePatchSyncRequested) {
    p.codePatchSyncRequested=false;
    VM_Magic.isync();
    VM_Synchronization.fetchAndDecrement(VM_Magic.getJTOC(),VM_ArchEntrypoints.toSyncProcessorsField.getOffset(),1);
  }
  if (!p.threadSwitchingEnabled()) {
    if (p.threadSwitchPending != 1) {
      p.threadSwitchPending=takeYieldpointVal;
    }
    return;
  }
  if (p.timeSliceExpired != 0) {
    p.timeSliceExpired=0;
    if (VM.CBSCallSamplesPerTick > 0) {
      p.yieldForCBSCall=true;
      p.takeYieldpoint=-1;
      p.firstCBSCallSample++;
      p.firstCBSCallSample=p.firstCBSCallSample % VM.CBSCallSampleStride;
      p.countdownCBSCall=p.firstCBSCallSample;
      p.numCBSCallSamples=VM.CBSCallSamplesPerTick;
    }
    if (VM.CBSMethodSamplesPerTick > 0) {
      p.yieldForCBSMethod=true;
      p.takeYieldpoint=-1;
      p.firstCBSMethodSample++;
      p.firstCBSMethodSample=p.firstCBSMethodSample % VM.CBSMethodSampleStride;
      p.countdownCBSMethod=p.firstCBSMethodSample;
      p.numCBSMethodSamples=VM.CBSMethodSamplesPerTick;
    }
    if (++p.interruptQuantumCounter >= VM.schedulingMultiplier) {
      threadSwitch=true;
      p.interruptQuantumCounter=0;
      if (VM_Scheduler.debugRequested && VM_GreenScheduler.allProcessorsInitialized) {
        VM_GreenScheduler.debuggerMutex.lock("String_Node_Str");
        if (VM_GreenScheduler.debuggerQueue.isEmpty()) {
          VM_GreenScheduler.debuggerMutex.unlock();
        }
 else {
          VM_GreenThread t=VM_GreenScheduler.debuggerQueue.dequeue();
          VM_GreenScheduler.debuggerMutex.unlock();
          t.schedule();
        }
      }
      if (VM_GreenScheduler.wakeupQueue.isReady()) {
        VM_GreenScheduler.wakeupMutex.lock("String_Node_Str");
        VM_GreenThread t=VM_GreenScheduler.wakeupQueue.dequeue();
        VM_GreenScheduler.wakeupMutex.unlock();
        if (t != null) {
          t.schedule();
        }
      }
    }
    if (VM.BuildForAdaptiveSystem) {
      VM_RuntimeMeasurements.takeTimerSample(whereFrom);
    }
    if (threadSwitch && (p.yieldForCBSMethod || p.yieldForCBSCall)) {
      p.threadSwitchWhenCBSComplete=true;
      threadSwitch=false;
    }
    if (VM.BuildForAdaptiveSystem) {
      threadSwitch|=OSR_Listener.checkForOSRPromotion(whereFrom);
    }
    if (threadSwitch) {
      p.yieldForCBSMethod=false;
      p.yieldForCBSCall=false;
      p.threadSwitchWhenCBSComplete=false;
    }
  }
  if (p.yieldForCBSCall) {
    if (!(whereFrom == BACKEDGE || whereFrom == OSROPT)) {
      if (--p.countdownCBSCall <= 0) {
        if (VM.BuildForAdaptiveSystem) {
          VM_RuntimeMeasurements.takeCBSCallSample(whereFrom);
        }
        p.countdownCBSCall=VM.CBSCallSampleStride;
        p.numCBSCallSamples--;
        if (p.numCBSCallSamples <= 0) {
          p.yieldForCBSCall=false;
          if (!p.yieldForCBSMethod) {
            p.threadSwitchWhenCBSComplete=false;
            threadSwitch=true;
          }
        }
      }
    }
    if (p.yieldForCBSCall) {
      p.takeYieldpoint=-1;
    }
  }
  if (p.yieldForCBSMethod) {
    if (--p.countdownCBSMethod <= 0) {
      if (VM.BuildForAdaptiveSystem) {
        VM_RuntimeMeasurements.takeCBSMethodSample(whereFrom);
      }
      p.countdownCBSMethod=VM.CBSMethodSampleStride;
      p.numCBSMethodSamples--;
      if (p.numCBSMethodSamples <= 0) {
        p.yieldForCBSMethod=false;
        if (!p.yieldForCBSCall) {
          p.threadSwitchWhenCBSComplete=false;
          threadSwitch=true;
        }
      }
    }
    if (p.yieldForCBSMethod) {
      p.takeYieldpoint=1;
    }
  }
  if (p.yieldToGCRequested) {
    p.yieldToGCRequested=false;
    p.yieldForCBSCall=false;
    p.yieldForCBSMethod=false;
    p.threadSwitchWhenCBSComplete=false;
    p.takeYieldpoint=0;
    threadSwitch=true;
  }
  if (VM.BuildForAdaptiveSystem && p.yieldToOSRRequested) {
    p.yieldToOSRRequested=false;
    OSR_Listener.handleOSRFromOpt();
    threadSwitch=true;
  }
  if (threadSwitch) {
    timerTickYield(whereFrom);
  }
  VM_GreenThread myThread=VM_GreenScheduler.getCurrentThread();
  if (VM.BuildForAdaptiveSystem && myThread.isWaitingForOsr) {
    ArchitectureSpecific.OSR_PostThreadSwitch.postProcess(myThread);
  }
}

Fixed version (ground truth):
/** 
 * Process a taken yieldpoint. May result in threadswitch, depending on state of various control flags on the processor object. NOTE: The ThreadSwitchSampling code in the adaptive system depends on (a) knowing how many stack frames there are between here and the code in which the yieldpoint is taken and (b) this number being identical for all possible paths (ie, all compilers) from a yieldpoint in compiled code to the entry of this method. Changing this portion of the call stack is delicate and requires changes in the various AOS listeners that do call stack sampling.
 */
@NoInline public static void yieldpoint(int whereFrom){
  boolean threadSwitch=false;
  boolean cbsOverrun=false;
  VM_GreenProcessor p=VM_GreenProcessor.getCurrentProcessor();
  int takeYieldpointVal=p.takeYieldpoint;
  p.takeYieldpoint=0;
  if (VM.BuildForPowerPC && p.codePatchSyncRequested) {
    p.codePatchSyncRequested=false;
    VM_Magic.isync();
    VM_Synchronization.fetchAndDecrement(VM_Magic.getJTOC(),VM_ArchEntrypoints.toSyncProcessorsField.getOffset(),1);
  }
  if (!p.threadSwitchingEnabled()) {
    if (p.threadSwitchPending != 1) {
      p.threadSwitchPending=takeYieldpointVal;
    }
    return;
  }
  if (p.timeSliceExpired != 0) {
    p.timeSliceExpired=0;
    if (p.yieldForCBSCall || p.yieldForCBSMethod) {
      cbsOverrun=true;
    }
 else {
      if (VM.CBSCallSamplesPerTick > 0) {
        p.yieldForCBSCall=true;
        p.takeYieldpoint=-1;
        p.firstCBSCallSample++;
        p.firstCBSCallSample=p.firstCBSCallSample % VM.CBSCallSampleStride;
        p.countdownCBSCall=p.firstCBSCallSample;
        p.numCBSCallSamples=VM.CBSCallSamplesPerTick;
      }
      if (VM.CBSMethodSamplesPerTick > 0) {
        p.yieldForCBSMethod=true;
        p.takeYieldpoint=-1;
        p.firstCBSMethodSample++;
        p.firstCBSMethodSample=p.firstCBSMethodSample % VM.CBSMethodSampleStride;
        p.countdownCBSMethod=p.firstCBSMethodSample;
        p.numCBSMethodSamples=VM.CBSMethodSamplesPerTick;
      }
    }
    if (++p.interruptQuantumCounter >= VM.schedulingMultiplier) {
      threadSwitch=true;
      p.interruptQuantumCounter=0;
      if (VM_Scheduler.debugRequested && VM_GreenScheduler.allProcessorsInitialized) {
        VM_GreenScheduler.debuggerMutex.lock("String_Node_Str");
        if (VM_GreenScheduler.debuggerQueue.isEmpty()) {
          VM_GreenScheduler.debuggerMutex.unlock();
        }
 else {
          VM_GreenThread t=VM_GreenScheduler.debuggerQueue.dequeue();
          VM_GreenScheduler.debuggerMutex.unlock();
          t.schedule();
        }
      }
      if (VM_GreenScheduler.wakeupQueue.isReady()) {
        VM_GreenScheduler.wakeupMutex.lock("String_Node_Str");
        VM_GreenThread t=VM_GreenScheduler.wakeupQueue.dequeue();
        VM_GreenScheduler.wakeupMutex.unlock();
        if (t != null) {
          t.schedule();
        }
      }
    }
    if (VM.BuildForAdaptiveSystem) {
      VM_RuntimeMeasurements.takeTimerSample(whereFrom);
    }
    if (threadSwitch && !cbsOverrun && (p.yieldForCBSMethod || p.yieldForCBSCall)) {
      p.threadSwitchWhenCBSComplete=true;
      threadSwitch=false;
    }
    if (VM.BuildForAdaptiveSystem) {
      threadSwitch|=OSR_Listener.checkForOSRPromotion(whereFrom);
    }
    if (threadSwitch) {
      p.yieldForCBSMethod=false;
      p.yieldForCBSCall=false;
      p.threadSwitchWhenCBSComplete=false;
    }
  }
  if (p.yieldForCBSCall) {
    if (!(whereFrom == BACKEDGE || whereFrom == OSROPT)) {
      if (--p.countdownCBSCall <= 0) {
        if (VM.BuildForAdaptiveSystem) {
          VM_RuntimeMeasurements.takeCBSCallSample(whereFrom);
        }
        p.countdownCBSCall=VM.CBSCallSampleStride;
        p.numCBSCallSamples--;
        if (p.numCBSCallSamples <= 0) {
          p.yieldForCBSCall=false;
          if (!p.yieldForCBSMethod) {
            p.threadSwitchWhenCBSComplete=false;
            threadSwitch=true;
          }
        }
      }
    }
    if (p.yieldForCBSCall) {
      p.takeYieldpoint=-1;
    }
  }
  if (p.yieldForCBSMethod) {
    if (--p.countdownCBSMethod <= 0) {
      if (VM.BuildForAdaptiveSystem) {
        VM_RuntimeMeasurements.takeCBSMethodSample(whereFrom);
      }
      p.countdownCBSMethod=VM.CBSMethodSampleStride;
      p.numCBSMethodSamples--;
      if (p.numCBSMethodSamples <= 0) {
        p.yieldForCBSMethod=false;
        if (!p.yieldForCBSCall) {
          p.threadSwitchWhenCBSComplete=false;
          threadSwitch=true;
        }
      }
    }
    if (p.yieldForCBSMethod) {
      p.takeYieldpoint=1;
    }
  }
  if (p.yieldToGCRequested) {
    p.yieldToGCRequested=false;
    p.yieldForCBSCall=false;
    p.yieldForCBSMethod=false;
    p.threadSwitchWhenCBSComplete=false;
    p.takeYieldpoint=0;
    threadSwitch=true;
  }
  if (VM.BuildForAdaptiveSystem && p.yieldToOSRRequested) {
    p.yieldToOSRRequested=false;
    OSR_Listener.handleOSRFromOpt();
    threadSwitch=true;
  }
  if (threadSwitch) {
    timerTickYield(whereFrom);
  }
  VM_GreenThread myThread=VM_GreenScheduler.getCurrentThread();
  if (VM.BuildForAdaptiveSystem && myThread.isWaitingForOsr) {
    ArchitectureSpecific.OSR_PostThreadSwitch.postProcess(myThread);
  }
}