Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
a390df62
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看板
提交
a390df62
编写于
9月 29, 2014
作者:
M
mgronlun
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8038624: interpretedVFrame::expressions() must respect InterpreterOopMap for liveness
Reviewed-by: coleenp, minqi
上级
dba9b6ab
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
147 addition
and
96 deletion
+147
-96
src/share/vm/interpreter/oopMapCache.cpp
src/share/vm/interpreter/oopMapCache.cpp
+5
-5
src/share/vm/interpreter/oopMapCache.hpp
src/share/vm/interpreter/oopMapCache.hpp
+16
-16
src/share/vm/runtime/vframe.cpp
src/share/vm/runtime/vframe.cpp
+125
-74
src/share/vm/runtime/vframe.hpp
src/share/vm/runtime/vframe.hpp
+1
-1
未找到文件。
src/share/vm/interpreter/oopMapCache.cpp
浏览文件 @
a390df62
...
@@ -180,7 +180,7 @@ InterpreterOopMap::~InterpreterOopMap() {
...
@@ -180,7 +180,7 @@ InterpreterOopMap::~InterpreterOopMap() {
}
}
}
}
bool
InterpreterOopMap
::
is_empty
()
{
bool
InterpreterOopMap
::
is_empty
()
const
{
bool
result
=
_method
==
NULL
;
bool
result
=
_method
==
NULL
;
assert
(
_method
!=
NULL
||
(
_bci
==
0
&&
assert
(
_method
!=
NULL
||
(
_bci
==
0
&&
(
_mask_size
==
0
||
_mask_size
==
USHRT_MAX
)
&&
(
_mask_size
==
0
||
_mask_size
==
USHRT_MAX
)
&&
...
@@ -196,7 +196,7 @@ void InterpreterOopMap::initialize() {
...
@@ -196,7 +196,7 @@ void InterpreterOopMap::initialize() {
for
(
int
i
=
0
;
i
<
N
;
i
++
)
_bit_mask
[
i
]
=
0
;
for
(
int
i
=
0
;
i
<
N
;
i
++
)
_bit_mask
[
i
]
=
0
;
}
}
void
InterpreterOopMap
::
iterate_oop
(
OffsetClosure
*
oop_closure
)
{
void
InterpreterOopMap
::
iterate_oop
(
OffsetClosure
*
oop_closure
)
const
{
int
n
=
number_of_entries
();
int
n
=
number_of_entries
();
int
word_index
=
0
;
int
word_index
=
0
;
uintptr_t
value
=
0
;
uintptr_t
value
=
0
;
...
@@ -238,7 +238,7 @@ void InterpreterOopMap::iterate_all(OffsetClosure* oop_closure, OffsetClosure* v
...
@@ -238,7 +238,7 @@ void InterpreterOopMap::iterate_all(OffsetClosure* oop_closure, OffsetClosure* v
#endif
#endif
void
InterpreterOopMap
::
print
()
{
void
InterpreterOopMap
::
print
()
const
{
int
n
=
number_of_entries
();
int
n
=
number_of_entries
();
tty
->
print
(
"oop map for "
);
tty
->
print
(
"oop map for "
);
method
()
->
print_value
();
method
()
->
print_value
();
...
@@ -469,7 +469,7 @@ void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
...
@@ -469,7 +469,7 @@ void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
}
}
}
}
inline
unsigned
int
OopMapCache
::
hash_value_for
(
methodHandle
method
,
int
bci
)
{
inline
unsigned
int
OopMapCache
::
hash_value_for
(
methodHandle
method
,
int
bci
)
const
{
// We use method->code_size() rather than method->identity_hash() below since
// We use method->code_size() rather than method->identity_hash() below since
// the mark may not be present if a pointer to the method is already reversed.
// the mark may not be present if a pointer to the method is already reversed.
return
((
unsigned
int
)
bci
)
return
((
unsigned
int
)
bci
)
...
@@ -522,7 +522,7 @@ void OopMapCache::flush_obsolete_entries() {
...
@@ -522,7 +522,7 @@ void OopMapCache::flush_obsolete_entries() {
void
OopMapCache
::
lookup
(
methodHandle
method
,
void
OopMapCache
::
lookup
(
methodHandle
method
,
int
bci
,
int
bci
,
InterpreterOopMap
*
entry_for
)
{
InterpreterOopMap
*
entry_for
)
const
{
MutexLocker
x
(
&
_mut
);
MutexLocker
x
(
&
_mut
);
OopMapCacheEntry
*
entry
=
NULL
;
OopMapCacheEntry
*
entry
=
NULL
;
...
...
src/share/vm/interpreter/oopMapCache.hpp
浏览文件 @
a390df62
...
@@ -101,32 +101,31 @@ class InterpreterOopMap: ResourceObj {
...
@@ -101,32 +101,31 @@ class InterpreterOopMap: ResourceObj {
// access methods
// access methods
Method
*
method
()
const
{
return
_method
;
}
Method
*
method
()
const
{
return
_method
;
}
void
set_method
(
Method
*
v
)
{
_method
=
v
;
}
void
set_method
(
Method
*
v
)
{
_method
=
v
;
}
int
bci
()
const
{
return
_bci
;
}
int
bci
()
const
{
return
_bci
;
}
void
set_bci
(
int
v
)
{
_bci
=
v
;
}
void
set_bci
(
int
v
)
{
_bci
=
v
;
}
int
mask_size
()
const
{
return
_mask_size
;
}
int
mask_size
()
const
{
return
_mask_size
;
}
void
set_mask_size
(
int
v
)
{
_mask_size
=
v
;
}
void
set_mask_size
(
int
v
)
{
_mask_size
=
v
;
}
int
number_of_entries
()
const
{
return
mask_size
()
/
bits_per_entry
;
}
// Test bit mask size and return either the in-line bit mask or allocated
// Test bit mask size and return either the in-line bit mask or allocated
// bit mask.
// bit mask.
uintptr_t
*
bit_mask
()
{
return
(
uintptr_t
*
)(
mask_size
()
<=
small_mask_limit
?
(
intptr_t
)
_bit_mask
:
_bit_mask
[
0
]);
}
uintptr_t
*
bit_mask
()
const
{
return
(
uintptr_t
*
)(
mask_size
()
<=
small_mask_limit
?
(
intptr_t
)
_bit_mask
:
_bit_mask
[
0
]);
}
// return the word size of_bit_mask. mask_size() <= 4 * MAX_USHORT
// return the word size of_bit_mask. mask_size() <= 4 * MAX_USHORT
size_t
mask_word_size
()
{
size_t
mask_word_size
()
const
{
return
(
mask_size
()
+
BitsPerWord
-
1
)
/
BitsPerWord
;
return
(
mask_size
()
+
BitsPerWord
-
1
)
/
BitsPerWord
;
}
}
uintptr_t
entry_at
(
int
offset
)
{
int
i
=
offset
*
bits_per_entry
;
return
bit_mask
()[
i
/
BitsPerWord
]
>>
(
i
%
BitsPerWord
);
}
uintptr_t
entry_at
(
int
offset
)
const
{
int
i
=
offset
*
bits_per_entry
;
return
bit_mask
()[
i
/
BitsPerWord
]
>>
(
i
%
BitsPerWord
);
}
void
set_expression_stack_size
(
int
sz
)
{
_expression_stack_size
=
sz
;
}
void
set_expression_stack_size
(
int
sz
)
{
_expression_stack_size
=
sz
;
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
#ifdef ENABLE_ZAP_DEAD_LOCALS
bool
is_dead
(
int
offset
)
{
return
(
entry_at
(
offset
)
&
(
1
<<
dead_bit_number
))
!=
0
;
}
bool
is_dead
(
int
offset
)
const
{
return
(
entry_at
(
offset
)
&
(
1
<<
dead_bit_number
))
!=
0
;
}
#endif
#endif
// Lookup
// Lookup
bool
match
(
methodHandle
method
,
int
bci
)
{
return
_method
==
method
()
&&
_bci
==
bci
;
}
bool
match
(
methodHandle
method
,
int
bci
)
const
{
return
_method
==
method
()
&&
_bci
==
bci
;
}
bool
is_empty
();
bool
is_empty
()
const
;
// Initialization
// Initialization
void
initialize
();
void
initialize
();
...
@@ -141,12 +140,13 @@ class InterpreterOopMap: ResourceObj {
...
@@ -141,12 +140,13 @@ class InterpreterOopMap: ResourceObj {
// in-line), allocate the space from a Resource area.
// in-line), allocate the space from a Resource area.
void
resource_copy
(
OopMapCacheEntry
*
from
);
void
resource_copy
(
OopMapCacheEntry
*
from
);
void
iterate_oop
(
OffsetClosure
*
oop_closure
);
void
iterate_oop
(
OffsetClosure
*
oop_closure
)
const
;
void
print
();
void
print
()
const
;
bool
is_oop
(
int
offset
)
{
return
(
entry_at
(
offset
)
&
(
1
<<
oop_bit_number
))
!=
0
;
}
int
number_of_entries
()
const
{
return
mask_size
()
/
bits_per_entry
;
}
bool
is_oop
(
int
offset
)
const
{
return
(
entry_at
(
offset
)
&
(
1
<<
oop_bit_number
))
!=
0
;
}
int
expression_stack_size
()
{
return
_expression_stack_size
;
}
int
expression_stack_size
()
const
{
return
_expression_stack_size
;
}
#ifdef ENABLE_ZAP_DEAD_LOCALS
#ifdef ENABLE_ZAP_DEAD_LOCALS
void
iterate_all
(
OffsetClosure
*
oop_closure
,
OffsetClosure
*
value_closure
,
OffsetClosure
*
dead_closure
);
void
iterate_all
(
OffsetClosure
*
oop_closure
,
OffsetClosure
*
value_closure
,
OffsetClosure
*
dead_closure
);
...
@@ -161,10 +161,10 @@ class OopMapCache : public CHeapObj<mtClass> {
...
@@ -161,10 +161,10 @@ class OopMapCache : public CHeapObj<mtClass> {
OopMapCacheEntry
*
_array
;
OopMapCacheEntry
*
_array
;
unsigned
int
hash_value_for
(
methodHandle
method
,
int
bci
);
unsigned
int
hash_value_for
(
methodHandle
method
,
int
bci
)
const
;
OopMapCacheEntry
*
entry_at
(
int
i
)
const
;
OopMapCacheEntry
*
entry_at
(
int
i
)
const
;
Mutex
_mut
;
mutable
Mutex
_mut
;
void
flush
();
void
flush
();
...
@@ -177,7 +177,7 @@ class OopMapCache : public CHeapObj<mtClass> {
...
@@ -177,7 +177,7 @@ class OopMapCache : public CHeapObj<mtClass> {
// Returns the oopMap for (method, bci) in parameter "entry".
// Returns the oopMap for (method, bci) in parameter "entry".
// Returns false if an oop map was not found.
// Returns false if an oop map was not found.
void
lookup
(
methodHandle
method
,
int
bci
,
InterpreterOopMap
*
entry
);
void
lookup
(
methodHandle
method
,
int
bci
,
InterpreterOopMap
*
entry
)
const
;
// Compute an oop map without updating the cache or grabbing any locks (for debugging)
// Compute an oop map without updating the cache or grabbing any locks (for debugging)
static
void
compute_one_oop_map
(
methodHandle
method
,
int
bci
,
InterpreterOopMap
*
entry
);
static
void
compute_one_oop_map
(
methodHandle
method
,
int
bci
,
InterpreterOopMap
*
entry
);
...
...
src/share/vm/runtime/vframe.cpp
浏览文件 @
a390df62
...
@@ -260,65 +260,156 @@ Method* interpretedVFrame::method() const {
...
@@ -260,65 +260,156 @@ Method* interpretedVFrame::method() const {
return
fr
().
interpreter_frame_method
();
return
fr
().
interpreter_frame_method
();
}
}
StackValueCollection
*
interpretedVFrame
::
locals
()
const
{
static
StackValue
*
create_stack_value_from_oop_map
(
const
InterpreterOopMap
&
oop_mask
,
int
length
=
method
()
->
max_locals
();
int
index
,
const
intptr_t
*
const
addr
)
{
assert
(
index
>=
0
&&
index
<
oop_mask
.
number_of_entries
(),
"invariant"
);
// categorize using oop_mask
if
(
oop_mask
.
is_oop
(
index
))
{
// reference (oop) "r"
Handle
h
(
addr
!=
NULL
?
(
*
(
oop
*
)
addr
)
:
(
oop
)
NULL
);
return
new
StackValue
(
h
);
}
// value (integer) "v"
return
new
StackValue
(
addr
!=
NULL
?
*
addr
:
0
);
}
static
bool
is_in_expression_stack
(
const
frame
&
fr
,
const
intptr_t
*
const
addr
)
{
assert
(
addr
!=
NULL
,
"invariant"
);
// Ensure to be 'inside' the expresion stack (i.e., addr >= sp for Intel).
// In case of exceptions, the expression stack is invalid and the sp
// will be reset to express this condition.
if
(
frame
::
interpreter_frame_expression_stack_direction
()
>
0
)
{
return
addr
<=
fr
.
interpreter_frame_tos_address
();
}
return
addr
>=
fr
.
interpreter_frame_tos_address
();
}
static
void
stack_locals
(
StackValueCollection
*
result
,
int
length
,
const
InterpreterOopMap
&
oop_mask
,
const
frame
&
fr
)
{
assert
(
result
!=
NULL
,
"invariant"
);
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
const
intptr_t
*
const
addr
=
fr
.
interpreter_frame_local_at
(
i
);
assert
(
addr
!=
NULL
,
"invariant"
);
assert
(
addr
>=
fr
.
sp
(),
"must be inside the frame"
);
StackValue
*
const
sv
=
create_stack_value_from_oop_map
(
oop_mask
,
i
,
addr
);
assert
(
sv
!=
NULL
,
"sanity check"
);
result
->
add
(
sv
);
}
}
static
void
stack_expressions
(
StackValueCollection
*
result
,
int
length
,
int
max_locals
,
const
InterpreterOopMap
&
oop_mask
,
const
frame
&
fr
)
{
assert
(
result
!=
NULL
,
"invariant"
);
if
(
method
()
->
is_native
())
{
for
(
int
i
=
0
;
i
<
length
;
++
i
)
{
// If the method is native, max_locals is not telling the truth.
const
intptr_t
*
addr
=
fr
.
interpreter_frame_expression_stack_at
(
i
);
// maxlocals then equals the size of parameters
assert
(
addr
!=
NULL
,
"invariant"
);
length
=
method
()
->
size_of_parameters
();
if
(
!
is_in_expression_stack
(
fr
,
addr
))
{
// Need to ensure no bogus escapes.
addr
=
NULL
;
}
StackValue
*
const
sv
=
create_stack_value_from_oop_map
(
oop_mask
,
i
+
max_locals
,
addr
);
assert
(
sv
!=
NULL
,
"sanity check"
);
result
->
add
(
sv
);
}
}
}
StackValueCollection
*
result
=
new
StackValueCollection
(
length
);
StackValueCollection
*
interpretedVFrame
::
locals
()
const
{
return
stack_data
(
false
);
}
StackValueCollection
*
interpretedVFrame
::
expressions
()
const
{
return
stack_data
(
true
);
}
/*
* Worker routine for fetching references and/or values
* for a particular bci in the interpretedVFrame.
*
* Returns data for either "locals" or "expressions",
* using bci relative oop_map (oop_mask) information.
*
* @param expressions bool switch controlling what data to return
(false == locals / true == expressions)
*
*/
StackValueCollection
*
interpretedVFrame
::
stack_data
(
bool
expressions
)
const
{
// Get oopmap describing oops and int for current bci
InterpreterOopMap
oop_mask
;
InterpreterOopMap
oop_mask
;
// oopmap for current bci
if
(
TraceDeoptimization
&&
Verbose
)
{
if
(
TraceDeoptimization
&&
Verbose
)
{
methodHandle
m_h
(
thread
(),
method
());
methodHandle
m_h
(
Thread
::
current
(),
method
());
OopMapCache
::
compute_one_oop_map
(
m_h
,
bci
(),
&
oop_mask
);
OopMapCache
::
compute_one_oop_map
(
m_h
,
bci
(),
&
oop_mask
);
}
else
{
}
else
{
method
()
->
mask_for
(
bci
(),
&
oop_mask
);
method
()
->
mask_for
(
bci
(),
&
oop_mask
);
}
}
// handle locals
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
// Find stack location
intptr_t
*
addr
=
locals_addr_at
(
i
);
// Depending on oop/int put it in the right package
const
int
mask_len
=
oop_mask
.
number_of_entries
();
StackValue
*
sv
;
if
(
oop_mask
.
is_oop
(
i
))
{
// If the method is native, method()->max_locals() is not telling the truth.
// oop value
// For our purposes, max locals instead equals the size of parameters.
Handle
h
(
*
(
oop
*
)
addr
);
const
int
max_locals
=
method
()
->
is_native
()
?
sv
=
new
StackValue
(
h
);
method
()
->
size_of_parameters
()
:
method
()
->
max_locals
();
}
else
{
// integer
assert
(
mask_len
>=
max_locals
,
"invariant"
);
sv
=
new
StackValue
(
*
addr
);
}
const
int
length
=
expressions
?
mask_len
-
max_locals
:
max_locals
;
assert
(
sv
!=
NULL
,
"sanity check"
);
assert
(
length
>=
0
,
"invariant"
);
result
->
add
(
sv
);
StackValueCollection
*
const
result
=
new
StackValueCollection
(
length
);
if
(
0
==
length
)
{
return
result
;
}
}
if
(
expressions
)
{
stack_expressions
(
result
,
length
,
max_locals
,
oop_mask
,
fr
());
}
else
{
stack_locals
(
result
,
length
,
oop_mask
,
fr
());
}
assert
(
length
==
result
->
size
(),
"invariant"
);
return
result
;
return
result
;
}
}
void
interpretedVFrame
::
set_locals
(
StackValueCollection
*
values
)
const
{
void
interpretedVFrame
::
set_locals
(
StackValueCollection
*
values
)
const
{
if
(
values
==
NULL
||
values
->
size
()
==
0
)
return
;
if
(
values
==
NULL
||
values
->
size
()
==
0
)
return
;
int
length
=
method
()
->
max_locals
();
// If the method is native, max_locals is not telling the truth.
if
(
method
()
->
is_native
())
{
// maxlocals then equals the size of parameters
// If the method is native, max_locals is not telling the truth.
const
int
max_locals
=
method
()
->
is_native
()
?
// maxlocals then equals the size of parameters
method
()
->
size_of_parameters
()
:
method
()
->
max_locals
();
length
=
method
()
->
size_of_parameters
();
}
assert
(
length
==
values
->
size
(),
"Mismatch between actual stack format and supplied data"
);
assert
(
max_locals
==
values
->
size
(),
"Mismatch between actual stack format and supplied data"
);
// handle locals
// handle locals
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
for
(
int
i
=
0
;
i
<
max_locals
;
i
++
)
{
// Find stack location
// Find stack location
intptr_t
*
addr
=
locals_addr_at
(
i
);
intptr_t
*
addr
=
locals_addr_at
(
i
);
// Depending on oop/int put it in the right package
// Depending on oop/int put it in the right package
StackValue
*
sv
=
values
->
at
(
i
);
const
StackValue
*
const
sv
=
values
->
at
(
i
);
assert
(
sv
!=
NULL
,
"sanity check"
);
assert
(
sv
!=
NULL
,
"sanity check"
);
if
(
sv
->
type
()
==
T_OBJECT
)
{
if
(
sv
->
type
()
==
T_OBJECT
)
{
*
(
oop
*
)
addr
=
(
sv
->
get_obj
())();
*
(
oop
*
)
addr
=
(
sv
->
get_obj
())();
...
@@ -328,46 +419,6 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
...
@@ -328,46 +419,6 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
}
}
}
}
StackValueCollection
*
interpretedVFrame
::
expressions
()
const
{
int
length
=
fr
().
interpreter_frame_expression_stack_size
();
if
(
method
()
->
is_native
())
{
// If the method is native, there is no expression stack
length
=
0
;
}
int
nof_locals
=
method
()
->
max_locals
();
StackValueCollection
*
result
=
new
StackValueCollection
(
length
);
InterpreterOopMap
oop_mask
;
// Get oopmap describing oops and int for current bci
if
(
TraceDeoptimization
&&
Verbose
)
{
methodHandle
m_h
(
method
());
OopMapCache
::
compute_one_oop_map
(
m_h
,
bci
(),
&
oop_mask
);
}
else
{
method
()
->
mask_for
(
bci
(),
&
oop_mask
);
}
// handle expressions
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
// Find stack location
intptr_t
*
addr
=
fr
().
interpreter_frame_expression_stack_at
(
i
);
// Depending on oop/int put it in the right package
StackValue
*
sv
;
if
(
oop_mask
.
is_oop
(
i
+
nof_locals
))
{
// oop value
Handle
h
(
*
(
oop
*
)
addr
);
sv
=
new
StackValue
(
h
);
}
else
{
// integer
sv
=
new
StackValue
(
*
addr
);
}
assert
(
sv
!=
NULL
,
"sanity check"
);
result
->
add
(
sv
);
}
return
result
;
}
// ------------- cChunk --------------
// ------------- cChunk --------------
entryVFrame
::
entryVFrame
(
const
frame
*
fr
,
const
RegisterMap
*
reg_map
,
JavaThread
*
thread
)
entryVFrame
::
entryVFrame
(
const
frame
*
fr
,
const
RegisterMap
*
reg_map
,
JavaThread
*
thread
)
...
...
src/share/vm/runtime/vframe.hpp
浏览文件 @
a390df62
...
@@ -186,7 +186,7 @@ class interpretedVFrame: public javaVFrame {
...
@@ -186,7 +186,7 @@ class interpretedVFrame: public javaVFrame {
private:
private:
static
const
int
bcp_offset
;
static
const
int
bcp_offset
;
intptr_t
*
locals_addr_at
(
int
offset
)
const
;
intptr_t
*
locals_addr_at
(
int
offset
)
const
;
StackValueCollection
*
stack_data
(
bool
expressions
)
const
;
// returns where the parameters starts relative to the frame pointer
// returns where the parameters starts relative to the frame pointer
int
start_of_parameters
()
const
;
int
start_of_parameters
()
const
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录