Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
402f8371
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看板
提交
402f8371
编写于
9月 10, 2014
作者:
R
rbackman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8030976: Untaken paths should be more vigorously pruned at highest optimization level
Reviewed-by: roland, vlivanov
上级
5bdeb058
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
12 addition
and
72 deletion
+12
-72
src/share/vm/oops/methodData.hpp
src/share/vm/oops/methodData.hpp
+1
-1
src/share/vm/opto/parse2.cpp
src/share/vm/opto/parse2.cpp
+5
-70
src/share/vm/runtime/deoptimization.cpp
src/share/vm/runtime/deoptimization.cpp
+2
-1
src/share/vm/runtime/deoptimization.hpp
src/share/vm/runtime/deoptimization.hpp
+3
-0
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+1
-0
未找到文件。
src/share/vm/oops/methodData.hpp
浏览文件 @
402f8371
...
@@ -2057,7 +2057,7 @@ public:
...
@@ -2057,7 +2057,7 @@ public:
// Whole-method sticky bits and flags
// Whole-method sticky bits and flags
enum
{
enum
{
_trap_hist_limit
=
19
,
// decoupled from Deoptimization::Reason_LIMIT
_trap_hist_limit
=
20
,
// decoupled from Deoptimization::Reason_LIMIT
_trap_hist_mask
=
max_jubyte
,
_trap_hist_mask
=
max_jubyte
,
_extra_data_count
=
4
// extra DataLayout headers, for trap history
_extra_data_count
=
4
// extra DataLayout headers, for trap history
};
// Public flag values
};
// Public flag values
...
...
src/share/vm/opto/parse2.cpp
浏览文件 @
402f8371
...
@@ -895,53 +895,12 @@ bool Parse::seems_never_taken(float prob) {
...
@@ -895,53 +895,12 @@ bool Parse::seems_never_taken(float prob) {
// if a path is never taken, its controlling comparison is
// if a path is never taken, its controlling comparison is
// already acting in a stable fashion. If the comparison
// already acting in a stable fashion. If the comparison
// seems stable, we will put an expensive uncommon trap
// seems stable, we will put an expensive uncommon trap
// on the untaken path. To be conservative, and to allow
// on the untaken path.
// partially executed counted loops to be compiled fully,
// we will plant uncommon traps only after pointer comparisons.
bool
Parse
::
seems_stable_comparison
(
BoolTest
::
mask
btest
,
Node
*
cmp
)
{
bool
Parse
::
seems_stable_comparison
(
BoolTest
::
mask
btest
,
Node
*
cmp
)
{
for
(
int
depth
=
4
;
depth
>
0
;
depth
--
)
{
if
(
C
->
too_many_traps
(
method
(),
bci
(),
Deoptimization
::
Reason_unstable_if
))
{
// The following switch can find CmpP here over half the time for
return
false
;
// dynamic language code rich with type tests.
// Code using counted loops or array manipulations (typical
// of benchmarks) will have many (>80%) CmpI instructions.
switch
(
cmp
->
Opcode
())
{
case
Op_CmpP
:
// A never-taken null check looks like CmpP/BoolTest::eq.
// These certainly should be closed off as uncommon traps.
if
(
btest
==
BoolTest
::
eq
)
return
true
;
// A never-failed type check looks like CmpP/BoolTest::ne.
// Let's put traps on those, too, so that we don't have to compile
// unused paths with indeterminate dynamic type information.
if
(
ProfileDynamicTypes
)
return
true
;
return
false
;
case
Op_CmpI
:
// A small minority (< 10%) of CmpP are masked as CmpI,
// as if by boolean conversion ((p == q? 1: 0) != 0).
// Detect that here, even if it hasn't optimized away yet.
// Specifically, this covers the 'instanceof' operator.
if
(
btest
==
BoolTest
::
ne
||
btest
==
BoolTest
::
eq
)
{
if
(
_gvn
.
type
(
cmp
->
in
(
2
))
->
singleton
()
&&
cmp
->
in
(
1
)
->
is_Phi
())
{
PhiNode
*
phi
=
cmp
->
in
(
1
)
->
as_Phi
();
int
true_path
=
phi
->
is_diamond_phi
();
if
(
true_path
>
0
&&
_gvn
.
type
(
phi
->
in
(
1
))
->
singleton
()
&&
_gvn
.
type
(
phi
->
in
(
2
))
->
singleton
())
{
// phi->region->if_proj->ifnode->bool->cmp
BoolNode
*
bol
=
phi
->
in
(
0
)
->
in
(
1
)
->
in
(
0
)
->
in
(
1
)
->
as_Bool
();
btest
=
bol
->
_test
.
_test
;
cmp
=
bol
->
in
(
1
);
continue
;
}
}
}
return
false
;
}
}
}
return
fals
e
;
return
tru
e
;
}
}
//-------------------------------repush_if_args--------------------------------
//-------------------------------repush_if_args--------------------------------
...
@@ -1180,32 +1139,8 @@ void Parse::adjust_map_after_if(BoolTest::mask btest, Node* c, float prob,
...
@@ -1180,32 +1139,8 @@ void Parse::adjust_map_after_if(BoolTest::mask btest, Node* c, float prob,
bool
is_fallthrough
=
(
path
==
successor_for_bci
(
iter
().
next_bci
()));
bool
is_fallthrough
=
(
path
==
successor_for_bci
(
iter
().
next_bci
()));
if
(
seems_never_taken
(
prob
)
&&
seems_stable_comparison
(
btest
,
c
))
{
if
(
seems_never_taken
(
prob
)
&&
seems_stable_comparison
(
btest
,
c
))
{
// If this might possibly turn into an implicit null check,
// and the null has never yet been seen, we need to generate
// an uncommon trap, so as to recompile instead of suffering
// with very slow branches. (We'll get the slow branches if
// the program ever changes phase and starts seeing nulls here.)
//
// We do not inspect for a null constant, since a node may
// optimize to 'null' later on.
//
// Null checks, and other tests which expect inequality,
// show btest == BoolTest::eq along the non-taken branch.
// On the other hand, type tests, must-be-null tests,
// and other tests which expect pointer equality,
// show btest == BoolTest::ne along the non-taken branch.
// We prune both types of branches if they look unused.
repush_if_args
();
repush_if_args
();
// We need to mark this branch as taken so that if we recompile we will
uncommon_trap
(
Deoptimization
::
Reason_unstable_if
,
// see that it is possible. In the tiered system the interpreter doesn't
// do profiling and by the time we get to the lower tier from the interpreter
// the path may be cold again. Make sure it doesn't look untaken
if
(
is_fallthrough
)
{
profile_not_taken_branch
(
!
ProfileInterpreter
);
}
else
{
profile_taken_branch
(
iter
().
get_dest
(),
!
ProfileInterpreter
);
}
uncommon_trap
(
Deoptimization
::
Reason_unreached
,
Deoptimization
::
Action_reinterpret
,
Deoptimization
::
Action_reinterpret
,
NULL
,
NULL
,
(
is_fallthrough
?
"taken always"
:
"taken never"
));
(
is_fallthrough
?
"taken always"
:
"taken never"
));
...
...
src/share/vm/runtime/deoptimization.cpp
浏览文件 @
402f8371
...
@@ -1835,7 +1835,8 @@ const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = {
...
@@ -1835,7 +1835,8 @@ const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = {
"predicate"
,
"predicate"
,
"loop_limit_check"
,
"loop_limit_check"
,
"speculate_class_check"
,
"speculate_class_check"
,
"rtm_state_change"
"rtm_state_change"
,
"unstable_if"
};
};
const
char
*
Deoptimization
::
_trap_action_name
[
Action_LIMIT
]
=
{
const
char
*
Deoptimization
::
_trap_action_name
[
Action_LIMIT
]
=
{
// Note: Keep this in sync. with enum DeoptAction.
// Note: Keep this in sync. with enum DeoptAction.
...
...
src/share/vm/runtime/deoptimization.hpp
浏览文件 @
402f8371
...
@@ -60,6 +60,7 @@ class Deoptimization : AllStatic {
...
@@ -60,6 +60,7 @@ class Deoptimization : AllStatic {
Reason_predicate
,
// compiler generated predicate failed
Reason_predicate
,
// compiler generated predicate failed
Reason_loop_limit_check
,
// compiler generated loop limits check failed
Reason_loop_limit_check
,
// compiler generated loop limits check failed
Reason_speculate_class_check
,
// saw unexpected object class from type speculation
Reason_speculate_class_check
,
// saw unexpected object class from type speculation
Reason_unstable_if
,
// a branch predicted always false was taken
Reason_rtm_state_change
,
// rtm state change detected
Reason_rtm_state_change
,
// rtm state change detected
Reason_LIMIT
,
Reason_LIMIT
,
// Note: Keep this enum in sync. with _trap_reason_name.
// Note: Keep this enum in sync. with _trap_reason_name.
...
@@ -315,6 +316,8 @@ class Deoptimization : AllStatic {
...
@@ -315,6 +316,8 @@ class Deoptimization : AllStatic {
return
Reason_null_check
;
// recorded per BCI as a null check
return
Reason_null_check
;
// recorded per BCI as a null check
else
if
(
reason
==
Reason_speculate_class_check
)
else
if
(
reason
==
Reason_speculate_class_check
)
return
Reason_class_check
;
return
Reason_class_check
;
else
if
(
reason
==
Reason_unstable_if
)
return
Reason_intrinsic
;
else
else
return
Reason_none
;
return
Reason_none
;
}
}
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
402f8371
...
@@ -2496,6 +2496,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > MetablockTreeDicti
...
@@ -2496,6 +2496,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList<Metablock> > MetablockTreeDicti
declare_constant(Deoptimization::Reason_age) \
declare_constant(Deoptimization::Reason_age) \
declare_constant(Deoptimization::Reason_predicate) \
declare_constant(Deoptimization::Reason_predicate) \
declare_constant(Deoptimization::Reason_loop_limit_check) \
declare_constant(Deoptimization::Reason_loop_limit_check) \
declare_constant(Deoptimization::Reason_unstable_if) \
declare_constant(Deoptimization::Reason_LIMIT) \
declare_constant(Deoptimization::Reason_LIMIT) \
declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \
\
\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录