sa-jdi

    return obj.getHandle().getJDoubleAt(getOffset());
  }
  
  public void setValue(Oop obj, double value)
    throws MutationException
  {}
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.DoubleField
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import java.io.PrintStream;
import sun.jvm.hotspot.runtime.VM;

public class Field
{
  private long offset;
  private FieldIdentifier id;
  private boolean isVMField;
  private InstanceKlass holder;
  private FieldType fieldType;
  private Symbol signature;
  private Symbol genericSignature;
  private AccessFlags accessFlags;
  private int fieldArrayIndex;
  
  Field(FieldIdentifier id, long offset, boolean isVMField)
  {
    this.offset = offset;
    this.id = id;
    this.isVMField = isVMField;
  }
  
  Field(InstanceKlass holder, int fieldArrayIndex)
  {
    this.holder = holder;
    this.fieldArrayIndex = fieldArrayIndex;
    
    ConstantPool cp = holder.getConstants();
    TypeArray fields = holder.getFields();
    short access = fields.getShortAt(fieldArrayIndex + InstanceKlass.ACCESS_FLAGS_OFFSET);
    short nameIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.NAME_INDEX_OFFSET);
    short signatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.SIGNATURE_INDEX_OFFSET);
    offset = VM.getVM().buildIntFromShorts(fields.getShortAt(fieldArrayIndex + InstanceKlass.LOW_OFFSET), fields.getShortAt(fieldArrayIndex + InstanceKlass.HIGH_OFFSET));
    
    short genericSignatureIndex = fields.getShortAt(fieldArrayIndex + InstanceKlass.GENERIC_SIGNATURE_INDEX_OFFSET);
    Symbol name = cp.getSymbolAt(nameIndex);
    id = new NamedFieldIdentifier(name.asString());
    signature = cp.getSymbolAt(signatureIndex);
    if (genericSignatureIndex != 0) {
      genericSignature = cp.getSymbolAt(genericSignatureIndex);
    } else {
      genericSignature = null;
    }
    fieldType = new FieldType(signature);
    accessFlags = new AccessFlags(access);
  }
  
  public long getOffset()
  {
    return offset;
  }
  
  public FieldIdentifier getID()
  {
    return id;
  }
  
  public boolean isVMField()
  {
    return isVMField;
  }
  
  public boolean isNamedField()
  {
    return id instanceof NamedFieldIdentifier;
  }
  
  public void printOn(PrintStream tty)
  {
    getID().printOn(tty);
    tty.print(" {" + getOffset() + "} :");
  }
  
  public InstanceKlass getFieldHolder()
  {
    return holder;
  }
  
  public int getFieldArrayIndex()
  {
    return fieldArrayIndex;
  }
  
  public long getAccessFlags()
  {
    return accessFlags.getValue();
  }
  
  public AccessFlags getAccessFlagsObj()
  {
    return accessFlags;
  }
  
  public FieldType getFieldType()
  {
    return fieldType;
  }
  
  public Symbol getSignature()
  {
    return signature;
  }
  
  public Symbol getGenericSignature()
  {
    return genericSignature;
  }
  
  public boolean isPublic()
  {
    return accessFlags.isPublic();
  }
  
  public boolean isPrivate()
  {
    return accessFlags.isPrivate();
  }
  
  public boolean isProtected()
  {
    return accessFlags.isProtected();
  }
  
  public boolean isPackagePrivate()
  {
    return (!isPublic()) && (!isPrivate()) && (!isProtected());
  }
  
  public boolean isStatic()
  {
    return accessFlags.isStatic();
  }
  
  public boolean isFinal()
  {
    return accessFlags.isFinal();
  }
  
  public boolean isVolatile()
  {
    return accessFlags.isVolatile();
  }
  
  public boolean isTransient()
  {
    return accessFlags.isTransient();
  }
  
  public boolean isSynthetic()
  {
    return accessFlags.isSynthetic();
  }
  
  public boolean isEnumConstant()
  {
    return accessFlags.isEnum();
  }
  
  public boolean equals(Object obj)
  {
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof Field)) {
      return false;
    }
    Field other = (Field)obj;
    return (getFieldHolder().equals(other.getFieldHolder())) && (getID().equals(other.getID()));
  }
  
  public int hashCode()
  {
    return getFieldHolder().hashCode() ^ getID().hashCode();
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.Field
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import java.io.PrintStream;

public class FieldIdentifier
{
  public String getName()
  {
    return "";
  }
  
  public void printOn(PrintStream tty)
  {
    tty.print(" - " + getName() + ":\t");
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.FieldIdentifier
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

public class FieldType$ArrayInfo
{
  private int dimension;
  private int elementBasicType;
  
  public FieldType$ArrayInfo(int dimension, int elementBasicType)
  {
    this.dimension = dimension;
    this.elementBasicType = elementBasicType;
  }
  
  public int dimension()
  {
    return dimension;
  }
  
  public int elementBasicType()
  {
    return elementBasicType;
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.FieldType.ArrayInfo
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.runtime.BasicType;
import sun.jvm.hotspot.utilities.Assert;

public class FieldType
{
  private Symbol signature;
  private char first;
  
  public FieldType(Symbol signature)
  {
    this.signature = signature;
    first = ((char)signature.getByteAt(0L));
    if (Assert.ASSERTS_ENABLED) {
      switch (first)
      {
      case 'B': 
      case 'C': 
      case 'D': 
      case 'F': 
      case 'I': 
      case 'J': 
      case 'L': 
      case 'S': 
      case 'Z': 
      case '[': 
        break;
      case 'E': 
      case 'G': 
      case 'H': 
      case 'K': 
      case 'M': 
      case 'N': 
      case 'O': 
      case 'P': 
      case 'Q': 
      case 'R': 
      case 'T': 
      case 'U': 
      case 'V': 
      case 'W': 
      case 'X': 
      case 'Y': 
      default: 
        Assert.that(false, "Unknown char in field signature \"" + signature.asString() + "\": " + first);
      }
    }
  }
  
  public boolean isOop()
  {
    return (isObject()) || (isArray());
  }
  
  public boolean isByte()
  {
    return first == 'B';
  }
  
  public boolean isChar()
  {
    return first == 'C';
  }
  
  public boolean isDouble()
  {
    return first == 'D';
  }
  
  public boolean isFloat()
  {
    return first == 'F';
  }
  
  public boolean isInt()
  {
    return first == 'I';
  }
  
  public boolean isLong()
  {
    return first == 'J';
  }
  
  public boolean isShort()
  {
    return first == 'S';
  }
  
  public boolean isBoolean()
  {
    return first == 'Z';
  }
  
  public boolean isObject()
  {
    return first == 'L';
  }
  
  public boolean isArray()
  {
    return first == '[';
  }
  
  public static class ArrayInfo
  {
    private int dimension;
    private int elementBasicType;
    
    public ArrayInfo(int dimension, int elementBasicType)
    {
      this.dimension = dimension;
      this.elementBasicType = elementBasicType;
    }
    
    public int dimension()
    {
      return dimension;
    }
    
    public int elementBasicType()
    {
      return elementBasicType;
    }
  }
  
  public ArrayInfo getArrayInfo()
  {
    int index = 1;
    int dim = 1;
    index = skipOptionalSize(signature, index);
    while (signature.getByteAt(index) == 91)
    {
      index++;
      dim++;
      skipOptionalSize(signature, index);
    }
    int elementType = BasicType.charToType((char)signature.getByteAt(index));
    return new ArrayInfo(dim, elementType);
  }
  
  private int skipOptionalSize(Symbol sig, int index)
  {
    byte c = sig.getByteAt(index);
    while ((c >= 48) && (c <= 57))
    {
      index++;
      c = sig.getByteAt(index);
    }
    return index;
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.FieldType
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.types.JFloatField;

public class FloatField
  extends Field
{
  public FloatField(FieldIdentifier id, long offset, boolean isVMField)
  {
    super(id, offset, isVMField);
  }
  
  public FloatField(JFloatField vmField, long startOffset)
  {
    super(new NamedFieldIdentifier(vmField.getName()), vmField.getOffset() + startOffset, true);
  }
  
  public FloatField(InstanceKlass holder, int fieldArrayIndex)
  {
    super(holder, fieldArrayIndex);
  }
  
  public float getValue(Oop obj)
  {
    return obj.getHandle().getJFloatAt(getOffset());
  }
  
  public void setValue(Oop obj, float value)
    throws MutationException
  {}
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.FloatField
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

final class GenerateOopMap$1
  implements GenerateOopMap.JumpClosure
{
  private final GenerateOopMap this$0;
  
  GenerateOopMap$1(GenerateOopMap paramGenerateOopMap) {}
  
  public void process(GenerateOopMap c, int bcpDelta, int[] data)
  {
    c.markBB(bcpDelta, data);
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.1
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

final class GenerateOopMap$2
  implements GenerateOopMap.JumpClosure
{
  private final GenerateOopMap this$0;
  
  GenerateOopMap$2(GenerateOopMap paramGenerateOopMap) {}
  
  public void process(GenerateOopMap c, int bcpDelta, int[] data)
  {
    c.mergeState(bcpDelta, data);
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.2
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

final class GenerateOopMap$3
  implements GenerateOopMap.JumpClosure
{
  private final GenerateOopMap this$0;
  
  GenerateOopMap$3(GenerateOopMap paramGenerateOopMap) {}
  
  public void process(GenerateOopMap c, int bcpDelta, int[] data)
  {
    c.mergeState(bcpDelta, data);
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.3
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

final class GenerateOopMap$4
  implements GenerateOopMap.JumpClosure
{
  private final GenerateOopMap this$0;
  
  GenerateOopMap$4(GenerateOopMap paramGenerateOopMap) {}
  
  public void process(GenerateOopMap c, int bciDelta, int[] change)
  {
    c.reachableBasicblock(bciDelta, change);
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.4
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.utilities.Assert;

class GenerateOopMap$BasicBlock
{
  private boolean _changed;
  static final int _dead_basic_block = -2;
  static final int _unreached = -1;
  int _bci;
  int _end_bci;
  int _max_locals;
  int _max_stack;
  CellTypeStateList _state;
  int _stack_top;
  int _monitor_top;
  
  CellTypeStateList vars()
  {
    return _state;
  }
  
  CellTypeStateList stack()
  {
    return _state.subList(_max_locals, _state.size());
  }
  
  boolean changed()
  {
    return _changed;
  }
  
  void setChanged(boolean s)
  {
    _changed = s;
  }
  
  boolean isReachable()
  {
    return _stack_top >= 0;
  }
  
  boolean isDead()
  {
    return _stack_top == -2;
  }
  
  boolean isAlive()
  {
    return _stack_top != -2;
  }
  
  void markAsAlive()
  {
    if (Assert.ASSERTS_ENABLED)
    {
      Assert.that(isDead(), "must be dead");
      _stack_top = -1;
    }
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.BasicBlock
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.runtime.SignatureIterator;

class GenerateOopMap$ComputeCallStack
  extends SignatureIterator
{
  CellTypeStateList _effect;
  int _idx;
  
  void set(CellTypeState state)
  {
    _effect.get(_idx++).set(state);
  }
  
  int length()
  {
    return _idx;
  }
  
  public void doBool()
  {
    set(CellTypeState.value);
  }
  
  public void doChar()
  {
    set(CellTypeState.value);
  }
  
  public void doFloat()
  {
    set(CellTypeState.value);
  }
  
  public void doByte()
  {
    set(CellTypeState.value);
  }
  
  public void doShort()
  {
    set(CellTypeState.value);
  }
  
  public void doInt()
  {
    set(CellTypeState.value);
  }
  
  public void doVoid()
  {
    set(CellTypeState.bottom);
  }
  
  public void doObject(int begin, int end)
  {
    set(CellTypeState.ref);
  }
  
  public void doArray(int begin, int end)
  {
    set(CellTypeState.ref);
  }
  
  public void doDouble()
  {
    set(CellTypeState.value);
    set(CellTypeState.value);
  }
  
  public void doLong()
  {
    set(CellTypeState.value);
    set(CellTypeState.value);
  }
  
  GenerateOopMap$ComputeCallStack(Symbol signature)
  {
    super(signature);
  }
  
  int computeForParameters(boolean is_static, CellTypeStateList effect)
  {
    _idx = 0;
    _effect = effect;
    if (!is_static) {
      effect.get(_idx++).set(CellTypeState.ref);
    }
    iterateParameters();
    
    return length();
  }
  
  int computeForReturntype(CellTypeStateList effect)
  {
    _idx = 0;
    _effect = effect;
    iterateReturntype();
    set(CellTypeState.bottom);
    
    return length();
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.ComputeCallStack
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.runtime.SignatureIterator;

class GenerateOopMap$ComputeEntryStack
  extends SignatureIterator
{
  CellTypeStateList _effect;
  int _idx;
  
  void set(CellTypeState state)
  {
    _effect.get(_idx++).set(state);
  }
  
  int length()
  {
    return _idx;
  }
  
  public void doBool()
  {
    set(CellTypeState.value);
  }
  
  public void doChar()
  {
    set(CellTypeState.value);
  }
  
  public void doFloat()
  {
    set(CellTypeState.value);
  }
  
  public void doByte()
  {
    set(CellTypeState.value);
  }
  
  public void doShort()
  {
    set(CellTypeState.value);
  }
  
  public void doInt()
  {
    set(CellTypeState.value);
  }
  
  public void doVoid()
  {
    set(CellTypeState.bottom);
  }
  
  public void doObject(int begin, int end)
  {
    set(CellTypeState.makeSlotRef(_idx));
  }
  
  public void doArray(int begin, int end)
  {
    set(CellTypeState.makeSlotRef(_idx));
  }
  
  public void doDouble()
  {
    set(CellTypeState.value);
    set(CellTypeState.value);
  }
  
  public void doLong()
  {
    set(CellTypeState.value);
    set(CellTypeState.value);
  }
  
  GenerateOopMap$ComputeEntryStack(Symbol signature)
  {
    super(signature);
  }
  
  int computeForParameters(boolean is_static, CellTypeStateList effect)
  {
    _idx = 0;
    _effect = effect;
    if (!is_static) {
      effect.get(_idx++).set(CellTypeState.makeSlotRef(0));
    }
    iterateParameters();
    
    return length();
  }
  
  int computeForReturntype(CellTypeStateList effect)
  {
    _idx = 0;
    _effect = effect;
    iterateReturntype();
    set(CellTypeState.bottom);
    
    return length();
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.ComputeEntryStack
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

abstract interface GenerateOopMap$JumpClosure
{
  public abstract void process(GenerateOopMap paramGenerateOopMap, int paramInt, int[] paramArrayOfInt);
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.JumpClosure
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import sun.jvm.hotspot.interpreter.BytecodeStream;
import sun.jvm.hotspot.utilities.Assert;

class GenerateOopMap$RetTable
{
  private GenerateOopMap.RetTableEntry _first;
  private static int _init_nof_entries;
  
  private void addJsr(int return_bci, int target_bci)
  {
    GenerateOopMap.RetTableEntry entry = _first;
    while ((entry != null) && (entry.targetBci() != target_bci)) {
      entry = entry.next();
    }
    if (entry == null)
    {
      entry = new GenerateOopMap.RetTableEntry(target_bci, _first);
      _first = entry;
    }
    entry.addJsr(return_bci);
  }
  
  void computeRetTable(Method method)
  {
    BytecodeStream i = new BytecodeStream(method);
    int bytecode;
    while ((bytecode = i.next()) >= 0) {
      switch (bytecode)
      {
      case 168: 
        addJsr(i.nextBCI(), i.dest());
        break;
      case 201: 
        addJsr(i.nextBCI(), i.dest_w());
      }
    }
  }
  
  void updateRetTable(int bci, int delta)
  {
    GenerateOopMap.RetTableEntry cur = _first;
    while (cur != null)
    {
      cur.addDelta(bci, delta);
      cur = cur.next();
    }
  }
  
  GenerateOopMap.RetTableEntry findJsrsForTarget(int targBci)
  {
    GenerateOopMap.RetTableEntry cur = _first;
    while (cur != null)
    {
      if (Assert.ASSERTS_ENABLED) {
        Assert.that(cur.targetBci() != -1, "sanity check");
      }
      if (cur.targetBci() == targBci) {
        return cur;
      }
      cur = cur.next();
    }
    throw new RuntimeException("Should not reach here");
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.RetTable
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import java.util.ArrayList;
import java.util.List;

class GenerateOopMap$RetTableEntry
{
  private static int _init_nof_jsrs;
  private int _target_bci;
  private List _jsrs;
  private RetTableEntry _next;
  
  GenerateOopMap$RetTableEntry(int target, RetTableEntry next)
  {
    _target_bci = target;
    _jsrs = new ArrayList(_init_nof_jsrs);
    _next = next;
  }
  
  int targetBci()
  {
    return _target_bci;
  }
  
  int nofJsrs()
  {
    return _jsrs.size();
  }
  
  int jsrs(int i)
  {
    return ((Integer)_jsrs.get(i)).intValue();
  }
  
  void addJsr(int return_bci)
  {
    _jsrs.add(new Integer(return_bci));
  }
  
  void addDelta(int bci, int delta)
  {
    if (_target_bci > bci) {
      _target_bci += delta;
    }
    for (int k = 0; k < nofJsrs(); k++)
    {
      int jsr = jsrs(k);
      if (jsr > bci) {
        _jsrs.set(k, new Integer(jsr + delta));
      }
    }
  }
  
  RetTableEntry next()
  {
    return _next;
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.oops.GenerateOopMap.RetTableEntry
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.oops;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import sun.jvm.hotspot.interpreter.BytecodeLookupswitch;
import sun.jvm.hotspot.interpreter.BytecodeStream;
import sun.jvm.hotspot.interpreter.BytecodeTableswitch;
import sun.jvm.hotspot.interpreter.Bytecodes;
import sun.jvm.hotspot.interpreter.LookupswitchPair;
import sun.jvm.hotspot.runtime.SignatureIterator;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.utilities.Assert;
import sun.jvm.hotspot.utilities.BitMap;
import sun.jvm.hotspot.utilities.ConstantTag;

public class GenerateOopMap
{
  private static final boolean DEBUG = false;
  private static final int MAXARGSIZE = 256;
  private static final int MAX_LOCAL_VARS = 65536;
  private static final boolean TraceMonitorMismatch = true;
  private static final boolean TraceOopMapRewrites = true;
  static CellTypeState[] epsilonCTS = { CellTypeState.bottom };
  static CellTypeState refCTS = CellTypeState.ref;
  static CellTypeState valCTS = CellTypeState.value;
  static CellTypeState[] vCTS = { CellTypeState.value, CellTypeState.bottom };
  static CellTypeState[] rCTS = { CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] rrCTS = { CellTypeState.ref, CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] vrCTS = { CellTypeState.value, CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] vvCTS = { CellTypeState.value, CellTypeState.value, CellTypeState.bottom };
  static CellTypeState[] rvrCTS = { CellTypeState.ref, CellTypeState.value, CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] vvrCTS = { CellTypeState.value, CellTypeState.value, CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] vvvCTS = { CellTypeState.value, CellTypeState.value, CellTypeState.value, CellTypeState.bottom };
  static CellTypeState[] vvvrCTS = { CellTypeState.value, CellTypeState.value, CellTypeState.value, CellTypeState.ref, CellTypeState.bottom };
  static CellTypeState[] vvvvCTS = { CellTypeState.value, CellTypeState.value, CellTypeState.value, CellTypeState.value, CellTypeState.bottom };
  protected static final int bad_monitors = -1;
  Method _method;
  RetTable _rt;
  int _max_locals;
  int _max_stack;
  int _max_monitors;
  boolean _has_exceptions;
  boolean _got_error;
  String _error_msg;
  boolean _monitor_safe;
  int _state_len;
  CellTypeStateList _state;
  char[] _state_vec_buf;
  int _stack_top;
  int _monitor_top;
  int _report_for_exit_bci;
  int _matching_enter_bci;
  BasicBlock[] _basic_blocks;
  int _gc_points;
  int _bb_count;
  BitMap _bb_hdr_bits;
  boolean _report_result;
  boolean _report_result_for_send;
  BytecodeStream _itr_send;
  List _init_vars;
  boolean _conflict;
  int _nof_refval_conflicts;
  int[] _new_var_map;
  
  static abstract interface JumpClosure
  {
    public abstract void process(GenerateOopMap paramGenerateOopMap, int paramInt, int[] paramArrayOfInt);
  }
  
  static class ComputeCallStack
    extends SignatureIterator
  {
    CellTypeStateList _effect;
    int _idx;
    
    void set(CellTypeState state)
    {
      _effect.get(_idx++).set(state);
    }
    
    int length()
    {
      return _idx;
    }
    
    public void doBool()
    {
      set(CellTypeState.value);
    }
    
    public void doChar()
    {
      set(CellTypeState.value);
    }
    
    public void doFloat()
    {
      set(CellTypeState.value);
    }
    
    public void doByte()
    {
      set(CellTypeState.value);
    }
    
    public void doShort()
    {
      set(CellTypeState.value);
    }
    
    public void doInt()
    {
      set(CellTypeState.value);
    }
    
    public void doVoid()
    {
      set(CellTypeState.bottom);
    }
    
    public void doObject(int begin, int end)
    {
      set(CellTypeState.ref);
    }
    
    public void doArray(int begin, int end)
    {
      set(CellTypeState.ref);
    }
    
    public void doDouble()
    {
      set(CellTypeState.value);
      set(CellTypeState.value);
    }
    
    public void doLong()
    {
      set(CellTypeState.value);
      set(CellTypeState.value);
    }
    
    ComputeCallStack(Symbol signature)
    {
      super();
    }
    
    int computeForParameters(boolean is_static, CellTypeStateList effect)
    {
      _idx = 0;
      _effect = effect;
      if (!is_static) {
        effect.get(_idx++).set(CellTypeState.ref);
      }
      iterateParameters();
      
      return length();
    }
    
    int computeForReturntype(CellTypeStateList effect)
    {
      _idx = 0;
      _effect = effect;
      iterateReturntype();
      set(CellTypeState.bottom);
      
      return length();
    }
  }
  
  static class ComputeEntryStack
    extends SignatureIterator
  {
    CellTypeStateList _effect;
    int _idx;
    
    void set(CellTypeState state)
    {
      _effect.get(_idx++).set(state);
    }
    
    int length()
    {
      return _idx;
    }
    
    public void doBool()
    {
      set(CellTypeState.value);
    }
    
    public void doChar()
    {
      set(CellTypeState.value);
    }
    
    public void doFloat()
    {
      set(CellTypeState.value);
    }
    
    public void doByte()
    {
      set(CellTypeState.value);
    }
    
    public void doShort()
    {
      set(CellTypeState.value);
    }
    
    public void doInt()
    {
      set(CellTypeState.value);
    }
    
    public void doVoid()
    {
      set(CellTypeState.bottom);
    }
    
    public void doObject(int begin, int end)
    {
      set(CellTypeState.makeSlotRef(_idx));
    }
    
    public void doArray(int begin, int end)
    {
      set(CellTypeState.makeSlotRef(_idx));
    }
    
    public void doDouble()
    {
      set(CellTypeState.value);
      set(CellTypeState.value);
    }
    
    public void doLong()
    {
      set(CellTypeState.value);
      set(CellTypeState.value);
    }
    
    ComputeEntryStack(Symbol signature)
    {
      super();
    }
    
    int computeForParameters(boolean is_static, CellTypeStateList effect)
    {
      _idx = 0;
      _effect = effect;
      if (!is_static) {
        effect.get(_idx++).set(CellTypeState.makeSlotRef(0));
      }
      iterateParameters();
      
      return length();
    }
    
    int computeForReturntype(CellTypeStateList effect)
    {
      _idx = 0;
      _effect = effect;
      iterateReturntype();
      set(CellTypeState.bottom);
      
      return length();
    }
  }
  
  static class RetTableEntry
  {
    private static int _init_nof_jsrs;
    private int _target_bci;
    private List _jsrs;
    private RetTableEntry _next;
    
    RetTableEntry(int target, RetTableEntry next)
    {
      _target_bci = target;
      _jsrs = new ArrayList(_init_nof_jsrs);
      _next = next;
    }
    
    int targetBci()
    {
      return _target_bci;
    }
    
    int nofJsrs()
    {
      return _jsrs.size();
    }
    
    int jsrs(int i)
    {
      return ((Integer)_jsrs.get(i)).intValue();
    }
    
    void addJsr(int return_bci)
    {
      _jsrs.add(new Integer(return_bci));
    }
    
    void addDelta(int bci, int delta)
    {
      if (_target_bci > bci) {
        _target_bci += delta;
      }
      for (int k = 0; k < nofJsrs(); k++)
      {
        int jsr = jsrs(k);
        if (jsr > bci) {
          _jsrs.set(k, new Integer(jsr + delta));
        }
      }
    }
    
    RetTableEntry next()
    {
      return _next;
    }
  }
  
  static class RetTable
  {
    private GenerateOopMap.RetTableEntry _first;
    private static int _init_nof_entries;
    
    private void addJsr(int return_bci, int target_bci)
    {
      GenerateOopMap.RetTableEntry entry = _first;
      while ((entry != null) && (entry.targetBci() != target_bci)) {
        entry = entry.next();
      }
      if (entry == null)
      {
        entry = new GenerateOopMap.RetTableEntry(target_bci, _first);
        _first = entry;
      }
      entry.addJsr(return_bci);
    }
    
    void computeRetTable(Method method)
    {
      BytecodeStream i = new BytecodeStream(method);
      int bytecode;
      while ((bytecode = i.next()) >= 0) {
        switch (bytecode)
        {
        case 168: 
          addJsr(i.nextBCI(), i.dest());
          break;
        case 201: 
          addJsr(i.nextBCI(), i.dest_w());
        }
      }
    }
    
    void updateRetTable(int bci, int delta)
    {
      GenerateOopMap.RetTableEntry cur = _first;
      while (cur != null)
      {
        cur.addDelta(bci, delta);
        cur = cur.next();
      }
    }
    
    GenerateOopMap.RetTableEntry findJsrsForTarget(int targBci)
    {
      GenerateOopMap.RetTableEntry cur = _first;
      while (cur != null)
      {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(cur.targetBci() != -1, "sanity check");
        }
        if (cur.targetBci() == targBci) {
          return cur;
        }
        cur = cur.next();
      }
      throw new RuntimeException("Should not reach here");
    }
  }
  
  static class BasicBlock
  {
    private boolean _changed;
    static final int _dead_basic_block = -2;
    static final int _unreached = -1;
    int _bci;
    int _end_bci;
    int _max_locals;
    int _max_stack;
    CellTypeStateList _state;
    int _stack_top;
    int _monitor_top;
    
    CellTypeStateList vars()
    {
      return _state;
    }
    
    CellTypeStateList stack()
    {
      return _state.subList(_max_locals, _state.size());
    }
    
    boolean changed()
    {
      return _changed;
    }
    
    void setChanged(boolean s)
    {
      _changed = s;
    }
    
    boolean isReachable()
    {
      return _stack_top >= 0;
    }
    
    boolean isDead()
    {
      return _stack_top == -2;
    }
    
    boolean isAlive()
    {
      return _stack_top != -2;
    }
    
    void markAsAlive()
    {
      if (Assert.ASSERTS_ENABLED)
      {
        Assert.that(isDead(), "must be dead");
        _stack_top = -1;
      }
    }
  }
  
  void initState()
  {
    _state_len = (_max_locals + _max_stack + _max_monitors);
    _state = new CellTypeStateList(_state_len);
    _state_vec_buf = new char[Math.max(_max_locals, Math.max(_max_stack, Math.max(_max_monitors, 1)))];
  }
  
  void makeContextUninitialized()
  {
    CellTypeStateList vs = vars();
    for (int i = 0; i < _max_locals; i++) {
      vs.get(i).set(CellTypeState.uninit);
    }
    _stack_top = 0;
    _monitor_top = 0;
  }
  
  int methodsigToEffect(Symbol signature, boolean isStatic, CellTypeStateList effect)
  {
    ComputeEntryStack ces = new ComputeEntryStack(signature);
    return ces.computeForParameters(isStatic, effect);
  }
  
  boolean mergeStateVectors(CellTypeStateList cts, CellTypeStateList bbts)
  {
    int len = _max_locals + _stack_top;
    boolean change = false;
    for (int i = len - 1; i >= 0; i--)
    {
      CellTypeState v = cts.get(i).merge(bbts.get(i), i);
      change = (change) || (!v.equal(bbts.get(i)));
      bbts.get(i).set(v);
    }
    if ((_max_monitors > 0) && (_monitor_top != -1))
    {
      int base = _max_locals + _max_stack;
      len = base + _monitor_top;
      for (i = len - 1; i >= base; i--)
      {
        CellTypeState v = cts.get(i).merge(bbts.get(i), i);
        
        change = (change) || (!v.equal(bbts.get(i)));
        bbts.get(i).set(v);
      }
    }
    return change;
  }
  
  void copyState(CellTypeStateList dst, CellTypeStateList src)
  {
    int len = _max_locals + _stack_top;
    for (int i = 0; i < len; i++) {
      if (src.get(i).isNonlockReference()) {
        dst.get(i).set(CellTypeState.makeSlotRef(i));
      } else {
        dst.get(i).set(src.get(i));
      }
    }
    if ((_max_monitors > 0) && (_monitor_top != -1))
    {
      int base = _max_locals + _max_stack;
      len = base + _monitor_top;
      for (int i = base; i < len; i++) {
        dst.get(i).set(src.get(i));
      }
    }
  }
  
  void mergeStateIntoBB(BasicBlock bb)
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(bb.isAlive(), "merging state into a dead basicblock");
    }
    if (_stack_top == _stack_top)
    {
      if (_monitor_top == _monitor_top)
      {
        if (mergeStateVectors(_state, _state)) {
          bb.setChanged(true);
        }
      }
      else
      {
        reportMonitorMismatch("monitor stack height merge conflict");
        
        _monitor_top = -1;
        bb.setChanged(true);
        _monitor_safe = false;
      }
    }
    else if (!bb.isReachable())
    {
      copyState(_state, _state);
      _stack_top = _stack_top;
      _monitor_top = _monitor_top;
      bb.setChanged(true);
    }
    else
    {
      throw new RuntimeException("stack height conflict: " + _stack_top + " vs. " + _stack_top);
    }
  }
  
  void mergeState(int bci, int[] data)
  {
    mergeStateIntoBB(getBasicBlockAt(bci));
  }
  
  void setVar(int localNo, CellTypeState cts)
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that((cts.isReference()) || (cts.isValue()) || (cts.isAddress()), "wrong celltypestate");
    }
    if ((localNo < 0) || (localNo > _max_locals)) {
      throw new RuntimeException("variable write error: r" + localNo);
    }
    vars().get(localNo).set(cts);
  }
  
  CellTypeState getVar(int localNo)
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(localNo < _max_locals + _nof_refval_conflicts, "variable read error");
    }
    if ((localNo < 0) || (localNo > _max_locals)) {
      throw new RuntimeException("variable read error: r" + localNo);
    }
    return vars().get(localNo).copy();
  }
  
  CellTypeState pop()
  {
    if (_stack_top <= 0) {
      throw new RuntimeException("stack underflow");
    }
    return stack().get(--_stack_top).copy();
  }
  
  void push(CellTypeState cts)
  {
    if (_stack_top >= _max_stack) {
      throw new RuntimeException("stack overflow");
    }
    stack().get(_stack_top++).set(cts);
  }
  
  CellTypeState monitorPop()
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(_monitor_top != -1, "monitorPop called on error monitor stack");
    }
    if (_monitor_top == 0)
    {
      _monitor_safe = false;
      _monitor_top = -1;
      
      reportMonitorMismatch("monitor stack underflow");
      
      return CellTypeState.ref;
    }
    return monitors().get(--_monitor_top).copy();
  }
  
  void monitorPush(CellTypeState cts)
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(_monitor_top != -1, "monitorPush called on error monitor stack");
    }
    if (_monitor_top >= _max_monitors)
    {
      _monitor_safe = false;
      _monitor_top = -1;
      
      reportMonitorMismatch("monitor stack overflow");
      
      return;
    }
    monitors().get(_monitor_top++).set(cts);
  }
  
  CellTypeStateList vars()
  {
    return _state;
  }
  
  CellTypeStateList stack()
  {
    return _state.subList(_max_locals, _state.size());
  }
  
  CellTypeStateList monitors()
  {
    return _state.subList(_max_locals + _max_stack, _state.size());
  }
  
  void replaceAllCTSMatches(CellTypeState match, CellTypeState replace)
  {
    int len = _max_locals + _stack_top;
    boolean change = false;
    for (int i = len - 1; i >= 0; i--) {
      if (match.equal(_state.get(i))) {
        _state.get(i).set(replace);
      }
    }
    if (_monitor_top > 0)
    {
      int base = _max_locals + _max_stack;
      len = base + _monitor_top;
      for (i = len - 1; i >= base; i--) {
        if (match.equal(_state.get(i))) {
          _state.get(i).set(replace);
        }
      }
    }
  }
  
  void printStates(PrintStream tty, CellTypeStateList vector, int num)
  {
    for (int i = 0; i < num; i++) {
      vector.get(i).print(tty);
    }
  }
  
  void printCurrentState(PrintStream tty, BytecodeStream currentBC, boolean detailed)
  {
    if (detailed)
    {
      tty.print("     " + currentBC.bci() + " vars     = ");
      printStates(tty, vars(), _max_locals);
      tty.print("    " + Bytecodes.name(currentBC.code()));
      switch (currentBC.code())
      {
      case 182: 
      case 183: 
      case 184: 
      case 185: 
      case 186: 
        int idx = currentBC.getIndexBig();
        tty.print(" idx " + idx);
      }
      tty.println();
      tty.print("          stack    = ");
      printStates(tty, stack(), _stack_top);
      tty.println();
      if (_monitor_top != -1)
      {
        tty.print("          monitors = ");
        printStates(tty, monitors(), _monitor_top);
      }
      else
      {
        tty.print("          [bad monitor stack]");
      }
      tty.println();
    }
    else
    {
      tty.print("    " + currentBC.bci() + "  vars = '" + stateVecToString(vars(), _max_locals) + "' ");
      
      tty.print("     stack = '" + stateVecToString(stack(), _stack_top) + "' ");
      if (_monitor_top != -1) {
        tty.print("  monitors = '" + stateVecToString(monitors(), _monitor_top) + "'  \t" + Bytecodes.name(currentBC.code()));
      } else {
        tty.print("  [bad monitor stack]");
      }
      switch (currentBC.code())
      {
      case 182: 
      case 183: 
      case 184: 
      case 185: 
      case 186: 
        int idx = currentBC.getIndexBig();
        tty.print(" idx " + idx);
      }
      tty.println();
    }
  }
  
  void reportMonitorMismatch(String msg)
  {
    if (Assert.ASSERTS_ENABLED)
    {
      System.err.print("    Monitor mismatch in method ");
      method().printValueOn(System.err);
      System.err.println(": " + msg);
    }
  }
  
  void initializeBB()
  {
    _gc_points = 0;
    _bb_count = 0;
    _bb_hdr_bits = new BitMap((int)_method.getCodeSize());
  }
  
  void markBBHeadersAndCountGCPoints()
  {
    initializeBB();
    
    boolean fellThrough = false;
    
    TypeArray excps = method().getExceptionTable();
    for (int i = 0; i < excps.getLength(); i += 4)
    {
      int handler_pc_idx = i + 2;
      markBB(excps.getIntAt(handler_pc_idx), null);
    }
    BytecodeStream bcs = new BytecodeStream(_method);
    int bytecode;
    while ((bytecode = bcs.next()) >= 0)
    {
      int bci = bcs.bci();
      if (!fellThrough) {
        markBB(bci, null);
      }
      fellThrough = jumpTargetsDo(bcs, new JumpClosure()
      {
        public void process(GenerateOopMap c, int bcpDelta, int[] data)
        {
          c.markBB(bcpDelta, data);
        }
      }, null);
      switch (bytecode)
      {
      case 168: 
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(!fellThrough, "should not happen");
        }
        markBB(bci + Bytecodes.lengthFor(bytecode), null);
        break;
      case 201: 
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(!fellThrough, "should not happen");
        }
        markBB(bci + Bytecodes.lengthFor(bytecode), null);
      }
      if (possibleGCPoint(bcs)) {
        _gc_points += 1;
      }
    }
  }
  
  boolean isBBHeader(int bci)
  {
    return _bb_hdr_bits.at(bci);
  }
  
  int gcPoints()
  {
    return _gc_points;
  }
  
  int bbCount()
  {
    return _bb_count;
  }
  
  void setBBMarkBit(int bci)
  {
    _bb_hdr_bits.atPut(bci, true);
  }
  
  void clear_bbmark_bit(int bci)
  {
    _bb_hdr_bits.atPut(bci, false);
  }
  
  BasicBlock getBasicBlockAt(int bci)
  {
    BasicBlock bb = getBasicBlockContaining(bci);
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(_bci == bci, "should have found BB");
    }
    return bb;
  }
  
  BasicBlock getBasicBlockContaining(int bci)
  {
    BasicBlock[] bbs = _basic_blocks;
    int lo = 0;int hi = _bb_count - 1;
    while (lo <= hi)
    {
      int m = (lo + hi) / 2;
      int mbci = _bci;
      if (m == _bb_count - 1)
      {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that((bci >= mbci) && (bci < method().getCodeSize()), "sanity check failed");
        }
        return bbs[m];
      }
      int nbci = 1_bci;
      if ((mbci <= bci) && (bci < nbci)) {
        return bbs[m];
      }
      if (mbci < bci)
      {
        lo = m + 1;
      }
      else
      {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(mbci > bci, "sanity check");
        }
        hi = m - 1;
      }
    }
    throw new RuntimeException("should have found BB");
  }
  
  void interpBB(BasicBlock bb)
  {
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(bb.isReachable(), "should be reachable or deadcode exist");
    }
    restoreState(bb);
    
    BytecodeStream itr = new BytecodeStream(_method);
    
    int lim_bci = nextBBStartPC(bb);
    itr.setInterval(_bci, lim_bci);
    if (Assert.ASSERTS_ENABLED) {
      Assert.that(lim_bci != _bci, "must be at least one instruction in a basicblock");
    }
    itr.next();
    while ((itr.nextBCI() < lim_bci) && (!_got_error))
    {
      if ((_has_exceptions) || (_monitor_top != 0)) {
        doExceptionEdge(itr);
      }
      interp1(itr);
      itr.next();
    }
    if (!_got_error)
    {
      if (Assert.ASSERTS_ENABLED) {
        Assert.that(itr.nextBCI() == lim_bci, "must point to end");
      }
      if ((_has_exceptions) || (_monitor_top != 0)) {
        doExceptionEdge(itr);
      }
      interp1(itr);
      
      boolean fall_through = jumpTargetsDo(itr, new JumpClosure()
      {
        public void process(GenerateOopMap c, int bcpDelta, int[] data)
        {
          c.mergeState(bcpDelta, data);
        }
      }, null);
      if (_got_error) {
        return;
      }
      if (itr.code() == 169)
      {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(!fall_through, "cannot be set if ret instruction");
        }
        retJumpTargetsDo(itr,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd