The right locks for frame rewriting / Exceptions
Tom Rodriguez
Thomas.Rodriguez at Sun.COM
Mon Oct 22 10:06:02 PDT 2007
> 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 ?
The main rule for modifying thread stacks in arbitrary ways is that any
changes which aren't thread safe need to guarantee that no safepoint
checks are performed while the stack is in an unsafe state. This means
that you can perform VM transitions or acquire most locks. The standard
MutexLocker includes safepoint checks though those can be skipped if you
use a MutexLockerEx. You need to make sure you don't stop the system
for an arbitrarily long time either since you'll be stopping all threads
if a GC is required during this period. The best example of this is the
deoptimization code which has an initial setup which is done without any
special care in the VM and then once it's collected all the information
it needs it it proceeds carefully while constructing the new interpreter
frames and populating them. A NoSafepointVerifier can be used to make
sure you aren't getting safepoint checks in situations you don't want.
It's possible you'd need your own lock to coordinate your work though I
don't know whether that's true. You'd need to create what's called a
leaf lock, meaning that no other locks can be acquired while it's held
and that it's generally held for a relatively short period of time. The
Patching_lock is an example of this.
Obviously both threads would have to be blocked at the point you are
doing this. How you coordinate them is up to you. You could use a
Monitor to coordinate them, though off hand I can't remember whether
you'd have to worry about any safepoint issues or if that's take care of
for you.
> 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...
It basically remove an existing frame either so that you can resume in
the caller or so that you can reexecute it. In the case of throwing an
exception where there is no handler in the current frame it unlocks any
locks held and then execution should move into the exception dispatch
code to figure out how to handle exceptions in the caller frame. The
basic model of exception dispatch is that you check the current frame
for a handler and resume execution at that handler if it exists,
otherwise you remove the current frame and then find the exception
handler for the current return address, which might be an interpreter or
compiled frame.
>
> 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 ?
The runtime sets up newly thrown exceptions in the _pending_exception
field of the thread. Runtime code written in C++ checks this field
directly. Generated code normally checks this field on return from
calls to the runtime and the value is moved out into a special register
if it's non-null and then we jump to the exception dispatch code. The
call_VM code normally takes care of this and it's a requirement that
generated code check this on return, otherwise the exception could hang
around forever.
tom
>
>
> 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