RFR: 8338471: Refactor Method::get_new_method() for better NoSuchMethodError handling [v2]
David Holmes
dholmes at openjdk.org
Mon Sep 9 21:48:05 UTC 2024
On Mon, 9 Sep 2024 16:03:26 GMT, Matias Saavedra Silva <matsaave at openjdk.org> wrote:
>> This redefine code is really complicated. Obsolete methods, which includes deleted methods get an incremented idnum in check_methods_and_mark_as_obsolete.
>>
>> // obsolete methods need a unique idnum so they become new entries in
>> // the jmethodID cache in InstanceKlass
>> assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
>> u2 num = InstanceKlass::cast(_the_class)->next_method_idnum();
>> if (num != ConstMethod::UNSET_IDNUM) {
>> old_method->set_method_idnum(num);
>> }
>>
>> When get_new_method() is called it compares InstanceKlass::_methods[idnum], then compares the Method at that index to the idnum that the method has stored. For deleted methods, this will return nullptr because the idnum comparison in method_with_idnum will not match, or idnum for the deleted method is greater than InstanceKlass::_methods.length(). I think it is sufficient to check for nullptr in get_new_method() for deleted methods but also the explicit is_deleted() comparison is much easier to understand that it's the right answer.
>>
>> Yes, there could be an assert in get_new_method(), the method passed in is_old(). All redefined methods are marked as is_old(). I believe all callers test this before making this call.
>
> Coleen is correct, all the callers do indeed check that the method `is_old()` but I think it's fine if we assert that in `get_new_method()` to make it clear that it is a requirement. The method `method_with_idnum()` can return nullptr here:
>
> if (m == nullptr || m->method_idnum() != idnum) {
> for (int index = 0; index < methods()->length(); ++index) {
> m = methods()->at(index);
> if (m->method_idnum() == idnum) {
> return m;
> }
> }
> // None found, return null for the caller to handle.
> return nullptr;
>
> As the comment suggests, the caller should handle nullptr, which in this case is `get_new_method()`. The callers of get_new_method() try to handle this but I think it's cleaner to check inside the method.
So is it the case that `nullptr` implies deleted, and deleted implies `nullptr`? If so checking for both is redundant and confusing because it makes it look like there are two distinct cases.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/20874#discussion_r1750978607
More information about the hotspot-dev
mailing list