Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
2182157d
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看板
提交
2182157d
编写于
8月 26, 2013
作者:
A
acorn
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8012294: remove generic handling for default methods
Reviewed-by: kamg, coleenp
上级
13b030b0
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
10 addition
and
2145 deletion
+10
-2145
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+0
-36
src/share/vm/classfile/defaultMethods.cpp
src/share/vm/classfile/defaultMethods.cpp
+10
-357
src/share/vm/classfile/genericSignatures.cpp
src/share/vm/classfile/genericSignatures.cpp
+0
-1279
src/share/vm/classfile/genericSignatures.hpp
src/share/vm/classfile/genericSignatures.hpp
+0
-467
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+0
-6
未找到文件。
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
2182157d
...
...
@@ -28,7 +28,6 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/genericSignatures.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
...
...
@@ -3039,35 +3038,6 @@ AnnotationArray* ClassFileParser::assemble_annotations(u1* runtime_visible_annot
return
annotations
;
}
#ifdef ASSERT
static
void
parseAndPrintGenericSignatures
(
instanceKlassHandle
this_klass
,
TRAPS
)
{
assert
(
ParseAllGenericSignatures
==
true
,
"Shouldn't call otherwise"
);
ResourceMark
rm
;
if
(
this_klass
->
generic_signature
()
!=
NULL
)
{
using
namespace
generic
;
ClassDescriptor
*
spec
=
ClassDescriptor
::
parse_generic_signature
(
this_klass
(),
CHECK
);
tty
->
print_cr
(
"Parsing %s"
,
this_klass
->
generic_signature
()
->
as_C_string
());
spec
->
print_on
(
tty
);
for
(
int
i
=
0
;
i
<
this_klass
->
methods
()
->
length
();
++
i
)
{
Method
*
m
=
this_klass
->
methods
()
->
at
(
i
);
MethodDescriptor
*
method_spec
=
MethodDescriptor
::
parse_generic_signature
(
m
,
spec
);
Symbol
*
sig
=
m
->
generic_signature
();
if
(
sig
==
NULL
)
{
sig
=
m
->
signature
();
}
tty
->
print_cr
(
"Parsing %s"
,
sig
->
as_C_string
());
method_spec
->
print_on
(
tty
);
}
}
}
#endif // def ASSERT
instanceKlassHandle
ClassFileParser
::
parse_super_class
(
int
super_class_index
,
TRAPS
)
{
instanceKlassHandle
super_klass
;
...
...
@@ -4060,12 +4030,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
java_lang_Class
::
create_mirror
(
this_klass
,
protection_domain
,
CHECK_
(
nullHandle
));
#ifdef ASSERT
if
(
ParseAllGenericSignatures
)
{
parseAndPrintGenericSignatures
(
this_klass
,
CHECK_
(
nullHandle
));
}
#endif
// Generate any default methods - default methods are interface methods
// that have a default implementation. This is new with Lambda project.
if
(
has_default_methods
&&
!
access_flags
.
is_interface
()
&&
...
...
src/share/vm/classfile/defaultMethods.cpp
浏览文件 @
2182157d
...
...
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "classfile/bytecodeAssembler.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/genericSignatures.hpp"
#include "classfile/symbolTable.hpp"
#include "memory/allocation.hpp"
#include "memory/metadataFactory.hpp"
...
...
@@ -75,14 +74,6 @@ class PseudoScope : public ResourceObj {
}
};
class
ContextMark
:
public
PseudoScopeMark
{
private:
generic
::
Context
::
Mark
_mark
;
public:
ContextMark
(
const
generic
::
Context
::
Mark
&
cm
)
:
_mark
(
cm
)
{}
virtual
void
destroy
()
{
_mark
.
destroy
();
}
};
#ifndef PRODUCT
static
void
print_slot
(
outputStream
*
str
,
Symbol
*
name
,
Symbol
*
signature
)
{
ResourceMark
rm
;
...
...
@@ -503,38 +494,6 @@ Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods
return
SymbolTable
::
new_symbol
(
ss
.
base
(),
(
int
)
ss
.
size
(),
CHECK_NULL
);
}
// A generic method family contains a set of all methods that implement a single
// language-level method. Because of erasure, these methods may have different
// signatures. As members of the set are collected while walking over the
// hierarchy, they are tagged with a qualification state. The qualification
// state for an erased method is set to disqualified if there exists a path
// from the root of hierarchy to the method that contains an interleaving
// language-equivalent method defined in an interface.
class
GenericMethodFamily
:
public
MethodFamily
{
private:
generic
::
MethodDescriptor
*
_descriptor
;
// language-level description
public:
GenericMethodFamily
(
generic
::
MethodDescriptor
*
canonical_desc
)
:
_descriptor
(
canonical_desc
)
{}
generic
::
MethodDescriptor
*
descriptor
()
const
{
return
_descriptor
;
}
bool
descriptor_matches
(
generic
::
MethodDescriptor
*
md
,
generic
::
Context
*
ctx
)
{
return
descriptor
()
->
covariant_match
(
md
,
ctx
);
}
#ifndef PRODUCT
Symbol
*
get_generic_sig
()
const
{
generic
::
Context
ctx
(
NULL
);
// empty, as _descriptor already canonicalized
TempNewSymbol
sig
=
descriptor
()
->
reify_signature
(
&
ctx
,
Thread
::
current
());
return
sig
;
}
#endif // ndef PRODUCT
};
class
StateRestorer
;
...
...
@@ -571,26 +530,6 @@ class StatefulMethodFamily : public ResourceObj {
StateRestorer
*
record_method_and_dq_further
(
Method
*
mo
);
};
// StatefulGenericMethodFamily is a wrapper around GenericMethodFamily that maintains the
// qualification state during hierarchy visitation, and applies that state
// when adding members to the GenericMethodFamily.
class
StatefulGenericMethodFamily
:
public
StatefulMethodFamily
{
public:
StatefulGenericMethodFamily
(
generic
::
MethodDescriptor
*
md
,
generic
::
Context
*
ctx
)
:
StatefulMethodFamily
(
new
GenericMethodFamily
(
md
->
canonicalize
(
ctx
)))
{
}
GenericMethodFamily
*
get_method_family
()
{
return
(
GenericMethodFamily
*
)
_method_family
;
}
bool
descriptor_matches
(
generic
::
MethodDescriptor
*
md
,
generic
::
Context
*
ctx
)
{
return
get_method_family
()
->
descriptor_matches
(
md
,
ctx
);
}
};
class
StateRestorer
:
public
PseudoScopeMark
{
private:
StatefulMethodFamily
*
_method
;
...
...
@@ -616,39 +555,6 @@ StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) {
return
mark
;
}
class
StatefulGenericMethodFamilies
:
public
ResourceObj
{
private:
GrowableArray
<
StatefulGenericMethodFamily
*>
_methods
;
public:
StatefulGenericMethodFamily
*
find_matching
(
generic
::
MethodDescriptor
*
md
,
generic
::
Context
*
ctx
)
{
for
(
int
i
=
0
;
i
<
_methods
.
length
();
++
i
)
{
StatefulGenericMethodFamily
*
existing
=
_methods
.
at
(
i
);
if
(
existing
->
descriptor_matches
(
md
,
ctx
))
{
return
existing
;
}
}
return
NULL
;
}
StatefulGenericMethodFamily
*
find_matching_or_create
(
generic
::
MethodDescriptor
*
md
,
generic
::
Context
*
ctx
)
{
StatefulGenericMethodFamily
*
method
=
find_matching
(
md
,
ctx
);
if
(
method
==
NULL
)
{
method
=
new
StatefulGenericMethodFamily
(
md
,
ctx
);
_methods
.
append
(
method
);
}
return
method
;
}
void
extract_families_into
(
GrowableArray
<
GenericMethodFamily
*>*
array
)
{
for
(
int
i
=
0
;
i
<
_methods
.
length
();
++
i
)
{
array
->
append
(
_methods
.
at
(
i
)
->
get_method_family
());
}
}
};
// Represents a location corresponding to a vtable slot for methods that
// neither the class nor any of it's ancestors provide an implementaion.
// Default methods may be present to fill this slot.
...
...
@@ -779,146 +685,11 @@ class FindMethodsByErasedSig : public HierarchyVisitor<FindMethodsByErasedSig> {
};
// Iterates over the type hierarchy looking for all methods with a specific
// method name. The result of this is a set of method families each of
// which is populated with a set of methods that implement the same
// language-level signature.
class
FindMethodsByGenericSig
:
public
HierarchyVisitor
<
FindMethodsByGenericSig
>
{
private:
// Context data
Thread
*
THREAD
;
generic
::
DescriptorCache
*
_cache
;
Symbol
*
_method_name
;
generic
::
Context
*
_ctx
;
StatefulGenericMethodFamilies
_families
;
public:
FindMethodsByGenericSig
(
generic
::
DescriptorCache
*
cache
,
Symbol
*
name
,
generic
::
Context
*
ctx
,
Thread
*
thread
)
:
_cache
(
cache
),
_method_name
(
name
),
_ctx
(
ctx
),
THREAD
(
thread
)
{}
void
get_discovered_families
(
GrowableArray
<
GenericMethodFamily
*>*
methods
)
{
_families
.
extract_families_into
(
methods
);
}
void
*
new_node_data
(
InstanceKlass
*
cls
)
{
return
new
PseudoScope
();
}
void
free_node_data
(
void
*
node_data
)
{
PseudoScope
::
cast
(
node_data
)
->
destroy
();
}
bool
visit
()
{
PseudoScope
*
scope
=
PseudoScope
::
cast
(
current_data
());
InstanceKlass
*
klass
=
current_class
();
InstanceKlass
*
sub
=
current_depth
()
>
0
?
class_at_depth
(
1
)
:
NULL
;
ContextMark
*
cm
=
new
ContextMark
(
_ctx
->
mark
());
scope
->
add_mark
(
cm
);
// will restore context when scope is freed
_ctx
->
apply_type_arguments
(
sub
,
klass
,
THREAD
);
int
start
,
end
=
0
;
start
=
klass
->
find_method_by_name
(
_method_name
,
&
end
);
if
(
start
!=
-
1
)
{
for
(
int
i
=
start
;
i
<
end
;
++
i
)
{
Method
*
m
=
klass
->
methods
()
->
at
(
i
);
// This gets the method's parameter list with its generic type
// parameters resolved
generic
::
MethodDescriptor
*
md
=
_cache
->
descriptor_for
(
m
,
THREAD
);
// Find all methods on this hierarchy that match this method
// (name, signature). This class collects other families of this
// method name.
StatefulGenericMethodFamily
*
family
=
_families
.
find_matching_or_create
(
md
,
_ctx
);
if
(
klass
->
is_interface
())
{
// ???
StateRestorer
*
restorer
=
family
->
record_method_and_dq_further
(
m
);
scope
->
add_mark
(
restorer
);
}
else
{
// This is the rule that methods in classes "win" (bad word) over
// methods in interfaces. This works because of single inheritance
family
->
set_target_if_empty
(
m
);
}
}
}
return
true
;
}
};
#ifndef PRODUCT
static
void
print_generic_families
(
GrowableArray
<
GenericMethodFamily
*>*
methods
,
Symbol
*
match
)
{
streamIndentor
si
(
tty
,
4
);
if
(
methods
->
length
()
==
0
)
{
tty
->
indent
();
tty
->
print_cr
(
"No Logical Method found"
);
}
for
(
int
i
=
0
;
i
<
methods
->
length
();
++
i
)
{
tty
->
indent
();
GenericMethodFamily
*
lm
=
methods
->
at
(
i
);
if
(
lm
->
contains_signature
(
match
))
{
tty
->
print_cr
(
"<Matching>"
);
}
else
{
tty
->
print_cr
(
"<Non-Matching>"
);
}
lm
->
print_sig_on
(
tty
,
lm
->
get_generic_sig
(),
1
);
}
}
#endif // ndef PRODUCT
static
void
create_overpasses
(
GrowableArray
<
EmptyVtableSlot
*>*
slots
,
InstanceKlass
*
klass
,
TRAPS
);
static
void
generate_generic_defaults
(
InstanceKlass
*
klass
,
GrowableArray
<
EmptyVtableSlot
*>*
empty_slots
,
EmptyVtableSlot
*
slot
,
int
current_slot_index
,
TRAPS
)
{
if
(
slot
->
is_bound
())
{
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
streamIndentor
si
(
tty
,
4
);
tty
->
indent
().
print_cr
(
"Already bound to logical method:"
);
GenericMethodFamily
*
lm
=
(
GenericMethodFamily
*
)(
slot
->
get_binding
());
lm
->
print_sig_on
(
tty
,
lm
->
get_generic_sig
(),
1
);
}
#endif // ndef PRODUCT
return
;
// covered by previous processing
}
generic
::
DescriptorCache
cache
;
generic
::
Context
ctx
(
&
cache
);
FindMethodsByGenericSig
visitor
(
&
cache
,
slot
->
name
(),
&
ctx
,
CHECK
);
visitor
.
run
(
klass
);
GrowableArray
<
GenericMethodFamily
*>
discovered_families
;
visitor
.
get_discovered_families
(
&
discovered_families
);
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
print_generic_families
(
&
discovered_families
,
slot
->
signature
());
}
#endif // ndef PRODUCT
// Find and populate any other slots that match the discovered families
for
(
int
j
=
current_slot_index
;
j
<
empty_slots
->
length
();
++
j
)
{
EmptyVtableSlot
*
open_slot
=
empty_slots
->
at
(
j
);
if
(
slot
->
name
()
==
open_slot
->
name
())
{
for
(
int
k
=
0
;
k
<
discovered_families
.
length
();
++
k
)
{
GenericMethodFamily
*
lm
=
discovered_families
.
at
(
k
);
if
(
lm
->
contains_signature
(
open_slot
->
signature
()))
{
lm
->
determine_target
(
klass
,
CHECK
);
open_slot
->
bind_family
(
lm
);
}
}
}
}
}
static
void
generate_erased_defaults
(
InstanceKlass
*
klass
,
GrowableArray
<
EmptyVtableSlot
*>*
empty_slots
,
EmptyVtableSlot
*
slot
,
TRAPS
)
{
...
...
@@ -943,21 +714,14 @@ static void merge_in_new_methods(InstanceKlass* klass,
//
// First if finds any name/signature slots that need any implementation (either
// because they are miranda or a superclass's implementation is an overpass
// itself). For each slot, iterate over the hierarchy, using generic signature
// information to partition any methods that match the name into method families
// where each family contains methods whose signatures are equivalent at the
// language level (i.e., their reified parameters match and return values are
// covariant). Check those sets to see if they contain a signature that matches
// the slot we're looking at (if we're lucky, there might be other empty slots
// that we can fill using the same analysis).
// itself). For each slot, iterate over the hierarchy, to see if they contain a
// signature that matches the slot we are looking at.
//
// For each slot filled, we generate an overpass method that either calls the
// unique default method candidate using invokespecial, or throws an exception
// (in the case of no default method candidates, or more than one valid
// candidate). These methods are then added to the class's method list. If
// the method set we're using contains methods (qualified or not) with a
// different runtime signature than the method we're creating, then we have to
// create bridges with those signatures too.
// candidate). These methods are then added to the class's method list.
// The JVM does not create bridges nor handle generic signatures here.
void
DefaultMethods
::
generate_default_methods
(
InstanceKlass
*
klass
,
GrowableArray
<
Method
*>*
mirandas
,
TRAPS
)
{
...
...
@@ -997,11 +761,7 @@ void DefaultMethods::generate_default_methods(
}
#endif // ndef PRODUCT
if
(
ParseGenericDefaults
)
{
generate_generic_defaults
(
klass
,
empty_slots
,
slot
,
i
,
CHECK
);
}
else
{
generate_erased_defaults
(
klass
,
empty_slots
,
slot
,
CHECK
);
}
generate_erased_defaults
(
klass
,
empty_slots
,
slot
,
CHECK
);
}
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
...
...
@@ -1019,13 +779,13 @@ void DefaultMethods::generate_default_methods(
}
/**
*
Generic analysis was used upon interface '_target' and found a unique
*
default method candidate with generic signature '_method_desc'.
This
*
Interface inheritance rules were used to find a unique default method
*
candidate for the resolved class.
This
* method is only viable if it would also be in the set of default method
* candidates if we ran a full analysis on the current class.
*
* The only reason that the method would not be in the set of candidates for
* the current class is if that there's another
covariantly
matching method
* the current class is if that there's another matching method
* which is "more specific" than the found method -- i.e., one could find a
* path in the interface hierarchy in which the matching method appears
* before we get to '_target'.
...
...
@@ -1110,48 +870,6 @@ class ErasedShadowChecker : public ShadowChecker {
:
ShadowChecker
(
thread
,
name
,
holder
,
target
)
{}
};
class
GenericShadowChecker
:
public
ShadowChecker
{
private:
generic
::
DescriptorCache
*
_cache
;
generic
::
MethodDescriptor
*
_method_desc
;
bool
path_has_shadow
()
{
generic
::
Context
ctx
(
_cache
);
for
(
int
i
=
current_depth
()
-
1
;
i
>
0
;
--
i
)
{
InstanceKlass
*
ik
=
class_at_depth
(
i
);
InstanceKlass
*
sub
=
class_at_depth
(
i
+
1
);
ctx
.
apply_type_arguments
(
sub
,
ik
,
THREAD
);
if
(
ik
->
is_interface
())
{
int
end
;
int
start
=
ik
->
find_method_by_name
(
_method_name
,
&
end
);
if
(
start
!=
-
1
)
{
for
(
int
j
=
start
;
j
<
end
;
++
j
)
{
Method
*
mo
=
ik
->
methods
()
->
at
(
j
);
generic
::
MethodDescriptor
*
md
=
_cache
->
descriptor_for
(
mo
,
THREAD
);
if
(
_method_desc
->
covariant_match
(
md
,
&
ctx
))
{
return
true
;
}
}
}
}
}
return
false
;
}
public:
GenericShadowChecker
(
generic
::
DescriptorCache
*
cache
,
Thread
*
thread
,
Symbol
*
name
,
InstanceKlass
*
holder
,
generic
::
MethodDescriptor
*
desc
,
InstanceKlass
*
target
)
:
ShadowChecker
(
thread
,
name
,
holder
,
target
)
{
_cache
=
cache
;
_method_desc
=
desc
;
}
};
// Find the unique qualified candidate from the perspective of the super_class
// which is the resolved_klass, which must be an immediate superinterface
...
...
@@ -1203,66 +921,6 @@ Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* s
}
}
// super_class is assumed to be the direct super of current_class
Method
*
find_generic_super_default
(
InstanceKlass
*
current_class
,
InstanceKlass
*
super_class
,
Symbol
*
method_name
,
Symbol
*
sig
,
TRAPS
)
{
generic
::
DescriptorCache
cache
;
generic
::
Context
ctx
(
&
cache
);
// Prime the initial generic context for current -> super_class
ctx
.
apply_type_arguments
(
current_class
,
super_class
,
CHECK_NULL
);
FindMethodsByGenericSig
visitor
(
&
cache
,
method_name
,
&
ctx
,
CHECK_NULL
);
visitor
.
run
(
super_class
);
GrowableArray
<
GenericMethodFamily
*>
families
;
visitor
.
get_discovered_families
(
&
families
);
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
print_generic_families
(
&
families
,
sig
);
}
#endif // ndef PRODUCT
GenericMethodFamily
*
selected_family
=
NULL
;
for
(
int
i
=
0
;
i
<
families
.
length
();
++
i
)
{
GenericMethodFamily
*
lm
=
families
.
at
(
i
);
if
(
lm
->
contains_signature
(
sig
))
{
lm
->
determine_target
(
current_class
,
CHECK_NULL
);
selected_family
=
lm
;
}
}
if
(
selected_family
->
has_target
())
{
Method
*
target
=
selected_family
->
get_selected_target
();
InstanceKlass
*
holder
=
InstanceKlass
::
cast
(
target
->
method_holder
());
// Verify that the identified method is valid from the context of
// the current class
GenericShadowChecker
checker
(
&
cache
,
THREAD
,
target
->
name
(),
holder
,
selected_family
->
descriptor
(),
super_class
);
checker
.
run
(
current_class
);
if
(
checker
.
found_shadow
())
{
#ifndef PRODUCT
if
(
TraceDefaultMethods
)
{
tty
->
print_cr
(
" Only candidate found was shadowed."
);
}
#endif // ndef PRODUCT
THROW_MSG_
(
vmSymbols
::
java_lang_AbstractMethodError
(),
"Accessible default method not found"
,
NULL
);
}
else
{
return
target
;
}
}
else
{
assert
(
selected_family
->
throws_exception
(),
"must have target or throw"
);
THROW_MSG_
(
vmSymbols
::
java_lang_AbstractMethodError
(),
selected_family
->
get_exception_message
()
->
as_C_string
(),
NULL
);
}
}
// This is called during linktime when we find an invokespecial call that
// refers to a direct superinterface. It indicates that we should find the
// default method in the hierarchy of that superinterface, and if that method
...
...
@@ -1296,13 +954,8 @@ Method* DefaultMethods::find_super_default(
assert
(
super_class
->
is_interface
(),
"only call for default methods"
);
Method
*
target
=
NULL
;
if
(
ParseGenericDefaults
)
{
target
=
find_generic_super_default
(
current_class
,
super_class
,
method_name
,
sig
,
CHECK_NULL
);
}
else
{
target
=
find_erased_super_default
(
current_class
,
super_class
,
method_name
,
sig
,
CHECK_NULL
);
}
target
=
find_erased_super_default
(
current_class
,
super_class
,
method_name
,
sig
,
CHECK_NULL
);
#ifndef PRODUCT
if
(
target
!=
NULL
)
{
...
...
src/share/vm/classfile/genericSignatures.cpp
已删除
100644 → 0
浏览文件 @
13b030b0
此差异已折叠。
点击以展开。
src/share/vm/classfile/genericSignatures.hpp
已删除
100644 → 0
浏览文件 @
13b030b0
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
#include "classfile/symbolTable.hpp"
#include "memory/allocation.hpp"
#include "runtime/signature.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
class
stringStream
;
namespace
generic
{
class
Identifier
;
class
ClassDescriptor
;
class
MethodDescriptor
;
class
TypeParameter
;
// a formal type parameter declared in generic signatures
class
TypeArgument
;
// The "type value" passed to fill parameters in supertypes
class
TypeVariable
;
// A usage of a type parameter as a value
/**
* Example:
*
* <T, V> class Foo extends Bar<String> { int m(V v) {} }
* ^^^^^^ ^^^^^^ ^^
* type parameters type argument type variable
*
* Note that a type variable could be passed as an argument too:
* <T, V> class Foo extends Bar<T> { int m(V v) {} }
* ^^^
* type argument's value is a type variable
*/
class
Type
;
class
ClassType
;
class
ArrayType
;
class
PrimitiveType
;
class
Context
;
class
DescriptorCache
;
class
DescriptorStream
;
class
Identifier
:
public
ResourceObj
{
private:
Symbol
*
_sym
;
int
_begin
;
int
_end
;
public:
Identifier
(
Symbol
*
sym
,
int
begin
,
int
end
)
:
_sym
(
sym
),
_begin
(
begin
),
_end
(
end
)
{}
bool
equals
(
Identifier
*
other
);
bool
equals
(
Symbol
*
sym
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif // ndef PRODUCT
};
class
Descriptor
:
public
ResourceObj
{
protected:
GrowableArray
<
TypeParameter
*>
_type_parameters
;
ClassDescriptor
*
_outer_class
;
Descriptor
(
GrowableArray
<
TypeParameter
*>&
params
,
ClassDescriptor
*
outer
)
:
_type_parameters
(
params
),
_outer_class
(
outer
)
{}
public:
ClassDescriptor
*
outer_class
()
{
return
_outer_class
;
}
void
set_outer_class
(
ClassDescriptor
*
sig
)
{
_outer_class
=
sig
;
}
virtual
ClassDescriptor
*
as_class_signature
()
{
return
NULL
;
}
virtual
MethodDescriptor
*
as_method_signature
()
{
return
NULL
;
}
bool
is_class_signature
()
{
return
as_class_signature
()
!=
NULL
;
}
bool
is_method_signature
()
{
return
as_method_signature
()
!=
NULL
;
}
GrowableArray
<
TypeParameter
*>&
type_parameters
()
{
return
_type_parameters
;
}
TypeParameter
*
find_type_parameter
(
Identifier
*
id
,
int
*
param_depth
);
virtual
void
bind_variables_to_parameters
()
=
0
;
#ifndef PRODUCT
virtual
void
print_on
(
outputStream
*
str
)
const
=
0
;
#endif
};
class
ClassDescriptor
:
public
Descriptor
{
private:
ClassType
*
_super
;
GrowableArray
<
ClassType
*>
_interfaces
;
MethodDescriptor
*
_outer_method
;
ClassDescriptor
(
GrowableArray
<
TypeParameter
*>&
ftp
,
ClassType
*
scs
,
GrowableArray
<
ClassType
*>&
sis
,
ClassDescriptor
*
outer_class
=
NULL
,
MethodDescriptor
*
outer_method
=
NULL
)
:
Descriptor
(
ftp
,
outer_class
),
_super
(
scs
),
_interfaces
(
sis
),
_outer_method
(
outer_method
)
{}
static
u2
get_outer_class_index
(
InstanceKlass
*
k
,
TRAPS
);
static
ClassDescriptor
*
parse_generic_signature
(
Klass
*
k
,
Symbol
*
original_name
,
TRAPS
);
public:
virtual
ClassDescriptor
*
as_class_signature
()
{
return
this
;
}
MethodDescriptor
*
outer_method
()
{
return
_outer_method
;
}
void
set_outer_method
(
MethodDescriptor
*
m
)
{
_outer_method
=
m
;
}
ClassType
*
super
()
{
return
_super
;
}
ClassType
*
interface_desc
(
Symbol
*
sym
);
static
ClassDescriptor
*
parse_generic_signature
(
Klass
*
k
,
TRAPS
);
static
ClassDescriptor
*
parse_generic_signature
(
Symbol
*
sym
);
// For use in superclass chains in positions where this is no generic info
static
ClassDescriptor
*
placeholder
(
InstanceKlass
*
klass
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
ClassDescriptor
*
canonicalize
(
Context
*
ctx
);
// Linking sets the position index in any contained TypeVariable type
// to correspond to the location of that identifier in the formal type
// parameters.
void
bind_variables_to_parameters
();
};
class
MethodDescriptor
:
public
Descriptor
{
private:
GrowableArray
<
Type
*>
_parameters
;
Type
*
_return_type
;
GrowableArray
<
Type
*>
_throws
;
MethodDescriptor
(
GrowableArray
<
TypeParameter
*>&
ftp
,
ClassDescriptor
*
outer
,
GrowableArray
<
Type
*>&
sigs
,
Type
*
rt
,
GrowableArray
<
Type
*>&
throws
)
:
Descriptor
(
ftp
,
outer
),
_parameters
(
sigs
),
_return_type
(
rt
),
_throws
(
throws
)
{}
public:
static
MethodDescriptor
*
parse_generic_signature
(
Method
*
m
,
ClassDescriptor
*
outer
);
static
MethodDescriptor
*
parse_generic_signature
(
Symbol
*
sym
,
ClassDescriptor
*
outer
);
MethodDescriptor
*
as_method_signature
()
{
return
this
;
}
// Performs generic analysis on the method parameters to determine
// if both methods refer to the same argument types.
bool
covariant_match
(
MethodDescriptor
*
other
,
Context
*
ctx
);
// Returns a new method descriptor with all generic variables
// removed and replaced with whatever is indicated using the Context.
MethodDescriptor
*
canonicalize
(
Context
*
ctx
);
void
bind_variables_to_parameters
();
#ifndef PRODUCT
TempNewSymbol
reify_signature
(
Context
*
ctx
,
TRAPS
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeParameter
:
public
ResourceObj
{
private:
Identifier
*
_identifier
;
ClassType
*
_class_bound
;
GrowableArray
<
ClassType
*>
_interface_bounds
;
// The position is the ordinal location of the parameter within the
// formal parameter list (excluding outer classes). It is only set for
// formal type parameters that are associated with a class -- method
// type parameters are left as -1. When resolving a generic variable to
// find the actual type, this index is used to access the generic type
// argument in the provided context object.
int
_position
;
// Assigned during variable linking
TypeParameter
(
Identifier
*
id
,
ClassType
*
class_bound
,
GrowableArray
<
ClassType
*>&
interface_bounds
)
:
_identifier
(
id
),
_class_bound
(
class_bound
),
_interface_bounds
(
interface_bounds
),
_position
(
-
1
)
{}
public:
static
TypeParameter
*
parse_generic_signature
(
DescriptorStream
*
str
);
ClassType
*
bound
();
int
position
()
{
return
_position
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
,
int
position
);
Identifier
*
identifier
()
{
return
_identifier
;
}
Type
*
resolve
(
Context
*
ctx
,
int
inner_depth
,
int
ctx_depth
);
TypeParameter
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
Type
:
public
ResourceObj
{
public:
static
Type
*
parse_generic_signature
(
DescriptorStream
*
str
);
virtual
ClassType
*
as_class
()
{
return
NULL
;
}
virtual
TypeVariable
*
as_variable
()
{
return
NULL
;
}
virtual
ArrayType
*
as_array
()
{
return
NULL
;
}
virtual
PrimitiveType
*
as_primitive
()
{
return
NULL
;
}
virtual
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
)
=
0
;
virtual
Type
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
)
=
0
;
virtual
void
bind_variables_to_parameters
(
Descriptor
*
sig
)
=
0
;
#ifndef PRODUCT
virtual
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
)
=
0
;
virtual
void
print_on
(
outputStream
*
str
)
const
=
0
;
#endif
};
class
ClassType
:
public
Type
{
friend
class
ClassDescriptor
;
protected:
Identifier
*
_identifier
;
GrowableArray
<
TypeArgument
*>
_type_arguments
;
ClassType
*
_outer_class
;
ClassType
(
Identifier
*
identifier
,
GrowableArray
<
TypeArgument
*>&
args
,
ClassType
*
outer
)
:
_identifier
(
identifier
),
_type_arguments
(
args
),
_outer_class
(
outer
)
{}
// Returns true if there are inner classes to read
static
Identifier
*
parse_generic_signature_simple
(
GrowableArray
<
TypeArgument
*>*
args
,
bool
*
has_inner
,
DescriptorStream
*
str
);
static
ClassType
*
parse_generic_signature
(
ClassType
*
outer
,
DescriptorStream
*
str
);
static
ClassType
*
from_symbol
(
Symbol
*
sym
);
public:
ClassType
*
as_class
()
{
return
this
;
}
static
ClassType
*
parse_generic_signature
(
DescriptorStream
*
str
);
static
ClassType
*
java_lang_Object
();
Identifier
*
identifier
()
{
return
_identifier
;
}
int
type_arguments_length
()
{
return
_type_arguments
.
length
();
}
TypeArgument
*
type_argument_at
(
int
i
);
virtual
ClassType
*
outer_class
()
{
return
_outer_class
;
}
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
ClassType
*
canonicalize
(
Context
*
ctx
,
int
context_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeVariable
:
public
Type
{
private:
Identifier
*
_id
;
TypeParameter
*
_parameter
;
// assigned during linking
// how many steps "out" from inner classes, -1 if method
int
_inner_depth
;
TypeVariable
(
Identifier
*
id
)
:
_id
(
id
),
_parameter
(
NULL
),
_inner_depth
(
0
)
{}
public:
TypeVariable
*
as_variable
()
{
return
this
;
}
static
TypeVariable
*
parse_generic_signature
(
DescriptorStream
*
str
);
Identifier
*
identifier
()
{
return
_id
;
}
TypeParameter
*
parameter
()
{
return
_parameter
;
}
int
inner_depth
()
{
return
_inner_depth
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
Type
*
resolve
(
Context
*
ctx
,
int
ctx_depth
);
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
Type
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
ArrayType
:
public
Type
{
private:
Type
*
_base
;
ArrayType
(
Type
*
base
)
:
_base
(
base
)
{}
public:
ArrayType
*
as_array
()
{
return
this
;
}
static
ArrayType
*
parse_generic_signature
(
DescriptorStream
*
str
);
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
ArrayType
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
PrimitiveType
:
public
Type
{
friend
class
Type
;
private:
char
_type
;
// includes V for void
PrimitiveType
(
char
&
type
)
:
_type
(
type
)
{}
public:
PrimitiveType
*
as_primitive
()
{
return
this
;
}
bool
covariant_match
(
Type
*
gt
,
Context
*
ctx
);
PrimitiveType
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
#ifndef PRODUCT
void
reify_signature
(
stringStream
*
ss
,
Context
*
ctx
);
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
TypeArgument
:
public
ResourceObj
{
private:
Type
*
_lower_bound
;
Type
*
_upper_bound
;
// may be null or == _lower_bound
TypeArgument
(
Type
*
lower_bound
,
Type
*
upper_bound
)
:
_lower_bound
(
lower_bound
),
_upper_bound
(
upper_bound
)
{}
public:
static
TypeArgument
*
parse_generic_signature
(
DescriptorStream
*
str
);
Type
*
lower_bound
()
{
return
_lower_bound
;
}
Type
*
upper_bound
()
{
return
_upper_bound
;
}
void
bind_variables_to_parameters
(
Descriptor
*
sig
);
TypeArgument
*
canonicalize
(
Context
*
ctx
,
int
ctx_depth
);
bool
covariant_match
(
TypeArgument
*
a
,
Context
*
ctx
);
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
class
Context
:
public
ResourceObj
{
private:
DescriptorCache
*
_cache
;
GrowableArray
<
ClassType
*>
_type_arguments
;
void
reset_to_mark
(
int
size
);
public:
// When this object goes out of scope or 'destroy' is
// called, then the application of the type to the
// context is wound-back (unless it's been deactivated).
class
Mark
:
public
StackObj
{
private:
mutable
Context
*
_context
;
int
_marked_size
;
bool
is_active
()
const
{
return
_context
!=
NULL
;
}
void
deactivate
()
const
{
_context
=
NULL
;
}
public:
Mark
()
:
_context
(
NULL
),
_marked_size
(
0
)
{}
Mark
(
Context
*
ctx
,
int
sz
)
:
_context
(
ctx
),
_marked_size
(
sz
)
{}
Mark
(
const
Mark
&
m
)
:
_context
(
m
.
_context
),
_marked_size
(
m
.
_marked_size
)
{
m
.
deactivate
();
// Ownership is transferred
}
Mark
&
operator
=
(
const
Mark
&
cm
)
{
destroy
();
_context
=
cm
.
_context
;
_marked_size
=
cm
.
_marked_size
;
cm
.
deactivate
();
return
*
this
;
}
void
destroy
();
~
Mark
()
{
destroy
();
}
};
Context
(
DescriptorCache
*
cache
)
:
_cache
(
cache
)
{}
Mark
mark
()
{
return
Mark
(
this
,
_type_arguments
.
length
());
}
void
apply_type_arguments
(
InstanceKlass
*
current
,
InstanceKlass
*
super
,
TRAPS
);
ClassType
*
at_depth
(
int
i
)
const
;
#ifndef PRODUCT
void
print_on
(
outputStream
*
str
)
const
;
#endif
};
/**
* Contains a cache of descriptors for classes and methods so they can be
* looked-up instead of reparsing each time they are needed.
*/
class
DescriptorCache
:
public
ResourceObj
{
private:
ResourceHashtable
<
InstanceKlass
*
,
ClassDescriptor
*>
_class_descriptors
;
ResourceHashtable
<
Method
*
,
MethodDescriptor
*>
_method_descriptors
;
public:
ClassDescriptor
*
descriptor_for
(
InstanceKlass
*
ikh
,
TRAPS
);
MethodDescriptor
*
descriptor_for
(
Method
*
mh
,
ClassDescriptor
*
cd
,
TRAPS
);
// Class descriptor derived from method holder
MethodDescriptor
*
descriptor_for
(
Method
*
mh
,
TRAPS
);
};
}
// namespace generic
#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
src/share/vm/runtime/globals.hpp
浏览文件 @
2182157d
...
...
@@ -3682,15 +3682,9 @@ class CommandLineFlags {
develop(bool, TraceDefaultMethods, false, \
"Trace the default method processing steps") \
\
develop(bool, ParseAllGenericSignatures, false, \
"Parse all generic signatures while classloading") \
\
develop(bool, VerifyGenericSignatures, false, \
"Abort VM on erroneous or inconsistent generic signatures") \
\
product(bool, ParseGenericDefaults, false, \
"Parse generic signatures for default method handling") \
\
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default value"\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录