[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: soot.baf.RetInst



On Fri, 2002-04-05 at 21:11, David Bélanger wrote:
> I'm not that familiar about the singleton model.
> For me it would mean a single instance of an object and
> object representing the same, immutable, data share
> the same instance.
> 
> If you consider soot.RefType though, a new instance
> is returned every time v is invoked even if the
> the same class name is provided.  It shouldn't make a difference
> in practice, but if you rename class name (for space
> saving) then you get into trouble.
> 
> Also, types used a lot like String could lead to a lot
> of memory used.

As far as I can see, RefType makes no use of the singleton pattern. I
think the intended design is the "flyweight" pattern. The internal
static field that is called "singleton" should really be called
"emptyType" or "nullType", since that what it is.

If you are concerned about duplicate RefTypes taking up too much space,
a simple solution would be to us the String.intern() method on the given
class name:

     public static RefType v(String className)
     {
         return new RefType(className.intern());
     }

However, David has the right idea if we wan to make RefType a proper
flyweight. The method I normally use in such cases would look like:

    public static RefType v(String className)
    {
      RefType t = (RefType) nameToRefType.get(className);

      if ( t == null ) // not in table => no flyweight exists yet
      {
        nameToRefType.put(className, t = new RefType(className.intern()));
      }

      return t;
    }

This would allow us to simplify the equals method to:

    public boolean equals(Object o)
    {
      return (this == o); // this is valid because we are using flyweights
    }

If you are concerned about hashing performance, I would also suggest
precomputing the hash code using a function known to work well in symbol
tables. For example,

    private int code = 0;

    private RefType(String className)
    {
      this.className = className;

      char[] chars = className.toCharArray();
      for (int i=0; i<chars.length; i++)
        code = (code << 1) ^ chars[i];
    }

    public int hashCode() { return code; }

-- 
Rhodes Brown
Sable Research - McGill University

Web:    http://www.sable.mcgill.ca
Email:  rhodesb@sable.mcgill.ca