Hi JOSers,

Just wanted to interject some of my experience with threading,
exceptions and JVMs in this discussion.  I'm very familiar with how
all of this stuff works in Kaffe, so I think I've got good
credentials.  On the other hand, I've never looked at any of the JOS
code, so I only understand what you're working on from emails that fly 
back and forth.

Anyway...

Todd wrote:
> I do NOT want to rewrite every single function call in the JVM to
> (a) check all of /its/ calls for exceptions and abort back to
> runOpcode() (which will in turn, have to abort) and (b) return true
> or false depending on if an exception was thrown or not.

Yes you do.  You do want every caller be able to tell if functions it
called have aborted or are aborting.  Without fail, you will define
functions that need to execute special code for handling failures.
I see two ways of doing that.

Originally, Kaffe would throw exceptions from deep within native code
and these exceptions would correctly unwind the native stack all the
way back into Java code, and proceed from there looking for exception
handlers.  This worked fine in most cases.  (As an aside, Kaffe uses
the same stack for Java and native code.)

What we discovered later is that frequently native code needs to do
things like release locks, or free data structures if an error
occurs.  Example

        lock_ClassPool();
        ...     
        jc = get_Class(...);
        ...
        unlock_ClassPool();
        
If get_Class() throws an error and unwinds the stack, the ClassPool
doesn't get unlocked.  Thus, this caller of get_Class() really needs
to handle the error.  Either a full-blown exception handler (ugly in
C, but see the book _C Interfaces and Implementations_ by David Hanson
for a setjmp-based implementation), or explicit return codes from the
methods.  We opted for explicit returns codes.  At the least, you'll
need to do this in your code that implements exceptions and exception
handling.  (Can't have them throwing errors, now can we?)

On the other hand, as Todd points out:

> the native portion of the class library (classpath?) is where you
> can't get around exception-handling in native methods.

That is, calls into native functions like FileInputStream.read()
should be able to just directly throw exceptions that will unroll the
native stack like they unroll the java stack.  

We decided (err, Godmar Back who designed/implemented this for Kaffe,
decided) to make all VM internal functions return an integer status
code and take an exception description struct.

So, the above code effectively looks like this in Kaffe:

        lock_ClassPool();
        ...     
        success = get_Class(..., &errorInfo);
        ...
        unlock_ClassPool();

At some point, a caller in an appropriate context will do:

        if (!success)
                throwError(&errorInfo);

Error info contains things like the name of the exception (or an
exception object) and the string message, etc.

throwError() can still be called by any code (e.g., native methods for 
class library functions like read()), but you just have to agree on
what functions/libraries use return codes and which ones are allowed
to throw exceptions willy-nilly.  

I hope this helps some,

Pat

----- ----- ---- ---  ---  --   -    -      -         -               -
Pat Tullmann                                       [EMAIL PROTECTED]
                   ${HOME} is where the .emacs is.

_______________________________________________
Kernel maillist  -  [EMAIL PROTECTED]
http://jos.org/mailman/listinfo/kernel

Reply via email to