RFR: 8264004: Don't use TRAPS if no exceptions are thrown [v2]
David Holmes
david.holmes at oracle.com
Tue Mar 23 13:01:40 UTC 2021
On 23/03/2021 9:54 pm, Coleen Phillimore wrote:
> On Tue, 23 Mar 2021 05:52:51 GMT, Ioi Lam <iklam at openjdk.org> wrote:
>
>>> src/hotspot/share/prims/jvmtiRedefineClasses.hpp line 484:
>>>
>>>> 482: void rewrite_cp_refs_in_method(methodHandle method,
>>>> 483: methodHandle * new_method_p, TRAPS);
>>>> 484: bool rewrite_cp_refs_in_methods(InstanceKlass* scratch_class, TRAPS);
>>>
>>> This method clears any pending exception and so should not be a TRAPS method.
>>
>> `VM_RedefineClasses::load_new_class_versions` also seems to never throw. These functions should be changed to take a `Thread*` parameter, and should use `HandleMark em(thread);` to guarantee that an exception never leaves the function.
>
> Both of these functions are good examples of the convention that we're trying to agree on. In, load_new_class_versions, TRAPS is passed to materialize THREAD. THREAD is used then in a lot of places, and also to pass to SystemDictionary::parse_stream(...TRAPS), which does have an exceptional return that must be handled.
> Removing TRAPS then adding:
> JavaThread* current = JavaThread::current();
> changing THREAD to current in most of the places seems ok, but passing 'current' to SystemDictionary::resolve_from_stream loses the information visually that this function returns an exception that must be handled.
Okay ...
Only a function that upon return may have directly, or indirectly,
caused an exception to be pending should be declared with TRAPS. The
caller is then expected to use the CHECK macros under most conditions.
If a function is going to call a TRAPS function but clear the exception,
then it should manifest a THREAD variable and pass that, both to
indicate the called function is TRAPS and to allow its own use of the
exception macros that depend on THREAD. But that function should not
itself declare TRAPS just to get THREAD.
How to manifest THREAD depends on the exact context, and we already have
these cases today:
- Thread* THREAD = Thread::current();
- Thread* THREAD = <pre-existing current thread variable by some name>
In this case I would expect to see:
jvmtiError VM_RedefineClasses::load_new_class_versions(Thread* current) {
...
ResourceMark rm(current);
JvmtiThreadState *state =
JvmtiThreadState::state_for(current->as_Java_thread());
...
HandleMark hm(current);
...
Handle the_class_loader(current, the_class->class_loader());
Handle protection_domain(current, the_class->protection_domain());
...
Thread* THREAD = current; // For exception processing
InstanceKlass* scratch_class = SystemDictionary::parse_stream(
the_class_sym,
the_class_loader,
&st,
cl_info,
THREAD);
...
if (HAS_PENDING_EXCEPTION) {
...
the_class->link_class(THREAD);
if (HAS_PENDING_EXCEPTION) {
...
I'll point out, to be clear that I recognise it, that the existing CATCH
macro does not fit in with these conventions as you only apply CATCH to
a function that never lets an exception escape, and such a function
should not be declared TRAPS and should never be passed THREAD, but you
need to manifest THREAD to use CATCH. I consider the CATCH macro to be a
well-intentioned mistake.
> We need some meta-writeup rather than these decisions made in pull requests, because if we made these decisions collectively, I missed out.
Once we've fleshed things out we can propose them for the style guide.
But it is easier to discuss concrete examples.
The important things (to me at least) at the moment are:
- we get rid of TRAPS from non-exception throwing code
- we pave the way to allow changing of TRAPS to declare "JavaThread*
THREAD" so that functions that always expect to be called on a
JavaThread can explicitly indicate that. (And that goes for non-TRAPS
functions too.)
- we simplify/clarify code that uses an arbitrary mix of names for the
current thread, and establish simple conventions to use going forward
and to apply a-posteri on a time available basis when we do cleanups
Cheers,
David
-----
> -------------
>
> PR: https://git.openjdk.java.net/jdk/pull/3141
>
More information about the serviceability-dev
mailing list