Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
cb1cb002
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看板
提交
cb1cb002
编写于
3月 17, 2010
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6930043: C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I
Reviewed-by: kvn
上级
21200b6a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
181 addition
and
67 deletion
+181
-67
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+104
-66
src/share/vm/opto/loopnode.hpp
src/share/vm/opto/loopnode.hpp
+1
-1
test/compiler/6930043/Test6930043.java
test/compiler/6930043/Test6930043.java
+76
-0
未找到文件。
src/share/vm/opto/loopTransform.cpp
浏览文件 @
cb1cb002
/*
* Copyright 2000-20
09
Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-20
10
Sun Microsystems, Inc. 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
...
...
@@ -2088,29 +2088,41 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invari
BoolNode
*
PhaseIdealLoop
::
rc_predicate
(
Node
*
ctrl
,
int
scale
,
Node
*
offset
,
Node
*
init
,
Node
*
limit
,
Node
*
stride
,
Node
*
range
)
{
Node
*
range
,
bool
upper
)
{
DEBUG_ONLY
(
ttyLocker
ttyl
);
if
(
TraceLoopPredicate
)
tty
->
print
(
"rc_predicate "
);
Node
*
max_idx_expr
=
init
;
int
stride_con
=
stride
->
get_int
();
if
((
stride_con
>
0
)
==
(
scale
>
0
))
{
if
((
stride_con
>
0
)
==
(
scale
>
0
)
==
upper
)
{
max_idx_expr
=
new
(
C
,
3
)
SubINode
(
limit
,
stride
);
register_new_node
(
max_idx_expr
,
ctrl
);
if
(
TraceLoopPredicate
)
tty
->
print
(
"(limit - stride) "
);
}
else
{
if
(
TraceLoopPredicate
)
tty
->
print
(
"init "
);
}
if
(
scale
!=
1
)
{
ConNode
*
con_scale
=
_igvn
.
intcon
(
scale
);
max_idx_expr
=
new
(
C
,
3
)
MulINode
(
max_idx_expr
,
con_scale
);
register_new_node
(
max_idx_expr
,
ctrl
);
if
(
TraceLoopPredicate
)
tty
->
print
(
"* %d "
,
scale
);
}
if
(
offset
&&
(
!
offset
->
is_Con
()
||
offset
->
get_int
()
!=
0
)){
max_idx_expr
=
new
(
C
,
3
)
AddINode
(
max_idx_expr
,
offset
);
register_new_node
(
max_idx_expr
,
ctrl
);
if
(
TraceLoopPredicate
)
if
(
offset
->
is_Con
())
tty
->
print
(
"+ %d "
,
offset
->
get_int
());
else
tty
->
print
(
"+ offset "
);
}
CmpUNode
*
cmp
=
new
(
C
,
3
)
CmpUNode
(
max_idx_expr
,
range
);
register_new_node
(
cmp
,
ctrl
);
BoolNode
*
bol
=
new
(
C
,
2
)
BoolNode
(
cmp
,
BoolTest
::
lt
);
register_new_node
(
bol
,
ctrl
);
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
"<u range"
);
return
bol
;
}
...
...
@@ -2187,7 +2199,6 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
while
(
if_proj_list
.
size
()
>
0
)
{
// Following are changed to nonnull when a predicate can be hoisted
ProjNode
*
new_predicate_proj
=
NULL
;
BoolNode
*
new_predicate_bol
=
NULL
;
ProjNode
*
proj
=
if_proj_list
.
pop
()
->
as_Proj
();
IfNode
*
iff
=
proj
->
in
(
0
)
->
as_If
();
...
...
@@ -2218,93 +2229,120 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
// Invariant test
new_predicate_proj
=
create_new_if_for_predicate
(
predicate_proj
);
Node
*
ctrl
=
new_predicate_proj
->
in
(
0
)
->
as_If
()
->
in
(
0
);
new_predicate_bol
=
invar
.
clone
(
bol
,
ctrl
)
->
as_Bool
();
if
(
TraceLoopPredicate
)
tty
->
print
(
"invariant"
);
BoolNode
*
new_predicate_bol
=
invar
.
clone
(
bol
,
ctrl
)
->
as_Bool
();
// Negate test if necessary
bool
negated
=
false
;
if
(
proj
->
_con
!=
predicate_proj
->
_con
)
{
new_predicate_bol
=
new
(
C
,
2
)
BoolNode
(
new_predicate_bol
->
in
(
1
),
new_predicate_bol
->
_test
.
negate
());
register_new_node
(
new_predicate_bol
,
ctrl
);
negated
=
true
;
}
IfNode
*
new_predicate_iff
=
new_predicate_proj
->
in
(
0
)
->
as_If
();
_igvn
.
hash_delete
(
new_predicate_iff
);
new_predicate_iff
->
set_req
(
1
,
new_predicate_bol
);
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
"invariant if%s: %d"
,
negated
?
" negated"
:
""
,
new_predicate_iff
->
_idx
);
}
else
if
(
cl
!=
NULL
&&
loop
->
is_range_check_if
(
iff
,
this
,
invar
))
{
// Range check (only for counted loops)
new_predicate_proj
=
create_new_if_for_predicate
(
predicate_proj
);
Node
*
ctrl
=
new_predicate_proj
->
in
(
0
)
->
as_If
()
->
in
(
0
);
assert
(
proj
->
_con
==
predicate_proj
->
_con
,
"must match"
);
// Range check for counted loops
const
Node
*
cmp
=
bol
->
in
(
1
)
->
as_Cmp
();
Node
*
idx
=
cmp
->
in
(
1
);
assert
(
!
invar
.
is_invariant
(
idx
),
"index is variant"
);
assert
(
cmp
->
in
(
2
)
->
Opcode
()
==
Op_LoadRange
,
"must be"
);
LoadRangeNode
*
ld_rng
=
(
LoadRangeNode
*
)
cmp
->
in
(
2
);
// LoadRangeNode
Node
*
ld_rng
=
cmp
->
in
(
2
);
// LoadRangeNode
assert
(
invar
.
is_invariant
(
ld_rng
),
"load range must be invariant"
);
ld_rng
=
(
LoadRangeNode
*
)
invar
.
clone
(
ld_rng
,
ctrl
);
int
scale
=
1
;
Node
*
offset
=
zero
;
bool
ok
=
is_scaled_iv_plus_offset
(
idx
,
cl
->
phi
(),
&
scale
,
&
offset
);
assert
(
ok
,
"must be index expression"
);
Node
*
init
=
cl
->
init_trip
();
Node
*
limit
=
cl
->
limit
();
Node
*
stride
=
cl
->
stride
();
// Build if's for the upper and lower bound tests. The
// lower_bound test will dominate the upper bound test and all
// cloned or created nodes will use the lower bound test as
// their declared control.
ProjNode
*
lower_bound_proj
=
create_new_if_for_predicate
(
predicate_proj
);
ProjNode
*
upper_bound_proj
=
create_new_if_for_predicate
(
predicate_proj
);
assert
(
upper_bound_proj
->
in
(
0
)
->
as_If
()
->
in
(
0
)
==
lower_bound_proj
,
"should dominate"
);
Node
*
ctrl
=
lower_bound_proj
->
in
(
0
)
->
as_If
()
->
in
(
0
);
// Perform cloning to keep Invariance state correct since the
// late schedule will place invariant things in the loop.
ld_rng
=
invar
.
clone
(
ld_rng
,
ctrl
);
if
(
offset
&&
offset
!=
zero
)
{
assert
(
invar
.
is_invariant
(
offset
),
"offset must be loop invariant"
);
offset
=
invar
.
clone
(
offset
,
ctrl
);
}
Node
*
init
=
cl
->
init_trip
();
Node
*
limit
=
cl
->
limit
();
Node
*
stride
=
cl
->
stride
();
new_predicate_bol
=
rc_predicate
(
ctrl
,
scale
,
offset
,
init
,
limit
,
stride
,
ld_rng
);
if
(
TraceLoopPredicate
)
tty
->
print
(
"range check"
);
}
if
(
new_predicate_proj
==
NULL
)
{
// Test the lower bound
Node
*
lower_bound_bol
=
rc_predicate
(
ctrl
,
scale
,
offset
,
init
,
limit
,
stride
,
ld_rng
,
false
);
IfNode
*
lower_bound_iff
=
lower_bound_proj
->
in
(
0
)
->
as_If
();
_igvn
.
hash_delete
(
lower_bound_iff
);
lower_bound_iff
->
set_req
(
1
,
lower_bound_bol
);
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
"lower bound check if: %d"
,
lower_bound_iff
->
_idx
);
// Test the upper bound
Node
*
upper_bound_bol
=
rc_predicate
(
ctrl
,
scale
,
offset
,
init
,
limit
,
stride
,
ld_rng
,
true
);
IfNode
*
upper_bound_iff
=
upper_bound_proj
->
in
(
0
)
->
as_If
();
_igvn
.
hash_delete
(
upper_bound_iff
);
upper_bound_iff
->
set_req
(
1
,
upper_bound_bol
);
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
"upper bound check if: %d"
,
lower_bound_iff
->
_idx
);
// Fall through into rest of the clean up code which will move
// any dependent nodes onto the upper bound test.
new_predicate_proj
=
upper_bound_proj
;
}
else
{
// The other proj of the "iff" is a uncommon trap projection, and we can assume
// the other proj will not be executed ("executed" means uct raised).
continue
;
}
else
{
// Success - attach condition (new_predicate_bol) to predicate if
invar
.
map_ctrl
(
proj
,
new_predicate_proj
);
// so that invariance test can be appropriate
IfNode
*
new_iff
=
new_predicate_proj
->
in
(
0
)
->
as_If
();
// Negate test if necessary
if
(
proj
->
_con
!=
predicate_proj
->
_con
)
{
new_predicate_bol
=
new
(
C
,
2
)
BoolNode
(
new_predicate_bol
->
in
(
1
),
new_predicate_bol
->
_test
.
negate
());
register_new_node
(
new_predicate_bol
,
new_iff
->
in
(
0
));
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
" if negated: %d"
,
iff
->
_idx
);
}
else
{
if
(
TraceLoopPredicate
)
tty
->
print_cr
(
" if: %d"
,
iff
->
_idx
);
}
_igvn
.
hash_delete
(
new_iff
);
new_iff
->
set_req
(
1
,
new_predicate_bol
);
_igvn
.
hash_delete
(
iff
);
iff
->
set_req
(
1
,
proj
->
is_IfFalse
()
?
cond_false
:
cond_true
);
}
Node
*
ctrl
=
new_predicate_proj
;
// new control
ProjNode
*
dp
=
proj
;
// old control
assert
(
get_loop
(
dp
)
==
loop
,
"guarenteed at the time of collecting proj"
);
// Find nodes (depends only on the test) off the surviving projection;
// move them outside the loop with the control of proj_clone
for
(
DUIterator_Fast
imax
,
i
=
dp
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
cd
=
dp
->
fast_out
(
i
);
// Control-dependent node
if
(
cd
->
depends_only_on_test
())
{
assert
(
cd
->
in
(
0
)
==
dp
,
""
);
_igvn
.
hash_delete
(
cd
);
cd
->
set_req
(
0
,
ctrl
);
// ctrl, not NULL
set_early_ctrl
(
cd
);
_igvn
.
_worklist
.
push
(
cd
);
IdealLoopTree
*
new_loop
=
get_loop
(
get_ctrl
(
cd
));
if
(
new_loop
!=
loop
)
{
if
(
!
loop
->
_child
)
loop
->
_body
.
yank
(
cd
);
if
(
!
new_loop
->
_child
)
new_loop
->
_body
.
push
(
cd
);
}
--
i
;
--
imax
;
// Success - attach condition (new_predicate_bol) to predicate if
invar
.
map_ctrl
(
proj
,
new_predicate_proj
);
// so that invariance test can be appropriate
// Eliminate the old if in the loop body
_igvn
.
hash_delete
(
iff
);
iff
->
set_req
(
1
,
proj
->
is_IfFalse
()
?
cond_false
:
cond_true
);
Node
*
ctrl
=
new_predicate_proj
;
// new control
ProjNode
*
dp
=
proj
;
// old control
assert
(
get_loop
(
dp
)
==
loop
,
"guaranteed at the time of collecting proj"
);
// Find nodes (depends only on the test) off the surviving projection;
// move them outside the loop with the control of proj_clone
for
(
DUIterator_Fast
imax
,
i
=
dp
->
fast_outs
(
imax
);
i
<
imax
;
i
++
)
{
Node
*
cd
=
dp
->
fast_out
(
i
);
// Control-dependent node
if
(
cd
->
depends_only_on_test
())
{
assert
(
cd
->
in
(
0
)
==
dp
,
""
);
_igvn
.
hash_delete
(
cd
);
cd
->
set_req
(
0
,
ctrl
);
// ctrl, not NULL
set_early_ctrl
(
cd
);
_igvn
.
_worklist
.
push
(
cd
);
IdealLoopTree
*
new_loop
=
get_loop
(
get_ctrl
(
cd
));
if
(
new_loop
!=
loop
)
{
if
(
!
loop
->
_child
)
loop
->
_body
.
yank
(
cd
);
if
(
!
new_loop
->
_child
)
new_loop
->
_body
.
push
(
cd
);
}
--
i
;
--
imax
;
}
hoisted
=
true
;
C
->
set_major_progress
();
}
hoisted
=
true
;
C
->
set_major_progress
();
}
// end while
#ifndef PRODUCT
// report that the loop predication has been actually performed
// for this loop
if
(
TraceLoopPredicate
&&
hoisted
)
{
tty
->
print
(
"Loop Predication Performed:"
);
loop
->
dump_head
();
}
// report that the loop predication has been actually performed
// for this loop
if
(
TraceLoopPredicate
&&
hoisted
)
{
tty
->
print
(
"Loop Predication Performed:"
);
loop
->
dump_head
();
}
#endif
return
hoisted
;
...
...
src/share/vm/opto/loopnode.hpp
浏览文件 @
cb1cb002
...
...
@@ -821,7 +821,7 @@ public:
BoolNode
*
rc_predicate
(
Node
*
ctrl
,
int
scale
,
Node
*
offset
,
Node
*
init
,
Node
*
limit
,
Node
*
stride
,
Node
*
range
);
Node
*
range
,
bool
upper
);
// Implementation of the loop predication to promote checks outside the loop
bool
loop_predication_impl
(
IdealLoopTree
*
loop
);
...
...
test/compiler/6930043/Test6930043.java
0 → 100644
浏览文件 @
cb1cb002
/*
* Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
/**
* @test
* @bug 6930043
* @summary C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I
*
* @run main Test6930043
*/
import
java.io.PrintStream
;
public
class
Test6930043
{
int
[]
a
;
int
idx
;
public
int
loop_back
(
int
i
,
int
i_0_
)
{
int
i_1_
=
0
;
int
[]
is
=
a
;
if
(
is
==
null
)
return
0
;
for
(
int
i_2_
=
i
;
i_2_
>=
i_0_
;
i_2_
--)
i_1_
+=
is
[
idx
=
i_2_
];
return
i_1_
;
}
public
int
loop_forw
(
int
start
,
int
end
)
{
int
result
=
0
;
int
[]
is
=
a
;
if
(
is
==
null
)
return
0
;
for
(
int
index
=
start
;
index
<
end
;
index
++)
result
+=
is
[
index
];
// result += is[idx = index];
return
result
;
}
public
static
void
main
(
String
[]
strings
)
{
Test6930043
var_Test6930043
=
new
Test6930043
();
var_Test6930043
.
a
=
new
int
[
1000000
];
var_Test6930043
.
loop_forw
(
10
,
999990
);
var_Test6930043
.
loop_forw
(
10
,
999990
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
try
{
if
(
var_Test6930043
.
loop_forw
(-
1
,
999990
)
!=
0
)
throw
new
InternalError
();
}
catch
(
ArrayIndexOutOfBoundsException
e
)
{
}
}
var_Test6930043
.
loop_back
(
999990
,
10
);
var_Test6930043
.
loop_back
(
999990
,
10
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
try
{
if
(
var_Test6930043
.
loop_back
(
999990
,
-
1
)
!=
0
)
throw
new
InternalError
();
}
catch
(
ArrayIndexOutOfBoundsException
e
)
{
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录