001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.compilers.opt.ir;
014    
015    import java.util.List;
016    
017    /**
018     *  This class holds each element in the GCIRMap
019     */
020    public final class GCIRMapElement {
021    
022      /**
023       *  The instruction, i.e., GC point
024       */
025      private final Instruction inst;
026    
027      /**
028       *  The list of references (either symbolic regs or physical regs & spills)
029       */
030      private final List<RegSpillListElement> regSpillList;
031    
032      /**
033       * Constructor
034       * @param inst the instruction of interest
035       * @param regSpillList the list of references either symbolic (before regalloc)
036       *                or physical/spill location (after regalloc)
037       */
038      public GCIRMapElement(Instruction inst, List<RegSpillListElement> regSpillList) {
039        this.inst = inst;
040        this.regSpillList = regSpillList;
041      }
042    
043      /**
044       * Create a twin entry: required when the same MIR GC point
045       * is split into two instructions, both of which are PEIs
046       * after register allocation/GCIRMap creation.
047       */
048      public GCIRMapElement createTwin(Instruction inst) {
049        return new GCIRMapElement(inst, this.regSpillList);
050      }
051    
052      /**
053       * return the instruction with this entry
054       * @return the instruction with this entry
055       */
056      public Instruction getInstruction() {
057        return inst;
058      }
059    
060      /**
061       * returns an enumerator to access the registers/spills for this entry
062       * @return an enumerator to access the registers/spills for this entry
063       */
064      public List<RegSpillListElement> regSpillList() {
065        return regSpillList;
066      }
067    
068      /**
069       * Add a new spill list element for this map element
070       */
071      public void addRegSpillElement(RegSpillListElement e) {
072        regSpillList.add(e);
073      }
074    
075      /**
076       * Delete a spill list element from this map element
077       */
078      public void deleteRegSpillElement(RegSpillListElement e) {
079        regSpillList.remove(e);
080      }
081    
082      /**
083       * Counts and returns the number of references for this map
084       * @return the number of references, either regs or spills for this map
085       */
086      public int countNumElements() {
087        return regSpillList.size();
088      }
089    
090      /**
091       * Counts and returns the number of register elements (not spills)
092       *     for this entry
093       * @return the number of register elements for this entry
094       */
095      public int countNumRegElements() {
096        int count = 0;
097    
098        for (RegSpillListElement elem : regSpillList) {
099          if (!elem.isSpill()) {
100            count++;
101          }
102        }
103        return count;
104      }
105    
106      /**
107       * Counts and returns the number of spill for this entry
108       * @return the number of spill for this entry
109       */
110      public int countNumSpillElements() {
111        int count = 0;
112        // traverse the list and compute how many spills exist
113        for (RegSpillListElement elem : regSpillList) {
114          if (elem.isSpill()) {
115            count++;
116          }
117        }
118        return count;
119      }
120    
121      /**
122       * Return a string version of this object
123       * @return a string version of this object
124       */
125      @Override
126      public String toString() {
127        StringBuilder buf = new StringBuilder("");
128        buf.append(" Instruction: ").append(inst.bcIndex).append(", ").append(inst);
129        for (RegSpillListElement elem : regSpillList) {
130          buf.append(elem).append("  ");
131        }
132        buf.append("\n");
133        return buf.toString();
134      }
135    }