void insertSpillCode(OPT_LinearScan.ActiveSet set) { if (USE_LINEAR_SCAN) { activeSet = set; }  if (verboseDebug) { System.out.println("INSERT SPILL CODE:"); }   for (Enumeration blocks = ir.getBasicBlocks(); blocks.hasMoreElements(); ) { OPT_BasicBlock bb = (OPT_BasicBlock)blocks.nextElement(); for (Enumeration e = bb.forwardInstrEnumerator(); e.hasMoreElements();) {    boolean beCheap = (ir.options.FREQ_FOCUS_EFFORT && bb.getInfrequent());  OPT_Instruction s = (OPT_Instruction)e.nextElement(); if (verboseDebug) { System.out.println(s); }    restoreScratchRegistersBefore(s);   if (s.operator == BBEND || isPEIWithCatch(s) || s.isBranch() || s.isReturn()) { restoreAllScratchRegistersBefore(s); }            if (s.operator == YIELDPOINT_PROLOGUE) { restoreAllScratchRegistersBefore(s); }      if (s.isGCPoint()) {   markDirtyScratchRegisters(s); }    for (Enumeration ops = s.getOperands(); ops.hasMoreElements(); ) { OPT_Operand op = (OPT_Operand)ops.nextElement(); if (op != null && op.isRegister()) { OPT_Register r = op.asRegister().register; if (!r.isPhysical()) {   ScratchRegister scratch = getCurrentScratchRegister(r,s); if (verboseDebug) { System.out.println(r + " SCRATCH " + scratch); } if (scratch != null) {   boolean defined = definedIn(r,s) || definesSpillLocation(r,s); if (defined) { scratch.setDirty(true); } replaceRegisterWithScratch(s,r,scratch.scratch); } else {       if (needScratch(r,s)) {  boolean used = usedIn(r,s) || usesSpillLocation(r,s); boolean defined = definedIn(r,s) || definesSpillLocation(r,s); if (used) { if (!usedIn(r,s)) { OPT_Register r2 = spillLocationUse(r,s); scratch = moveToScratchBefore(s,r2,beCheap); if (verboseDebug) { System.out.println("MOVED TO SCRATCH BEFORE " + r2 + " " + scratch); } } else { scratch = moveToScratchBefore(s,r,beCheap); if (verboseDebug) { System.out.println("MOVED TO SCRATCH BEFORE " + r + " " + scratch); } } } if (defined) { scratch = holdInScratchAfter(s,r,beCheap); scratch.setDirty(true); if (verboseDebug) { System.out.println("HELD IN SCRATCH AFTER" + r + " " + scratch); } }  replaceRegisterWithScratch(s,r,scratch.scratch); } else {  if (s.operator != YIELDPOINT_OSR) {     replaceOperandWithSpillLocation(s,op.asRegister());  VM._assert(NOT_REACHED);   }  } } } } }    if (isSysCall(s)) { OPT_CallingConvention.saveNonvolatilesAroundSysCall(s,ir); }  } }
void insertSpillCode() { insertSpillCode(null);
  void insertSpillCode(OPT_LinearScan.ActiveSet set) {    if (USE_LINEAR_SCAN) {      activeSet = set;    }    if (verboseDebug) {      System.out.println("INSERT SPILL CODE:");    }    // walk over each instruction in the IR    for (Enumeration blocks = ir.getBasicBlocks(); blocks.hasMoreElements(); ) {      OPT_BasicBlock bb = (OPT_BasicBlock)blocks.nextElement();      for (Enumeration e = bb.forwardInstrEnumerator(); e.hasMoreElements();) {        // If the following is true, don't expend effort trying to        // optimize scratch assignements        boolean beCheap = (ir.options.FREQ_FOCUS_EFFORT && bb.getInfrequent());        OPT_Instruction s = (OPT_Instruction)e.nextElement();        if (verboseDebug) {          System.out.println(s);        }        // If any scratch registers are currently in use, but use physical        // registers that appear in s, then free the scratch register.        restoreScratchRegistersBefore(s);          // we must spill all scratch registers before leaving this basic block        if (s.operator == BBEND || isPEIWithCatch(s) || s.isBranch() || s.isReturn()) {          restoreAllScratchRegistersBefore(s);        }        // SJF: This is a bad hack which avoids bug 2642.  For some reason,        // if we cache a reference value in ECX across the prologue_yieldpoint in        // method java.Hashtable.put(), bad things happen and the program        // non-deterministically crashes with apparent bad GC Maps.          // I have not figured out what's really going on, despite great        // effort.  I'm giving up for now, and instead resorting to this        // woeful hack to avoid the problem.        // To reproduce the bug, comment out the following and run SPECjbb        // using the night-sanity parameters on OptOptSemispace; the program        // should crash with a bad GC map about half the time.        if (s.operator == YIELDPOINT_PROLOGUE) {          restoreAllScratchRegistersBefore(s);        }        // If s is a GC point, and scratch register r currently caches the        // value of symbolic symb, and r is dirty: Then update the GC map to         // account for the fact that symb's spill location does not        // currently hold a valid reference.        if (s.isGCPoint()) {          // note that if we're being cheap, no scratch registers are          // currently dirty, since we've restored them all.          markDirtyScratchRegisters(s);        }        // Walk over each operand and insert the appropriate spill code.        // for the operand.        for (Enumeration ops = s.getOperands(); ops.hasMoreElements(); ) {          OPT_Operand op = (OPT_Operand)ops.nextElement();          if (op != null && op.isRegister()) {            OPT_Register r = op.asRegister().register;            if (!r.isPhysical()) {              // Is r currently assigned to a scratch register?              // Note that if we're being cheap, the answer is always no (null)              ScratchRegister scratch = getCurrentScratchRegister(r,s);              if (verboseDebug) {                System.out.println(r + " SCRATCH " + scratch);              }              if (scratch != null) {                // r is currently assigned to a scratch register.  Continue to                // use the same scratch register.                boolean defined = definedIn(r,s) || definesSpillLocation(r,s);                if (defined) {                  scratch.setDirty(true);                }                replaceRegisterWithScratch(s,r,scratch.scratch);              } else {                // r is currently NOT assigned to a scratch register.                // Do we need to create a new scratch register to hold r?                // Note that we never need scratch floating point register                // for FMOVs, since we already have a scratch stack location                // reserved.                // If we're being cheap, then always create a new scratch register.                if (needScratch(r,s)) {                  // We must create a new scratch register.                  boolean used = usedIn(r,s) || usesSpillLocation(r,s);                  boolean defined = definedIn(r,s) || definesSpillLocation(r,s);                  if (used) {                    if (!usedIn(r,s)) {                      OPT_Register r2 = spillLocationUse(r,s);                      scratch = moveToScratchBefore(s,r2,beCheap);                      if (verboseDebug) {                        System.out.println("MOVED TO SCRATCH BEFORE " + r2 +                                            " " + scratch);                      }                    } else {                      scratch = moveToScratchBefore(s,r,beCheap);                      if (verboseDebug) {                        System.out.println("MOVED TO SCRATCH BEFORE " + r +                                            " " + scratch);                      }                    }                  }                     if (defined) {                    scratch = holdInScratchAfter(s,r,beCheap);                    scratch.setDirty(true);                    if (verboseDebug) {                      System.out.println("HELD IN SCRATCH AFTER" + r +                                          " " + scratch);                    }                  }                  // replace the register in the target instruction.                  replaceRegisterWithScratch(s,r,scratch.scratch);                } else {                  //-#if RVM_WITH_OSR                  if (s.operator != YIELDPOINT_OSR) {                  //-#endif                                    //-#if RVM_FOR_IA32                  // No need to use a scratch register here.                  replaceOperandWithSpillLocation(s,op.asRegister());                  //-#else                  VM._assert(NOT_REACHED);                  //-#endif                  //-#if RVM_WITH_OSR                  }                  //-#endif                }              }            }          }        }        // deal with sys calls that may bash non-volatiles        //-#if RVM_FOR_IA32        if (isSysCall(s)) {          OPT_CallingConvention.saveNonvolatilesAroundSysCall(s,ir);        }        //-#endif      }    }  }