RFR: 8274983: Pattern.matcher performance regression after JDK-8238358
Dean Long
dlong at openjdk.java.net
Sat Nov 20 10:52:07 UTC 2021
On Sat, 20 Nov 2021 04:40:51 GMT, Xin Liu <xliu at openjdk.org> wrote:
>> It looks like this does what we want for private interface methods, but I'm wondering if we handle all combinations of private/final and invokevirtual/invokeinterface, or are we missing some cases where can_be_statically_bound() would return true?
>
> hi, @dean-long,
>
> I think C1 covers all cases as long as the target method is loaded. I have seen cases which target methods haven't been loaded in startup time, but they are rare.
>
> ciMethod::can_be_statically_bound() return true if the method is private or final. The matrix shows the modifiers of target methods.
>
> | | final | private |
> |-----------------|-------|---------|
> | invokevirtual | 1 | 2 |
> | invokespecial | N/A1 | 3 |
> | invokeinterface | N/A2 | 4 |
>
> 1. generates the optimized virtual call because [x->target_is_final()](https://github.com/openjdk/jdk/blob/master/src/hotspot/share/c1/c1_LIRGenerator.cpp#L2799) is true.
> 2. transforms to `invokespecial` [here](https://github.com/openjdk/jdk/blob/master/src/hotspot/share/c1/c1_GraphBuilder.cpp#L1885) , then it will be case 3.
> 3. generates the optimize virtual call because `x->code() == Bytecodes::_invokespecial` is true.
> 4. is what this patch covers.
>
> NA-1. I think it's impossible for javac. it would be an optimized virtual call like case 3 even it existed.
> NA-2: it's an illegal modifier for an interface method.
> https://docs.oracle.com/javase/specs/jls/se17/html/jls-9.html#jls-InterfaceMethodModifier
Thanks @navyxliu. I wonder if we can do 2) and 3) for invokeinterface, simplying the patch. Something like:
// Some methods are obviously bindable without any type checks so
// convert them directly to an invokespecial or invokestatic.
if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
switch (bc_raw) {
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface::
code = Bytecodes::_invokespecial;
break;
[...]
// invoke-special-super
if (code == Bytecodes::_invokespecial && !target->is_object_initializer()) {
ciInstanceKlass* sender_klass = calling_klass;
if (sender_klass->is_interface()) {
[...]
What do you think?
-------------
PR: https://git.openjdk.java.net/jdk/pull/6445
More information about the hotspot-compiler-dev
mailing list