harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Harmony Bootstrap JVM <boot...@earthlink.net>
Subject Re: Some questions about the architecture
Date Fri, 21 Oct 2005 15:27:42 GMT

Comments below.

-----Original Message-----
From: Rodrigo Kumpera <kumpera@gmail.com>
Sent: Oct 20, 2005 1:49 PM
To: harmony-dev@incubator.apache.org
Subject: Re: Some questions about the architecture

...snip...
>
>
> By IP I mean Intruction Pointer, the  EIP register in x86 f.e. What I
> mean was something like this:
>
> void throw_exception(jobject_t *ex) {
>         long * ip = (*(&ex - 1)); //the return address is after the arguments
>         long * sp = (*(&ex - 2)); //the old frame pointer is after the return address
>         jclass_t * cl = ex->vtable->class_obj;
>
>         printf("obj 0x%x ip 0x%x sp 0x%x\n", obj, ip, sp);
>
>         printf("------\n");
>         //this code performs stack unwinding, it misses synchronized methods .
>         while(isNotThreadBaseFunction(ip)) {
>                 printf("trace element ip 0x%x sp 0x%x\n", ip, sp);
>                 catch_info_t * info = find_catch_info(ip, cl);
>                 if(info) restore_to(ip, sp, ex, info);
>                 ip = (long *)*(sp+ 1);
>                 sp = (long *)*sp;
>         }
>         printf("-----\n");
>         fflush(stdout);
>         //uncaught exception, must never happen, this is a JVM bug.
>         //in my vm, at least, uncaught exceptions where handled by the
> implementation of Thread.
> }
>
> find_catch_info was implemented in java, but looks something like this
> (don't bother with the linear search for now):
>
> catch_info * find_catch_info(long *ip, jclass_t *ex) {
>   if(ip < vm ->compiledMethodsStart || ip > vm->compiledMethodsEnd)
>       return 0;
>   foreach(compiled_method_t * m, vm->compiledMethods)
>       if(m->owns(ip)) //this instruction pointer belongs to this method
>          return m->findCatch(ip, ex); //find a catch block for the exception
>   return 0;
> }
>
> restore_to is implemented this way:
>
> state void restore_to(long *ip, long *frame, jobject_t *ex, catch_info *info)  {
>    asm("movl %0, %%eax;"
>                 "movl %1, %%ebx;"
>                 "movl %2, %%ecx;"
>                 "movl %3, %%edx;"
>                 "movl %%ebx, %%ebp;"
>                 "movl %%ebp, %%esp;"
>                 "subl %%edx, %%esp;"
>                 "pushl %%ecx;"
>                 "pushl %%eax;"
>                 "ret;"
>                         :
>                         :"m"(ip), "m"(frame), "m"(ex), "m"(info->stackDelta)
> //stackDelta is local storage + temp storage
>                         :"%eax", "%ebx", "%ecx", "%edx");
> }
>
> This stuff works only in a JIT only enviroment, but only some minor
> tweaks would be required to work in a hybrid enviroment
>
> ---
>
> Thanks for your clarification on the term 'IP address'.  Back to your
> question:
>
>     > It does, but by stack walking I meant not returning null, but having
>     > the code analise the call stack for a proper IP address to use.
>
> In this implementation, unprotected exceptions are handled in
> 'jvm/src/opcode.c' by references to thread_throw_exception()
> in 'jvm/src/thread.c'.  Stack printing is available through the
> various utilities (esp. jvmutil_print_stack_common())
> in 'jvm/src/jvmutil.c'.  Protected exceptions are handled by the
> exception list found in the 'jvm_pc' field 'excpatridx'.  When an
> exception is found, this list is queried (by the ATHROW opcode,
> which will be available with 0.0.2) and, if found, JVM thread control
> is transferred to that handler.  If it is _not_ found, thread_throw_exception()
> is called and the thread dies at the end of opcode_run().  This functionality
> looks very similar to your code shown above.
>
> ---
> >
> ...snip...
> >
> > Dan Lydick
> >
>
>
>
>
> Dan Lydick
>


Dan,

I'm confused by all this classification on types of exceptions (from
the code you make a distiction from caugth/uncaugth and
Exception/Error/Throwable). My view is that these are not an issue for
the runtime besides the verifier.

We could have the following code on java.lang.Thread:

private void doRun() {
  try {
    if(runnable != null)
     runnable.run();
   else
      this.run();
  } catch(Throwable t) {
    this.threadGroup.uncaughtException(t);
  }
  terminate();
}


The runtime would only assert that the exception have not fallen out
and not care about how it would be handled.

---

I agree that the verifier should look into this, but what happens if
you get a divide by zero error?  Or a null pointer exception?  These
are not available to the verifier, but are runtime conditions that
do not arise in advance.  Therefore, they need to be checked at
run time and exceptions thrown.  These two examples are subclasses
to java.lang.RuntimeException and may be thrown at any time.

Try taking a look at the JVM specification, section 2.16.  I have tried
to write my code to implement the functionality described there.  I
would appreciate you studying section 2.16 and comparing it against
my implementation of the exception mechanism to see if you find
any flaws in my logic.  If so, please let me know what you find.  One
question that I have is that in 'jvm/src/opcode.c' there are a number
of references to thread_throw_exception().  The first parameter is the
type of event, either a java.lang.Error or a java.lang.Exception or
a java.lang.Throwable.  Can I get by without java.lang.Throwable?
Everything I throw so far is either an Error or an Exception.  I just
included Throwable in case I had something else because I think I
remember something in the spec about "something that is not an
Error or an Exception," so I thought I would try to cover all angles.
Thanks for your help.


Dan Lydick

---



Dan Lydick

Mime
View raw message