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 }