Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
c993be01
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看板
提交
c993be01
编写于
4年前
作者:
A
apetushkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8220293: Deadlock in JFR string pool
Reviewed-by: rehn, egahlin
上级
f1429fec
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
101 addition
and
84 deletion
+101
-84
src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
...share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
+3
-1
src/share/vm/jfr/recorder/storage/jfrBuffer.cpp
src/share/vm/jfr/recorder/storage/jfrBuffer.cpp
+9
-6
src/share/vm/jfr/recorder/storage/jfrBuffer.hpp
src/share/vm/jfr/recorder/storage/jfrBuffer.hpp
+2
-3
src/share/vm/jfr/recorder/storage/jfrMemorySpace.inline.hpp
src/share/vm/jfr/recorder/storage/jfrMemorySpace.inline.hpp
+11
-11
src/share/vm/jfr/recorder/storage/jfrStorage.cpp
src/share/vm/jfr/recorder/storage/jfrStorage.cpp
+5
-4
src/share/vm/jfr/recorder/storage/jfrStorageUtils.hpp
src/share/vm/jfr/recorder/storage/jfrStorageUtils.hpp
+9
-1
src/share/vm/jfr/recorder/storage/jfrStorageUtils.inline.hpp
src/share/vm/jfr/recorder/storage/jfrStorageUtils.inline.hpp
+23
-0
src/share/vm/jfr/recorder/stringpool/jfrStringPool.cpp
src/share/vm/jfr/recorder/stringpool/jfrStringPool.cpp
+36
-53
src/share/vm/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp
src/share/vm/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp
+3
-5
未找到文件。
src/share/vm/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
浏览文件 @
c993be01
/*
* Copyright (c) 2016, 201
8
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 201
9
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -135,6 +135,8 @@ void JfrCheckpointManager::register_service_thread(const Thread* thread) {
void
JfrCheckpointManager
::
register_full
(
BufferPtr
t
,
Thread
*
thread
)
{
// nothing here at the moment
assert
(
t
!=
NULL
,
"invariant"
);
assert
(
t
->
acquired_by
(
thread
),
"invariant"
);
assert
(
t
->
retired
(),
"invariant"
);
}
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrBuffer.cpp
浏览文件 @
c993be01
/*
* Copyright (c) 2011, 201
8
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 201
9
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -137,6 +137,14 @@ void JfrBuffer::clear_identity() {
_identity
=
NULL
;
}
bool
JfrBuffer
::
acquired_by
(
const
void
*
id
)
const
{
return
identity
()
==
id
;
}
bool
JfrBuffer
::
acquired_by_self
()
const
{
return
acquired_by
(
Thread
::
current
());
}
#ifdef ASSERT
static
bool
validate_to
(
const
JfrBuffer
*
const
to
,
size_t
size
)
{
assert
(
to
!=
NULL
,
"invariant"
);
...
...
@@ -154,10 +162,6 @@ static bool validate_this(const JfrBuffer* const t, size_t size) {
assert
(
t
->
top
()
+
size
<=
t
->
pos
(),
"invariant"
);
return
true
;
}
bool
JfrBuffer
::
acquired_by_self
()
const
{
return
identity
()
==
Thread
::
current
();
}
#endif // ASSERT
void
JfrBuffer
::
move
(
JfrBuffer
*
const
to
,
size_t
size
)
{
...
...
@@ -184,7 +188,6 @@ void JfrBuffer::concurrent_move_and_reinitialize(JfrBuffer* const to, size_t siz
set_concurrent_top
(
start
());
}
// flags
enum
FLAG
{
RETIRED
=
1
,
TRANSIENT
=
2
,
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrBuffer.hpp
浏览文件 @
c993be01
...
...
@@ -57,7 +57,6 @@ class JfrBuffer {
u4
_size
;
const
u1
*
stable_top
()
const
;
void
clear_flags
();
public:
JfrBuffer
();
...
...
@@ -150,6 +149,8 @@ class JfrBuffer {
void
acquire
(
const
void
*
id
);
bool
try_acquire
(
const
void
*
id
);
bool
acquired_by
(
const
void
*
id
)
const
;
bool
acquired_by_self
()
const
;
void
release
();
void
move
(
JfrBuffer
*
const
to
,
size_t
size
);
...
...
@@ -166,8 +167,6 @@ class JfrBuffer {
bool
retired
()
const
;
void
set_retired
();
void
clear_retired
();
debug_only
(
bool
acquired_by_self
()
const
;)
};
class
JfrAgeNode
:
public
JfrBuffer
{
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrMemorySpace.inline.hpp
浏览文件 @
c993be01
...
...
@@ -346,19 +346,19 @@ inline void process_free_list(Processor& processor, Mspace* mspace, jfr_iter_dir
template
<
typename
Mspace
>
inline
bool
ReleaseOp
<
Mspace
>::
process
(
typename
Mspace
::
Type
*
t
)
{
assert
(
t
!=
NULL
,
"invariant"
);
if
(
t
->
retired
()
||
t
->
try_acquire
(
_thread
))
{
if
(
t
->
transient
())
{
if
(
_release_full
)
{
mspace_release_full_critical
(
t
,
_mspace
);
}
else
{
mspace_release_free_critical
(
t
,
_mspace
);
}
return
true
;
// assumes some means of exclusive access to t
if
(
t
->
transient
())
{
if
(
_release_full
)
{
mspace_release_full_critical
(
t
,
_mspace
);
}
else
{
mspace_release_free_critical
(
t
,
_mspace
);
}
t
->
reinitialize
();
assert
(
t
->
empty
(),
"invariant"
);
t
->
release
();
// publish
return
true
;
}
t
->
reinitialize
();
assert
(
t
->
empty
(),
"invariant"
);
assert
(
!
t
->
retired
(),
"invariant"
);
t
->
release
();
// publish
return
true
;
}
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrStorage.cpp
浏览文件 @
c993be01
...
...
@@ -340,9 +340,9 @@ static bool full_buffer_registration(BufferPtr buffer, JfrStorageAgeMspace* age_
void
JfrStorage
::
register_full
(
BufferPtr
buffer
,
Thread
*
thread
)
{
assert
(
buffer
!=
NULL
,
"invariant"
);
assert
(
buffer
->
retired
(),
"invariant"
);
assert
(
buffer
->
acquired_by
(
thread
),
"invariant"
);
if
(
!
full_buffer_registration
(
buffer
,
_age_mspace
,
control
(),
thread
))
{
handle_registration_failure
(
buffer
);
buffer
->
release
();
}
if
(
control
().
should_post_buffer_full_message
())
{
_post_box
.
post
(
MSG_FULLBUFFER
);
...
...
@@ -377,8 +377,8 @@ void JfrStorage::release(BufferPtr buffer, Thread* thread) {
}
}
assert
(
buffer
->
empty
(),
"invariant"
);
assert
(
buffer
->
identity
()
!=
NULL
,
"invariant"
);
control
().
increment_dead
();
buffer
->
release
();
buffer
->
set_retired
();
}
...
...
@@ -733,13 +733,14 @@ public:
Scavenger
(
JfrStorageControl
&
control
,
Mspace
*
mspace
)
:
_control
(
control
),
_mspace
(
mspace
),
_count
(
0
),
_amount
(
0
)
{}
bool
process
(
Type
*
t
)
{
if
(
t
->
retired
())
{
assert
(
t
->
identity
()
!=
NULL
,
"invariant"
);
assert
(
t
->
empty
(),
"invariant"
);
assert
(
!
t
->
transient
(),
"invariant"
);
assert
(
!
t
->
lease
(),
"invariant"
);
assert
(
t
->
empty
(),
"invariant"
);
assert
(
t
->
identity
()
==
NULL
,
"invariant"
);
++
_count
;
_amount
+=
t
->
total_size
();
t
->
clear_retired
();
t
->
release
();
_control
.
decrement_dead
();
mspace_release_full_critical
(
t
,
_mspace
);
}
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrStorageUtils.hpp
浏览文件 @
c993be01
...
...
@@ -92,7 +92,6 @@ class ConcurrentWriteOpExcludeRetired : private ConcurrentWriteOp<Operation> {
size_t
processed
()
const
{
return
ConcurrentWriteOp
<
Operation
>::
processed
();
}
};
template
<
typename
Operation
>
class
MutexedWriteOp
{
private:
...
...
@@ -104,6 +103,15 @@ class MutexedWriteOp {
size_t
processed
()
const
{
return
_operation
.
processed
();
}
};
template
<
typename
Operation
>
class
ExclusiveOp
:
private
MutexedWriteOp
<
Operation
>
{
public:
typedef
typename
Operation
::
Type
Type
;
ExclusiveOp
(
Operation
&
operation
)
:
MutexedWriteOp
<
Operation
>
(
operation
)
{}
bool
process
(
Type
*
t
);
size_t
processed
()
const
{
return
MutexedWriteOp
<
Operation
>::
processed
();
}
};
enum
jfr_operation_mode
{
mutexed
=
1
,
concurrent
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/storage/jfrStorageUtils.inline.hpp
浏览文件 @
c993be01
...
...
@@ -26,6 +26,7 @@
#define SHARE_VM_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_INLINE_HPP
#include "jfr/recorder/storage/jfrStorageUtils.hpp"
#include "runtime/thread.inline.hpp"
template
<
typename
T
>
inline
bool
UnBufferedWriteToChunk
<
T
>::
write
(
T
*
t
,
const
u1
*
data
,
size_t
size
)
{
...
...
@@ -75,6 +76,28 @@ inline bool MutexedWriteOp<Operation>::process(typename Operation::Type* t) {
return
result
;
}
template
<
typename
Type
>
static
void
retired_sensitive_acquire
(
Type
*
t
)
{
assert
(
t
!=
NULL
,
"invariant"
);
if
(
t
->
retired
())
{
return
;
}
Thread
*
const
thread
=
Thread
::
current
();
while
(
!
t
->
try_acquire
(
thread
))
{
if
(
t
->
retired
())
{
return
;
}
}
}
template
<
typename
Operation
>
inline
bool
ExclusiveOp
<
Operation
>::
process
(
typename
Operation
::
Type
*
t
)
{
retired_sensitive_acquire
(
t
);
assert
(
t
->
acquired_by_self
()
||
t
->
retired
(),
"invariant"
);
// User is required to ensure proper release of the acquisition
return
MutexedWriteOp
<
Operation
>::
process
(
t
);
}
template
<
typename
Operation
>
inline
bool
DiscardOp
<
Operation
>::
process
(
typename
Operation
::
Type
*
t
)
{
assert
(
t
!=
NULL
,
"invariant"
);
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/stringpool/jfrStringPool.cpp
浏览文件 @
c993be01
/*
* Copyright (c) 2016, 201
8
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 201
9
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -139,93 +139,76 @@ bool JfrStringPool::add(bool epoch, jlong id, jstring string, JavaThread* jt) {
return
current_epoch
;
}
class
StringPoolWriteOp
{
template
<
template
<
typename
>
class
Operation
>
class
StringPoolOp
{
public:
typedef
JfrStringPoolBuffer
Type
;
private:
UnBufferedWriteToChunk
<
Type
>
_writer
;
Operation
<
Type
>
_op
;
Thread
*
_thread
;
size_t
_strings_processed
;
public:
StringPoolWriteOp
(
JfrChunkWriter
&
writer
,
Thread
*
thread
)
:
_writer
(
writer
),
_thread
(
thread
),
_strings_processed
(
0
)
{}
StringPoolOp
()
:
_op
(),
_thread
(
Thread
::
current
()),
_strings_processed
(
0
)
{}
StringPoolOp
(
JfrChunkWriter
&
writer
,
Thread
*
thread
)
:
_op
(
writer
),
_thread
(
thread
),
_strings_processed
(
0
)
{}
bool
write
(
Type
*
buffer
,
const
u1
*
data
,
size_t
size
)
{
buffer
->
acquire
(
_thread
);
// blocking
assert
(
buffer
->
acquired_by
(
_thread
)
||
buffer
->
retired
(),
"invariant"
);
const
uint64_t
nof_strings_used
=
buffer
->
string_count
();
assert
(
nof_strings_used
>
0
,
"invariant"
);
buffer
->
set_string_top
(
buffer
->
string_top
()
+
nof_strings_used
);
// "size processed" for string pool buffers is the number of processed string elements
_strings_processed
+=
nof_strings_used
;
const
bool
ret
=
_writer
.
write
(
buffer
,
data
,
size
);
buffer
->
release
();
return
ret
;
return
_op
.
write
(
buffer
,
data
,
size
);
}
size_t
processed
()
{
return
_strings_processed
;
}
};
typedef
StringPoolWriteOp
WriteOperation
;
typedef
ConcurrentWriteOp
<
WriteOperation
>
ConcurrentWriteOperation
;
size_t
JfrStringPool
::
write
()
{
Thread
*
const
thread
=
Thread
::
current
();
WriteOperation
wo
(
_chunkwriter
,
thread
);
ConcurrentWriteOperation
cwo
(
wo
);
assert
(
_free_list_mspace
->
is_full_empty
(),
"invariant"
);
process_free_list
(
cwo
,
_free_list_mspace
);
return
wo
.
processed
();
}
template
<
typename
Type
>
class
StringPoolDiscarderStub
{
public:
bool
write
(
Type
*
buffer
,
const
u1
*
data
,
size_t
size
)
{
// stub only, discard happens at higher level
return
true
;
}
};
typedef
MutexedWriteOp
<
WriteOperation
>
MutexedWriteOperation
;
typedef
StringPoolOp
<
UnBufferedWriteToChunk
>
WriteOperation
;
typedef
StringPoolOp
<
StringPoolDiscarderStub
>
DiscardOperation
;
typedef
ExclusiveOp
<
WriteOperation
>
ExclusiveWriteOperation
;
typedef
ExclusiveOp
<
DiscardOperation
>
ExclusiveDiscardOperation
;
typedef
ReleaseOp
<
JfrStringPoolMspace
>
StringPoolReleaseOperation
;
typedef
CompositeOperation
<
MutexedWriteOperation
,
StringPoolReleaseOperation
>
StringPoolWriteOperation
;
typedef
CompositeOperation
<
ExclusiveWriteOperation
,
StringPoolReleaseOperation
>
StringPoolWriteOperation
;
typedef
CompositeOperation
<
ExclusiveDiscardOperation
,
StringPoolReleaseOperation
>
StringPoolDiscardOperation
;
size_t
JfrStringPool
::
write_at_safepoint
()
{
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"invariant"
);
size_t
JfrStringPool
::
write
()
{
Thread
*
const
thread
=
Thread
::
current
();
WriteOperation
wo
(
_chunkwriter
,
thread
);
MutexedWriteOperation
m
wo
(
wo
);
ExclusiveWriteOperation
e
wo
(
wo
);
StringPoolReleaseOperation
spro
(
_free_list_mspace
,
thread
,
false
);
StringPoolWriteOperation
spwo
(
&
m
wo
,
&
spro
);
StringPoolWriteOperation
spwo
(
&
e
wo
,
&
spro
);
assert
(
_free_list_mspace
->
is_full_empty
(),
"invariant"
);
process_free_list
(
spwo
,
_free_list_mspace
);
return
wo
.
processed
();
}
class
StringPoolBufferDiscarder
{
private:
Thread
*
_thread
;
size_t
_processed
;
public:
typedef
JfrStringPoolBuffer
Type
;
StringPoolBufferDiscarder
()
:
_thread
(
Thread
::
current
()),
_processed
(
0
)
{}
bool
process
(
Type
*
buffer
)
{
buffer
->
acquire
(
_thread
);
// serialized access
const
u1
*
const
current_top
=
buffer
->
top
();
const
size_t
unflushed_size
=
buffer
->
pos
()
-
current_top
;
if
(
unflushed_size
==
0
)
{
assert
(
buffer
->
string_count
()
==
0
,
"invariant"
);
buffer
->
release
();
return
true
;
}
buffer
->
set_top
(
current_top
+
unflushed_size
);
const
uint64_t
nof_strings_used
=
buffer
->
string_count
();
buffer
->
set_string_top
(
buffer
->
string_top
()
+
nof_strings_used
);
// "size processed" for string pool buffers is the number of string elements
_processed
+=
(
size_t
)
nof_strings_used
;
buffer
->
release
();
return
true
;
}
size_t
processed
()
const
{
return
_processed
;
}
};
size_t
JfrStringPool
::
write_at_safepoint
()
{
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"invariant"
);
return
write
();
}
size_t
JfrStringPool
::
clear
()
{
StringPoolBufferDiscarder
discard_operation
;
DiscardOperation
discard_operation
;
ExclusiveDiscardOperation
edo
(
discard_operation
);
StringPoolReleaseOperation
spro
(
_free_list_mspace
,
Thread
::
current
(),
false
);
StringPoolDiscardOperation
spdo
(
&
edo
,
&
spro
);
assert
(
_free_list_mspace
->
is_full_empty
(),
"invariant"
);
process_free_list
(
discard_operation
,
_free_list_mspace
);
process_free_list
(
spdo
,
_free_list_mspace
);
return
discard_operation
.
processed
();
}
void
JfrStringPool
::
register_full
(
BufferPtr
t
,
Thread
*
thread
)
{
// nothing here at the moment
assert
(
t
!=
NULL
,
"invariant"
);
assert
(
t
->
acquired_by
(
thread
),
"invariant"
);
assert
(
t
->
retired
(),
"invariant"
);
}
...
...
This diff is collapsed.
Click to expand it.
src/share/vm/jfr/recorder/stringpool/jfrStringPoolBuffer.cpp
浏览文件 @
c993be01
/*
* Copyright (c) 2016, 201
8
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 201
9
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -29,11 +29,9 @@ JfrStringPoolBuffer::JfrStringPoolBuffer() : JfrBuffer(), _string_count_pos(0),
void
JfrStringPoolBuffer
::
reinitialize
()
{
assert
(
acquired_by_self
()
||
retired
(),
"invariant"
);
concurrent_top
();
set_pos
((
start
()));
set_string_pos
(
0
);
set_string_top
(
0
);
set_concurrent_top
(
start
()
);
JfrBuffer
::
reinitialize
(
);
}
uint64_t
JfrStringPoolBuffer
::
string_pos
()
const
{
...
...
@@ -57,7 +55,7 @@ void JfrStringPoolBuffer::set_string_pos(uint64_t value) {
}
void
JfrStringPoolBuffer
::
increment
(
uint64_t
value
)
{
assert
(
acquired_by_self
()
||
retired
()
,
"invariant"
);
assert
(
acquired_by_self
(),
"invariant"
);
++
_string_count_pos
;
}
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
新手
引导
客服
返回
顶部