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.osr; 014 015 import org.jikesrvm.VM; 016 017 /** 018 * An iterator over an encoded OSR map. 019 * It is a bit odd to used now. 020 * <pre> 021 * while (it.hasMore()) { 022 * it.getKind(); 023 * it.getNumber(); 024 * it.getMethodId(); 025 * it.getBcIndex(); 026 * .... 027 * 028 * it.moveToNext(); 029 * } 030 *</pre> 031 */ 032 033 public class OSRMapIterator implements OSRConstants { 034 private int curidx; 035 private final int[] maps; 036 private int curmid; 037 private int curmpc; 038 039 private boolean moreMethId = false; 040 private boolean moreElemnt = false; 041 042 public OSRMapIterator(int[] mapcode, int index) { 043 // skip over the map of registers which are references. 044 this.curidx = index + 1; 045 this.maps = mapcode; 046 047 if ((mapcode[index] & NEXT_BIT) != 0) { 048 this.moreMethId = true; 049 moveToNextMethodId(); 050 } 051 } 052 053 public boolean hasMore() { 054 return this.moreElemnt; 055 } 056 057 /** 058 * after finishing iteration of one method, move to the next, 059 * it if is empty, move further. 060 */ 061 private void moveToNextMethodId() { 062 // VM.sysWriteln("move to next method id "+this.curidx); 063 064 this.curmid = maps[curidx] & ~NEXT_BIT; 065 this.moreMethId = (maps[curidx] & NEXT_BIT) != 0; 066 067 this.curidx++; 068 this.curmpc = maps[curidx] & ~NEXT_BIT; 069 this.moreElemnt = (maps[curidx] & NEXT_BIT) != 0; 070 071 this.curidx++; 072 073 // if this method id entry is empty, skip to the next 074 if (!hasMoreElements() && hasMoreMethodId()) { 075 moveToNextMethodId(); 076 } 077 } 078 079 /** has next method id to iterate? */ 080 private boolean hasMoreMethodId() { 081 return this.moreMethId; 082 } 083 084 /** has next element of this method id to iterate? */ 085 private boolean hasMoreElements() { 086 return this.moreElemnt; 087 } 088 089 /** 090 * Moves the index to the next element, update more first because 091 * we use last element's bit to indicate whether this element is 092 * available. 093 */ 094 public void moveToNext() { 095 if (VM.VerifyAssertions) VM._assert(this.hasMore()); 096 097 this.moreElemnt = (maps[curidx] & NEXT_BIT) != 0; 098 this.curidx += 2; 099 if (!hasMoreElements() && hasMoreMethodId()) { 100 moveToNextMethodId(); 101 } 102 } 103 104 /* for the current element, provide a list of queries. */ 105 106 /** what kind. */ 107 public boolean getKind() { 108 return (maps[curidx] & KIND_MASK) >> KIND_SHIFT != 0; 109 } 110 111 /** type code. */ 112 public byte getTypeCode() { 113 return (byte)((maps[curidx] & TCODE_MASK) >> TCODE_SHIFT); 114 } 115 116 /** number */ 117 public char getNumber() { 118 return (char)((maps[curidx] & NUM_MASK) >> NUM_SHIFT); 119 } 120 121 /** value type */ 122 public byte getValueType() { 123 return (byte)((maps[curidx] & VTYPE_MASK) >> VTYPE_SHIFT); 124 } 125 126 /** value */ 127 public int getValue() { 128 return maps[curidx + 1]; 129 } 130 131 /** current mid */ 132 public int getMethodId() { 133 return this.curmid; 134 } 135 136 /** current pc */ 137 public int getBcIndex() { 138 return this.curmpc; 139 } 140 }