Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
6aa38de8
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看板
提交
6aa38de8
编写于
4月 24, 2016
作者:
R
robm
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
58bd7dcb
03a93d1d
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
491 addition
and
41 deletion
+491
-41
src/os/posix/vm/os_posix.cpp
src/os/posix/vm/os_posix.cpp
+16
-1
src/os/solaris/vm/os_solaris.cpp
src/os/solaris/vm/os_solaris.cpp
+1
-8
src/share/vm/c1/c1_Runtime1.cpp
src/share/vm/c1/c1_Runtime1.cpp
+3
-0
src/share/vm/opto/c2compiler.cpp
src/share/vm/opto/c2compiler.cpp
+7
-0
src/share/vm/opto/c2compiler.hpp
src/share/vm/opto/c2compiler.hpp
+1
-0
src/share/vm/opto/cfgnode.cpp
src/share/vm/opto/cfgnode.cpp
+16
-9
src/share/vm/opto/compile.cpp
src/share/vm/opto/compile.cpp
+3
-1
src/share/vm/opto/parse1.cpp
src/share/vm/opto/parse1.cpp
+30
-4
src/share/vm/opto/runtime.cpp
src/share/vm/opto/runtime.cpp
+12
-11
src/share/vm/opto/type.cpp
src/share/vm/opto/type.cpp
+43
-3
src/share/vm/opto/type.hpp
src/share/vm/opto/type.hpp
+5
-0
src/share/vm/services/heapDumper.cpp
src/share/vm/services/heapDumper.cpp
+3
-4
test/compiler/types/TestMeetIncompatibleInterfaceArrays.java
test/compiler/types/TestMeetIncompatibleInterfaceArrays.java
+351
-0
未找到文件。
src/os/posix/vm/os_posix.cpp
浏览文件 @
6aa38de8
/*
* Copyright (c) 1999, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 201
5
, 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
...
...
@@ -678,6 +678,21 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
#if defined(IA64) && !defined(AIX)
{
SIGSEGV
,
SEGV_PSTKOVF
,
"SEGV_PSTKOVF"
,
"Paragraph stack overflow"
},
#endif
#if defined(__sparc) && defined(SOLARIS)
// define Solaris Sparc M7 ADI SEGV signals
#if !defined(SEGV_ACCADI)
#define SEGV_ACCADI 3
#endif
{
SIGSEGV
,
SEGV_ACCADI
,
"SEGV_ACCADI"
,
"ADI not enabled for mapped object."
},
#if !defined(SEGV_ACCDERR)
#define SEGV_ACCDERR 4
#endif
{
SIGSEGV
,
SEGV_ACCDERR
,
"SEGV_ACCDERR"
,
"ADI disrupting exception."
},
#if !defined(SEGV_ACCPERR)
#define SEGV_ACCPERR 5
#endif
{
SIGSEGV
,
SEGV_ACCPERR
,
"SEGV_ACCPERR"
,
"ADI precise exception."
},
#endif // defined(__sparc) && defined(SOLARIS)
{
SIGBUS
,
BUS_ADRALN
,
"BUS_ADRALN"
,
"Invalid address alignment."
},
{
SIGBUS
,
BUS_ADRERR
,
"BUS_ADRERR"
,
"Nonexistent physical address."
},
{
SIGBUS
,
BUS_OBJERR
,
"BUS_OBJERR"
,
"Object-specific hardware error."
},
...
...
src/os/solaris/vm/os_solaris.cpp
浏览文件 @
6aa38de8
...
...
@@ -6248,14 +6248,7 @@ bool os::is_headless_jre() {
}
size_t
os
::
write
(
int
fd
,
const
void
*
buf
,
unsigned
int
nBytes
)
{
Thread
*
t
=
ThreadLocalStorage
::
thread
();
if
(
t
->
is_Java_thread
())
{
INTERRUPTIBLE_RETURN_INT
(
::
write
(
fd
,
buf
,
nBytes
),
os
::
Solaris
::
clear_interrupted
);
}
else
{
size_t
res
;
RESTARTABLE
((
size_t
)
::
write
(
fd
,
buf
,
(
size_t
)
nBytes
),
res
);
return
res
;
}
INTERRUPTIBLE_RETURN_INT
(
::
write
(
fd
,
buf
,
nBytes
),
os
::
Solaris
::
clear_interrupted
);
}
int
os
::
close
(
int
fd
)
{
...
...
src/share/vm/c1/c1_Runtime1.cpp
浏览文件 @
6aa38de8
...
...
@@ -312,6 +312,7 @@ JRT_ENTRY(void, Runtime1::new_instance(JavaThread* thread, Klass* klass))
NOT_PRODUCT
(
_new_instance_slowcase_cnt
++
;)
assert
(
klass
->
is_klass
(),
"not a class"
);
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
instanceKlassHandle
h
(
thread
,
klass
);
h
->
check_valid_for_instantiation
(
true
,
CHECK
);
// make sure klass is initialized
...
...
@@ -347,6 +348,7 @@ JRT_ENTRY(void, Runtime1::new_object_array(JavaThread* thread, Klass* array_klas
// anymore after new_objArray() and no GC can happen before.
// (This may have to change if this code changes!)
assert
(
array_klass
->
is_klass
(),
"not a class"
);
Handle
holder
(
THREAD
,
array_klass
->
klass_holder
());
// keep the klass alive
Klass
*
elem_klass
=
ObjArrayKlass
::
cast
(
array_klass
)
->
element_klass
();
objArrayOop
obj
=
oopFactory
::
new_objArray
(
elem_klass
,
length
,
CHECK
);
thread
->
set_vm_result
(
obj
);
...
...
@@ -363,6 +365,7 @@ JRT_ENTRY(void, Runtime1::new_multi_array(JavaThread* thread, Klass* klass, int
assert
(
klass
->
is_klass
(),
"not a class"
);
assert
(
rank
>=
1
,
"rank must be nonzero"
);
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
klass
)
->
multi_allocate
(
rank
,
dims
,
CHECK
);
thread
->
set_vm_result
(
obj
);
JRT_END
...
...
src/share/vm/opto/c2compiler.cpp
浏览文件 @
6aa38de8
...
...
@@ -49,6 +49,9 @@ const char* C2Compiler::retry_no_subsuming_loads() {
const
char
*
C2Compiler
::
retry_no_escape_analysis
()
{
return
"retry without escape analysis"
;
}
const
char
*
C2Compiler
::
retry_class_loading_during_parsing
()
{
return
"retry class loading during parsing"
;
}
bool
C2Compiler
::
init_c2_runtime
()
{
// Check assumptions used while running ADLC
...
...
@@ -115,6 +118,10 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
// Check result and retry if appropriate.
if
(
C
.
failure_reason
()
!=
NULL
)
{
if
(
C
.
failure_reason_is
(
retry_class_loading_during_parsing
()))
{
env
->
record_failure
(
C
.
failure_reason
());
continue
;
// retry
}
if
(
C
.
failure_reason_is
(
retry_no_subsuming_loads
()))
{
assert
(
subsume_loads
,
"must make progress"
);
subsume_loads
=
false
;
...
...
src/share/vm/opto/c2compiler.hpp
浏览文件 @
6aa38de8
...
...
@@ -49,6 +49,7 @@ public:
// sentinel value used to trigger backtracking in compile_method().
static
const
char
*
retry_no_subsuming_loads
();
static
const
char
*
retry_no_escape_analysis
();
static
const
char
*
retry_class_loading_during_parsing
();
// Print compilation timers and statistics
void
print_timers
();
...
...
src/share/vm/opto/cfgnode.cpp
浏览文件 @
6aa38de8
...
...
@@ -973,7 +973,7 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const {
#ifdef ASSERT
// The following logic has been moved into TypeOopPtr::filter.
const
Type
*
jt
=
t
->
join_speculative
(
_type
);
if
(
jt
->
empty
()
)
{
// Emptied out???
if
(
jt
->
empty
()
)
{
// Emptied out???
// Check for evil case of 't' being a class and '_type' expecting an
// interface. This can happen because the bytecodes do not contain
...
...
@@ -984,14 +984,21 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const {
// be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows
// into a Phi which "knows" it's an Interface type we'll have to
// uplift the type.
if
(
!
t
->
empty
()
&&
ttip
&&
ttip
->
is_loaded
()
&&
ttip
->
klass
()
->
is_interface
()
)
{
assert
(
ft
==
_type
,
""
);
}
// Uplift to interface
else
if
(
!
t
->
empty
()
&&
ttkp
&&
ttkp
->
is_loaded
()
&&
ttkp
->
klass
()
->
is_interface
()
)
{
assert
(
ft
==
_type
,
""
);
}
// Uplift to interface
// Otherwise it's something stupid like non-overlapping int ranges
// found on dying counted loops.
else
{
assert
(
ft
==
Type
::
TOP
,
""
);
}
// Canonical empty value
if
(
!
t
->
empty
()
&&
ttip
&&
ttip
->
is_loaded
()
&&
ttip
->
klass
()
->
is_interface
())
{
assert
(
ft
==
_type
,
""
);
// Uplift to interface
}
else
if
(
!
t
->
empty
()
&&
ttkp
&&
ttkp
->
is_loaded
()
&&
ttkp
->
klass
()
->
is_interface
())
{
assert
(
ft
==
_type
,
""
);
// Uplift to interface
}
else
{
// We also have to handle 'evil cases' of interface- vs. class-arrays
Type
::
get_arrays_base_elements
(
jt
,
_type
,
NULL
,
&
ttip
);
if
(
!
t
->
empty
()
&&
ttip
!=
NULL
&&
ttip
->
is_loaded
()
&&
ttip
->
klass
()
->
is_interface
())
{
assert
(
ft
==
_type
,
""
);
// Uplift to array of interface
}
else
{
// Otherwise it's something stupid like non-overlapping int ranges
// found on dying counted loops.
assert
(
ft
==
Type
::
TOP
,
""
);
// Canonical empty value
}
}
}
else
{
...
...
src/share/vm/opto/compile.cpp
浏览文件 @
6aa38de8
...
...
@@ -791,7 +791,9 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
}
JVMState
*
jvms
=
build_start_state
(
start
(),
tf
());
if
((
jvms
=
cg
->
generate
(
jvms
))
==
NULL
)
{
record_method_not_compilable
(
"method parse failed"
);
if
(
!
failure_reason_is
(
C2Compiler
::
retry_class_loading_during_parsing
()))
{
record_method_not_compilable
(
"method parse failed"
);
}
return
;
}
GraphKit
kit
(
jvms
);
...
...
src/share/vm/opto/parse1.cpp
浏览文件 @
6aa38de8
...
...
@@ -27,6 +27,7 @@
#include "interpreter/linkResolver.hpp"
#include "oops/method.hpp"
#include "opto/addnode.hpp"
#include "opto/c2compiler.hpp"
#include "opto/idealGraphPrinter.hpp"
#include "opto/locknode.hpp"
#include "opto/memnode.hpp"
...
...
@@ -988,7 +989,23 @@ void Parse::do_exits() {
if
(
tf
()
->
range
()
->
cnt
()
>
TypeFunc
::
Parms
)
{
const
Type
*
ret_type
=
tf
()
->
range
()
->
field_at
(
TypeFunc
::
Parms
);
Node
*
ret_phi
=
_gvn
.
transform
(
_exits
.
argument
(
0
)
);
assert
(
_exits
.
control
()
->
is_top
()
||
!
_gvn
.
type
(
ret_phi
)
->
empty
(),
"return value must be well defined"
);
if
(
!
_exits
.
control
()
->
is_top
()
&&
_gvn
.
type
(
ret_phi
)
->
empty
())
{
// In case of concurrent class loading, the type we set for the
// ret_phi in build_exits() may have been too optimistic and the
// ret_phi may be top now.
// Otherwise, we've encountered an error and have to mark the method as
// not compilable. Just using an assertion instead would be dangerous
// as this could lead to an infinite compile loop in non-debug builds.
{
MutexLockerEx
ml
(
Compile_lock
,
Mutex
::
_no_safepoint_check_flag
);
if
(
C
->
env
()
->
system_dictionary_modification_counter_changed
())
{
C
->
record_failure
(
C2Compiler
::
retry_class_loading_during_parsing
());
}
else
{
C
->
record_method_not_compilable
(
"Can't determine return type."
);
}
}
return
;
}
if
(
ret_type
->
isa_int
())
{
BasicType
ret_bt
=
method
()
->
return_type
()
->
basic_type
();
ret_phi
=
mask_int_value
(
ret_phi
,
ret_bt
,
&
_gvn
);
...
...
@@ -2116,15 +2133,24 @@ void Parse::return_current(Node* value) {
// here.
Node
*
phi
=
_exits
.
argument
(
0
);
const
TypeInstPtr
*
tr
=
phi
->
bottom_type
()
->
isa_instptr
();
if
(
tr
&&
tr
->
klass
()
->
is_loaded
()
&&
tr
->
klass
()
->
is_interface
()
)
{
if
(
tr
&&
tr
->
klass
()
->
is_loaded
()
&&
tr
->
klass
()
->
is_interface
())
{
const
TypeInstPtr
*
tp
=
value
->
bottom_type
()
->
isa_instptr
();
if
(
tp
&&
tp
->
klass
()
->
is_loaded
()
&&
!
tp
->
klass
()
->
is_interface
())
{
// sharpen the type eagerly; this eases certain assert checking
if
(
tp
->
higher_equal
(
TypeInstPtr
::
NOTNULL
))
tr
=
tr
->
join_speculative
(
TypeInstPtr
::
NOTNULL
)
->
is_instptr
();
value
=
_gvn
.
transform
(
new
(
C
)
CheckCastPPNode
(
0
,
value
,
tr
));
value
=
_gvn
.
transform
(
new
(
C
)
CheckCastPPNode
(
0
,
value
,
tr
));
}
}
else
{
// Also handle returns of oop-arrays to an arrays-of-interface return
const
TypeInstPtr
*
phi_tip
;
const
TypeInstPtr
*
val_tip
;
Type
::
get_arrays_base_elements
(
phi
->
bottom_type
(),
value
->
bottom_type
(),
&
phi_tip
,
&
val_tip
);
if
(
phi_tip
!=
NULL
&&
phi_tip
->
is_loaded
()
&&
phi_tip
->
klass
()
->
is_interface
()
&&
val_tip
!=
NULL
&&
val_tip
->
is_loaded
()
&&
!
val_tip
->
klass
()
->
is_interface
())
{
value
=
_gvn
.
transform
(
new
(
C
)
CheckCastPPNode
(
0
,
value
,
phi
->
bottom_type
()));
}
}
phi
->
add_req
(
value
);
...
...
src/share/vm/opto/runtime.cpp
浏览文件 @
6aa38de8
...
...
@@ -231,22 +231,17 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thre
// These checks are cheap to make and support reflective allocation.
int
lh
=
klass
->
layout_helper
();
if
(
Klass
::
layout_helper_needs_slow_path
(
lh
)
||
!
InstanceKlass
::
cast
(
klass
)
->
is_initialized
())
{
KlassHandle
kh
(
THREAD
,
klass
);
kh
->
check_valid_for_instantiation
(
false
,
THREAD
);
if
(
Klass
::
layout_helper_needs_slow_path
(
lh
)
||
!
InstanceKlass
::
cast
(
klass
)
->
is_initialized
())
{
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
klass
->
check_valid_for_instantiation
(
false
,
THREAD
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
InstanceKlass
::
cast
(
kh
())
->
initialize
(
THREAD
);
}
if
(
!
HAS_PENDING_EXCEPTION
)
{
klass
=
kh
();
}
else
{
klass
=
NULL
;
InstanceKlass
::
cast
(
klass
)
->
initialize
(
THREAD
);
}
}
if
(
klass
!=
NULL
)
{
if
(
!
HAS_PENDING_EXCEPTION
)
{
// Scavenge and allocate an instance.
Handle
holder
(
THREAD
,
klass
->
klass_holder
());
// keep the klass alive
oop
result
=
InstanceKlass
::
cast
(
klass
)
->
allocate_instance
(
THREAD
);
thread
->
set_vm_result
(
result
);
...
...
@@ -286,6 +281,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::new_array_C(Klass* array_type, int len, JavaT
// Although the oopFactory likes to work with the elem_type,
// the compiler prefers the array_type, since it must already have
// that latter value in hand for the fast path.
Handle
holder
(
THREAD
,
array_type
->
klass_holder
());
// keep the array klass alive
Klass
*
elem_type
=
ObjArrayKlass
::
cast
(
array_type
)
->
element_klass
();
result
=
oopFactory
::
new_objArray
(
elem_type
,
len
,
THREAD
);
}
...
...
@@ -364,6 +360,7 @@ JRT_ENTRY(void, OptoRuntime::multianewarray2_C(Klass* elem_type, int len1, int l
jint
dims
[
2
];
dims
[
0
]
=
len1
;
dims
[
1
]
=
len2
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
2
,
dims
,
THREAD
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
...
...
@@ -380,6 +377,7 @@ JRT_ENTRY(void, OptoRuntime::multianewarray3_C(Klass* elem_type, int len1, int l
dims
[
0
]
=
len1
;
dims
[
1
]
=
len2
;
dims
[
2
]
=
len3
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
3
,
dims
,
THREAD
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
...
...
@@ -397,6 +395,7 @@ JRT_ENTRY(void, OptoRuntime::multianewarray4_C(Klass* elem_type, int len1, int l
dims
[
1
]
=
len2
;
dims
[
2
]
=
len3
;
dims
[
3
]
=
len4
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
4
,
dims
,
THREAD
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
...
...
@@ -415,6 +414,7 @@ JRT_ENTRY(void, OptoRuntime::multianewarray5_C(Klass* elem_type, int len1, int l
dims
[
2
]
=
len3
;
dims
[
3
]
=
len4
;
dims
[
4
]
=
len5
;
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
5
,
dims
,
THREAD
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
...
...
@@ -432,6 +432,7 @@ JRT_ENTRY(void, OptoRuntime::multianewarrayN_C(Klass* elem_type, arrayOopDesc* d
jint
*
c_dims
=
NEW_RESOURCE_ARRAY
(
jint
,
len
);
Copy
::
conjoint_jints_atomic
(
j_dims
,
c_dims
,
len
);
Handle
holder
(
THREAD
,
elem_type
->
klass_holder
());
// keep the klass alive
oop
obj
=
ArrayKlass
::
cast
(
elem_type
)
->
multi_allocate
(
len
,
c_dims
,
THREAD
);
deoptimize_caller_frame
(
thread
,
HAS_PENDING_EXCEPTION
);
thread
->
set_vm_result
(
obj
);
...
...
src/share/vm/opto/type.cpp
浏览文件 @
6aa38de8
...
...
@@ -149,6 +149,33 @@ BasicType Type::array_element_basic_type() const {
return
bt
;
}
// For two instance arrays of same dimension, return the base element types.
// Otherwise or if the arrays have different dimensions, return NULL.
void
Type
::
get_arrays_base_elements
(
const
Type
*
a1
,
const
Type
*
a2
,
const
TypeInstPtr
**
e1
,
const
TypeInstPtr
**
e2
)
{
if
(
e1
)
*
e1
=
NULL
;
if
(
e2
)
*
e2
=
NULL
;
const
TypeAryPtr
*
a1tap
=
(
a1
==
NULL
)
?
NULL
:
a1
->
isa_aryptr
();
const
TypeAryPtr
*
a2tap
=
(
a2
==
NULL
)
?
NULL
:
a2
->
isa_aryptr
();
if
(
a1tap
!=
NULL
&&
a2tap
!=
NULL
)
{
// Handle multidimensional arrays
const
TypePtr
*
a1tp
=
a1tap
->
elem
()
->
make_ptr
();
const
TypePtr
*
a2tp
=
a2tap
->
elem
()
->
make_ptr
();
while
(
a1tp
&&
a1tp
->
isa_aryptr
()
&&
a2tp
&&
a2tp
->
isa_aryptr
())
{
a1tap
=
a1tp
->
is_aryptr
();
a2tap
=
a2tp
->
is_aryptr
();
a1tp
=
a1tap
->
elem
()
->
make_ptr
();
a2tp
=
a2tap
->
elem
()
->
make_ptr
();
}
if
(
a1tp
&&
a1tp
->
isa_instptr
()
&&
a2tp
&&
a2tp
->
isa_instptr
())
{
if
(
e1
)
*
e1
=
a1tp
->
is_instptr
();
if
(
e2
)
*
e2
=
a2tp
->
is_instptr
();
}
}
}
//---------------------------get_typeflow_type---------------------------------
// Import a type produced by ciTypeFlow.
const
Type
*
Type
::
get_typeflow_type
(
ciType
*
type
)
{
...
...
@@ -1984,7 +2011,11 @@ const Type* TypeAry::remove_speculative() const {
bool
TypeAry
::
interface_vs_oop
(
const
Type
*
t
)
const
{
const
TypeAry
*
t_ary
=
t
->
is_ary
();
if
(
t_ary
)
{
return
_elem
->
interface_vs_oop
(
t_ary
->
_elem
);
const
TypePtr
*
this_ptr
=
_elem
->
make_ptr
();
// In case we have narrow_oops
const
TypePtr
*
t_ptr
=
t_ary
->
_elem
->
make_ptr
();
if
(
this_ptr
!=
NULL
&&
t_ptr
!=
NULL
)
{
return
this_ptr
->
interface_vs_oop
(
t_ptr
);
}
}
return
false
;
}
...
...
@@ -2836,8 +2867,17 @@ const Type *TypeOopPtr::filter_helper(const Type *kills, bool include_speculativ
// be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows
// into a Phi which "knows" it's an Interface type we'll have to
// uplift the type.
if
(
!
empty
()
&&
ktip
!=
NULL
&&
ktip
->
is_loaded
()
&&
ktip
->
klass
()
->
is_interface
())
return
kills
;
// Uplift to interface
if
(
!
empty
())
{
if
(
ktip
!=
NULL
&&
ktip
->
is_loaded
()
&&
ktip
->
klass
()
->
is_interface
())
{
return
kills
;
// Uplift to interface
}
// Also check for evil cases of 'this' being a class array
// and 'kills' expecting an array of interfaces.
Type
::
get_arrays_base_elements
(
ft
,
kills
,
NULL
,
&
ktip
);
if
(
ktip
!=
NULL
&&
ktip
->
is_loaded
()
&&
ktip
->
klass
()
->
is_interface
())
{
return
kills
;
// Uplift to array of interface
}
}
return
Type
::
TOP
;
// Canonical empty value
}
...
...
src/share/vm/opto/type.hpp
浏览文件 @
6aa38de8
...
...
@@ -367,6 +367,11 @@ public:
return
_const_basic_type
[
type
];
}
// For two instance arrays of same dimension, return the base element types.
// Otherwise or if the arrays have different dimensions, return NULL.
static
void
get_arrays_base_elements
(
const
Type
*
a1
,
const
Type
*
a2
,
const
TypeInstPtr
**
e1
,
const
TypeInstPtr
**
e2
);
// Mapping to the array element's basic type.
BasicType
array_element_basic_type
()
const
;
...
...
src/share/vm/services/heapDumper.cpp
浏览文件 @
6aa38de8
...
...
@@ -468,7 +468,7 @@ void DumpWriter::close() {
// flush and close dump file
if
(
is_open
())
{
flush
();
os
::
close
(
file_descriptor
());
::
close
(
file_descriptor
());
set_file_descriptor
(
-
1
);
}
}
...
...
@@ -480,12 +480,11 @@ void DumpWriter::write_internal(void* s, size_t len) {
ssize_t
n
=
0
;
while
(
len
>
0
)
{
uint
tmp
=
(
uint
)
MIN2
(
len
,
(
size_t
)
UINT_MAX
);
n
=
os
::
write
(
file_descriptor
(),
pos
,
tmp
);
n
=
::
write
(
file_descriptor
(),
pos
,
tmp
);
if
(
n
<
0
)
{
// EINTR cannot happen here, os::write will take care of that
set_error
(
strerror
(
errno
));
os
::
close
(
file_descriptor
());
::
close
(
file_descriptor
());
set_file_descriptor
(
-
1
);
return
;
}
...
...
test/compiler/types/TestMeetIncompatibleInterfaceArrays.java
0 → 100644
浏览文件 @
6aa38de8
/*
* Copyright 2015 SAP AG. 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 8141551
* @summary C2 can not handle returns with inccompatible interface arrays
* @library /testlibrary /testlibrary/whitebox/
* @build sun.hotspot.WhiteBox
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm
* -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -Xbatch
* -XX:CompileThreshold=1
* -XX:-TieredCompilation
* -XX:CICompilerCount=1
* -XX:+PrintCompilation
* -XX:+PrintInlining
* -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run
* -XX:CompileCommand=dontinline,TestMeetIncompatibleInterfaceArrays$Helper.createI2*
* -XX:CompileCommand=quiet
* TestMeetIncompatibleInterfaceArrays 0
* @run main/othervm
* -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -Xbatch
* -XX:CompileThreshold=1
* -XX:-TieredCompilation
* -XX:CICompilerCount=1
* -XX:+PrintCompilation
* -XX:+PrintInlining
* -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run
* -XX:CompileCommand=inline,TestMeetIncompatibleInterfaceArrays$Helper.createI2*
* -XX:CompileCommand=quiet
* TestMeetIncompatibleInterfaceArrays 1
* @run main/othervm
* -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -Xbatch
* -XX:CompileThreshold=1
* -XX:Tier0InvokeNotifyFreqLog=0 -XX:Tier2InvokeNotifyFreqLog=0 -XX:Tier3InvokeNotifyFreqLog=0 -XX:Tier23InlineeNotifyFreqLog=0
* -XX:Tier3InvocationThreshold=2 -XX:Tier3MinInvocationThreshold=2 -XX:Tier3CompileThreshold=2
* -XX:Tier4InvocationThreshold=1 -XX:Tier4MinInvocationThreshold=1 -XX:Tier4CompileThreshold=1
* -XX:+TieredCompilation
* -XX:CICompilerCount=2
* -XX:+PrintCompilation
* -XX:+PrintInlining
* -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run
* -XX:CompileCommand=compileonly,TestMeetIncompatibleInterfaceArrays$Helper.createI2*
* -XX:CompileCommand=inline,TestMeetIncompatibleInterfaceArrays$Helper.createI2*
* -XX:CompileCommand=quiet
* TestMeetIncompatibleInterfaceArrays 2
*
* @author volker.simonis@gmail.com
*/
import
java.io.FileOutputStream
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
jdk.internal.org.objectweb.asm.ClassWriter
;
import
jdk.internal.org.objectweb.asm.MethodVisitor
;
import
static
jdk
.
internal
.
org
.
objectweb
.
asm
.
Opcodes
.*;
import
sun.hotspot.WhiteBox
;
public
class
TestMeetIncompatibleInterfaceArrays
extends
ClassLoader
{
private
static
final
WhiteBox
WB
=
WhiteBox
.
getWhiteBox
();
public
static
interface
I1
{
public
String
getName
();
}
public
static
interface
I2
{
public
String
getName
();
}
public
static
class
I2C
implements
I2
{
public
String
getName
()
{
return
"I2"
;}
}
public
static
class
I21C
implements
I2
,
I1
{
public
String
getName
()
{
return
"I2 and I1"
;}
}
public
static
class
Helper
{
public
static
I2
createI2Array0
()
{
return
new
I2C
();
}
public
static
I2
[]
createI2Array1
()
{
return
new
I2C
[]
{
new
I2C
()
};
}
public
static
I2
[][]
createI2Array2
()
{
return
new
I2C
[][]
{
new
I2C
[]
{
new
I2C
()
}
};
}
public
static
I2
[][][]
createI2Array3
()
{
return
new
I2C
[][][]
{
new
I2C
[][]
{
new
I2C
[]
{
new
I2C
()
}
}
};
}
public
static
I2
[][][][]
createI2Array4
()
{
return
new
I2C
[][][][]
{
new
I2C
[][][]
{
new
I2C
[][]
{
new
I2C
[]
{
new
I2C
()
}
}
}
};
}
public
static
I2
[][][][][]
createI2Array5
()
{
return
new
I2C
[][][][][]
{
new
I2C
[][][][]
{
new
I2C
[][][]
{
new
I2C
[][]
{
new
I2C
[]
{
new
I2C
()
}
}
}
}
};
}
public
static
I2
createI21Array0
()
{
return
new
I21C
();
}
public
static
I2
[]
createI21Array1
()
{
return
new
I21C
[]
{
new
I21C
()
};
}
public
static
I2
[][]
createI21Array2
()
{
return
new
I21C
[][]
{
new
I21C
[]
{
new
I21C
()
}
};
}
public
static
I2
[][][]
createI21Array3
()
{
return
new
I21C
[][][]
{
new
I21C
[][]
{
new
I21C
[]
{
new
I21C
()
}
}
};
}
public
static
I2
[][][][]
createI21Array4
()
{
return
new
I21C
[][][][]
{
new
I21C
[][][]
{
new
I21C
[][]
{
new
I21C
[]
{
new
I21C
()
}
}
}
};
}
public
static
I2
[][][][][]
createI21Array5
()
{
return
new
I21C
[][][][][]
{
new
I21C
[][][][]
{
new
I21C
[][][]
{
new
I21C
[][]
{
new
I21C
[]
{
new
I21C
()
}
}
}
}
};
}
}
// Location for the generated class files
public
static
final
String
PATH
=
System
.
getProperty
(
"test.classes"
,
"."
)
+
java
.
io
.
File
.
separator
;
/*
* With 'good == false' this helper method creates the following classes
* (using the nested 'Helper' class and the nested interfaces 'I1' and 'I2').
* For brevity I omit the enclosing class 'TestMeetIncompatibleInterfaceArrays' in the
* following examples:
*
* public class MeetIncompatibleInterfaceArrays0ASM {
* public static I1 run() {
* return Helper.createI2Array0(); // returns I2
* }
* public static void test() {
* I1 i1 = run();
* System.out.println(i1.getName());
* }
* }
* public class MeetIncompatibleInterfaceArrays1ASM {
* public static I1[] run() {
* return Helper.createI2Array1(); // returns I2[]
* }
* public static void test() {
* I1[] i1 = run();
* System.out.println(i1[0].getName());
* }
* }
* ...
* // MeetIncompatibleInterfaceArrays4ASM is special because it creates
* // an illegal class which will be rejected by the verifier.
* public class MeetIncompatibleInterfaceArrays4ASM {
* public static I1[][][][] run() {
* return Helper.createI2Array3(); // returns I1[][][] which gives a verifier error because return expects I1[][][][]
* }
* public static void test() {
* I1[][][][][] i1 = run();
* System.out.println(i1[0][0][0][0][0].getName());
* }
* ...
* public class MeetIncompatibleInterfaceArrays5ASM {
* public static I1[][][][][] run() {
* return Helper.createI2Array5(); // returns I2[][][][][]
* }
* public static void test() {
* I1[][][][][] i1 = run();
* System.out.println(i1[0][0][0][0][0].getName());
* }
* }
*
* Notice that this is not legal Java code. We would have to use a cast in "run()" to make it legal:
*
* public static I1[] run() {
* return (I1[])Helper.createI2Array1(); // returns I2[]
* }
*
* But in pure bytecode, the "run()" methods are perfectly legal:
*
* public static I1[] run();
* Code:
* 0: invokestatic #16 // Method Helper.createI2Array1:()[LI2;
* 3: areturn
*
* The "test()" method calls the "getName()" function from I1 on the objects returned by "run()".
* This will epectedly fail with an "IncompatibleClassChangeError" because the objects returned
* by "run()" (and by createI2Array()) are actually of type "I2C" and only implement "I2" but not "I1".
*
*
* With 'good == true' this helper method will create the following classes:
*
* public class MeetIncompatibleInterfaceArraysGood0ASM {
* public static I1 run() {
* return Helper.createI21Array0(); // returns I2
* }
* public static void test() {
* I1 i1 = run();
* System.out.println(i1.getName());
* }
* }
*
* Calling "test()" on these objects will succeed and output "I2 and I1" because now the "run()"
* method calls "createI21Array()" which actually return an object (or an array of objects) of
* type "I21C" which implements both "I2" and "I1".
*
* Notice that at the bytecode level, the code for the "run()" and "test()" methods in
* "MeetIncompatibleInterfaceArraysASM" and "MeetIncompatibleInterfaceArraysGoodASM" look exactly
* the same. I.e. the verifier has no chance to verify if the I2 object returned by "createI1Array()"
* or "createI21Array()" implements "I1" or not. That's actually the reason why both versions of
* generated classes are legal from a verifier point of view.
*
*/
static
void
generateTestClass
(
int
dim
,
boolean
good
)
throws
Exception
{
String
baseClassName
=
"MeetIncompatibleInterfaceArrays"
;
if
(
good
)
baseClassName
+=
"Good"
;
String
createName
=
"createI2"
+
(
good
?
"1"
:
""
)
+
"Array"
;
String
a
=
""
;
for
(
int
i
=
0
;
i
<
dim
;
i
++)
a
+=
"["
;
ClassWriter
cw
=
new
ClassWriter
(
ClassWriter
.
COMPUTE_FRAMES
);
cw
.
visit
(
V1_8
,
ACC_PUBLIC
,
baseClassName
+
dim
+
"ASM"
,
null
,
"java/lang/Object"
,
null
);
MethodVisitor
constr
=
cw
.
visitMethod
(
ACC_PUBLIC
,
"<init>"
,
"()V"
,
null
,
null
);
constr
.
visitCode
();
constr
.
visitVarInsn
(
ALOAD
,
0
);
constr
.
visitMethodInsn
(
INVOKESPECIAL
,
"java/lang/Object"
,
"<init>"
,
"()V"
,
false
);
constr
.
visitInsn
(
RETURN
);
constr
.
visitMaxs
(
0
,
0
);
constr
.
visitEnd
();
MethodVisitor
run
=
cw
.
visitMethod
(
ACC_PUBLIC
|
ACC_STATIC
,
"run"
,
"()"
+
a
+
"LTestMeetIncompatibleInterfaceArrays$I1;"
,
null
,
null
);
run
.
visitCode
();
if
(
dim
==
4
)
{
run
.
visitMethodInsn
(
INVOKESTATIC
,
"TestMeetIncompatibleInterfaceArrays$Helper"
,
createName
+
3
,
"()"
+
"[[["
+
"LTestMeetIncompatibleInterfaceArrays$I2;"
,
false
);
}
else
{
run
.
visitMethodInsn
(
INVOKESTATIC
,
"TestMeetIncompatibleInterfaceArrays$Helper"
,
createName
+
dim
,
"()"
+
a
+
"LTestMeetIncompatibleInterfaceArrays$I2;"
,
false
);
}
run
.
visitInsn
(
ARETURN
);
run
.
visitMaxs
(
0
,
0
);
run
.
visitEnd
();
MethodVisitor
test
=
cw
.
visitMethod
(
ACC_PUBLIC
|
ACC_STATIC
,
"test"
,
"()V"
,
null
,
null
);
test
.
visitCode
();
test
.
visitMethodInsn
(
INVOKESTATIC
,
baseClassName
+
dim
+
"ASM"
,
"run"
,
"()"
+
a
+
"LTestMeetIncompatibleInterfaceArrays$I1;"
,
false
);
test
.
visitVarInsn
(
ASTORE
,
0
);
if
(
dim
>
0
)
{
test
.
visitVarInsn
(
ALOAD
,
0
);
for
(
int
i
=
1
;
i
<=
dim
;
i
++)
{
test
.
visitInsn
(
ICONST_0
);
test
.
visitInsn
(
AALOAD
);
}
test
.
visitVarInsn
(
ASTORE
,
1
);
}
test
.
visitFieldInsn
(
GETSTATIC
,
"java/lang/System"
,
"out"
,
"Ljava/io/PrintStream;"
);
test
.
visitVarInsn
(
ALOAD
,
dim
>
0
?
1
:
0
);
test
.
visitMethodInsn
(
INVOKEINTERFACE
,
"TestMeetIncompatibleInterfaceArrays$I1"
,
"getName"
,
"()Ljava/lang/String;"
,
true
);
test
.
visitMethodInsn
(
INVOKEVIRTUAL
,
"java/io/PrintStream"
,
"println"
,
"(Ljava/lang/Object;)V"
,
false
);
test
.
visitInsn
(
RETURN
);
test
.
visitMaxs
(
0
,
0
);
test
.
visitEnd
();
// Get the bytes of the class..
byte
[]
b
=
cw
.
toByteArray
();
// ..and write them into a class file (for debugging)
FileOutputStream
fos
=
new
FileOutputStream
(
PATH
+
baseClassName
+
dim
+
"ASM.class"
);
fos
.
write
(
b
);
fos
.
close
();
}
public
static
String
[][]
tier
=
{
{
"interpreted"
,
"C2 (tier 4) without inlining"
,
"C2 (tier4) without inlining"
},
{
"interpreted"
,
"C2 (tier 4) with inlining"
,
"C2 (tier4) with inlining"
},
{
"interpreted"
,
"C1 (tier 3) with inlining"
,
"C2 (tier4) with inlining"
}
};
public
static
void
main
(
String
[]
args
)
throws
Exception
{
final
int
pass
=
Integer
.
parseInt
(
args
.
length
>
0
?
args
[
0
]
:
"0"
);
// Load and initialize some classes required for compilation
Class
.
forName
(
"TestMeetIncompatibleInterfaceArrays$I1"
);
Class
.
forName
(
"TestMeetIncompatibleInterfaceArrays$I2"
);
Class
.
forName
(
"TestMeetIncompatibleInterfaceArrays$Helper"
);
for
(
int
g
=
0
;
g
<
2
;
g
++)
{
String
baseClassName
=
"MeetIncompatibleInterfaceArrays"
;
boolean
good
=
(
g
==
0
)
?
false
:
true
;
if
(
good
)
baseClassName
+=
"Good"
;
for
(
int
i
=
0
;
i
<
6
;
i
++)
{
System
.
out
.
println
();
System
.
out
.
println
(
"Creating "
+
baseClassName
+
i
+
"ASM.class"
);
System
.
out
.
println
(
"========================================"
+
"="
+
"========="
);
// Create the "MeetIncompatibleInterfaceArrays<i>ASM" class
generateTestClass
(
i
,
good
);
Class
<?>
c
=
null
;
try
{
c
=
Class
.
forName
(
baseClassName
+
i
+
"ASM"
);
}
catch
(
VerifyError
ve
)
{
if
(
i
==
4
)
{
System
.
out
.
println
(
"OK - must be ("
+
ve
.
getMessage
()
+
")."
);
}
else
{
throw
ve
;
}
continue
;
}
// Call MeetIncompatibleInterfaceArrays<i>ASM.test()
Method
m
=
c
.
getMethod
(
"test"
);
Method
r
=
c
.
getMethod
(
"run"
);
for
(
int
j
=
0
;
j
<
3
;
j
++)
{
System
.
out
.
println
((
j
+
1
)
+
". invokation of "
+
baseClassName
+
i
+
"ASM.test() [should be "
+
tier
[
pass
][
j
]
+
"]"
);
try
{
m
.
invoke
(
null
);
}
catch
(
InvocationTargetException
ite
)
{
if
(
good
)
{
throw
ite
;
}
else
{
if
(
ite
.
getCause
()
instanceof
IncompatibleClassChangeError
)
{
System
.
out
.
println
(
" OK - catched InvocationTargetException("
+
ite
.
getCause
().
getMessage
()
+
")."
);
}
else
{
throw
ite
;
}
}
}
}
System
.
out
.
println
(
"Method "
+
r
+
(
WB
.
isMethodCompiled
(
r
)
?
" has"
:
" has not"
)
+
" been compiled."
);
if
(!
WB
.
isMethodCompiled
(
r
))
{
throw
new
Exception
(
"Method "
+
r
+
" must be compiled!"
);
}
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录