The right locks for frame rewriting / Exceptions

David Holmes David.Holmes at Sun.COM
Sat Oct 20 06:13:43 PDT 2007


Peter,

Regarding the thread question. Take a look at attach_current_thread to see 
how a Java Thread object is created for an existing native thread. There 
should always be an associated Thread oop while a JavaThread is active. Of 
course when you are starting a java.lang.Thread you already have the Thread oop.

David Holmes

Peter Helfer wrote:
> Ok, I found one answer myself... for the rest I am still trying to 
> figure out. One additional question which came to my mind:
> 
> When creating a new JavaThread, do I have to pass a java.lang.Thread-Oop 
> to the newly created thread ? And if so, what is the right way to create 
> that ?
> 
>  
> JavaThread* TPool::createThread(ThreadFunction entrypoint){
>         JavaThread* result_thread = NULL;
>         {
>          MutexLocker ml_thread(Threads_lock);
>          result_thread = new JavaThread(entrypoint); //size = 0
>          if (result_thread->osthread() != NULL) {
>                 //jobject javalangThreadObj = DO I NEED THAT ?
>                 // result_thread->prepare(javalangThreadObj);
>          } else {
>                 delete result_thread;
>                 result_thread = NULL;
>                 // no message of failed thread creation...
>          }
>          // Thread::start(result_thread) -- nope, we are just creating it...
>         }
> }
>  
> 
> 
> Regards, Peter
> 
> 
> 
> 2007/10/18, Peter Helfer < peter.helfer.java at gmail.com 
> <mailto:peter.helfer.java at gmail.com>>:
> 
>     Hi all
> 
>     I'm on the way to do some frame-hacking (patch_pc, copy some frames
>     into another thread..)
> 
>     Now I need to be sure, that what I am doing is safe with regard to:
>     - any GC operation working on either of the two thread stacks
>     - neither thread is running currently on that part of the stack
>       = one thread must be sleeping, the other might call a VM function
>     to do exactly that stack-changing operation (even in its own stack..)
>     Q1) what kind of lock(s) is suited for this operation ?
> 
> 
> 
>     Additionally, assume I have an interpreted method calling an
>     interpreted method; this one rethrows an exception - that is, the
>     local exception handler couldn't handle the exception. Did I get
>     that right: (x86-specific)
> 
>     - Bytecode 'athrow' calls Interpreter::throw_exception_entry() with
>     the exception object (oop) in RAX. This empties the expression stack
>     and FPU stack, and calls
>     InterpreterRuntime::exception_handler_for_exception. This resolves
>     the exception into the handler for it, returning the exception in
>     RDX; and the handler in RAX.
>     The resolving process checks whether a 'catch' is around for that
>     (methodOop->fast_exception_handler_bci_for greater zero), adds this
>     BCI to the BCP, (handler_pc = h_method->code_base() + handler_bci)
>     and returns the dispatch table entry for that one: continuation =
>     Interpreter::dispatch_table(vtos)[*handler_pc];
>     Oh, Im getting off topic: if there is no handler around, it returns
>     the Interpreter::remove_activation_entry().
> 
>     This remove_activation_entry does save the exception from the stack
>     into RAX, and saves RAX again in currentThread::vmResult. Now it
>     calls masm->remove_activation(TosState=vtos, returnaddr=rdx,
>     throwMonitorException=false, installMonitorException=true,
>     notifyJVMDI=false). After the removal, it restores the exception
>     into RAX (verifyOop as well), and calls just again (save temporarly
>     RAX, RDX) InterpreterRuntime::exception_handler_for_exception, save
>     this result into RBX (restore RDX, RAX) and jump there..
> 
>     Q2) Now what does remove_activation exactly ? It does unlocking of
>     objects under certain circumstances... now could somebody literate
>     please shed some light on that ? I haven't figured out, how that
>     beast works... 
> 
> 
> Doh, I can answer that myself after scrolling around... Read the source, 
> luke :-)  interp_masm_i486.cpp says:
> 
> // remove activation
> //
> // Unlock the receiver if this is a synchronized method.
> // Unlock any Java monitors from synchronized blocks.
> // Remove the activation from the stack.
> //
> // If there are locked Java monitors
> //    If throw_monitor_exception
> //       throws IllegalMonitorStateException
> //    Else if install_monitor_exception
> //       installs IllegalMonitorStateException
> //    Else
> //       no error processing
> 
> 
>     Q3) implicit exceptions are being generated by some fancy path
>     leading to THROW_MSG/THROW_OOP which finally creates a exception oop
>     of the desired type, and sets that for the thread: 
>     thread->set_pending_exception(h_exception(), file, line) - but where
>     are they picked up again ?
> 
> 
> 
>     Regards, Peter
> 
> 
> 
>     PS: the next questions will be most probably about deoptimizing...
>     be prepared for nasty questions :-) !
> 
> 
> 
> 
> 



More information about the hotspot-runtime-dev mailing list