Default method resolution question
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Mon Sep 16 04:39:45 PDT 2013
Hi,
I hit an assert when doing CHA for a default method during JIT-compilation:
# Internal Error (src/share/vm/code/dependencies.cpp:1411)
# assert(wf.check_method_context(ctxk, m)) failed: proper context
Call stack:
Dependencies::find_unique_concrete_method
ciMethod::find_monomorphic_target
Compile::optimize_inlining
Compile::optimize_virtual_call
Parse::do_call
...
What does check_method_context do it resolves the method again and then
do pointer comparison to check that result it the same. And it doesn't
work for default methods:
Dependency method not found in the associated context:
context = javasoft.sqe.tests.api.java.util.TreeSet.SharedData$1
method = java.util.TreeSet::parallelStream
found = java.util.TreeSet::parallelStream
My main suspicion is that the problem is in check_method_context (the
check is imprecise and already has a number of exceptions), but I want
to double-check. Does method resolution behavior I see look normal?
Here are my observations.
Method passed into Dependencies::find_unique_concrete_method:
{method}
- this oop: 0xb69eab58
- method holder: 'java/util/TreeSet'
- constants: 0xb69eacd8 constant pool [305] {0xb69eacdc} for
'java/util/TreeSet' cache=0xb69eb2b8
- access: 0x80001041 public volatile synthetic
- name: 'parallelStream'
- signature: '()Ljava/util/stream/Stream;'
- max stack: 2
- max locals: 1
- size of params: 1
- method size: 14
- highest level: 4
- vtable index: 22
- i2i entry: 0xfa00b940
- adapters: AHE at 0x081982ac: 0xa0000000 i2c: 0xfa0aaec0 c2i:
0xfa0aaf49 c2iUV: 0xfa0aaf28
- compiled entry 0xfa1704ec
- code size: 5
- code start: 0xb69eab44
- code end (excl): 0xb69eab49
- method data: 0xb6806b10
- checked ex length: 0
- localvar length: 0
- compiled code: nmethod 584533 988
java.util.TreeSet::parallelStream (5 bytes)
Method resolved in check_method_context:
{method}
- this oop: 0xb69ea978
- method holder: 'java/util/TreeSet'
- constants: 0xb69eacd8 constant pool [305] {0xb69eacdc} for
'java/util/TreeSet' cache=0xb69eb2b8
- access: 0x1041 public volatile synthetic
- name: 'parallelStream'
- signature: 'Ljava/util/stream/Stream'
- max stack: 2
- max locals: 1
- size of params: 1
- method size: 14
- vtable index: 22
- i2i entry: 0xfa00b940
- adapters: AHE at 0x081982ac: 0xa0000000 i2c: 0xfa0aaec0 c2i:
0xfa0aaf49 c2iUV: 0xfa0aaf28
- compiled entry 0xfa0aaf49
- code size: 5
- code start: 0xb69ea964
- code end (excl): 0xb69ea969
- method data: 0xb6584270
- checked ex length: 0
- localvar length: 0
Class hierarchy:
javasoft.sqe.tests.api.java.util.TreeSet.SharedData$1 extends
java.util.TreeSet<E>
java.util.TreeSet<E> extends java.util.AbstractSet<E>
implements java.util.NavigableSet<E>,
java.lang.Cloneable,
java.io.Serializable
public interface Collection<E> extends Iterable<E> {
default Stream<E> parallelStream() { ... }
Original method pointer is acquired through ciMethod::resolve_invoke call.
resolved_method && CallInfo from LinkResolver::resolve_virtual_call:
(dbx) print resolved_method
resolved_method = {
_value = 0xb69ea978 <=============
_thread = 0x8232c00
}
(dbx) print result
result = {
_resolved_klass = {
_value = 0xb69ea618
}
_selected_klass = {
_value = 0xb69f3bb0
}
_resolved_method = {
_value = 0xb69ea978 <===========
_thread = 0x8232c00
}
_selected_method = {
_value = 0xb69eab58 <===========
_thread = 0x8232c00
}
_vtable_index = 22
_resolved_appendix = {
_handle = (nil)
}
_resolved_method_type = {
_handle = (nil)
}
}
_resolved_method is the same as computed in check_method_context.
_selected_method is loaded from vtable at linkResolver.cpp:943:
selected_method = methodHandle(THREAD,
inst->method_at_vtable(vtable_index));
Best regards,
Vladimir Ivanov
More information about the hotspot-runtime-dev
mailing list