Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
debdc89e
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看板
提交
debdc89e
编写于
6月 02, 2011
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7050554: JSR 292 - need optimization for selectAlternative
Reviewed-by: kvn, jrose
上级
9afeef74
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
112 addition
and
58 deletion
+112
-58
src/share/vm/ci/ciCallProfile.hpp
src/share/vm/ci/ciCallProfile.hpp
+4
-3
src/share/vm/ci/ciMethodHandle.cpp
src/share/vm/ci/ciMethodHandle.cpp
+1
-1
src/share/vm/ci/ciMethodHandle.hpp
src/share/vm/ci/ciMethodHandle.hpp
+3
-4
src/share/vm/compiler/compileBroker.cpp
src/share/vm/compiler/compileBroker.cpp
+22
-7
src/share/vm/opto/callGenerator.cpp
src/share/vm/opto/callGenerator.cpp
+76
-24
src/share/vm/opto/callGenerator.hpp
src/share/vm/opto/callGenerator.hpp
+2
-0
src/share/vm/opto/doCall.cpp
src/share/vm/opto/doCall.cpp
+4
-19
未找到文件。
src/share/vm/ci/ciCallProfile.hpp
浏览文件 @
debdc89e
...
...
@@ -36,6 +36,7 @@ class ciCallProfile : StackObj {
private:
// Fields are initialized directly by ciMethod::call_profile_at_bci.
friend
class
ciMethod
;
friend
class
ciMethodHandle
;
enum
{
MorphismLimit
=
2
};
// Max call site's morphism we care about
int
_limit
;
// number of receivers have been determined
...
...
@@ -58,10 +59,10 @@ private:
public:
// Note: The following predicates return false for invalid profiles:
bool
has_receiver
(
int
i
)
{
return
_limit
>
i
;
}
int
morphism
()
{
return
_morphism
;
}
bool
has_receiver
(
int
i
)
const
{
return
_limit
>
i
;
}
int
morphism
()
const
{
return
_morphism
;
}
int
count
()
{
return
_count
;
}
int
count
()
const
{
return
_count
;
}
int
receiver_count
(
int
i
)
{
assert
(
i
<
_limit
,
"out of Call Profile MorphismLimit"
);
return
_receiver_count
[
i
];
...
...
src/share/vm/ci/ciMethodHandle.cpp
浏览文件 @
debdc89e
...
...
@@ -43,7 +43,7 @@ ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) const {
methodHandle
callee
(
_callee
->
get_methodOop
());
// We catch all exceptions here that could happen in the method
// handle compiler and stop the VM.
MethodHandleCompiler
mhc
(
h
,
callee
->
name
(),
callee
->
signature
(),
_profile
->
count
(),
is_invokedynamic
,
THREAD
);
MethodHandleCompiler
mhc
(
h
,
callee
->
name
(),
callee
->
signature
(),
_profile
.
count
(),
is_invokedynamic
,
THREAD
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
methodHandle
m
=
mhc
.
compile
(
THREAD
);
if
(
!
HAS_PENDING_EXCEPTION
)
{
...
...
src/share/vm/ci/ciMethodHandle.hpp
浏览文件 @
debdc89e
...
...
@@ -36,7 +36,7 @@ class ciMethodHandle : public ciInstance {
private:
ciMethod
*
_callee
;
ciMethod
*
_caller
;
ciCallProfile
*
_profile
;
ciCallProfile
_profile
;
// Return an adapter for this MethodHandle.
ciMethod
*
get_adapter_impl
(
bool
is_invokedynamic
)
const
;
...
...
@@ -49,8 +49,7 @@ public:
ciMethodHandle
(
instanceHandle
h_i
)
:
ciInstance
(
h_i
),
_callee
(
NULL
),
_caller
(
NULL
),
_profile
(
NULL
)
_caller
(
NULL
)
{}
// What kind of ciObject is this?
...
...
@@ -58,7 +57,7 @@ public:
void
set_callee
(
ciMethod
*
m
)
{
_callee
=
m
;
}
void
set_caller
(
ciMethod
*
m
)
{
_caller
=
m
;
}
void
set_call_profile
(
ciCallProfile
*
profile
)
{
_profile
=
profile
;
}
void
set_call_profile
(
ciCallProfile
profile
)
{
_profile
=
profile
;
}
// Return an adapter for a MethodHandle call.
ciMethod
*
get_method_handle_adapter
()
const
{
return
get_adapter
(
false
);
}
...
...
src/share/vm/compiler/compileBroker.cpp
浏览文件 @
debdc89e
...
...
@@ -300,12 +300,23 @@ void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int
st
->
print
(
"%7d "
,
(
int
)
st
->
time_stamp
().
milliseconds
());
// print timestamp
st
->
print
(
"%4d "
,
compile_id
);
// print compilation number
// For unloaded methods the transition to zombie occurs after the
// method is cleared so it's impossible to report accurate
// information for that case.
bool
is_synchronized
=
false
;
bool
has_exception_handler
=
false
;
bool
is_native
=
false
;
if
(
method
!=
NULL
)
{
is_synchronized
=
method
->
is_synchronized
();
has_exception_handler
=
method
->
has_exception_handler
();
is_native
=
method
->
is_native
();
}
// method attributes
const
char
compile_type
=
is_osr_method
?
'%'
:
' '
;
const
char
sync_char
=
method
->
is_synchronized
()
?
's'
:
' '
;
const
char
exception_char
=
method
->
has_exception_handler
()
?
'!'
:
' '
;
const
char
sync_char
=
is_synchronized
?
's'
:
' '
;
const
char
exception_char
=
has_exception_handler
?
'!'
:
' '
;
const
char
blocking_char
=
is_blocking
?
'b'
:
' '
;
const
char
native_char
=
method
->
is_native
()
?
'n'
:
' '
;
const
char
native_char
=
is_native
?
'n'
:
' '
;
// print method attributes
st
->
print
(
"%c%c%c%c%c "
,
compile_type
,
sync_char
,
exception_char
,
blocking_char
,
native_char
);
...
...
@@ -316,11 +327,15 @@ void CompileTask::print_compilation_impl(outputStream* st, methodOop method, int
}
st
->
print
(
" "
);
// more indent
method
->
print_short_name
(
st
);
if
(
is_osr_method
)
{
st
->
print
(
" @ %d"
,
osr_bci
);
if
(
method
==
NULL
)
{
st
->
print
(
"(method)"
);
}
else
{
method
->
print_short_name
(
st
);
if
(
is_osr_method
)
{
st
->
print
(
" @ %d"
,
osr_bci
);
}
st
->
print
(
" (%d bytes)"
,
method
->
code_size
());
}
st
->
print
(
" (%d bytes)"
,
method
->
code_size
());
if
(
msg
!=
NULL
)
{
st
->
print
(
" %s"
,
msg
);
...
...
src/share/vm/opto/callGenerator.cpp
浏览文件 @
debdc89e
...
...
@@ -698,6 +698,46 @@ CallGenerator* CallGenerator::for_predicted_dynamic_call(ciMethodHandle* predict
}
CallGenerator
*
CallGenerator
::
for_method_handle_inline
(
Node
*
method_handle
,
JVMState
*
jvms
,
ciMethod
*
caller
,
ciMethod
*
callee
,
ciCallProfile
profile
)
{
if
(
method_handle
->
Opcode
()
==
Op_ConP
)
{
const
TypeOopPtr
*
oop_ptr
=
method_handle
->
bottom_type
()
->
is_oopptr
();
ciObject
*
const_oop
=
oop_ptr
->
const_oop
();
ciMethodHandle
*
method_handle
=
const_oop
->
as_method_handle
();
// Set the callee to have access to the class and signature in
// the MethodHandleCompiler.
method_handle
->
set_callee
(
callee
);
method_handle
->
set_caller
(
caller
);
method_handle
->
set_call_profile
(
profile
);
// Get an adapter for the MethodHandle.
ciMethod
*
target_method
=
method_handle
->
get_method_handle_adapter
();
if
(
target_method
!=
NULL
)
{
CallGenerator
*
hit_cg
=
Compile
::
current
()
->
call_generator
(
target_method
,
-
1
,
false
,
jvms
,
true
,
1
);
if
(
hit_cg
!=
NULL
&&
hit_cg
->
is_inline
())
return
hit_cg
;
}
}
else
if
(
method_handle
->
Opcode
()
==
Op_Phi
&&
method_handle
->
req
()
==
3
&&
method_handle
->
in
(
1
)
->
Opcode
()
==
Op_ConP
&&
method_handle
->
in
(
2
)
->
Opcode
()
==
Op_ConP
)
{
// selectAlternative idiom merging two constant MethodHandles.
// Generate a guard so that each can be inlined. We might want to
// do more inputs at later point but this gets the most common
// case.
const
TypeOopPtr
*
oop_ptr
=
method_handle
->
in
(
1
)
->
bottom_type
()
->
is_oopptr
();
ciObject
*
const_oop
=
oop_ptr
->
const_oop
();
ciMethodHandle
*
mh
=
const_oop
->
as_method_handle
();
CallGenerator
*
cg1
=
for_method_handle_inline
(
method_handle
->
in
(
1
),
jvms
,
caller
,
callee
,
profile
);
CallGenerator
*
cg2
=
for_method_handle_inline
(
method_handle
->
in
(
2
),
jvms
,
caller
,
callee
,
profile
);
if
(
cg1
!=
NULL
&&
cg2
!=
NULL
)
{
return
new
PredictedDynamicCallGenerator
(
mh
,
cg2
,
cg1
,
PROB_FAIR
);
}
}
return
NULL
;
}
JVMState
*
PredictedDynamicCallGenerator
::
generate
(
JVMState
*
jvms
)
{
GraphKit
kit
(
jvms
);
PhaseGVN
&
gvn
=
kit
.
gvn
();
...
...
@@ -707,33 +747,45 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
log
->
elem
(
"predicted_dynamic_call bci='%d'"
,
jvms
->
bci
());
}
// Get the constant pool cache from the caller class.
ciMethod
*
caller_method
=
jvms
->
method
();
ciBytecodeStream
str
(
caller_method
);
str
.
force_bci
(
jvms
->
bci
());
// Set the stream to the invokedynamic bci.
ciCPCache
*
cpcache
=
str
.
get_cpcache
();
// Get the offset of the CallSite from the constant pool cache
// pointer.
int
index
=
str
.
get_method_index
();
size_t
call_site_offset
=
cpcache
->
get_f1_offset
(
index
);
// Load the CallSite object from the constant pool cache.
const
TypeOopPtr
*
cpcache_ptr
=
TypeOopPtr
::
make_from_constant
(
cpcache
);
Node
*
cpcache_adr
=
kit
.
makecon
(
cpcache_ptr
);
Node
*
call_site_adr
=
kit
.
basic_plus_adr
(
cpcache_adr
,
cpcache_adr
,
call_site_offset
);
Node
*
call_site
=
kit
.
make_load
(
kit
.
control
(),
call_site_adr
,
TypeInstPtr
::
BOTTOM
,
T_OBJECT
,
Compile
::
AliasIdxRaw
);
// Load the target MethodHandle from the CallSite object.
Node
*
target_adr
=
kit
.
basic_plus_adr
(
call_site
,
call_site
,
java_lang_invoke_CallSite
::
target_offset_in_bytes
());
Node
*
target_mh
=
kit
.
make_load
(
kit
.
control
(),
target_adr
,
TypeInstPtr
::
BOTTOM
,
T_OBJECT
);
// Check if the MethodHandle is still the same.
const
TypeOopPtr
*
predicted_mh_ptr
=
TypeOopPtr
::
make_from_constant
(
_predicted_method_handle
,
true
);
Node
*
predicted_mh
=
kit
.
makecon
(
predicted_mh_ptr
);
Node
*
cmp
=
gvn
.
transform
(
new
(
kit
.
C
,
3
)
CmpPNode
(
target_mh
,
predicted_mh
));
Node
*
bol
=
gvn
.
transform
(
new
(
kit
.
C
,
2
)
BoolNode
(
cmp
,
BoolTest
::
eq
)
);
Node
*
bol
=
NULL
;
int
bc
=
jvms
->
method
()
->
java_code_at_bci
(
jvms
->
bci
());
if
(
bc
==
Bytecodes
::
_invokespecial
)
{
// This is the selectAlternative idiom for guardWithTest
Node
*
receiver
=
kit
.
argument
(
0
);
// Check if the MethodHandle is the expected one
Node
*
cmp
=
gvn
.
transform
(
new
(
kit
.
C
,
3
)
CmpPNode
(
receiver
,
predicted_mh
));
bol
=
gvn
.
transform
(
new
(
kit
.
C
,
2
)
BoolNode
(
cmp
,
BoolTest
::
eq
)
);
}
else
{
assert
(
bc
==
Bytecodes
::
_invokedynamic
,
"must be"
);
// Get the constant pool cache from the caller class.
ciMethod
*
caller_method
=
jvms
->
method
();
ciBytecodeStream
str
(
caller_method
);
str
.
force_bci
(
jvms
->
bci
());
// Set the stream to the invokedynamic bci.
ciCPCache
*
cpcache
=
str
.
get_cpcache
();
// Get the offset of the CallSite from the constant pool cache
// pointer.
int
index
=
str
.
get_method_index
();
size_t
call_site_offset
=
cpcache
->
get_f1_offset
(
index
);
// Load the CallSite object from the constant pool cache.
const
TypeOopPtr
*
cpcache_ptr
=
TypeOopPtr
::
make_from_constant
(
cpcache
);
Node
*
cpcache_adr
=
kit
.
makecon
(
cpcache_ptr
);
Node
*
call_site_adr
=
kit
.
basic_plus_adr
(
cpcache_adr
,
cpcache_adr
,
call_site_offset
);
Node
*
call_site
=
kit
.
make_load
(
kit
.
control
(),
call_site_adr
,
TypeInstPtr
::
BOTTOM
,
T_OBJECT
,
Compile
::
AliasIdxRaw
);
// Load the target MethodHandle from the CallSite object.
Node
*
target_adr
=
kit
.
basic_plus_adr
(
call_site
,
call_site
,
java_lang_invoke_CallSite
::
target_offset_in_bytes
());
Node
*
target_mh
=
kit
.
make_load
(
kit
.
control
(),
target_adr
,
TypeInstPtr
::
BOTTOM
,
T_OBJECT
);
// Check if the MethodHandle is still the same.
Node
*
cmp
=
gvn
.
transform
(
new
(
kit
.
C
,
3
)
CmpPNode
(
target_mh
,
predicted_mh
));
bol
=
gvn
.
transform
(
new
(
kit
.
C
,
2
)
BoolNode
(
cmp
,
BoolTest
::
eq
)
);
}
IfNode
*
iff
=
kit
.
create_and_xform_if
(
kit
.
control
(),
bol
,
_hit_prob
,
COUNT_UNKNOWN
);
kit
.
set_control
(
gvn
.
transform
(
new
(
kit
.
C
,
1
)
IfTrueNode
(
iff
)));
Node
*
slow_ctl
=
gvn
.
transform
(
new
(
kit
.
C
,
1
)
IfFalseNode
(
iff
));
...
...
src/share/vm/opto/callGenerator.hpp
浏览文件 @
debdc89e
...
...
@@ -111,6 +111,8 @@ class CallGenerator : public ResourceObj {
static
CallGenerator
*
for_dynamic_call
(
ciMethod
*
m
);
// invokedynamic
static
CallGenerator
*
for_virtual_call
(
ciMethod
*
m
,
int
vtable_index
);
// virtual, interface
static
CallGenerator
*
for_method_handle_inline
(
Node
*
method_handle
,
JVMState
*
jvms
,
ciMethod
*
caller
,
ciMethod
*
callee
,
ciCallProfile
profile
);
// How to generate a replace a direct call with an inline version
static
CallGenerator
*
for_late_inline
(
ciMethod
*
m
,
CallGenerator
*
inline_cg
);
...
...
src/share/vm/opto/doCall.cpp
浏览文件 @
debdc89e
...
...
@@ -123,24 +123,9 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
GraphKit
kit
(
jvms
);
Node
*
n
=
kit
.
argument
(
0
);
if
(
n
->
Opcode
()
==
Op_ConP
)
{
const
TypeOopPtr
*
oop_ptr
=
n
->
bottom_type
()
->
is_oopptr
();
ciObject
*
const_oop
=
oop_ptr
->
const_oop
();
ciMethodHandle
*
method_handle
=
const_oop
->
as_method_handle
();
// Set the callee to have access to the class and signature in
// the MethodHandleCompiler.
method_handle
->
set_callee
(
call_method
);
method_handle
->
set_caller
(
caller
);
method_handle
->
set_call_profile
(
&
profile
);
// Get an adapter for the MethodHandle.
ciMethod
*
target_method
=
method_handle
->
get_method_handle_adapter
();
if
(
target_method
!=
NULL
)
{
CallGenerator
*
hit_cg
=
this
->
call_generator
(
target_method
,
vtable_index
,
false
,
jvms
,
true
,
prof_factor
);
if
(
hit_cg
!=
NULL
&&
hit_cg
->
is_inline
())
return
hit_cg
;
}
CallGenerator
*
cg
=
CallGenerator
::
for_method_handle_inline
(
n
,
jvms
,
caller
,
call_method
,
profile
);
if
(
cg
!=
NULL
)
{
return
cg
;
}
return
CallGenerator
::
for_direct_call
(
call_method
);
...
...
@@ -157,7 +142,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
// the MethodHandleCompiler.
method_handle
->
set_callee
(
call_method
);
method_handle
->
set_caller
(
caller
);
method_handle
->
set_call_profile
(
&
profile
);
method_handle
->
set_call_profile
(
profile
);
// Get an adapter for the MethodHandle.
ciMethod
*
target_method
=
method_handle
->
get_invokedynamic_adapter
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录