Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
d5230111
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看板
提交
d5230111
编写于
12月 05, 2014
作者:
A
amurillo
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
c2862eb9
1120bb2f
变更
25
展开全部
隐藏空白更改
内联
并排
Showing
25 changed file
with
579 addition
and
524 deletion
+579
-524
make/hotspot_version
make/hotspot_version
+1
-1
make/jprt.properties
make/jprt.properties
+0
-407
src/share/vm/classfile/javaClasses.cpp
src/share/vm/classfile/javaClasses.cpp
+27
-3
src/share/vm/classfile/javaClasses.hpp
src/share/vm/classfile/javaClasses.hpp
+4
-1
src/share/vm/compiler/compileBroker.cpp
src/share/vm/compiler/compileBroker.cpp
+1
-1
src/share/vm/compiler/compileLog.cpp
src/share/vm/compiler/compileLog.cpp
+4
-3
src/share/vm/oops/instanceKlass.cpp
src/share/vm/oops/instanceKlass.cpp
+13
-14
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlass.hpp
+1
-2
src/share/vm/opto/connode.cpp
src/share/vm/opto/connode.cpp
+95
-0
src/share/vm/opto/connode.hpp
src/share/vm/opto/connode.hpp
+16
-1
src/share/vm/opto/escape.cpp
src/share/vm/opto/escape.cpp
+3
-0
src/share/vm/opto/ifg.cpp
src/share/vm/opto/ifg.cpp
+30
-10
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+32
-0
src/share/vm/opto/loopnode.hpp
src/share/vm/opto/loopnode.hpp
+2
-0
src/share/vm/opto/phaseX.cpp
src/share/vm/opto/phaseX.cpp
+34
-5
src/share/vm/opto/subnode.cpp
src/share/vm/opto/subnode.cpp
+0
-2
src/share/vm/opto/subnode.hpp
src/share/vm/opto/subnode.hpp
+0
-2
src/share/vm/prims/jvm.cpp
src/share/vm/prims/jvm.cpp
+27
-9
src/share/vm/prims/methodHandles.cpp
src/share/vm/prims/methodHandles.cpp
+17
-51
src/share/vm/prims/methodHandles.hpp
src/share/vm/prims/methodHandles.hpp
+2
-6
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/arguments.cpp
+1
-1
test/compiler/EliminateAutoBox/UnsignedLoads.java
test/compiler/EliminateAutoBox/UnsignedLoads.java
+1
-1
test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java
...ler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java
+174
-0
test/compiler/loopopts/TestDeadBackbranchArrayAccess.java
test/compiler/loopopts/TestDeadBackbranchArrayAccess.java
+58
-0
test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java
test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java
+36
-4
未找到文件。
make/hotspot_version
浏览文件 @
d5230111
...
...
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2014
HS_MAJOR_VER=25
HS_MINOR_VER=40
HS_BUILD_NUMBER=2
1
HS_BUILD_NUMBER=2
2
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
...
...
make/jprt.properties
已删除
100644 → 0
浏览文件 @
c2862eb9
此差异已折叠。
点击以展开。
src/share/vm/classfile/javaClasses.cpp
浏览文件 @
d5230111
...
...
@@ -41,6 +41,7 @@
#include "oops/method.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
...
...
@@ -2775,12 +2776,35 @@ Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
return
(
Metadata
*
)
mname
->
address_field
(
_vmtarget_offset
);
}
bool
java_lang_invoke_MemberName
::
is_method
(
oop
mname
)
{
assert
(
is_instance
(
mname
),
"must be MemberName"
);
return
(
flags
(
mname
)
&
(
MN_IS_METHOD
|
MN_IS_CONSTRUCTOR
))
>
0
;
}
#if INCLUDE_JVMTI
// Can be executed on VM thread only
void
java_lang_invoke_MemberName
::
adjust_vmtarget
(
oop
mname
,
Metadata
*
ref
)
{
assert
((
is_instance
(
mname
)
&&
(
flags
(
mname
)
&
(
MN_IS_METHOD
|
MN_IS_CONSTRUCTOR
))
>
0
),
"wrong type"
);
void
java_lang_invoke_MemberName
::
adjust_vmtarget
(
oop
mname
,
Method
*
old_method
,
Method
*
new_method
,
bool
*
trace_name_printed
)
{
assert
(
is_method
(
mname
),
"wrong type"
);
assert
(
Thread
::
current
()
->
is_VM_thread
(),
"not VM thread"
);
mname
->
address_field_put
(
_vmtarget_offset
,
(
address
)
ref
);
Method
*
target
=
(
Method
*
)
mname
->
address_field
(
_vmtarget_offset
);
if
(
target
==
old_method
)
{
mname
->
address_field_put
(
_vmtarget_offset
,
(
address
)
new_method
);
if
(
RC_TRACE_IN_RANGE
(
0x00100000
,
0x00400000
))
{
if
(
!
(
*
trace_name_printed
))
{
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG
((
"adjust: name=%s"
,
old_method
->
method_holder
()
->
external_name
()));
*
trace_name_printed
=
true
;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE
(
0x00400000
,
(
"MemberName method update: %s(%s)"
,
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
}
}
}
#endif // INCLUDE_JVMTI
...
...
src/share/vm/classfile/javaClasses.hpp
浏览文件 @
d5230111
...
...
@@ -1096,7 +1096,8 @@ class java_lang_invoke_MemberName: AllStatic {
static
Metadata
*
vmtarget
(
oop
mname
);
static
void
set_vmtarget
(
oop
mname
,
Metadata
*
target
);
#if INCLUDE_JVMTI
static
void
adjust_vmtarget
(
oop
mname
,
Metadata
*
target
);
static
void
adjust_vmtarget
(
oop
mname
,
Method
*
old_method
,
Method
*
new_method
,
bool
*
trace_name_printed
);
#endif // INCLUDE_JVMTI
static
intptr_t
vmindex
(
oop
mname
);
...
...
@@ -1110,6 +1111,8 @@ class java_lang_invoke_MemberName: AllStatic {
return
obj
!=
NULL
&&
is_subclass
(
obj
->
klass
());
}
static
bool
is_method
(
oop
obj
);
// Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
enum
{
MN_IS_METHOD
=
0x00010000
,
// method (not constructor)
...
...
src/share/vm/compiler/compileBroker.cpp
浏览文件 @
d5230111
...
...
@@ -1845,7 +1845,7 @@ void CompileBroker::init_compiler_thread_log() {
os
::
file_separator
(),
thread_id
,
os
::
current_process_id
());
}
fp
=
fopen
(
file_name
,
"
a
t"
);
fp
=
fopen
(
file_name
,
"
w
t"
);
if
(
fp
!=
NULL
)
{
if
(
LogCompilation
&&
Verbose
)
{
tty
->
print_cr
(
"Opening compilation log %s"
,
file_name
);
...
...
src/share/vm/compiler/compileLog.cpp
浏览文件 @
d5230111
...
...
@@ -55,8 +55,10 @@ CompileLog::CompileLog(const char* file_name, FILE* fp, intx thread_id)
}
CompileLog
::~
CompileLog
()
{
delete
_out
;
delete
_out
;
// Close fd in fileStream::~fileStream()
_out
=
NULL
;
// Remove partial file after merging in CompileLog::finish_log_on_error
unlink
(
_file
);
FREE_C_HEAP_ARRAY
(
char
,
_identities
,
mtCompiler
);
FREE_C_HEAP_ARRAY
(
char
,
_file
,
mtCompiler
);
}
...
...
@@ -268,10 +270,9 @@ void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen)
}
file
->
print_raw_cr
(
"</compilation_log>"
);
close
(
partial_fd
);
unlink
(
partial_file
);
}
CompileLog
*
next_log
=
log
->
_next
;
delete
log
;
delete
log
;
// Removes partial file
log
=
next_log
;
}
_first
=
NULL
;
...
...
src/share/vm/oops/instanceKlass.cpp
浏览文件 @
d5230111
...
...
@@ -2947,28 +2947,27 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
return
NULL
;
}
void
InstanceKlass
::
add_member_name
(
int
index
,
Handle
mem_name
)
{
bool
InstanceKlass
::
add_member_name
(
Handle
mem_name
)
{
jweak
mem_name_wref
=
JNIHandles
::
make_weak_global
(
mem_name
);
MutexLocker
ml
(
MemberNameTable_lock
);
assert
(
0
<=
index
&&
index
<
idnum_allocated_count
(),
"index is out of bounds"
);
DEBUG_ONLY
(
No_Safepoint_Verifier
nsv
);
if
(
_member_names
==
NULL
)
{
_member_names
=
new
(
ResourceObj
::
C_HEAP
,
mtClass
)
MemberNameTable
(
idnum_allocated_count
());
// Check if method has been redefined while taking out MemberNameTable_lock, if so
// return false. We cannot cache obsolete methods. They will crash when the function
// is called!
Method
*
method
=
(
Method
*
)
java_lang_invoke_MemberName
::
vmtarget
(
mem_name
());
if
(
method
->
is_obsolete
())
{
return
false
;
}
else
if
(
method
->
is_old
())
{
// Replace method with redefined version
java_lang_invoke_MemberName
::
set_vmtarget
(
mem_name
(),
method_with_idnum
(
method
->
method_idnum
()));
}
_member_names
->
add_member_name
(
index
,
mem_name_wref
);
}
oop
InstanceKlass
::
get_member_name
(
int
index
)
{
MutexLocker
ml
(
MemberNameTable_lock
);
assert
(
0
<=
index
&&
index
<
idnum_allocated_count
(),
"index is out of bounds"
);
DEBUG_ONLY
(
No_Safepoint_Verifier
nsv
);
if
(
_member_names
==
NULL
)
{
return
NULL
;
_member_names
=
new
(
ResourceObj
::
C_HEAP
,
mtClass
)
MemberNameTable
(
idnum_allocated_count
())
;
}
oop
mem_name
=
_member_names
->
get_member_name
(
index
);
return
mem_nam
e
;
_member_names
->
add_member_name
(
mem_name_wref
);
return
tru
e
;
}
// -----------------------------------------------------------------------------------------------------
...
...
src/share/vm/oops/instanceKlass.hpp
浏览文件 @
d5230111
...
...
@@ -1091,8 +1091,7 @@ public:
// JSR-292 support
MemberNameTable
*
member_names
()
{
return
_member_names
;
}
void
set_member_names
(
MemberNameTable
*
member_names
)
{
_member_names
=
member_names
;
}
void
add_member_name
(
int
index
,
Handle
member_name
);
oop
get_member_name
(
int
index
);
bool
add_member_name
(
Handle
member_name
);
public:
// JVMTI support
...
...
src/share/vm/opto/connode.cpp
浏览文件 @
d5230111
...
...
@@ -441,6 +441,101 @@ Node *ConstraintCastNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
return
this
;
}
uint
CastIINode
::
size_of
()
const
{
return
sizeof
(
*
this
);
}
uint
CastIINode
::
cmp
(
const
Node
&
n
)
const
{
return
TypeNode
::
cmp
(
n
)
&&
((
CastIINode
&
)
n
).
_carry_dependency
==
_carry_dependency
;
}
Node
*
CastIINode
::
Identity
(
PhaseTransform
*
phase
)
{
if
(
_carry_dependency
)
{
return
this
;
}
return
ConstraintCastNode
::
Identity
(
phase
);
}
const
Type
*
CastIINode
::
Value
(
PhaseTransform
*
phase
)
const
{
const
Type
*
res
=
ConstraintCastNode
::
Value
(
phase
);
// Try to improve the type of the CastII if we recognize a CmpI/If
// pattern.
if
(
_carry_dependency
)
{
if
(
in
(
0
)
!=
NULL
&&
(
in
(
0
)
->
is_IfFalse
()
||
in
(
0
)
->
is_IfTrue
()))
{
Node
*
proj
=
in
(
0
);
if
(
proj
->
in
(
0
)
->
in
(
1
)
->
is_Bool
())
{
Node
*
b
=
proj
->
in
(
0
)
->
in
(
1
);
if
(
b
->
in
(
1
)
->
Opcode
()
==
Op_CmpI
)
{
Node
*
cmp
=
b
->
in
(
1
);
if
(
cmp
->
in
(
1
)
==
in
(
1
)
&&
phase
->
type
(
cmp
->
in
(
2
))
->
isa_int
())
{
const
TypeInt
*
in2_t
=
phase
->
type
(
cmp
->
in
(
2
))
->
is_int
();
const
Type
*
t
=
TypeInt
::
INT
;
BoolTest
test
=
b
->
as_Bool
()
->
_test
;
if
(
proj
->
is_IfFalse
())
{
test
=
test
.
negate
();
}
BoolTest
::
mask
m
=
test
.
_test
;
jlong
lo_long
=
min_jint
;
jlong
hi_long
=
max_jint
;
if
(
m
==
BoolTest
::
le
||
m
==
BoolTest
::
lt
)
{
hi_long
=
in2_t
->
_hi
;
if
(
m
==
BoolTest
::
lt
)
{
hi_long
-=
1
;
}
}
else
if
(
m
==
BoolTest
::
ge
||
m
==
BoolTest
::
gt
)
{
lo_long
=
in2_t
->
_lo
;
if
(
m
==
BoolTest
::
gt
)
{
lo_long
+=
1
;
}
}
else
if
(
m
==
BoolTest
::
eq
)
{
lo_long
=
in2_t
->
_lo
;
hi_long
=
in2_t
->
_hi
;
}
else
if
(
m
==
BoolTest
::
ne
)
{
// can't do any better
}
else
{
stringStream
ss
;
test
.
dump_on
(
&
ss
);
fatal
(
err_msg_res
(
"unexpected comparison %s"
,
ss
.
as_string
()));
}
int
lo_int
=
(
int
)
lo_long
;
int
hi_int
=
(
int
)
hi_long
;
if
(
lo_long
!=
(
jlong
)
lo_int
)
{
lo_int
=
min_jint
;
}
if
(
hi_long
!=
(
jlong
)
hi_int
)
{
hi_int
=
max_jint
;
}
t
=
TypeInt
::
make
(
lo_int
,
hi_int
,
Type
::
WidenMax
);
res
=
res
->
filter_speculative
(
t
);
return
res
;
}
}
}
}
}
return
res
;
}
Node
*
CastIINode
::
Ideal_DU_postCCP
(
PhaseCCP
*
ccp
)
{
if
(
_carry_dependency
)
{
return
NULL
;
}
return
ConstraintCastNode
::
Ideal_DU_postCCP
(
ccp
);
}
#ifndef PRODUCT
void
CastIINode
::
dump_spec
(
outputStream
*
st
)
const
{
TypeNode
::
dump_spec
(
st
);
if
(
_carry_dependency
)
{
st
->
print
(
" carry dependency"
);
}
}
#endif
//=============================================================================
...
...
src/share/vm/opto/connode.hpp
浏览文件 @
d5230111
...
...
@@ -241,10 +241,25 @@ public:
//------------------------------CastIINode-------------------------------------
// cast integer to integer (different range)
class
CastIINode
:
public
ConstraintCastNode
{
private:
// Can this node be removed post CCP or does it carry a required dependency?
const
bool
_carry_dependency
;
protected:
virtual
uint
cmp
(
const
Node
&
n
)
const
;
virtual
uint
size_of
()
const
;
public:
CastIINode
(
Node
*
n
,
const
Type
*
t
)
:
ConstraintCastNode
(
n
,
t
)
{}
CastIINode
(
Node
*
n
,
const
Type
*
t
,
bool
carry_dependency
=
false
)
:
ConstraintCastNode
(
n
,
t
),
_carry_dependency
(
carry_dependency
)
{}
virtual
int
Opcode
()
const
;
virtual
uint
ideal_reg
()
const
{
return
Op_RegI
;
}
virtual
Node
*
Identity
(
PhaseTransform
*
phase
);
virtual
const
Type
*
Value
(
PhaseTransform
*
phase
)
const
;
virtual
Node
*
Ideal_DU_postCCP
(
PhaseCCP
*
);
#ifndef PRODUCT
virtual
void
dump_spec
(
outputStream
*
st
)
const
;
#endif
};
//------------------------------CastPPNode-------------------------------------
...
...
src/share/vm/opto/escape.cpp
浏览文件 @
d5230111
...
...
@@ -1106,6 +1106,9 @@ bool ConnectionGraph::complete_connection_graph(
// Each 4 iterations calculate how much time it will take
// to complete graph construction.
time
.
stop
();
// Poll for requests from shutdown mechanism to quiesce compiler
// because Connection graph construction may take long time.
CompileBroker
::
maybe_block
();
double
stop_time
=
time
.
seconds
();
double
time_per_iter
=
(
stop_time
-
start_time
)
/
(
double
)
SAMPLE_SIZE
;
double
time_until_end
=
time_per_iter
*
(
double
)(
java_objects_length
-
next
);
...
...
src/share/vm/opto/ifg.cpp
浏览文件 @
d5230111
...
...
@@ -541,17 +541,37 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if
(
!
n
->
is_Proj
()
||
// Could also be a flags-projection of a dead ADD or such.
(
_lrg_map
.
live_range_id
(
def
)
&&
!
liveout
.
member
(
_lrg_map
.
live_range_id
(
def
))))
{
block
->
remove_node
(
j
-
1
);
if
(
lrgs
(
r
).
_def
==
n
)
{
lrgs
(
r
).
_def
=
0
;
bool
remove
=
true
;
if
(
n
->
is_MachProj
())
{
// Don't remove KILL projections if their "defining" nodes have
// memory effects (have SCMemProj projection node) -
// they are not dead even when their result is not used.
// For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes.
// The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
// when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
// in block in such order that KILL MachProj nodes are processed first.
uint
cnt
=
def
->
outcnt
();
for
(
uint
i
=
0
;
i
<
cnt
;
i
++
)
{
Node
*
proj
=
def
->
raw_out
(
i
);
if
(
proj
->
Opcode
()
==
Op_SCMemProj
)
{
remove
=
false
;
break
;
}
}
}
if
(
remove
)
{
block
->
remove_node
(
j
-
1
);
if
(
lrgs
(
r
).
_def
==
n
)
{
lrgs
(
r
).
_def
=
0
;
}
n
->
disconnect_inputs
(
NULL
,
C
);
_cfg
.
unmap_node_from_block
(
n
);
n
->
replace_by
(
C
->
top
());
// Since yanking a Node from block, high pressure moves up one
hrp_index
[
0
]
--
;
hrp_index
[
1
]
--
;
continue
;
}
n
->
disconnect_inputs
(
NULL
,
C
);
_cfg
.
unmap_node_from_block
(
n
);
n
->
replace_by
(
C
->
top
());
// Since yanking a Node from block, high pressure moves up one
hrp_index
[
0
]
--
;
hrp_index
[
1
]
--
;
continue
;
}
// Fat-projections kill many registers which cannot be used to
...
...
src/share/vm/opto/loopTransform.cpp
浏览文件 @
d5230111
...
...
@@ -881,6 +881,20 @@ Node *PhaseIdealLoop::clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ct
return
n
;
}
bool
PhaseIdealLoop
::
cast_incr_before_loop
(
Node
*
incr
,
Node
*
ctrl
,
Node
*
loop
)
{
Node
*
castii
=
new
(
C
)
CastIINode
(
incr
,
TypeInt
::
INT
,
true
);
castii
->
set_req
(
0
,
ctrl
);
register_new_node
(
castii
,
ctrl
);
for
(
DUIterator_Fast
imax
,
i
=
incr
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
n
=
incr
->
fast_out
(
i
);
if
(
n
->
is_Phi
()
&&
n
->
in
(
0
)
==
loop
)
{
int
nrep
=
n
->
replace_edge
(
incr
,
castii
);
return
true
;
}
}
return
false
;
}
//------------------------------insert_pre_post_loops--------------------------
// Insert pre and post loops. If peel_only is set, the pre-loop can not have
// more iterations added. It acts as a 'peel' only, no lower-bound RCE, no
...
...
@@ -1079,6 +1093,24 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
}
}
// Nodes inside the loop may be control dependent on a predicate
// that was moved before the preloop. If the back branch of the main
// or post loops becomes dead, those nodes won't be dependent on the
// test that guards that loop nest anymore which could lead to an
// incorrect array access because it executes independently of the
// test that was guarding the loop nest. We add a special CastII on
// the if branch that enters the loop, between the input induction
// variable value and the induction variable Phi to preserve correct
// dependencies.
// CastII for the post loop:
bool
inserted
=
cast_incr_before_loop
(
zer_opaq
->
in
(
1
),
zer_taken
,
post_head
);
assert
(
inserted
,
"no castII inserted"
);
// CastII for the main loop:
inserted
=
cast_incr_before_loop
(
pre_incr
,
min_taken
,
main_head
);
assert
(
inserted
,
"no castII inserted"
);
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
// RCE and alignment may change this later.
Node
*
cmp_end
=
pre_end
->
cmp_node
();
...
...
src/share/vm/opto/loopnode.hpp
浏览文件 @
d5230111
...
...
@@ -602,6 +602,8 @@ class PhaseIdealLoop : public PhaseTransform {
return
ctrl
;
}
bool
cast_incr_before_loop
(
Node
*
incr
,
Node
*
ctrl
,
Node
*
loop
);
public:
bool
has_node
(
Node
*
n
)
const
{
guarantee
(
n
!=
NULL
,
"No Node."
);
...
...
src/share/vm/opto/phaseX.cpp
浏览文件 @
d5230111
...
...
@@ -1340,15 +1340,27 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
}
}
if
(
use
->
is_Cmp
()
)
{
// Enable CMP/BOOL optimization
uint
use_op
=
use
->
Opcode
();
if
(
use
->
is_Cmp
())
{
// Enable CMP/BOOL optimization
add_users_to_worklist
(
use
);
// Put Bool on worklist
// Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
// phi merging either 0 or 1 onto the worklist
if
(
use
->
outcnt
()
>
0
)
{
Node
*
bol
=
use
->
raw_out
(
0
);
if
(
bol
->
outcnt
()
>
0
)
{
Node
*
iff
=
bol
->
raw_out
(
0
);
if
(
iff
->
outcnt
()
==
2
)
{
if
(
use_op
==
Op_CmpI
&&
iff
->
is_CountedLoopEnd
())
{
CountedLoopEndNode
*
cle
=
iff
->
as_CountedLoopEnd
();
if
(
cle
->
limit
()
==
n
&&
cle
->
phi
()
!=
NULL
)
{
// If an opaque node feeds into the limit condition of a
// CountedLoop, we need to process the Phi node for the
// induction variable when the opaque node is removed:
// the range of values taken by the Phi is now known and
// so its type is also known.
_worklist
.
push
(
cle
->
phi
());
}
}
else
if
(
iff
->
outcnt
()
==
2
)
{
// Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
// phi merging either 0 or 1 onto the worklist
Node
*
ifproj0
=
iff
->
raw_out
(
0
);
Node
*
ifproj1
=
iff
->
raw_out
(
1
);
if
(
ifproj0
->
outcnt
()
>
0
&&
ifproj1
->
outcnt
()
>
0
)
{
...
...
@@ -1360,9 +1372,26 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
}
}
}
if
(
use_op
==
Op_CmpI
)
{
Node
*
in1
=
use
->
in
(
1
);
for
(
uint
i
=
0
;
i
<
in1
->
outcnt
();
i
++
)
{
if
(
in1
->
raw_out
(
i
)
->
Opcode
()
==
Op_CastII
)
{
Node
*
castii
=
in1
->
raw_out
(
i
);
if
(
castii
->
in
(
0
)
!=
NULL
&&
castii
->
in
(
0
)
->
in
(
0
)
!=
NULL
&&
castii
->
in
(
0
)
->
in
(
0
)
->
is_If
())
{
Node
*
ifnode
=
castii
->
in
(
0
)
->
in
(
0
);
if
(
ifnode
->
in
(
1
)
!=
NULL
&&
ifnode
->
in
(
1
)
->
is_Bool
()
&&
ifnode
->
in
(
1
)
->
in
(
1
)
==
use
)
{
// Reprocess a CastII node that may depend on an
// opaque node value when the opaque node is
// removed. In case it carries a dependency we can do
// a better job of computing its type.
_worklist
.
push
(
castii
);
}
}
}
}
}
}
uint
use_op
=
use
->
Opcode
();
// If changed Cast input, check Phi users for simple cycles
if
(
use
->
is_ConstraintCast
()
||
use
->
is_CheckCastPP
()
)
{
for
(
DUIterator_Fast
i2max
,
i2
=
use
->
fast_outs
(
i2max
);
i2
<
i2max
;
i2
++
)
{
...
...
src/share/vm/opto/subnode.cpp
浏览文件 @
d5230111
...
...
@@ -1147,12 +1147,10 @@ const Type *BoolTest::cc2logical( const Type *CC ) const {
//------------------------------dump_spec-------------------------------------
// Print special per-node info
#ifndef PRODUCT
void
BoolTest
::
dump_on
(
outputStream
*
st
)
const
{
const
char
*
msg
[]
=
{
"eq"
,
"gt"
,
"of"
,
"lt"
,
"ne"
,
"le"
,
"nof"
,
"ge"
};
st
->
print
(
"%s"
,
msg
[
_test
]);
}
#endif
//=============================================================================
uint
BoolNode
::
hash
()
const
{
return
(
Node
::
hash
()
<<
3
)
|
(
_test
.
_test
+
1
);
}
...
...
src/share/vm/opto/subnode.hpp
浏览文件 @
d5230111
...
...
@@ -275,9 +275,7 @@ struct BoolTest VALUE_OBJ_CLASS_SPEC {
mask
commute
(
)
const
{
return
mask
(
"032147658"
[
_test
]
-
'0'
);
}
mask
negate
(
)
const
{
return
mask
(
_test
^
4
);
}
bool
is_canonical
(
)
const
{
return
(
_test
==
BoolTest
::
ne
||
_test
==
BoolTest
::
lt
||
_test
==
BoolTest
::
le
||
_test
==
BoolTest
::
overflow
);
}
#ifndef PRODUCT
void
dump_on
(
outputStream
*
st
)
const
;
#endif
};
//------------------------------BoolNode---------------------------------------
...
...
src/share/vm/prims/jvm.cpp
浏览文件 @
d5230111
...
...
@@ -603,13 +603,14 @@ JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
// Make shallow object copy
const
int
size
=
obj
->
size
();
oop
new_obj
=
NULL
;
oop
new_obj
_oop
=
NULL
;
if
(
obj
->
is_array
())
{
const
int
length
=
((
arrayOop
)
obj
())
->
length
();
new_obj
=
CollectedHeap
::
array_allocate
(
klass
,
size
,
length
,
CHECK_NULL
);
new_obj
_oop
=
CollectedHeap
::
array_allocate
(
klass
,
size
,
length
,
CHECK_NULL
);
}
else
{
new_obj
=
CollectedHeap
::
obj_allocate
(
klass
,
size
,
CHECK_NULL
);
new_obj
_oop
=
CollectedHeap
::
obj_allocate
(
klass
,
size
,
CHECK_NULL
);
}
// 4839641 (4840070): We must do an oop-atomic copy, because if another thread
// is modifying a reference field in the clonee, a non-oop-atomic copy might
// be suspended in the middle of copying the pointer and end up with parts
...
...
@@ -620,24 +621,41 @@ JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
// The same is true of StubRoutines::object_copy and the various oop_copy
// variants, and of the code generated by the inline_native_clone intrinsic.
assert
(
MinObjAlignmentInBytes
>=
BytesPerLong
,
"objects misaligned"
);
Copy
::
conjoint_jlongs_atomic
((
jlong
*
)
obj
(),
(
jlong
*
)
new_obj
,
Copy
::
conjoint_jlongs_atomic
((
jlong
*
)
obj
(),
(
jlong
*
)
new_obj
_oop
,
(
size_t
)
align_object_size
(
size
)
/
HeapWordsPerLong
);
// Clear the header
new_obj
->
init_mark
();
new_obj
_oop
->
init_mark
();
// Store check (mark entire object and let gc sort it out)
BarrierSet
*
bs
=
Universe
::
heap
()
->
barrier_set
();
assert
(
bs
->
has_write_region_opt
(),
"Barrier set does not have write_region"
);
bs
->
write_region
(
MemRegion
((
HeapWord
*
)
new_obj
,
size
));
bs
->
write_region
(
MemRegion
((
HeapWord
*
)
new_obj_oop
,
size
));
Handle
new_obj
(
THREAD
,
new_obj_oop
);
// Special handling for MemberNames. Since they contain Method* metadata, they
// must be registered so that RedefineClasses can fix metadata contained in them.
if
(
java_lang_invoke_MemberName
::
is_instance
(
new_obj
())
&&
java_lang_invoke_MemberName
::
is_method
(
new_obj
()))
{
Method
*
method
=
(
Method
*
)
java_lang_invoke_MemberName
::
vmtarget
(
new_obj
());
// MemberName may be unresolved, so doesn't need registration until resolved.
if
(
method
!=
NULL
)
{
methodHandle
m
(
THREAD
,
method
);
// This can safepoint and redefine method, so need both new_obj and method
// in a handle, for two different reasons. new_obj can move, method can be
// deleted if nothing is using it on the stack.
m
->
method_holder
()
->
add_member_name
(
new_obj
());
}
}
// Caution: this involves a java upcall, so the clone should be
// "gc-robust" by this stage.
if
(
klass
->
has_finalizer
())
{
assert
(
obj
->
is_instance
(),
"should be instanceOop"
);
new_obj
=
InstanceKlass
::
register_finalizer
(
instanceOop
(
new_obj
),
CHECK_NULL
);
new_obj_oop
=
InstanceKlass
::
register_finalizer
(
instanceOop
(
new_obj
()),
CHECK_NULL
);
new_obj
=
Handle
(
THREAD
,
new_obj_oop
);
}
return
JNIHandles
::
make_local
(
env
,
oop
(
new_obj
));
return
JNIHandles
::
make_local
(
env
,
new_obj
(
));
JVM_END
// java.lang.Compiler ////////////////////////////////////////////////////
...
...
@@ -4526,7 +4544,7 @@ JVM_END
JVM_ENTRY
(
void
,
JVM_GetVersionInfo
(
JNIEnv
*
env
,
jvm_version_info
*
info
,
size_t
info_size
))
{
memset
(
info
,
0
,
sizeof
(
info_size
)
);
memset
(
info
,
0
,
info_size
);
info
->
jvm_version
=
Abstract_VM_Version
::
jvm_version
();
info
->
update_version
=
0
;
/* 0 in HotSpot Express VM */
...
...
src/share/vm/prims/methodHandles.cpp
浏览文件 @
d5230111
...
...
@@ -29,7 +29,6 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
...
...
@@ -271,9 +270,12 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
// This is done eagerly, since it is readily available without
// constructing any new objects.
// TO DO: maybe intern mname_oop
m
->
method_holder
()
->
add_member_name
(
m
->
method_idnum
(),
mname
);
return
mname
();
if
(
m
->
method_holder
()
->
add_member_name
(
mname
))
{
return
mname
();
}
else
{
// Redefinition caused this to fail. Return NULL (and an exception?)
return
NULL
;
}
}
oop
MethodHandles
::
init_field_MemberName
(
Handle
mname
,
fieldDescriptor
&
fd
,
bool
is_setter
)
{
...
...
@@ -946,63 +948,27 @@ MemberNameTable::~MemberNameTable() {
}
}
void
MemberNameTable
::
add_member_name
(
int
index
,
jweak
mem_name_wref
)
{
assert_locked_or_safepoint
(
MemberNameTable_lock
);
this
->
at_put_grow
(
index
,
mem_name_wref
);
}
// Return a member name oop or NULL.
oop
MemberNameTable
::
get_member_name
(
int
index
)
{
void
MemberNameTable
::
add_member_name
(
jweak
mem_name_wref
)
{
assert_locked_or_safepoint
(
MemberNameTable_lock
);
jweak
ref
=
this
->
at
(
index
);
oop
mem_name
=
JNIHandles
::
resolve
(
ref
);
return
mem_name
;
this
->
push
(
mem_name_wref
);
}
#if INCLUDE_JVMTI
oop
MemberNameTable
::
find_member_name_by_method
(
Method
*
old_method
)
{
assert_locked_or_safepoint
(
MemberNameTable_lock
);
oop
found
=
NULL
;
int
len
=
this
->
length
();
for
(
int
idx
=
0
;
idx
<
len
;
idx
++
)
{
oop
mem_name
=
JNIHandles
::
resolve
(
this
->
at
(
idx
));
if
(
mem_name
==
NULL
)
{
continue
;
}
Method
*
method
=
(
Method
*
)
java_lang_invoke_MemberName
::
vmtarget
(
mem_name
);
if
(
method
==
old_method
)
{
found
=
mem_name
;
break
;
}
}
return
found
;
}
// It is called at safepoint only
// It is called at safepoint only for RedefineClasses
void
MemberNameTable
::
adjust_method_entries
(
Method
**
old_methods
,
Method
**
new_methods
,
int
methods_length
,
bool
*
trace_name_printed
)
{
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"only called at safepoint"
);
//
search the MemberNameTable for uses of either obsolete or EMCP methods
//
For each redefined method
for
(
int
j
=
0
;
j
<
methods_length
;
j
++
)
{
Method
*
old_method
=
old_methods
[
j
];
Method
*
new_method
=
new_methods
[
j
];
oop
mem_name
=
find_member_name_by_method
(
old_method
);
if
(
mem_name
!=
NULL
)
{
java_lang_invoke_MemberName
::
adjust_vmtarget
(
mem_name
,
new_method
);
if
(
RC_TRACE_IN_RANGE
(
0x00100000
,
0x00400000
))
{
if
(
!
(
*
trace_name_printed
))
{
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG
((
"adjust: name=%s"
,
old_method
->
method_holder
()
->
external_name
()));
*
trace_name_printed
=
true
;
}
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE
(
0x00400000
,
(
"MemberName method update: %s(%s)"
,
new_method
->
name
()
->
as_C_string
(),
new_method
->
signature
()
->
as_C_string
()));
// search the MemberNameTable for uses of either obsolete or EMCP methods
for
(
int
idx
=
0
;
idx
<
length
();
idx
++
)
{
oop
mem_name
=
JNIHandles
::
resolve
(
this
->
at
(
idx
));
if
(
mem_name
!=
NULL
)
{
java_lang_invoke_MemberName
::
adjust_vmtarget
(
mem_name
,
old_method
,
new_method
,
trace_name_printed
);
}
}
}
...
...
src/share/vm/prims/methodHandles.hpp
浏览文件 @
d5230111
/*
* Copyright (c) 2008, 201
3
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 201
4
, 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
...
...
@@ -236,18 +236,14 @@ class MemberNameTable : public GrowableArray<jweak> {
public:
MemberNameTable
(
int
methods_cnt
);
~
MemberNameTable
();
void
add_member_name
(
int
index
,
jweak
mem_name_ref
);
oop
get_member_name
(
int
index
);
void
add_member_name
(
jweak
mem_name_ref
);
#if INCLUDE_JVMTI
public:
// RedefineClasses() API support:
// If a MemberName refers to old_method then update it
// to refer to new_method.
void
adjust_method_entries
(
Method
**
old_methods
,
Method
**
new_methods
,
int
methods_length
,
bool
*
trace_name_printed
);
private:
oop
find_member_name_by_method
(
Method
*
old_method
);
#endif // INCLUDE_JVMTI
};
...
...
src/share/vm/runtime/arguments.cpp
浏览文件 @
d5230111
...
...
@@ -3543,7 +3543,7 @@ static bool check_endorsed_and_ext_dirs() {
if
(
nonEmptyDirs
>
0
)
{
jio_fprintf
(
defaultStream
::
output_stream
(),
"Endorsed standards override mechanism and extension mechanism"
"Endorsed standards override mechanism and extension mechanism
"
"will not be supported in a future release.
\n
"
"Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).
\n
"
);
return
false
;
...
...
test/compiler/EliminateAutoBox/UnsignedLoads.java
浏览文件 @
d5230111
...
...
@@ -26,7 +26,7 @@
/*
* @test
* @library /testlibrary
* @run main/othervm -Xbatch -XX:+EliminateAutoBox
* @run main/othervm -Xbatch -XX:+
IgnoreUnrecognizedVMOptions -XX:+
EliminateAutoBox
* -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort
* UnsignedLoads
*/
...
...
test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java
0 → 100644
浏览文件 @
d5230111
/*
* 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 8042235
* @summary redefining method used by multiple MethodHandles crashes VM
* @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java
* @run main RedefineMethodUsedByMultipleMethodHandles
*/
import
java.io.*
;
import
java.lang.instrument.*
;
import
java.lang.invoke.*
;
import
java.lang.invoke.MethodHandles.Lookup
;
import
java.lang.management.*
;
import
java.lang.reflect.*
;
import
java.nio.file.*
;
import
java.security.*
;
import
java.util.jar.*
;
import
javax.tools.*
;
import
jdk.internal.org.objectweb.asm.*
;
public
class
RedefineMethodUsedByMultipleMethodHandles
{
static
class
Foo
{
public
static
Object
getName
()
{
return
"foo"
;
}
}
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
Lookup
lookup
=
MethodHandles
.
lookup
();
Method
fooMethod
=
Foo
.
class
.
getDeclaredMethod
(
"getName"
);
// fooMH2 displaces fooMH1 from the MemberNamesTable
MethodHandle
fooMH1
=
lookup
.
unreflect
(
fooMethod
);
MethodHandle
fooMH2
=
lookup
.
unreflect
(
fooMethod
);
System
.
out
.
println
(
"fooMH1.invoke = "
+
fooMH1
.
invokeExact
());
System
.
out
.
println
(
"fooMH2.invoke = "
+
fooMH2
.
invokeExact
());
// Redefining Foo.getName() causes vmtarget to be updated
// in fooMH2 but not fooMH1
redefineFoo
();
// Full GC causes fooMH1.vmtarget to be deallocated
System
.
gc
();
// Calling fooMH1.vmtarget crashes the VM
System
.
out
.
println
(
"fooMH1.invoke = "
+
fooMH1
.
invokeExact
());
}
/**
* Adds the class file bytes for {@code c} to {@code jar}.
*/
static
void
add
(
JarOutputStream
jar
,
Class
<?>
c
)
throws
IOException
{
String
classAsPath
=
c
.
getName
().
replace
(
'.'
,
'/'
)
+
".class"
;
jar
.
putNextEntry
(
new
JarEntry
(
classAsPath
));
InputStream
stream
=
c
.
getClassLoader
().
getResourceAsStream
(
classAsPath
);
int
b
;
while
((
b
=
stream
.
read
())
!=
-
1
)
{
jar
.
write
(
b
);
}
}
static
void
redefineFoo
()
throws
Exception
{
Manifest
manifest
=
new
Manifest
();
manifest
.
getMainAttributes
().
put
(
Attributes
.
Name
.
MANIFEST_VERSION
,
"1.0"
);
Attributes
mainAttrs
=
manifest
.
getMainAttributes
();
mainAttrs
.
putValue
(
"Agent-Class"
,
FooAgent
.
class
.
getName
());
mainAttrs
.
putValue
(
"Can-Redefine-Classes"
,
"true"
);
mainAttrs
.
putValue
(
"Can-Retransform-Classes"
,
"true"
);
Path
jar
=
Files
.
createTempFile
(
"myagent"
,
".jar"
);
try
{
JarOutputStream
jarStream
=
new
JarOutputStream
(
new
FileOutputStream
(
jar
.
toFile
()),
manifest
);
add
(
jarStream
,
FooAgent
.
class
);
add
(
jarStream
,
FooTransformer
.
class
);
jarStream
.
close
();
runAgent
(
jar
);
}
finally
{
Files
.
deleteIfExists
(
jar
);
}
}
public
static
void
runAgent
(
Path
agent
)
throws
Exception
{
String
vmName
=
ManagementFactory
.
getRuntimeMXBean
().
getName
();
int
p
=
vmName
.
indexOf
(
'@'
);
assert
p
!=
-
1
:
"VM name not in <pid>@<host> format: "
+
vmName
;
String
pid
=
vmName
.
substring
(
0
,
p
);
ClassLoader
cl
=
ToolProvider
.
getSystemToolClassLoader
();
Class
<?>
c
=
Class
.
forName
(
"com.sun.tools.attach.VirtualMachine"
,
true
,
cl
);
Method
attach
=
c
.
getDeclaredMethod
(
"attach"
,
String
.
class
);
Method
loadAgent
=
c
.
getDeclaredMethod
(
"loadAgent"
,
String
.
class
);
Method
detach
=
c
.
getDeclaredMethod
(
"detach"
);
Object
vm
=
attach
.
invoke
(
null
,
pid
);
loadAgent
.
invoke
(
vm
,
agent
.
toString
());
detach
.
invoke
(
vm
);
}
public
static
class
FooAgent
{
public
static
void
agentmain
(
@SuppressWarnings
(
"unused"
)
String
args
,
Instrumentation
inst
)
throws
Exception
{
assert
inst
.
isRedefineClassesSupported
();
assert
inst
.
isRetransformClassesSupported
();
inst
.
addTransformer
(
new
FooTransformer
(),
true
);
Class
<?>[]
classes
=
inst
.
getAllLoadedClasses
();
for
(
int
i
=
0
;
i
<
classes
.
length
;
i
++)
{
Class
<?>
c
=
classes
[
i
];
if
(
c
==
Foo
.
class
)
{
inst
.
retransformClasses
(
new
Class
[]{
c
});
}
}
}
}
static
class
FooTransformer
implements
ClassFileTransformer
{
@Override
public
byte
[]
transform
(
ClassLoader
cl
,
String
className
,
Class
<?>
classBeingRedefined
,
ProtectionDomain
protectionDomain
,
byte
[]
classfileBuffer
)
throws
IllegalClassFormatException
{
if
(
Foo
.
class
.
equals
(
classBeingRedefined
))
{
System
.
out
.
println
(
"redefining "
+
classBeingRedefined
);
ClassReader
cr
=
new
ClassReader
(
classfileBuffer
);
ClassWriter
cw
=
new
ClassWriter
(
cr
,
ClassWriter
.
COMPUTE_FRAMES
);
ClassVisitor
adapter
=
new
ClassVisitor
(
Opcodes
.
ASM5
,
cw
)
{
@Override
public
MethodVisitor
visitMethod
(
int
access
,
String
base
,
String
desc
,
String
signature
,
String
[]
exceptions
)
{
MethodVisitor
mv
=
cv
.
visitMethod
(
access
,
base
,
desc
,
signature
,
exceptions
);
if
(
mv
!=
null
)
{
mv
=
new
MethodVisitor
(
Opcodes
.
ASM5
,
mv
)
{
@Override
public
void
visitLdcInsn
(
Object
cst
)
{
System
.
out
.
println
(
"replacing \""
+
cst
+
"\" with \"bar\""
);
mv
.
visitLdcInsn
(
"bar"
);
}
};
}
return
mv
;
}
};
cr
.
accept
(
adapter
,
ClassReader
.
SKIP_FRAMES
);
cw
.
visitEnd
();
return
cw
.
toByteArray
();
}
return
classfileBuffer
;
}
}
}
test/compiler/loopopts/TestDeadBackbranchArrayAccess.java
0 → 100644
浏览文件 @
d5230111
/*
* 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 8054478
* @summary dead backbranch in main loop results in erroneous array access
* @run main/othervm -XX:CompileOnly=TestDeadBackbranchArrayAccess -Xcomp TestDeadBackbranchArrayAccess
*
*/
public
class
TestDeadBackbranchArrayAccess
{
static
char
[]
pattern0
=
{
0
};
static
char
[]
pattern1
=
{
1
};
static
void
test
(
char
[]
array
)
{
if
(
pattern1
==
null
)
return
;
int
i
=
0
;
int
pos
=
0
;
char
c
=
array
[
pos
];
while
(
i
>=
0
&&
(
c
==
pattern0
[
i
]
||
c
==
pattern1
[
i
]))
{
i
--;
pos
--;
if
(
pos
!=
-
1
)
{
c
=
array
[
pos
];
}
}
}
public
static
void
main
(
String
[]
args
)
{
for
(
int
i
=
0
;
i
<
1000000
;
i
++)
{
test
(
new
char
[
1
]);
}
}
}
test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java
浏览文件 @
d5230111
...
...
@@ -26,10 +26,16 @@
* @bug 8064667
* @summary Sanity test for -XX:+CheckEndorsedAndExtDirs
* @library /testlibrary
* @run main/othervm
-XX:+CheckEndorsedAndExtDirs
EndorsedExtDirs
* @run main/othervm EndorsedExtDirs
*/
import
com.oracle.java.testlibrary.*
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.attribute.BasicFileAttributes
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -38,9 +44,28 @@ public class EndorsedExtDirs {
public
static
void
main
(
String
arg
[])
throws
Exception
{
fatalError
(
"-XX:+CheckEndorsedAndExtDirs"
,
"-Djava.endorsed.dirs=foo"
);
fatalError
(
"-XX:+CheckEndorsedAndExtDirs"
,
"-Djava.ext.dirs=bar"
);
testNonEmptySystemExtDirs
();
}
static
void
fatalError
(
String
...
args
)
throws
Exception
{
static
void
testNonEmptySystemExtDirs
()
throws
Exception
{
String
home
=
System
.
getProperty
(
"java.home"
);
Path
ext
=
Paths
.
get
(
home
,
"lib"
,
"ext"
);
String
extDirs
=
System
.
getProperty
(
"java.ext.dirs"
);
String
[]
dirs
=
extDirs
.
split
(
File
.
pathSeparator
);
long
count
=
0
;
for
(
String
d
:
dirs
)
{
Path
path
=
Paths
.
get
(
d
);
if
(
Files
.
notExists
(
path
)
||
path
.
equals
(
ext
))
continue
;
count
+=
Files
.
find
(
path
,
1
,
(
Path
p
,
BasicFileAttributes
attr
)
->
p
.
getFileName
().
toString
().
endsWith
(
".jar"
))
.
count
();
}
if
(
count
>
0
)
{
fatalError
(
"-XX:+CheckEndorsedAndExtDirs"
);
}
}
static
ProcessBuilder
newProcessBuilder
(
String
...
args
)
{
List
<
String
>
commands
=
new
ArrayList
<>();
String
java
=
System
.
getProperty
(
"java.home"
)
+
"/bin/java"
;
commands
.
add
(
java
);
...
...
@@ -51,8 +76,15 @@ public class EndorsedExtDirs {
commands
.
add
(
cpath
);
commands
.
add
(
"EndorsedExtDirs"
);
System
.
out
.
println
(
"Launching "
+
commands
);
ProcessBuilder
pb
=
new
ProcessBuilder
(
commands
);
System
.
out
.
println
(
"Process "
+
commands
);
return
new
ProcessBuilder
(
commands
);
}
static
void
fatalError
(
String
...
args
)
throws
Exception
{
fatalError
(
newProcessBuilder
(
args
));
}
static
void
fatalError
(
ProcessBuilder
pb
)
throws
Exception
{
OutputAnalyzer
output
=
new
OutputAnalyzer
(
pb
.
start
());
output
.
shouldContain
(
"Could not create the Java Virtual Machine"
);
output
.
shouldHaveExitValue
(
1
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录