Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
82666eba
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看板
提交
82666eba
编写于
5月 16, 2011
作者:
K
kvn
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
Summary: Fix problems in new RCE code. Reviewed-by: never
上级
da8420a4
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
94 addition
and
105 deletion
+94
-105
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/loopTransform.cpp
+92
-105
src/share/vm/opto/loopnode.hpp
src/share/vm/opto/loopnode.hpp
+2
-0
未找到文件。
src/share/vm/opto/loopTransform.cpp
浏览文件 @
82666eba
...
@@ -1453,6 +1453,23 @@ bool IdealLoopTree::dominates_backedge(Node* ctrl) {
...
@@ -1453,6 +1453,23 @@ bool IdealLoopTree::dominates_backedge(Node* ctrl) {
return
_phase
->
dom_lca_internal
(
ctrl
,
backedge
)
==
ctrl
;
return
_phase
->
dom_lca_internal
(
ctrl
,
backedge
)
==
ctrl
;
}
}
//------------------------------adjust_limit-----------------------------------
// Helper function for add_constraint().
Node
*
PhaseIdealLoop
::
adjust_limit
(
int
stride_con
,
Node
*
scale
,
Node
*
offset
,
Node
*
rc_limit
,
Node
*
loop_limit
,
Node
*
pre_ctrl
)
{
// Compute "I :: (limit-offset)/scale"
Node
*
con
=
new
(
C
,
3
)
SubINode
(
rc_limit
,
offset
);
register_new_node
(
con
,
pre_ctrl
);
Node
*
X
=
new
(
C
,
3
)
DivINode
(
0
,
con
,
scale
);
register_new_node
(
X
,
pre_ctrl
);
// Adjust loop limit
loop_limit
=
(
stride_con
>
0
)
?
(
Node
*
)(
new
(
C
,
3
)
MinINode
(
loop_limit
,
X
))
:
(
Node
*
)(
new
(
C
,
3
)
MaxINode
(
loop_limit
,
X
));
register_new_node
(
loop_limit
,
pre_ctrl
);
return
loop_limit
;
}
//------------------------------add_constraint---------------------------------
//------------------------------add_constraint---------------------------------
// Constrain the main loop iterations so the conditions:
// Constrain the main loop iterations so the conditions:
// low_limit <= scale_con * I + offset < upper_limit
// low_limit <= scale_con * I + offset < upper_limit
...
@@ -1469,7 +1486,11 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
...
@@ -1469,7 +1486,11 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
// pre-loop must check for underflow and the post-loop for overflow.
// pre-loop must check for underflow and the post-loop for overflow.
// Negative stride*scale reverses this; pre-loop checks for overflow and
// Negative stride*scale reverses this; pre-loop checks for overflow and
// post-loop for underflow.
// post-loop for underflow.
if
(
stride_con
*
scale_con
>
0
)
{
Node
*
scale
=
_igvn
.
intcon
(
scale_con
);
set_ctrl
(
scale
,
C
->
root
());
if
((
stride_con
^
scale_con
)
>=
0
)
{
// Use XOR to avoid overflow
// The overflow limit: scale*I+offset < upper_limit
// The overflow limit: scale*I+offset < upper_limit
// For main-loop compute
// For main-loop compute
// ( if (scale > 0) /* and stride > 0 */
// ( if (scale > 0) /* and stride > 0 */
...
@@ -1478,23 +1499,10 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
...
@@ -1478,23 +1499,10 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
// I > (upper_limit-offset)/scale
// I > (upper_limit-offset)/scale
// )
// )
//
//
// (upper_limit-offset) may overflow
when offset < 0
.
// (upper_limit-offset) may overflow
or underflow
.
// But it is fine since main loop will either have
// But it is fine since main loop will either have
// less iterations or will be skipped in such case.
// less iterations or will be skipped in such case.
Node
*
con
=
new
(
C
,
3
)
SubINode
(
upper_limit
,
offset
);
*
main_limit
=
adjust_limit
(
stride_con
,
scale
,
offset
,
upper_limit
,
*
main_limit
,
pre_ctrl
);
register_new_node
(
con
,
pre_ctrl
);
Node
*
scale
=
_igvn
.
intcon
(
scale_con
);
set_ctrl
(
scale
,
C
->
root
());
Node
*
X
=
new
(
C
,
3
)
DivINode
(
0
,
con
,
scale
);
register_new_node
(
X
,
pre_ctrl
);
// Adjust main-loop last iteration
Node
*
loop_limit
=
*
main_limit
;
loop_limit
=
(
stride_con
>
0
)
// scale > 0
?
(
Node
*
)(
new
(
C
,
3
)
MinINode
(
loop_limit
,
X
))
:
(
Node
*
)(
new
(
C
,
3
)
MaxINode
(
loop_limit
,
X
));
register_new_node
(
loop_limit
,
pre_ctrl
);
*
main_limit
=
loop_limit
;
// The underflow limit: low_limit <= scale*I+offset.
// The underflow limit: low_limit <= scale*I+offset.
// For pre-loop compute
// For pre-loop compute
...
@@ -1509,76 +1517,33 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
...
@@ -1509,76 +1517,33 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
if
(
low_limit
->
get_int
()
==
-
max_jint
)
{
if
(
low_limit
->
get_int
()
==
-
max_jint
)
{
if
(
!
RangeLimitCheck
)
return
;
if
(
!
RangeLimitCheck
)
return
;
// We need this guard when scale*pre_limit+offset >= limit
// We need this guard when scale*pre_limit+offset >= limit
// due to underflow so we need execute pre-loop until
// due to underflow. So we need execute pre-loop until
// scale*I+offset >= min_int. But (low_limit-offset) will
// scale*I+offset >= min_int. But (min_int-offset) will
// underflow when offset > 0 and X will be > original_limit.
// underflow when offset > 0 and X will be > original_limit
// To avoid it we replace offset = offset > 0 ? 0 : offset
// when stride > 0. To avoid it we replace positive offset with 0.
// and add min(pre_limit, original_limit).
//
// Also (min_int+1 == -max_int) is used instead of min_int here
// to avoid problem with scale == -1 (min_int/(-1) == min_int).
Node
*
shift
=
_igvn
.
intcon
(
31
);
Node
*
shift
=
_igvn
.
intcon
(
31
);
set_ctrl
(
shift
,
C
->
root
());
set_ctrl
(
shift
,
C
->
root
());
Node
*
neg_off
=
new
(
C
,
3
)
RShiftINode
(
offset
,
shift
);
Node
*
sign
=
new
(
C
,
3
)
RShiftINode
(
offset
,
shift
);
register_new_node
(
neg_off
,
pre_ctrl
);
register_new_node
(
sign
,
pre_ctrl
);
offset
=
new
(
C
,
3
)
AndINode
(
offset
,
neg_off
);
offset
=
new
(
C
,
3
)
AndINode
(
offset
,
sign
);
register_new_node
(
offset
,
pre_ctrl
);
register_new_node
(
offset
,
pre_ctrl
);
}
else
{
}
else
{
assert
(
low_limit
->
get_int
()
==
0
,
"wrong low limit for range check"
);
assert
(
low_limit
->
get_int
()
==
0
,
"wrong low limit for range check"
);
// The only problem we have here when offset == min_int
// The only problem we have here when offset == min_int
// since (0-min_int) == min_int. It may be fine for scale > 0
// since (0-min_int) == min_int. It may be fine for stride > 0
// but for scale < 0 X will be < original_limit.
// but for stride < 0 X will be < original_limit. To avoid it
// max(pre_limit, original_limit) is used in do_range_check().
}
}
con
=
new
(
C
,
3
)
SubINode
(
low_limit
,
offset
);
// Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
register_new_node
(
con
,
pre_ctrl
);
*
pre_limit
=
adjust_limit
((
-
stride_con
),
scale
,
offset
,
low_limit
,
*
pre_limit
,
pre_ctrl
);
scale
=
_igvn
.
intcon
(
scale_con
);
set_ctrl
(
scale
,
C
->
root
());
X
=
new
(
C
,
3
)
DivINode
(
0
,
con
,
scale
);
register_new_node
(
X
,
pre_ctrl
);
// Adjust pre-loop last iteration
loop_limit
=
*
pre_limit
;
loop_limit
=
(
stride_con
>
0
)
// scale > 0
?
(
Node
*
)(
new
(
C
,
3
)
MaxINode
(
loop_limit
,
X
))
:
(
Node
*
)(
new
(
C
,
3
)
MinINode
(
loop_limit
,
X
));
register_new_node
(
loop_limit
,
pre_ctrl
);
*
pre_limit
=
loop_limit
;
}
else
{
// stride_con*scale_con < 0
}
else
{
// stride_con*scale_con < 0
// For negative stride*scale pre-loop checks for overflow and
// For negative stride*scale pre-loop checks for overflow and
// post-loop for underflow.
// post-loop for underflow.
//
//
// The underflow limit: low_limit <= scale*I+offset.
// For main-loop compute
// scale*I+offset+1 > low_limit
// ( if (scale < 0) /* and stride > 0 */
// I < (low_limit-(offset+1))/scale
// else /* scale < 0 and stride < 0 */
// I > (low_limit-(offset+1))/scale
// )
if
(
low_limit
->
get_int
()
==
-
max_jint
)
{
if
(
!
RangeLimitCheck
)
return
;
}
else
{
assert
(
low_limit
->
get_int
()
==
0
,
"wrong low limit for range check"
);
}
Node
*
one
=
_igvn
.
intcon
(
1
);
set_ctrl
(
one
,
C
->
root
());
Node
*
plus_one
=
new
(
C
,
3
)
AddINode
(
offset
,
one
);
register_new_node
(
plus_one
,
pre_ctrl
);
Node
*
con
=
new
(
C
,
3
)
SubINode
(
low_limit
,
plus_one
);
register_new_node
(
con
,
pre_ctrl
);
Node
*
scale
=
_igvn
.
intcon
(
scale_con
);
set_ctrl
(
scale
,
C
->
root
());
Node
*
X
=
new
(
C
,
3
)
DivINode
(
0
,
con
,
scale
);
register_new_node
(
X
,
pre_ctrl
);
// Adjust main-loop last iteration
Node
*
loop_limit
=
*
main_limit
;
loop_limit
=
(
stride_con
>
0
)
// scale < 0
?
(
Node
*
)(
new
(
C
,
3
)
MinINode
(
loop_limit
,
X
))
:
(
Node
*
)(
new
(
C
,
3
)
MaxINode
(
loop_limit
,
X
));
register_new_node
(
loop_limit
,
pre_ctrl
);
*
main_limit
=
loop_limit
;
// The overflow limit: scale*I+offset < upper_limit
// The overflow limit: scale*I+offset < upper_limit
// For pre-loop compute
// For pre-loop compute
// NOT(scale*I+offset < upper_limit)
// NOT(scale*I+offset < upper_limit)
...
@@ -1586,26 +1551,55 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
...
@@ -1586,26 +1551,55 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
// scale*I+offset+1 > upper_limit
// scale*I+offset+1 > upper_limit
// ( if (scale < 0) /* and stride > 0 */
// ( if (scale < 0) /* and stride > 0 */
// I < (upper_limit-(offset+1))/scale
// I < (upper_limit-(offset+1))/scale
// else /* scale
<
0 and stride < 0 */
// else /* scale
>
0 and stride < 0 */
// I > (upper_limit-(offset+1))/scale
// I > (upper_limit-(offset+1))/scale
// )
// )
plus_one
=
new
(
C
,
3
)
AddINode
(
offset
,
one
);
//
// (upper_limit-offset-1) may underflow or overflow.
// To avoid it min(pre_limit, original_limit) is used
// in do_range_check() for stride > 0 and max() for < 0.
Node
*
one
=
_igvn
.
intcon
(
1
);
set_ctrl
(
one
,
C
->
root
());
Node
*
plus_one
=
new
(
C
,
3
)
AddINode
(
offset
,
one
);
register_new_node
(
plus_one
,
pre_ctrl
);
register_new_node
(
plus_one
,
pre_ctrl
);
con
=
new
(
C
,
3
)
SubINode
(
upper_limit
,
plus_one
);
// Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
register_new_node
(
con
,
pre_ctrl
);
*
pre_limit
=
adjust_limit
((
-
stride_con
),
scale
,
plus_one
,
upper_limit
,
*
pre_limit
,
pre_ctrl
);
scale
=
_igvn
.
intcon
(
scale_con
);
set_ctrl
(
scale
,
C
->
root
());
if
(
low_limit
->
get_int
()
==
-
max_jint
)
{
X
=
new
(
C
,
3
)
DivINode
(
0
,
con
,
scale
);
if
(
!
RangeLimitCheck
)
return
;
register_new_node
(
X
,
pre_ctrl
);
// We need this guard when scale*main_limit+offset >= limit
// due to underflow. So we need execute main-loop while
// Adjust pre-loop last iteration
// scale*I+offset+1 > min_int. But (min_int-offset-1) will
loop_limit
=
*
pre_limit
;
// underflow when (offset+1) > 0 and X will be < main_limit
loop_limit
=
(
stride_con
>
0
)
// scale < 0
// when scale < 0 (and stride > 0). To avoid it we replace
?
(
Node
*
)(
new
(
C
,
3
)
MaxINode
(
loop_limit
,
X
))
// positive (offset+1) with 0.
:
(
Node
*
)(
new
(
C
,
3
)
MinINode
(
loop_limit
,
X
));
//
register_new_node
(
loop_limit
,
pre_ctrl
);
// Also (min_int+1 == -max_int) is used instead of min_int here
*
pre_limit
=
loop_limit
;
// to avoid problem with scale == -1 (min_int/(-1) == min_int).
Node
*
shift
=
_igvn
.
intcon
(
31
);
set_ctrl
(
shift
,
C
->
root
());
Node
*
sign
=
new
(
C
,
3
)
RShiftINode
(
plus_one
,
shift
);
register_new_node
(
sign
,
pre_ctrl
);
plus_one
=
new
(
C
,
3
)
AndINode
(
plus_one
,
sign
);
register_new_node
(
plus_one
,
pre_ctrl
);
}
else
{
assert
(
low_limit
->
get_int
()
==
0
,
"wrong low limit for range check"
);
// The only problem we have here when offset == max_int
// since (max_int+1) == min_int and (0-min_int) == min_int.
// But it is fine since main loop will either have
// less iterations or will be skipped in such case.
}
// The underflow limit: low_limit <= scale*I+offset.
// For main-loop compute
// scale*I+offset+1 > low_limit
// ( if (scale < 0) /* and stride > 0 */
// I < (low_limit-(offset+1))/scale
// else /* scale > 0 and stride < 0 */
// I > (low_limit-(offset+1))/scale
// )
*
main_limit
=
adjust_limit
(
stride_con
,
scale
,
plus_one
,
low_limit
,
*
main_limit
,
pre_ctrl
);
}
}
}
}
...
@@ -1869,13 +1863,8 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
...
@@ -1869,13 +1863,8 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
// The underflow and overflow limits: 0 <= scale*I+offset < limit
// The underflow and overflow limits: 0 <= scale*I+offset < limit
add_constraint
(
stride_con
,
scale_con
,
offset
,
zero
,
limit
,
pre_ctrl
,
&
pre_limit
,
&
main_limit
);
add_constraint
(
stride_con
,
scale_con
,
offset
,
zero
,
limit
,
pre_ctrl
,
&
pre_limit
,
&
main_limit
);
if
(
!
conditional_rc
)
{
if
(
!
conditional_rc
)
{
conditional_rc
=
!
loop
->
dominates_backedge
(
iff
);
// (0-offset)/scale could be outside of loop iterations range.
// It is also needed if offset->_lo == min_int since
conditional_rc
=
!
loop
->
dominates_backedge
(
iff
)
||
RangeLimitCheck
;
// (0-min_int) == min_int. It may be fine for stride > 0
// but for stride < 0 pre_limit will be < original_limit.
const
TypeInt
*
offset_t
=
_igvn
.
type
(
offset
)
->
is_int
();
conditional_rc
|=
RangeLimitCheck
&&
(
offset_t
->
_lo
==
min_jint
)
&&
(
scale_con
<
0
)
&&
(
stride_con
<
0
);
}
}
}
else
{
}
else
{
#ifndef PRODUCT
#ifndef PRODUCT
...
@@ -1905,16 +1894,14 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
...
@@ -1905,16 +1894,14 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
// Fall into LT case
// Fall into LT case
case
BoolTest
::
lt
:
case
BoolTest
::
lt
:
// The underflow and overflow limits: MIN_INT <= scale*I+offset < limit
// The underflow and overflow limits: MIN_INT <= scale*I+offset < limit
// Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here
// to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT.
add_constraint
(
stride_con
,
scale_con
,
offset
,
mini
,
limit
,
pre_ctrl
,
&
pre_limit
,
&
main_limit
);
add_constraint
(
stride_con
,
scale_con
,
offset
,
mini
,
limit
,
pre_ctrl
,
&
pre_limit
,
&
main_limit
);
if
(
!
conditional_rc
)
{
if
(
!
conditional_rc
)
{
conditional_rc
=
!
loop
->
dominates_backedge
(
iff
);
// ((MIN_INT+1)-offset)/scale could be outside of loop iterations range.
// It is also needed if scale*pre_limit+offset >= limit
// Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could
// due to underflow so we need execute pre-loop until
// still be outside of loop range.
// scale*I+offset >= min_int. But (low_limit-offset) will
conditional_rc
=
!
loop
->
dominates_backedge
(
iff
)
||
RangeLimitCheck
;
// underflow when offset > 0 and X will be > original_limit.
const
TypeInt
*
offset_t
=
_igvn
.
type
(
offset
)
->
is_int
();
conditional_rc
|=
RangeLimitCheck
&&
(
offset_t
->
_hi
>
0
)
&&
(
scale_con
>
0
)
&&
(
stride_con
>
0
);
}
}
break
;
break
;
default:
default:
...
...
src/share/vm/opto/loopnode.hpp
浏览文件 @
82666eba
...
@@ -932,6 +932,8 @@ public:
...
@@ -932,6 +932,8 @@ public:
// the pre-loop or the post-loop until the condition holds true in the main
// the pre-loop or the post-loop until the condition holds true in the main
// loop. Scale_con, offset and limit are all loop invariant.
// loop. Scale_con, offset and limit are all loop invariant.
void
add_constraint
(
int
stride_con
,
int
scale_con
,
Node
*
offset
,
Node
*
low_limit
,
Node
*
upper_limit
,
Node
*
pre_ctrl
,
Node
**
pre_limit
,
Node
**
main_limit
);
void
add_constraint
(
int
stride_con
,
int
scale_con
,
Node
*
offset
,
Node
*
low_limit
,
Node
*
upper_limit
,
Node
*
pre_ctrl
,
Node
**
pre_limit
,
Node
**
main_limit
);
// Helper function for add_constraint().
Node
*
adjust_limit
(
int
stride_con
,
Node
*
scale
,
Node
*
offset
,
Node
*
rc_limit
,
Node
*
loop_limit
,
Node
*
pre_ctrl
);
// Partially peel loop up through last_peel node.
// Partially peel loop up through last_peel node.
bool
partial_peel
(
IdealLoopTree
*
loop
,
Node_List
&
old_new
);
bool
partial_peel
(
IdealLoopTree
*
loop
,
Node_List
&
old_new
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录