So I think this is the construct that is broken right now:

  public Object clone() {
    try {
      return super.clone();
    } catch (CloneNotSupportException cnse) {
      throw new RuntimeException(cnse);
    }
  }

Correct me if I'm wrong (I haven't studied the bytecode for this
scenario), but I thought the problem was that the exception handler we
introduce has the same range as the existing one, and never ends up
getting called -- thus never performing a MONITOREXIT on the resolve lock,
and thus tripping the method level accounting for monitors? 

It's hard to precisely express with source code, but I imagine our current
transformation would end up looking something like this: 

  public Object clone() {
    TCObject tco;            

    try {
      <T> returnValue;
      <T> toClone = this;
      tco = (toClone instanceof Manageable) ? 
        ((Manageable)toClone).__tc_managed() :
        null;
      if (tco != null) {
        MONITORENTER(tco.getResolveLock);
        tco.resolveAllRefs();
        returnValue = Util.fixTC(..);        
        MONITOREXIT(tco.getResolveLock());
      } else {
        returnValue = toClone.clone();
      }
      return returnValue;             
    } catch (CloneNotSupportException cnse) {
      throw new RuntimeException(cnse);
    } catch (Throwable t) {
      MONITOREXIT(tco.getResolveLock());
      throw t;
    }
  }

That code is all kinds of wrong (minimally in how it handles the resolve
lock monitor)

I'm probably missing something, but why can't we just put our processing
in a separate method and avoid any complications with existing exception
handlers? The code end up looking something like this then:

public Object clone() {
   try {
        return __tc_clone();
   } catch (CloneNotSupportedException cnse) {
      Throw new RuntimeException(cnse);
   }
} 

private Object __tc_clone() throws CloneNotSupportedException {
   TCObject tco = (this instanceof Manageable) ? 
      ((Manageable) this).__tc_managed() : 
      null;
   if (tco != null) {
      synchronized (tco.getResolveLock()) {
         tco.resolveAllRefs();
         return Util.fixTC(this, super.clone());
     }
   }

   return super.clone();  
}

The only real difference is that our special logic is self contained. 

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:tc-dev-
> [EMAIL PROTECTED] On Behalf Of Alex Miller
> Sent: Thursday, August 23, 2007 3:40 PM
> To: tc-dev
> Subject: Re: [tc-dev] [JIRA] Commented: (DEV-865)
> CloneNotSupportedException got swallowed and replaced by
> IllegalMonitorStateException
> 
> Anyone have any thoughts on this?
> 
> 


_______________________________________________
tc-dev mailing list
[email protected]
http://lists.terracotta.org/mailman/listinfo/tc-dev

Reply via email to