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