Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
e5f7b8b0
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看板
提交
e5f7b8b0
编写于
5月 16, 2011
作者:
N
never
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
Reviewed-by: kvn, iveresov
上级
82666eba
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
160 addition
and
2 deletion
+160
-2
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+6
-0
src/share/vm/runtime/sweeper.cpp
src/share/vm/runtime/sweeper.cpp
+122
-0
src/share/vm/runtime/sweeper.hpp
src/share/vm/runtime/sweeper.hpp
+7
-0
src/share/vm/runtime/thread.cpp
src/share/vm/runtime/thread.cpp
+10
-0
src/share/vm/runtime/thread.hpp
src/share/vm/runtime/thread.hpp
+15
-2
未找到文件。
src/share/vm/runtime/globals.hpp
浏览文件 @
e5f7b8b0
...
@@ -2909,6 +2909,12 @@ class CommandLineFlags {
...
@@ -2909,6 +2909,12 @@ class CommandLineFlags {
product(intx, NmethodSweepCheckInterval, 5, \
product(intx, NmethodSweepCheckInterval, 5, \
"Compilers wake up every n seconds to possibly sweep nmethods") \
"Compilers wake up every n seconds to possibly sweep nmethods") \
\
\
notproduct(bool, LogSweeper, false, \
"Keep a ring buffer of sweeper activity") \
\
notproduct(intx, SweeperLogEntries, 1024, \
"Number of records in the ring buffer of sweeper activity") \
\
notproduct(intx, MemProfilingInterval, 500, \
notproduct(intx, MemProfilingInterval, 500, \
"Time between each invocation of the MemProfiler") \
"Time between each invocation of the MemProfiler") \
\
\
...
...
src/share/vm/runtime/sweeper.cpp
浏览文件 @
e5f7b8b0
...
@@ -37,6 +37,94 @@
...
@@ -37,6 +37,94 @@
#include "utilities/events.hpp"
#include "utilities/events.hpp"
#include "utilities/xmlstream.hpp"
#include "utilities/xmlstream.hpp"
#ifdef ASSERT
#define SWEEP(nm) record_sweep(nm, __LINE__)
// Sweeper logging code
class
SweeperRecord
{
public:
int
traversal
;
int
invocation
;
int
compile_id
;
long
traversal_mark
;
int
state
;
const
char
*
kind
;
address
vep
;
address
uep
;
int
line
;
void
print
()
{
tty
->
print_cr
(
"traversal = %d invocation = %d compile_id = %d %s uep = "
PTR_FORMAT
" vep = "
PTR_FORMAT
" state = %d traversal_mark %d line = %d"
,
traversal
,
invocation
,
compile_id
,
kind
==
NULL
?
""
:
kind
,
uep
,
vep
,
state
,
traversal_mark
,
line
);
}
};
static
int
_sweep_index
=
0
;
static
SweeperRecord
*
_records
=
NULL
;
void
NMethodSweeper
::
report_events
(
int
id
,
address
entry
)
{
if
(
_records
!=
NULL
)
{
for
(
int
i
=
_sweep_index
;
i
<
SweeperLogEntries
;
i
++
)
{
if
(
_records
[
i
].
uep
==
entry
||
_records
[
i
].
vep
==
entry
||
_records
[
i
].
compile_id
==
id
)
{
_records
[
i
].
print
();
}
}
for
(
int
i
=
0
;
i
<
_sweep_index
;
i
++
)
{
if
(
_records
[
i
].
uep
==
entry
||
_records
[
i
].
vep
==
entry
||
_records
[
i
].
compile_id
==
id
)
{
_records
[
i
].
print
();
}
}
}
}
void
NMethodSweeper
::
report_events
()
{
if
(
_records
!=
NULL
)
{
for
(
int
i
=
_sweep_index
;
i
<
SweeperLogEntries
;
i
++
)
{
// skip empty records
if
(
_records
[
i
].
vep
==
NULL
)
continue
;
_records
[
i
].
print
();
}
for
(
int
i
=
0
;
i
<
_sweep_index
;
i
++
)
{
// skip empty records
if
(
_records
[
i
].
vep
==
NULL
)
continue
;
_records
[
i
].
print
();
}
}
}
void
NMethodSweeper
::
record_sweep
(
nmethod
*
nm
,
int
line
)
{
if
(
_records
!=
NULL
)
{
_records
[
_sweep_index
].
traversal
=
_traversals
;
_records
[
_sweep_index
].
traversal_mark
=
nm
->
_stack_traversal_mark
;
_records
[
_sweep_index
].
invocation
=
_invocations
;
_records
[
_sweep_index
].
compile_id
=
nm
->
compile_id
();
_records
[
_sweep_index
].
kind
=
nm
->
compile_kind
();
_records
[
_sweep_index
].
state
=
nm
->
_state
;
_records
[
_sweep_index
].
vep
=
nm
->
verified_entry_point
();
_records
[
_sweep_index
].
uep
=
nm
->
entry_point
();
_records
[
_sweep_index
].
line
=
line
;
_sweep_index
=
(
_sweep_index
+
1
)
%
SweeperLogEntries
;
}
}
#else
#define SWEEP(nm)
#endif
long
NMethodSweeper
::
_traversals
=
0
;
// No. of stack traversals performed
long
NMethodSweeper
::
_traversals
=
0
;
// No. of stack traversals performed
nmethod
*
NMethodSweeper
::
_current
=
NULL
;
// Current nmethod
nmethod
*
NMethodSweeper
::
_current
=
NULL
;
// Current nmethod
int
NMethodSweeper
::
_seen
=
0
;
// No. of nmethods we have currently processed in current pass of CodeCache
int
NMethodSweeper
::
_seen
=
0
;
// No. of nmethods we have currently processed in current pass of CodeCache
...
@@ -137,6 +225,13 @@ void NMethodSweeper::possibly_sweep() {
...
@@ -137,6 +225,13 @@ void NMethodSweeper::possibly_sweep() {
if
(
old
!=
0
)
{
if
(
old
!=
0
)
{
return
;
return
;
}
}
#ifdef ASSERT
if
(
LogSweeper
&&
_records
==
NULL
)
{
// Create the ring buffer for the logging code
_records
=
NEW_C_HEAP_ARRAY
(
SweeperRecord
,
SweeperLogEntries
);
memset
(
_records
,
0
,
sizeof
(
SweeperRecord
)
*
SweeperLogEntries
);
}
#endif
if
(
_invocations
>
0
)
{
if
(
_invocations
>
0
)
{
sweep_code_cache
();
sweep_code_cache
();
_invocations
--
;
_invocations
--
;
...
@@ -213,10 +308,29 @@ void NMethodSweeper::sweep_code_cache() {
...
@@ -213,10 +308,29 @@ void NMethodSweeper::sweep_code_cache() {
}
}
}
}
class
NMethodMarker
:
public
StackObj
{
private:
CompilerThread
*
_thread
;
public:
NMethodMarker
(
nmethod
*
nm
)
{
_thread
=
CompilerThread
::
current
();
_thread
->
set_scanned_nmethod
(
nm
);
}
~
NMethodMarker
()
{
_thread
->
set_scanned_nmethod
(
NULL
);
}
};
void
NMethodSweeper
::
process_nmethod
(
nmethod
*
nm
)
{
void
NMethodSweeper
::
process_nmethod
(
nmethod
*
nm
)
{
assert
(
!
CodeCache_lock
->
owned_by_self
(),
"just checking"
);
assert
(
!
CodeCache_lock
->
owned_by_self
(),
"just checking"
);
// Make sure this nmethod doesn't get unloaded during the scan,
// since the locks acquired below might safepoint.
NMethodMarker
nmm
(
nm
);
SWEEP
(
nm
);
// Skip methods that are currently referenced by the VM
// Skip methods that are currently referenced by the VM
if
(
nm
->
is_locked_by_vm
())
{
if
(
nm
->
is_locked_by_vm
())
{
// But still remember to clean-up inline caches for alive nmethods
// But still remember to clean-up inline caches for alive nmethods
...
@@ -224,8 +338,10 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -224,8 +338,10 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
// Clean-up all inline caches that points to zombie/non-reentrant methods
// Clean-up all inline caches that points to zombie/non-reentrant methods
MutexLocker
cl
(
CompiledIC_lock
);
MutexLocker
cl
(
CompiledIC_lock
);
nm
->
cleanup_inline_caches
();
nm
->
cleanup_inline_caches
();
SWEEP
(
nm
);
}
else
{
}
else
{
_locked_seen
++
;
_locked_seen
++
;
SWEEP
(
nm
);
}
}
return
;
return
;
}
}
...
@@ -247,6 +363,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -247,6 +363,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
}
}
nm
->
mark_for_reclamation
();
nm
->
mark_for_reclamation
();
_rescan
=
true
;
_rescan
=
true
;
SWEEP
(
nm
);
}
}
}
else
if
(
nm
->
is_not_entrant
())
{
}
else
if
(
nm
->
is_not_entrant
())
{
// If there is no current activations of this method on the
// If there is no current activations of this method on the
...
@@ -257,6 +374,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -257,6 +374,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
}
}
nm
->
make_zombie
();
nm
->
make_zombie
();
_rescan
=
true
;
_rescan
=
true
;
SWEEP
(
nm
);
}
else
{
}
else
{
// Still alive, clean up its inline caches
// Still alive, clean up its inline caches
MutexLocker
cl
(
CompiledIC_lock
);
MutexLocker
cl
(
CompiledIC_lock
);
...
@@ -265,6 +383,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -265,6 +383,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
// request a rescan. If this method stays on the stack for a
// request a rescan. If this method stays on the stack for a
// long time we don't want to keep rescanning the code cache.
// long time we don't want to keep rescanning the code cache.
_not_entrant_seen_on_stack
++
;
_not_entrant_seen_on_stack
++
;
SWEEP
(
nm
);
}
}
}
else
if
(
nm
->
is_unloaded
())
{
}
else
if
(
nm
->
is_unloaded
())
{
// Unloaded code, just make it a zombie
// Unloaded code, just make it a zombie
...
@@ -273,10 +392,12 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -273,10 +392,12 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
if
(
nm
->
is_osr_method
())
{
if
(
nm
->
is_osr_method
())
{
// No inline caches will ever point to osr methods, so we can just remove it
// No inline caches will ever point to osr methods, so we can just remove it
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
MutexLockerEx
mu
(
CodeCache_lock
,
Mutex
::
_no_safepoint_check_flag
);
SWEEP
(
nm
);
nm
->
flush
();
nm
->
flush
();
}
else
{
}
else
{
nm
->
make_zombie
();
nm
->
make_zombie
();
_rescan
=
true
;
_rescan
=
true
;
SWEEP
(
nm
);
}
}
}
else
{
}
else
{
assert
(
nm
->
is_alive
(),
"should be alive"
);
assert
(
nm
->
is_alive
(),
"should be alive"
);
...
@@ -293,6 +414,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
...
@@ -293,6 +414,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
// Clean-up all inline caches that points to zombie/non-reentrant methods
// Clean-up all inline caches that points to zombie/non-reentrant methods
MutexLocker
cl
(
CompiledIC_lock
);
MutexLocker
cl
(
CompiledIC_lock
);
nm
->
cleanup_inline_caches
();
nm
->
cleanup_inline_caches
();
SWEEP
(
nm
);
}
}
}
}
...
...
src/share/vm/runtime/sweeper.hpp
浏览文件 @
e5f7b8b0
...
@@ -57,6 +57,13 @@ class NMethodSweeper : public AllStatic {
...
@@ -57,6 +57,13 @@ class NMethodSweeper : public AllStatic {
public:
public:
static
long
traversal_count
()
{
return
_traversals
;
}
static
long
traversal_count
()
{
return
_traversals
;
}
#ifdef ASSERT
// Keep track of sweeper activity in the ring buffer
static
void
record_sweep
(
nmethod
*
nm
,
int
line
);
static
void
report_events
(
int
id
,
address
entry
);
static
void
report_events
();
#endif
static
void
scan_stacks
();
// Invoked at the end of each safepoint
static
void
scan_stacks
();
// Invoked at the end of each safepoint
static
void
sweep_code_cache
();
// Concurrent part of sweep job
static
void
sweep_code_cache
();
// Concurrent part of sweep job
static
void
possibly_sweep
();
// Compiler threads call this to sweep
static
void
possibly_sweep
();
// Compiler threads call this to sweep
...
...
src/share/vm/runtime/thread.cpp
浏览文件 @
e5f7b8b0
...
@@ -2942,12 +2942,22 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
...
@@ -2942,12 +2942,22 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
_queue
=
queue
;
_queue
=
queue
;
_counters
=
counters
;
_counters
=
counters
;
_buffer_blob
=
NULL
;
_buffer_blob
=
NULL
;
_scanned_nmethod
=
NULL
;
#ifndef PRODUCT
#ifndef PRODUCT
_ideal_graph_printer
=
NULL
;
_ideal_graph_printer
=
NULL
;
#endif
#endif
}
}
void
CompilerThread
::
oops_do
(
OopClosure
*
f
,
CodeBlobClosure
*
cf
)
{
JavaThread
::
oops_do
(
f
,
cf
);
if
(
_scanned_nmethod
!=
NULL
&&
cf
!=
NULL
)
{
// Safepoints can occur when the sweeper is scanning an nmethod so
// process it here to make sure it isn't unloaded in the middle of
// a scan.
cf
->
do_code_blob
(
_scanned_nmethod
);
}
}
// ======= Threads ========
// ======= Threads ========
...
...
src/share/vm/runtime/thread.hpp
浏览文件 @
e5f7b8b0
...
@@ -439,7 +439,7 @@ class Thread: public ThreadShadow {
...
@@ -439,7 +439,7 @@ class Thread: public ThreadShadow {
// GC support
// GC support
// Apply "f->do_oop" to all root oops in "this".
// Apply "f->do_oop" to all root oops in "this".
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
void
oops_do
(
OopClosure
*
f
,
CodeBlobClosure
*
cf
);
v
irtual
v
oid
oops_do
(
OopClosure
*
f
,
CodeBlobClosure
*
cf
);
// Handles the parallel case for the method below.
// Handles the parallel case for the method below.
private:
private:
...
@@ -1381,7 +1381,7 @@ public:
...
@@ -1381,7 +1381,7 @@ public:
void
trace_frames
()
PRODUCT_RETURN
;
void
trace_frames
()
PRODUCT_RETURN
;
// Print an annotated view of the stack frames
// Print an annotated view of the stack frames
void
print_frame_layout
(
int
depth
=
0
,
bool
validate_only
=
false
)
PRODUCT
_RETURN
;
void
print_frame_layout
(
int
depth
=
0
,
bool
validate_only
=
false
)
NOT_DEBUG
_RETURN
;
void
validate_frame_layout
()
{
void
validate_frame_layout
()
{
print_frame_layout
(
0
,
true
);
print_frame_layout
(
0
,
true
);
}
}
...
@@ -1698,6 +1698,8 @@ class CompilerThread : public JavaThread {
...
@@ -1698,6 +1698,8 @@ class CompilerThread : public JavaThread {
CompileQueue
*
_queue
;
CompileQueue
*
_queue
;
BufferBlob
*
_buffer_blob
;
BufferBlob
*
_buffer_blob
;
nmethod
*
_scanned_nmethod
;
// nmethod being scanned by the sweeper
public:
public:
static
CompilerThread
*
current
();
static
CompilerThread
*
current
();
...
@@ -1726,6 +1728,11 @@ class CompilerThread : public JavaThread {
...
@@ -1726,6 +1728,11 @@ class CompilerThread : public JavaThread {
_log
=
log
;
_log
=
log
;
}
}
// GC support
// Apply "f->do_oop" to all root oops in "this".
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
void
oops_do
(
OopClosure
*
f
,
CodeBlobClosure
*
cf
);
#ifndef PRODUCT
#ifndef PRODUCT
private:
private:
IdealGraphPrinter
*
_ideal_graph_printer
;
IdealGraphPrinter
*
_ideal_graph_printer
;
...
@@ -1737,6 +1744,12 @@ public:
...
@@ -1737,6 +1744,12 @@ public:
// Get/set the thread's current task
// Get/set the thread's current task
CompileTask
*
task
()
{
return
_task
;
}
CompileTask
*
task
()
{
return
_task
;
}
void
set_task
(
CompileTask
*
task
)
{
_task
=
task
;
}
void
set_task
(
CompileTask
*
task
)
{
_task
=
task
;
}
// Track the nmethod currently being scanned by the sweeper
void
set_scanned_nmethod
(
nmethod
*
nm
)
{
assert
(
_scanned_nmethod
==
NULL
||
nm
==
NULL
,
"should reset to NULL before writing a new value"
);
_scanned_nmethod
=
nm
;
}
};
};
inline
CompilerThread
*
CompilerThread
::
current
()
{
inline
CompilerThread
*
CompilerThread
::
current
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录