org.ow2.fastrmic.Variables Maven / Gradle / Ivy
/**
RMIC.java --
Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
*/
package org.ow2.fastrmic;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
class Variables {
private final TreeSet free = new TreeSet();
private final HashMap names = new HashMap();
private final HashSet wides = new HashSet();
private final HashSet declared = new HashSet();
private boolean allocated = false;
/**
* @return max number of local vars used
*/
public int max() {
int max = 0;
Iterator it = free.iterator();
while (it.hasNext()) {
Integer val = (Integer) it.next();
if (val.intValue() > max) {
max = val.intValue();
}
}
return max;
}
/**
* @return number or global vars
*/
public int declaredSize() {
return declared.size();
}
public void declare(Object name) {
declare(name, 1);
}
public void declareWide(Object name) {
declare(name, 2);
}
public void declare(Object name, int size) {
if (allocated)
throw new IllegalStateException("cannot declare after allocating");
if (size != 1 && size != 2)
throw new IllegalArgumentException("size must be 1 or 2");
if (names.containsKey(name))
throw new IllegalStateException("already allocated " + name);
allocateNew(name, size);
declared.add(name);
}
private int allocateNew(Object name, int size) {
// total allocation size is first unallocated slot
int i = free.size() + names.size() + wides.size();
names.put(name, new Integer(i));
if (size == 2)
wides.add(name);
return i;
}
public int allocate(Object name) {
return allocate(name, 1);
}
public int allocateWide(Object name) {
return allocate(name, 2);
}
public int allocate(Object name, int size) {
allocated = true;
if (size != 1 && size != 2)
throw new IllegalArgumentException("size must be 1 or 2");
if (names.containsKey(name))
throw new IllegalStateException("already allocated " + name);
if (size == 2) {
// look for consecutive free slots
for (Iterator it = free.iterator(); it.hasNext();) {
Integer i = (Integer) it.next();
Integer next = new Integer(i.intValue() + 1);
if (free.contains(next)) {
free.remove(i);
free.remove(next);
wides.add(name);
names.put(name, i);
return i.intValue();
}
}
} else if (free.size() > 0) {
Integer i = (Integer) free.iterator().next();
free.remove(i);
names.put(name, i);
return i.intValue();
}
return allocateNew(name, size);
}
public int deallocate(Object name) {
if (!names.containsKey(name))
throw new IllegalArgumentException("no variable " + name);
if (declared.contains(name))
throw new IllegalStateException(name + " can't be deallocated");
Integer i = (Integer) names.get(name);
names.remove(name);
free.add(i);
if (wides.remove(name)) {
free.add(new Integer(i.intValue() + 1));
}
return i.intValue();
}
public int get(Object name) {
if (!names.containsKey(name))
throw new IllegalArgumentException("no variable " + name);
return ((Integer) names.get(name)).intValue();
}
}