Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
8fdb95ad
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8fdb95ad
编写于
3月 18, 2009
作者:
A
acorn
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
Reviewed-by: kamg, coleenp
上级
579d807c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
176 addition
and
155 deletion
+176
-155
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+4
-3
src/share/vm/oops/instanceKlass.cpp
src/share/vm/oops/instanceKlass.cpp
+19
-0
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlass.hpp
+3
-0
src/share/vm/oops/klassVtable.cpp
src/share/vm/oops/klassVtable.cpp
+142
-147
src/share/vm/oops/klassVtable.hpp
src/share/vm/oops/klassVtable.hpp
+8
-5
未找到文件。
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
8fdb95ad
...
...
@@ -2747,9 +2747,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
super_klass
(),
methods
(),
access_flags
,
class_loader
(),
class_name
(),
local_interfaces
());
class_loader
,
class_name
,
local_interfaces
(),
CHECK_
(
nullHandle
));
// Size of Java itable (in words)
itable_size
=
access_flags
.
is_interface
()
?
0
:
klassItable
::
compute_itable_size
(
transitive_interfaces
);
...
...
src/share/vm/oops/instanceKlass.cpp
浏览文件 @
8fdb95ad
...
...
@@ -1859,6 +1859,25 @@ bool instanceKlass::is_same_class_package(oop class_loader1, symbolOop class_nam
}
}
// Returns true iff super_method can be overridden by a method in targetclassname
// See JSL 3rd edition 8.4.6.1
// Assumes name-signature match
// "this" is instanceKlass of super_method which must exist
// note that the instanceKlass of the method in the targetclassname has not always been created yet
bool
instanceKlass
::
is_override
(
methodHandle
super_method
,
Handle
targetclassloader
,
symbolHandle
targetclassname
,
TRAPS
)
{
// Private methods can not be overridden
if
(
super_method
->
is_private
())
{
return
false
;
}
// If super method is accessible, then override
if
((
super_method
->
is_protected
())
||
(
super_method
->
is_public
()))
{
return
true
;
}
// Package-private methods are not inherited outside of package
assert
(
super_method
->
is_package_private
(),
"must be package private"
);
return
(
is_same_class_package
(
targetclassloader
(),
targetclassname
()));
}
jint
instanceKlass
::
compute_modifier_flags
(
TRAPS
)
const
{
klassOop
k
=
as_klassOop
();
...
...
src/share/vm/oops/instanceKlass.hpp
浏览文件 @
8fdb95ad
...
...
@@ -303,6 +303,9 @@ class instanceKlass: public Klass {
inner_class_next_offset
=
4
};
// method override check
bool
is_override
(
methodHandle
super_method
,
Handle
targetclassloader
,
symbolHandle
targetclassname
,
TRAPS
);
// package
bool
is_same_class_package
(
klassOop
class2
);
bool
is_same_class_package
(
oop
classloader2
,
symbolOop
classname2
);
...
...
src/share/vm/oops/klassVtable.cpp
浏览文件 @
8fdb95ad
...
...
@@ -45,9 +45,10 @@ void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
klassOop
super
,
objArrayOop
methods
,
AccessFlags
class_flags
,
oop
classloader
,
symbolOop
classname
,
objArrayOop
local_interfaces
Handle
classloader
,
symbolHandle
classname
,
objArrayOop
local_interfaces
,
TRAPS
)
{
No_Safepoint_Verifier
nsv
;
...
...
@@ -64,9 +65,9 @@ void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
int
len
=
methods
->
length
();
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
assert
(
methods
->
obj_at
(
i
)
->
is_method
(),
"must be a methodOop"
);
method
Oop
m
=
methodOop
(
methods
->
obj_at
(
i
));
method
Handle
mh
(
THREAD
,
methodOop
(
methods
->
obj_at
(
i
)
));
if
(
needs_new_vtable_entry
(
m
,
super
,
classloader
,
classname
,
class_flags
))
{
if
(
needs_new_vtable_entry
(
m
h
,
super
,
classloader
,
classname
,
class_flags
,
THREAD
))
{
vtable_length
+=
vtableEntry
::
size
();
// we need a new entry
}
}
...
...
@@ -117,6 +118,7 @@ int klassVtable::initialize_from_super(KlassHandle super) {
superVtable
->
copy_vtable_to
(
table
());
#ifndef PRODUCT
if
(
PrintVtables
&&
Verbose
)
{
ResourceMark
rm
;
tty
->
print_cr
(
"copy vtable from %s to %s size %d"
,
sk
->
internal_name
(),
klass
()
->
internal_name
(),
_length
);
}
#endif
...
...
@@ -159,13 +161,13 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
int
len
=
methods
()
->
length
();
int
initialized
=
super_vtable_len
;
// update_
super
_vtable can stop for gc - ensure using handles
// update_
inherited
_vtable can stop for gc - ensure using handles
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
HandleMark
hm
(
THREAD
);
assert
(
methods
()
->
obj_at
(
i
)
->
is_method
(),
"must be a methodOop"
);
methodHandle
mh
(
THREAD
,
(
methodOop
)
methods
()
->
obj_at
(
i
));
bool
needs_new_entry
=
update_
super
_vtable
(
ik
(),
mh
,
super_vtable_len
,
checkconstraints
,
CHECK
);
bool
needs_new_entry
=
update_
inherited
_vtable
(
ik
(),
mh
,
super_vtable_len
,
checkconstraints
,
CHECK
);
if
(
needs_new_entry
)
{
put_method_at
(
mh
(),
initialized
);
...
...
@@ -177,7 +179,7 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
// add miranda methods; it will also update the value of initialized
fill_in_mirandas
(
initialized
);
// In class hiera
chieswhere the acce
sibility is not increasing (i.e., going from private ->
// In class hiera
rchies where the acces
sibility is not increasing (i.e., going from private ->
// package_private -> publicprotected), the vtable might actually be smaller than our initial
// calculation.
assert
(
initialized
<=
_length
,
"vtable initialization failed"
);
...
...
@@ -188,26 +190,49 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
}
}
// Interates through the vtables to find the broadest access level. This
// will always be monotomic for valid Java programs - but not neccesarily
// for incompatible class files.
klassVtable
::
AccessType
klassVtable
::
vtable_accessibility_at
(
int
i
)
{
// This vtable is not implementing the specific method
if
(
i
>=
length
())
return
acc_private
;
// Compute AccessType for current method. public or protected we are done.
methodOop
m
=
method_at
(
i
);
if
(
m
->
is_protected
()
||
m
->
is_public
())
return
acc_publicprotected
;
AccessType
acc
=
m
->
is_package_private
()
?
acc_package_private
:
acc_private
;
// Compute AccessType for method in super classes
klassOop
super
=
klass
()
->
super
();
AccessType
super_acc
=
(
super
!=
NULL
)
?
instanceKlass
::
cast
(
klass
()
->
super
())
->
vtable
()
->
vtable_accessibility_at
(
i
)
:
acc_private
;
// Called for cases where a method does not override its superclass' vtable entry
// For bytecodes not produced by javac together it is possible that a method does not override
// the superclass's method, but might indirectly override a super-super class's vtable entry
// If none found, return a null superk, else return the superk of the method this does override
instanceKlass
*
klassVtable
::
find_transitive_override
(
instanceKlass
*
initialsuper
,
methodHandle
target_method
,
int
vtable_index
,
Handle
target_loader
,
symbolHandle
target_classname
,
Thread
*
THREAD
)
{
instanceKlass
*
superk
=
initialsuper
;
while
(
superk
!=
NULL
&&
superk
->
super
()
!=
NULL
)
{
instanceKlass
*
supersuperklass
=
instanceKlass
::
cast
(
superk
->
super
());
klassVtable
*
ssVtable
=
supersuperklass
->
vtable
();
if
(
vtable_index
<
ssVtable
->
length
())
{
methodOop
super_method
=
ssVtable
->
method_at
(
vtable_index
);
#ifndef PRODUCT
symbolHandle
name
(
THREAD
,
target_method
()
->
name
());
symbolHandle
signature
(
THREAD
,
target_method
()
->
signature
());
assert
(
super_method
->
name
()
==
name
()
&&
super_method
->
signature
()
==
signature
(),
"vtable entry name/sig mismatch"
);
#endif
if
(
supersuperklass
->
is_override
(
super_method
,
target_loader
,
target_classname
,
THREAD
))
{
#ifndef PRODUCT
if
(
PrintVtables
&&
Verbose
)
{
ResourceMark
rm
(
THREAD
);
tty
->
print
(
"transitive overriding superclass %s with %s::%s index %d, original flags: "
,
supersuperklass
->
internal_name
(),
_klass
->
internal_name
(),
(
target_method
()
!=
NULL
)
?
target_method
()
->
name
()
->
as_C_string
()
:
"<NULL>"
,
vtable_index
);
super_method
->
access_flags
().
print_on
(
tty
);
tty
->
print
(
"overriders flags: "
);
target_method
->
access_flags
().
print_on
(
tty
);
tty
->
cr
();
}
#endif
/*PRODUCT*/
break
;
// return found superk
}
}
else
{
// super class has no vtable entry here, stop transitive search
superk
=
(
instanceKlass
*
)
NULL
;
break
;
}
// if no override found yet, continue to search up
superk
=
instanceKlass
::
cast
(
superk
->
super
());
}
// Merge
return
(
AccessType
)
MAX2
((
int
)
acc
,
(
int
)
super_acc
);
return
superk
;
}
...
...
@@ -215,7 +240,8 @@ klassVtable::AccessType klassVtable::vtable_accessibility_at(int i) {
// OR return true if a new vtable entry is required
// Only called for instanceKlass's, i.e. not for arrays
// If that changed, could not use _klass as handle for klass
bool
klassVtable
::
update_super_vtable
(
instanceKlass
*
klass
,
methodHandle
target_method
,
int
super_vtable_len
,
bool
checkconstraints
,
TRAPS
)
{
bool
klassVtable
::
update_inherited_vtable
(
instanceKlass
*
klass
,
methodHandle
target_method
,
int
super_vtable_len
,
bool
checkconstraints
,
TRAPS
)
{
ResourceMark
rm
;
bool
allocate_new
=
true
;
assert
(
klass
->
oop_is_instance
(),
"must be instanceKlass"
);
...
...
@@ -242,58 +268,35 @@ bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_
}
// private methods always have a new entry in the vtable
// specification interpretation since classic has
// private methods not overriding
if
(
target_method
()
->
is_private
())
{
return
allocate_new
;
}
// search through the vtable and update overridden entries
// Since check_signature_loaders acquires SystemDictionary_lock
// which can block for gc, once we are in this loop, use handles, not
// unhandled oops unless they are reinitialized for each loop
// handles for name, signature, klass, target_method
// not for match_method, holder
// which can block for gc, once we are in this loop, use handles
// For classfiles built with >= jdk7, we now look for transitive overrides
symbolHandle
name
(
THREAD
,
target_method
()
->
name
());
symbolHandle
signature
(
THREAD
,
target_method
()
->
signature
());
Handle
target_loader
(
THREAD
,
_klass
->
class_loader
());
symbolHandle
target_classname
(
THREAD
,
_klass
->
name
());
for
(
int
i
=
0
;
i
<
super_vtable_len
;
i
++
)
{
methodOop
match
_method
=
method_at
(
i
);
methodOop
super
_method
=
method_at
(
i
);
// Check if method name matches
if
(
match_method
->
name
()
==
name
()
&&
match
_method
->
signature
()
==
signature
())
{
if
(
super_method
->
name
()
==
name
()
&&
super
_method
->
signature
()
==
signature
())
{
instanceKlass
*
holder
=
(
THREAD
,
instanceKlass
::
cast
(
match_method
->
method_holder
()));
// get super_klass for method_holder for the found method
instanceKlass
*
super_klass
=
instanceKlass
::
cast
(
super_method
->
method_holder
());
// Check if the match_method is accessable from current class
bool
same_package_init
=
false
;
bool
same_package_flag
=
false
;
bool
simple_match
=
match_method
->
is_public
()
||
match_method
->
is_protected
();
if
(
!
simple_match
)
{
same_package_init
=
true
;
same_package_flag
=
holder
->
is_same_class_package
(
_klass
->
class_loader
(),
_klass
->
name
());
simple_match
=
match_method
->
is_package_private
()
&&
same_package_flag
;
}
// match_method is the superclass' method. Note we can't override
// and shouldn't access superclass' ACC_PRIVATE methods
// (although they have been copied into our vtable)
// A simple form of this statement is:
// if ( (match_method->is_public() || match_method->is_protected()) ||
// (match_method->is_package_private() && holder->is_same_class_package(klass->class_loader(), klass->name()))) {
//
// The complexity is introduced it avoid recomputing 'is_same_class_package' which is expensive.
if
(
simple_match
)
{
// Check if target_method and match_method has same level of accessibility. The accesibility of the
// match method is the "most-general" visibility of all entries at it's particular vtable index for
// all superclasses. This check must be done before we override the current entry in the vtable.
AccessType
at
=
vtable_accessibility_at
(
i
);
bool
same_access
=
false
;
if
(
(
at
==
acc_publicprotected
&&
(
target_method
()
->
is_public
()
||
target_method
()
->
is_protected
())
||
(
at
==
acc_package_private
&&
(
target_method
()
->
is_package_private
()
&&
((
same_package_init
&&
same_package_flag
)
||
(
!
same_package_init
&&
holder
->
is_same_class_package
(
_klass
->
class_loader
(),
_klass
->
name
())))))))
{
same_access
=
true
;
}
if
((
super_klass
->
is_override
(
super_method
,
target_loader
,
target_classname
,
THREAD
))
||
((
klass
->
major_version
()
>=
VTABLE_TRANSITIVE_OVERRIDE_VERSION
)
&&
((
super_klass
=
find_transitive_override
(
super_klass
,
target_method
,
i
,
target_loader
,
target_classname
,
THREAD
))
!=
(
instanceKlass
*
)
NULL
)))
{
// overriding, so no new entry
allocate_new
=
false
;
if
(
checkconstraints
)
{
// Override vtable entry if passes loader constraint check
...
...
@@ -302,15 +305,12 @@ bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_
// have already made any needed loader constraints.
// Since loader constraints are transitive, it is enough
// to link to the first super, and we get all the others.
symbolHandle
signature
(
THREAD
,
target_method
()
->
signature
());
Handle
this_loader
(
THREAD
,
_klass
->
class_loader
());
instanceKlassHandle
super_klass
(
THREAD
,
_klass
->
super
());
Handle
super_loader
(
THREAD
,
super_klass
->
class_loader
());
if
(
t
his
_loader
()
!=
super_loader
())
{
if
(
t
arget
_loader
()
!=
super_loader
())
{
ResourceMark
rm
(
THREAD
);
char
*
failed_type_name
=
SystemDictionary
::
check_signature_loaders
(
signature
,
t
his
_loader
,
SystemDictionary
::
check_signature_loaders
(
signature
,
t
arget
_loader
,
super_loader
,
true
,
CHECK_
(
false
));
if
(
failed_type_name
!=
NULL
)
{
...
...
@@ -320,7 +320,7 @@ bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_
"(instance of %s), have different Class objects for the type "
"%s used in the signature"
;
char
*
sig
=
target_method
()
->
name_and_sig_as_C_string
();
const
char
*
loader1
=
SystemDictionary
::
loader_name
(
t
his
_loader
());
const
char
*
loader1
=
SystemDictionary
::
loader_name
(
t
arget
_loader
());
char
*
current
=
_klass
->
name
()
->
as_C_string
();
const
char
*
loader2
=
SystemDictionary
::
loader_name
(
super_loader
());
size_t
buflen
=
strlen
(
msg
)
+
strlen
(
sig
)
+
strlen
(
loader1
)
+
...
...
@@ -331,59 +331,46 @@ bool klassVtable::update_super_vtable(instanceKlass* klass, methodHandle target_
THROW_MSG_
(
vmSymbols
::
java_lang_LinkageError
(),
buf
,
false
);
}
}
}
put_method_at
(
target_method
(),
i
);
}
if
(
same_access
)
{
// target and match has same accessiblity - share entry
allocate_new
=
false
;
target_method
()
->
set_vtable_index
(
i
);
put_method_at
(
target_method
(),
i
);
target_method
()
->
set_vtable_index
(
i
);
#ifndef PRODUCT
if
(
PrintVtables
&&
Verbose
)
{
AccessType
targetacc
;
if
(
target_method
()
->
is_protected
()
||
target_method
()
->
is_public
())
{
targetacc
=
acc_publicprotected
;
}
else
{
targetacc
=
target_method
()
->
is_package_private
()
?
acc_package_private
:
acc_private
;
}
tty
->
print_cr
(
"overriding with %s::%s index %d, original flags: %x overriders flags: %x"
,
_klass
->
internal_name
(),
(
target_method
()
!=
NULL
)
?
target_method
()
->
name
()
->
as_C_string
()
:
"<NULL>"
,
i
,
at
,
targetacc
);
}
if
(
PrintVtables
&&
Verbose
)
{
tty
->
print
(
"overriding with %s::%s index %d, original flags: "
,
_klass
->
internal_name
(),
(
target_method
()
!=
NULL
)
?
target_method
()
->
name
()
->
as_C_string
()
:
"<NULL>"
,
i
);
super_method
->
access_flags
().
print_on
(
tty
);
tty
->
print
(
"overriders flags: "
);
target_method
->
access_flags
().
print_on
(
tty
);
tty
->
cr
();
}
#endif
/*PRODUCT*/
}
else
{
}
else
{
// allocate_new = true; default. We might override one entry,
// but not override another. Once we override one, not need new
#ifndef PRODUCT
if
(
PrintVtables
&&
Verbose
)
{
AccessType
targetacc
;
if
(
target_method
()
->
is_protected
()
||
target_method
()
->
is_public
())
{
targetacc
=
acc_publicprotected
;
}
else
{
targetacc
=
target_method
()
->
is_package_private
()
?
acc_package_private
:
acc_private
;
}
tty
->
print_cr
(
"override %s %s::%s at index %d, original flags: %x overriders flags: %x"
,
allocate_new
?
"+ new"
:
"only"
,
_klass
->
internal_name
(),
(
target_method
()
!=
NULL
)
?
target_method
()
->
name
()
->
as_C_string
()
:
"<NULL>"
,
i
,
at
,
targetacc
);
}
#endif
/*PRODUCT*/
if
(
PrintVtables
&&
Verbose
)
{
tty
->
print
(
"NOT overriding with %s::%s index %d, original flags: "
,
_klass
->
internal_name
(),
(
target_method
()
!=
NULL
)
?
target_method
()
->
name
()
->
as_C_string
()
:
"<NULL>"
,
i
);
super_method
->
access_flags
().
print_on
(
tty
);
tty
->
print
(
"overriders flags: "
);
target_method
->
access_flags
().
print_on
(
tty
);
tty
->
cr
();
}
#endif
/*PRODUCT*/
}
}
}
return
allocate_new
;
}
void
klassVtable
::
put_method_at
(
methodOop
m
,
int
index
)
{
assert
(
m
->
is_oop_or_null
(),
"Not an oop or null"
);
#ifndef PRODUCT
if
(
PrintVtables
&&
Verbose
)
{
ResourceMark
rm
;
tty
->
print_cr
(
"adding %s::%s at index %d"
,
_klass
->
internal_name
(),
(
m
!=
NULL
)
?
m
->
name
()
->
as_C_string
()
:
"<NULL>"
,
index
);
}
...
...
@@ -397,19 +384,23 @@ void klassVtable::put_method_at(methodOop m, int index) {
// by "classloader" and "classname".
// NOTE: The logic used here is very similar to the one used for computing
// the vtables indices for a method. We cannot directly use that function because,
// when the Universe is boostrapping, a super's vtable might not be initialized.
bool
klassVtable
::
needs_new_vtable_entry
(
methodOop
target_method
,
// we allocate the instanceKlass at load time, and that requires that the
// superclass has been loaded.
// However, the vtable entries are filled in at link time, and therefore
// the superclass' vtable may not yet have been filled in.
bool
klassVtable
::
needs_new_vtable_entry
(
methodHandle
target_method
,
klassOop
super
,
oop
classloader
,
symbolOop
classname
,
AccessFlags
class_flags
)
{
if
((
class_flags
.
is_final
()
||
target_method
->
is_final
())
||
Handle
classloader
,
symbolHandle
classname
,
AccessFlags
class_flags
,
TRAPS
)
{
if
((
class_flags
.
is_final
()
||
target_method
()
->
is_final
())
||
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
(
target_method
->
is_static
())
||
(
target_method
()
->
is_static
())
||
// static methods don't need to be in vtable
(
target_method
->
name
()
==
vmSymbols
::
object_initializer_name
())
(
target_method
()
->
name
()
==
vmSymbols
::
object_initializer_name
())
// <init> is never called dynamically-bound
)
{
return
false
;
...
...
@@ -421,55 +412,58 @@ bool klassVtable::needs_new_vtable_entry(methodOop target_method,
}
// private methods always have a new entry in the vtable
if
(
target_method
->
is_private
())
{
// specification interpretation since classic has
// private methods not overriding
if
(
target_method
()
->
is_private
())
{
return
true
;
}
// search through the super class hierarchy to see if we need
// a new entry
symbolOop
name
=
target_method
->
name
();
symbolOop
signature
=
target_method
->
signature
();
ResourceMark
rm
;
symbolOop
name
=
target_method
()
->
name
();
symbolOop
signature
=
target_method
()
->
signature
();
klassOop
k
=
super
;
methodOop
match
_method
=
NULL
;
methodOop
super
_method
=
NULL
;
instanceKlass
*
holder
=
NULL
;
methodOop
recheck_method
=
NULL
;
while
(
k
!=
NULL
)
{
// lookup through the hierarchy for a method with matching name and sign.
match
_method
=
instanceKlass
::
cast
(
k
)
->
lookup_method
(
name
,
signature
);
if
(
match
_method
==
NULL
)
{
super
_method
=
instanceKlass
::
cast
(
k
)
->
lookup_method
(
name
,
signature
);
if
(
super
_method
==
NULL
)
{
break
;
// we still have to search for a matching miranda method
}
// get the class holding the matching method
holder
=
instanceKlass
::
cast
(
match_method
->
method_holder
());
if
(
!
match_method
->
is_static
())
{
// we want only instance method matches
if
((
target_method
->
is_public
()
||
target_method
->
is_protected
())
&&
(
match_method
->
is_public
()
||
match_method
->
is_protected
()))
{
// target and match are public/protected; we do not need a new entry
return
false
;
}
if
(
target_method
->
is_package_private
()
&&
match_method
->
is_package_private
()
&&
holder
->
is_same_class_package
(
classloader
,
classname
))
{
// target and match are P private; we do not need a new entry
// make sure you use that class for is_override
instanceKlass
*
superk
=
instanceKlass
::
cast
(
super_method
->
method_holder
());
// we want only instance method matches
// pretend private methods are not in the super vtable
// since we do override around them: e.g. a.m pub/b.m private/c.m pub,
// ignore private, c.m pub does override a.m pub
// For classes that were not javac'd together, we also do transitive overriding around
// methods that have less accessibility
if
((
!
super_method
->
is_static
())
&&
(
!
super_method
->
is_private
()))
{
if
(
superk
->
is_override
(
super_method
,
classloader
,
classname
,
THREAD
))
{
return
false
;
// else keep looking for transitive overrides
}
}
k
=
holder
->
super
();
// haven't found a match yet; continue to look
// Start with lookup result and continue to search up
k
=
superk
->
super
();
// haven't found an override match yet; continue to look
}
// if the target method is public or protected it may have a matching
// miranda method in the super, whose entry it should re-use.
if
(
target_method
->
is_public
()
||
target_method
->
is_protected
())
{
instanceKlass
*
sk
=
instanceKlass
::
cast
(
super
);
if
(
sk
->
has_miranda_methods
())
{
if
(
sk
->
lookup_method_in_all_interfaces
(
name
,
signature
)
!=
NULL
)
{
return
false
;
// found a matching miranda; we do not need a new entry
}
// Actually, to handle cases that javac would not generate, we need
// this check for all access permissions.
instanceKlass
*
sk
=
instanceKlass
::
cast
(
super
);
if
(
sk
->
has_miranda_methods
()
)
{
if
(
sk
->
lookup_method_in_all_interfaces
(
name
,
signature
)
!=
NULL
)
{
return
false
;
// found a matching miranda; we do not need a new entry
}
}
return
true
;
// found no match; we need a new entry
}
...
...
@@ -884,7 +878,7 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
_klass
->
name
()
->
as_C_string
());
// I
n
terate through all interfaces
// Iterate through all interfaces
int
i
;
for
(
i
=
0
;
i
<
num_interfaces
;
i
++
)
{
itableOffsetEntry
*
ioe
=
offset_entry
(
i
);
...
...
@@ -1012,6 +1006,7 @@ void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_m
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
}
break
;
}
ime
++
;
}
...
...
src/share/vm/oops/klassVtable.hpp
浏览文件 @
8fdb95ad
...
...
@@ -70,8 +70,9 @@ class klassVtable : public ResourceObj {
// conputes vtable length (in words) and the number of miranda methods
static
void
compute_vtable_size_and_num_mirandas
(
int
&
vtable_length
,
int
&
num_miranda_methods
,
klassOop
super
,
objArrayOop
methods
,
AccessFlags
class_flags
,
oop
classloader
,
symbolOop
classname
,
objArrayOop
local_interfaces
);
AccessFlags
class_flags
,
Handle
classloader
,
symbolHandle
classname
,
objArrayOop
local_interfaces
,
TRAPS
);
// RedefineClasses() API support:
// If any entry of this vtable points to any of old_methods,
...
...
@@ -111,14 +112,16 @@ class klassVtable : public ResourceObj {
protected:
friend
class
vtableEntry
;
private:
enum
{
VTABLE_TRANSITIVE_OVERRIDE_VERSION
=
51
}
;
void
copy_vtable_to
(
vtableEntry
*
start
);
int
initialize_from_super
(
KlassHandle
super
);
int
index_of
(
methodOop
m
,
int
len
)
const
;
// same as index_of, but search only up to len
void
put_method_at
(
methodOop
m
,
int
index
);
static
bool
needs_new_vtable_entry
(
methodOop
m
,
klassOop
super
,
oop
classloader
,
symbolOop
classname
,
AccessFlags
access_flags
);
AccessType
vtable_accessibility_at
(
int
i
);
static
bool
needs_new_vtable_entry
(
methodHandle
m
,
klassOop
super
,
Handle
classloader
,
symbolHandle
classname
,
AccessFlags
access_flags
,
TRAPS
);
bool
update_super_vtable
(
instanceKlass
*
klass
,
methodHandle
target_method
,
int
super_vtable_len
,
bool
checkconstraints
,
TRAPS
);
bool
update_inherited_vtable
(
instanceKlass
*
klass
,
methodHandle
target_method
,
int
super_vtable_len
,
bool
checkconstraints
,
TRAPS
);
instanceKlass
*
find_transitive_override
(
instanceKlass
*
initialsuper
,
methodHandle
target_method
,
int
vtable_index
,
Handle
target_loader
,
symbolHandle
target_classname
,
Thread
*
THREAD
);
// support for miranda methods
bool
is_miranda_entry_at
(
int
i
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录