Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
5724a929
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看板
提交
5724a929
编写于
10月 24, 2014
作者:
A
acorn
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8043275: 8u40 backport: Fix interface initialization for default methods.
Reviewed-by: dcubed, coleenp
上级
9839aaf9
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
248 addition
and
42 deletion
+248
-42
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+12
-7
src/share/vm/classfile/classFileParser.hpp
src/share/vm/classfile/classFileParser.hpp
+1
-1
src/share/vm/oops/instanceKlass.cpp
src/share/vm/oops/instanceKlass.cpp
+39
-26
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlass.hpp
+19
-6
test/runtime/lambda-features/InvokespecialInterface.java
test/runtime/lambda-features/InvokespecialInterface.java
+2
-2
test/runtime/lambda-features/TestInterfaceInit.java
test/runtime/lambda-features/TestInterfaceInit.java
+87
-0
test/runtime/lambda-features/TestInterfaceOrder.java
test/runtime/lambda-features/TestInterfaceOrder.java
+88
-0
未找到文件。
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
5724a929
...
...
@@ -2529,7 +2529,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
Array
<
Method
*>*
ClassFileParser
::
parse_methods
(
bool
is_interface
,
AccessFlags
*
promoted_flags
,
bool
*
has_final_method
,
bool
*
ha
s_default_methods
,
bool
*
declare
s_default_methods
,
TRAPS
)
{
ClassFileStream
*
cfs
=
stream
();
cfs
->
guarantee_more
(
2
,
CHECK_NULL
);
// length
...
...
@@ -2548,11 +2548,11 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
if
(
method
->
is_final
())
{
*
has_final_method
=
true
;
}
if
(
is_interface
&&
!
(
*
has_default_methods
)
&&
!
method
->
is_abstract
()
&&
!
method
->
is_static
()
&&
!
method
->
is_private
())
{
// default method
*
ha
s_default_methods
=
true
;
// declares_default_methods: declares concrete instance methods, any access flags
// used for interface initialization, and default method inheritance analysis
if
(
is_interface
&&
!
(
*
declares_default_methods
)
&&
!
method
->
is_abstract
()
&&
!
method
->
is_static
())
{
*
declare
s_default_methods
=
true
;
}
_methods
->
at_put
(
index
,
method
());
}
...
...
@@ -3691,6 +3691,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
JvmtiCachedClassFileData
*
cached_class_file
=
NULL
;
Handle
class_loader
(
THREAD
,
loader_data
->
class_loader
());
bool
has_default_methods
=
false
;
bool
declares_default_methods
=
false
;
ResourceMark
rm
(
THREAD
);
ClassFileStream
*
cfs
=
stream
();
...
...
@@ -3928,8 +3929,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Array
<
Method
*>*
methods
=
parse_methods
(
access_flags
.
is_interface
(),
&
promoted_flags
,
&
has_final_method
,
&
ha
s_default_methods
,
&
declare
s_default_methods
,
CHECK_
(
nullHandle
));
if
(
declares_default_methods
)
{
has_default_methods
=
true
;
}
// Additional attributes
ClassAnnotationCollector
parsed_annotations
;
...
...
@@ -4072,6 +4076,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass
->
set_minor_version
(
minor_version
);
this_klass
->
set_major_version
(
major_version
);
this_klass
->
set_has_default_methods
(
has_default_methods
);
this_klass
->
set_declares_default_methods
(
declares_default_methods
);
if
(
!
host_klass
.
is_null
())
{
assert
(
this_klass
->
is_anonymous
(),
"should be the same"
);
...
...
src/share/vm/classfile/classFileParser.hpp
浏览文件 @
5724a929
...
...
@@ -247,7 +247,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array
<
Method
*>*
parse_methods
(
bool
is_interface
,
AccessFlags
*
promoted_flags
,
bool
*
has_final_method
,
bool
*
has_default_method
,
bool
*
declares_default_methods
,
TRAPS
);
intArray
*
sort_methods
(
Array
<
Method
*>*
methods
);
...
...
src/share/vm/oops/instanceKlass.cpp
浏览文件 @
5724a929
...
...
@@ -780,6 +780,41 @@ void InstanceKlass::link_methods(TRAPS) {
}
}
// Eagerly initialize superinterfaces that declare default methods (concrete instance: any access)
void
InstanceKlass
::
initialize_super_interfaces
(
instanceKlassHandle
this_oop
,
TRAPS
)
{
if
(
this_oop
->
has_default_methods
())
{
for
(
int
i
=
0
;
i
<
this_oop
->
local_interfaces
()
->
length
();
++
i
)
{
Klass
*
iface
=
this_oop
->
local_interfaces
()
->
at
(
i
);
InstanceKlass
*
ik
=
InstanceKlass
::
cast
(
iface
);
if
(
ik
->
should_be_initialized
())
{
if
(
ik
->
has_default_methods
())
{
ik
->
initialize_super_interfaces
(
ik
,
THREAD
);
}
// Only initialize() interfaces that "declare" concrete methods.
// has_default_methods drives searching superinterfaces since it
// means has_default_methods in its superinterface hierarchy
if
(
!
HAS_PENDING_EXCEPTION
&&
ik
->
declares_default_methods
())
{
ik
->
initialize
(
THREAD
);
}
if
(
HAS_PENDING_EXCEPTION
)
{
Handle
e
(
THREAD
,
PENDING_EXCEPTION
);
CLEAR_PENDING_EXCEPTION
;
{
EXCEPTION_MARK
;
// Locks object, set state, and notify all waiting threads
this_oop
->
set_initialization_state_and_notify
(
initialization_error
,
THREAD
);
// ignore any exception thrown, superclass initialization error is
// thrown below
CLEAR_PENDING_EXCEPTION
;
}
THROW_OOP
(
e
());
}
}
}
}
}
void
InstanceKlass
::
initialize_impl
(
instanceKlassHandle
this_oop
,
TRAPS
)
{
// Make sure klass is linked (verified) before initialization
...
...
@@ -859,33 +894,11 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
}
}
// Recursively initialize any superinterfaces that declare default methods
// Only need to recurse if has_default_methods which includes declaring and
// inheriting default methods
if
(
this_oop
->
has_default_methods
())
{
// Step 7.5: initialize any interfaces which have default methods
for
(
int
i
=
0
;
i
<
this_oop
->
local_interfaces
()
->
length
();
++
i
)
{
Klass
*
iface
=
this_oop
->
local_interfaces
()
->
at
(
i
);
InstanceKlass
*
ik
=
InstanceKlass
::
cast
(
iface
);
if
(
ik
->
has_default_methods
()
&&
ik
->
should_be_initialized
())
{
ik
->
initialize
(
THREAD
);
if
(
HAS_PENDING_EXCEPTION
)
{
Handle
e
(
THREAD
,
PENDING_EXCEPTION
);
CLEAR_PENDING_EXCEPTION
;
{
EXCEPTION_MARK
;
// Locks object, set state, and notify all waiting threads
this_oop
->
set_initialization_state_and_notify
(
initialization_error
,
THREAD
);
// ignore any exception thrown, superclass initialization error is
// thrown below
CLEAR_PENDING_EXCEPTION
;
}
DTRACE_CLASSINIT_PROBE_WAIT
(
super__failed
,
InstanceKlass
::
cast
(
this_oop
()),
-
1
,
wait
);
THROW_OOP
(
e
());
}
}
}
this_oop
->
initialize_super_interfaces
(
this_oop
,
CHECK
);
}
// Step 8
...
...
src/share/vm/oops/instanceKlass.hpp
浏览文件 @
5724a929
...
...
@@ -229,12 +229,13 @@ class InstanceKlass: public Klass {
bool
_has_unloaded_dependent
;
enum
{
_misc_rewritten
=
1
<<
0
,
// methods rewritten.
_misc_has_nonstatic_fields
=
1
<<
1
,
// for sizing with UseCompressedOops
_misc_should_verify_class
=
1
<<
2
,
// allow caching of preverification
_misc_is_anonymous
=
1
<<
3
,
// has embedded _host_klass field
_misc_is_contended
=
1
<<
4
,
// marked with contended annotation
_misc_has_default_methods
=
1
<<
5
// class/superclass/implemented interfaces has default methods
_misc_rewritten
=
1
<<
0
,
// methods rewritten.
_misc_has_nonstatic_fields
=
1
<<
1
,
// for sizing with UseCompressedOops
_misc_should_verify_class
=
1
<<
2
,
// allow caching of preverification
_misc_is_anonymous
=
1
<<
3
,
// has embedded _host_klass field
_misc_is_contended
=
1
<<
4
,
// marked with contended annotation
_misc_has_default_methods
=
1
<<
5
,
// class/superclass/implemented interfaces has default methods
_misc_declares_default_methods
=
1
<<
6
// directly declares default methods (any access)
};
u2
_misc_flags
;
u2
_minor_version
;
// minor version number of class file
...
...
@@ -680,6 +681,17 @@ class InstanceKlass: public Klass {
}
}
bool
declares_default_methods
()
const
{
return
(
_misc_flags
&
_misc_declares_default_methods
)
!=
0
;
}
void
set_declares_default_methods
(
bool
b
)
{
if
(
b
)
{
_misc_flags
|=
_misc_declares_default_methods
;
}
else
{
_misc_flags
&=
~
_misc_declares_default_methods
;
}
}
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline
u2
next_method_idnum
();
void
set_initial_method_idnum
(
u2
value
)
{
_idnum_allocated_count
=
value
;
}
...
...
@@ -1046,6 +1058,7 @@ private:
static
bool
link_class_impl
(
instanceKlassHandle
this_oop
,
bool
throw_verifyerror
,
TRAPS
);
static
bool
verify_code
(
instanceKlassHandle
this_oop
,
bool
throw_verifyerror
,
TRAPS
);
static
void
initialize_impl
(
instanceKlassHandle
this_oop
,
TRAPS
);
static
void
initialize_super_interfaces
(
instanceKlassHandle
this_oop
,
TRAPS
);
static
void
eager_initialize_impl
(
instanceKlassHandle
this_oop
);
static
void
set_initialization_state_and_notify_impl
(
instanceKlassHandle
this_oop
,
ClassState
state
,
TRAPS
);
static
void
call_class_initializer_impl
(
instanceKlassHandle
this_oop
,
TRAPS
);
...
...
test/runtime/lambda-features/InvokespecialInterface.java
浏览文件 @
5724a929
...
...
@@ -33,11 +33,12 @@
import
java.util.function.*
;
import
java.util.*
;
public
class
InvokespecialInterface
{
interface
I
{
default
void
imethod
()
{
System
.
out
.
println
(
"I::imethod"
);
}
}
class
C
implements
I
{
static
class
C
implements
I
{
public
void
foo
()
{
I
.
super
.
imethod
();
}
// invokespecial InterfaceMethod
public
void
bar
()
{
I
i
=
this
;
i
.
imethod
();
}
// invokeinterface same
public
void
doSomeInvokedynamic
()
{
...
...
@@ -48,7 +49,6 @@ class C implements I {
}
}
public
class
InvokespecialInterface
{
public
static
void
main
(
java
.
lang
.
String
[]
unused
)
{
// need to create C and call I::foo()
C
c
=
new
C
();
...
...
test/runtime/lambda-features/TestInterfaceInit.java
0 → 100644
浏览文件 @
5724a929
/*
* Copyright (c) 2014, 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.
*
*/
/*
* @test
* @bug 8034275
* @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods
* @run main TestInterfaceInit
*/
import
java.util.List
;
import
java.util.Arrays
;
import
java.util.ArrayList
;
public
class
TestInterfaceInit
{
static
List
<
Class
<?>>
cInitOrder
=
new
ArrayList
<>();
// Declares a default method and initializes
interface
I
{
boolean
v
=
TestInterfaceInit
.
out
(
I
.
class
);
default
void
x
()
{}
}
// Declares a default method and initializes
interface
J
extends
I
{
boolean
v
=
TestInterfaceInit
.
out
(
J
.
class
);
default
void
x
()
{}
}
// No default method, does not initialize
interface
JN
extends
J
{
boolean
v
=
TestInterfaceInit
.
out
(
JN
.
class
);
}
// Declares a default method and initializes
interface
K
extends
I
{
boolean
v
=
TestInterfaceInit
.
out
(
K
.
class
);
default
void
x
()
{}
}
// No default method, does not initialize
interface
KN
extends
K
{
boolean
v
=
TestInterfaceInit
.
out
(
KN
.
class
);
}
interface
L
extends
JN
,
KN
{
boolean
v
=
TestInterfaceInit
.
out
(
L
.
class
);
default
void
x
()
{}
}
public
static
void
main
(
String
[]
args
)
{
// Trigger initialization
boolean
v
=
L
.
v
;
List
<
Class
<?>>
expectedCInitOrder
=
Arrays
.
asList
(
I
.
class
,
J
.
class
,
K
.
class
,
L
.
class
);
if
(!
cInitOrder
.
equals
(
expectedCInitOrder
))
{
throw
new
RuntimeException
(
String
.
format
(
"Class initialization array %s not equal to expected array %s"
,
cInitOrder
,
expectedCInitOrder
));
}
}
static
boolean
out
(
Class
c
)
{
System
.
out
.
println
(
"#: initializing "
+
c
.
getName
());
cInitOrder
.
add
(
c
);
return
true
;
}
}
test/runtime/lambda-features/TestInterfaceOrder.java
0 → 100644
浏览文件 @
5724a929
/*
* Copyright (c) 2014, 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.
*
*/
/*
* @test
* @bug 8034275
* @summary [JDK 8u40] Test interface initialization order
* @run main TestInterfaceOrder
*/
import
java.util.List
;
import
java.util.Arrays
;
import
java.util.ArrayList
;
public
class
TestInterfaceOrder
{
static
List
<
Class
<?>>
cInitOrder
=
new
ArrayList
<>();
public
static
void
main
(
java
.
lang
.
String
[]
args
)
{
//Trigger initialization
C
c
=
new
C
();
List
<
Class
<?>>
expectedCInitOrder
=
Arrays
.
asList
(
I
.
class
,
J
.
class
,
A
.
class
,
K
.
class
,
B
.
class
,
L
.
class
,
C
.
class
);
if
(!
cInitOrder
.
equals
(
expectedCInitOrder
))
{
throw
new
RuntimeException
(
String
.
format
(
"Class initialization order %s not equal to expected order %s"
,
cInitOrder
,
expectedCInitOrder
));
}
}
interface
I
{
boolean
v
=
TestInterfaceOrder
.
out
(
I
.
class
);
default
void
i
()
{}
}
interface
J
extends
I
{
boolean
v
=
TestInterfaceOrder
.
out
(
J
.
class
);
default
void
j
()
{}
}
static
class
A
implements
J
{
static
boolean
v
=
TestInterfaceOrder
.
out
(
A
.
class
);
}
interface
K
extends
I
{
boolean
v
=
TestInterfaceOrder
.
out
(
K
.
class
);
default
void
k
()
{}
}
static
class
B
extends
A
implements
K
{
static
boolean
v
=
TestInterfaceOrder
.
out
(
B
.
class
);
}
interface
L
{
boolean
v
=
TestInterfaceOrder
.
out
(
L
.
class
);
default
void
l
()
{}
}
static
class
C
extends
B
implements
L
{
static
boolean
v
=
TestInterfaceOrder
.
out
(
C
.
class
);
}
static
boolean
out
(
Class
c
)
{
System
.
out
.
println
(
"#: initializing "
+
c
.
getName
());
cInitOrder
.
add
(
c
);
return
true
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录