Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
ca1cddf2
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看板
提交
ca1cddf2
编写于
12月 11, 2008
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6765745: par compact - allow young gen spaces to be split
Reviewed-by: jmasa
上级
aefd5725
变更
2
展开全部
显示空白变更内容
内联
并排
Showing
2 changed file
with
517 addition
and
163 deletion
+517
-163
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
.../gc_implementation/parallelScavenge/psParallelCompact.cpp
+380
-158
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
.../gc_implementation/parallelScavenge/psParallelCompact.hpp
+137
-5
未找到文件。
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
浏览文件 @
ca1cddf2
此差异已折叠。
点击以展开。
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
浏览文件 @
ca1cddf2
...
@@ -36,6 +36,123 @@ class PreGCValues;
...
@@ -36,6 +36,123 @@ class PreGCValues;
class
MoveAndUpdateClosure
;
class
MoveAndUpdateClosure
;
class
RefProcTaskExecutor
;
class
RefProcTaskExecutor
;
// The SplitInfo class holds the information needed to 'split' a source region
// so that the live data can be copied to two destination *spaces*. Normally,
// all the live data in a region is copied to a single destination space (e.g.,
// everything live in a region in eden is copied entirely into the old gen).
// However, when the heap is nearly full, all the live data in eden may not fit
// into the old gen. Copying only some of the regions from eden to old gen
// requires finding a region that does not contain a partial object (i.e., no
// live object crosses the region boundary) somewhere near the last object that
// does fit into the old gen. Since it's not always possible to find such a
// region, splitting is necessary for predictable behavior.
//
// A region is always split at the end of the partial object. This avoids
// additional tests when calculating the new location of a pointer, which is a
// very hot code path. The partial object and everything to its left will be
// copied to another space (call it dest_space_1). The live data to the right
// of the partial object will be copied either within the space itself, or to a
// different destination space (distinct from dest_space_1).
//
// Split points are identified during the summary phase, when region
// destinations are computed: data about the split, including the
// partial_object_size, is recorded in a SplitInfo record and the
// partial_object_size field in the summary data is set to zero. The zeroing is
// possible (and necessary) since the partial object will move to a different
// destination space than anything to its right, thus the partial object should
// not affect the locations of any objects to its right.
//
// The recorded data is used during the compaction phase, but only rarely: when
// the partial object on the split region will be copied across a destination
// region boundary. This test is made once each time a region is filled, and is
// a simple address comparison, so the overhead is negligible (see
// PSParallelCompact::first_src_addr()).
//
// Notes:
//
// Only regions with partial objects are split; a region without a partial
// object does not need any extra bookkeeping.
//
// At most one region is split per space, so the amount of data required is
// constant.
//
// A region is split only when the destination space would overflow. Once that
// happens, the destination space is abandoned and no other data (even from
// other source spaces) is targeted to that destination space. Abandoning the
// destination space may leave a somewhat large unused area at the end, if a
// large object caused the overflow.
//
// Future work:
//
// More bookkeeping would be required to continue to use the destination space.
// The most general solution would allow data from regions in two different
// source spaces to be "joined" in a single destination region. At the very
// least, additional code would be required in next_src_region() to detect the
// join and skip to an out-of-order source region. If the join region was also
// the last destination region to which a split region was copied (the most
// likely case), then additional work would be needed to get fill_region() to
// stop iteration and switch to a new source region at the right point. Basic
// idea would be to use a fake value for the top of the source space. It is
// doable, if a bit tricky.
//
// A simpler (but less general) solution would fill the remainder of the
// destination region with a dummy object and continue filling the next
// destination region.
class
SplitInfo
{
public:
// Return true if this split info is valid (i.e., if a split has been
// recorded). The very first region cannot have a partial object and thus is
// never split, so 0 is the 'invalid' value.
bool
is_valid
()
const
{
return
_src_region_idx
>
0
;
}
// Return true if this split holds data for the specified source region.
inline
bool
is_split
(
size_t
source_region
)
const
;
// The index of the split region, the size of the partial object on that
// region and the destination of the partial object.
size_t
src_region_idx
()
const
{
return
_src_region_idx
;
}
size_t
partial_obj_size
()
const
{
return
_partial_obj_size
;
}
HeapWord
*
destination
()
const
{
return
_destination
;
}
// The destination count of the partial object referenced by this split
// (either 1 or 2). This must be added to the destination count of the
// remainder of the source region.
unsigned
int
destination_count
()
const
{
return
_destination_count
;
}
// If a word within the partial object will be written to the first word of a
// destination region, this is the address of the destination region;
// otherwise this is NULL.
HeapWord
*
dest_region_addr
()
const
{
return
_dest_region_addr
;
}
// If a word within the partial object will be written to the first word of a
// destination region, this is the address of that word within the partial
// object; otherwise this is NULL.
HeapWord
*
first_src_addr
()
const
{
return
_first_src_addr
;
}
// Record the data necessary to split the region src_region_idx.
void
record
(
size_t
src_region_idx
,
size_t
partial_obj_size
,
HeapWord
*
destination
);
void
clear
();
DEBUG_ONLY
(
void
verify_clear
();)
private:
size_t
_src_region_idx
;
size_t
_partial_obj_size
;
HeapWord
*
_destination
;
unsigned
int
_destination_count
;
HeapWord
*
_dest_region_addr
;
HeapWord
*
_first_src_addr
;
};
inline
bool
SplitInfo
::
is_split
(
size_t
region_idx
)
const
{
return
_src_region_idx
==
region_idx
&&
is_valid
();
}
class
SpaceInfo
class
SpaceInfo
{
{
public:
public:
...
@@ -58,18 +175,23 @@ class SpaceInfo
...
@@ -58,18 +175,23 @@ class SpaceInfo
// is no start array.
// is no start array.
ObjectStartArray
*
start_array
()
const
{
return
_start_array
;
}
ObjectStartArray
*
start_array
()
const
{
return
_start_array
;
}
SplitInfo
&
split_info
()
{
return
_split_info
;
}
void
set_space
(
MutableSpace
*
s
)
{
_space
=
s
;
}
void
set_space
(
MutableSpace
*
s
)
{
_space
=
s
;
}
void
set_new_top
(
HeapWord
*
addr
)
{
_new_top
=
addr
;
}
void
set_new_top
(
HeapWord
*
addr
)
{
_new_top
=
addr
;
}
void
set_min_dense_prefix
(
HeapWord
*
addr
)
{
_min_dense_prefix
=
addr
;
}
void
set_min_dense_prefix
(
HeapWord
*
addr
)
{
_min_dense_prefix
=
addr
;
}
void
set_dense_prefix
(
HeapWord
*
addr
)
{
_dense_prefix
=
addr
;
}
void
set_dense_prefix
(
HeapWord
*
addr
)
{
_dense_prefix
=
addr
;
}
void
set_start_array
(
ObjectStartArray
*
s
)
{
_start_array
=
s
;
}
void
set_start_array
(
ObjectStartArray
*
s
)
{
_start_array
=
s
;
}
void
publish_new_top
()
const
{
_space
->
set_top
(
_new_top
);
}
private:
private:
MutableSpace
*
_space
;
MutableSpace
*
_space
;
HeapWord
*
_new_top
;
HeapWord
*
_new_top
;
HeapWord
*
_min_dense_prefix
;
HeapWord
*
_min_dense_prefix
;
HeapWord
*
_dense_prefix
;
HeapWord
*
_dense_prefix
;
ObjectStartArray
*
_start_array
;
ObjectStartArray
*
_start_array
;
SplitInfo
_split_info
;
};
};
class
ParallelCompactData
class
ParallelCompactData
...
@@ -230,9 +352,14 @@ public:
...
@@ -230,9 +352,14 @@ public:
// must be region-aligned; end need not be.
// must be region-aligned; end need not be.
void
summarize_dense_prefix
(
HeapWord
*
beg
,
HeapWord
*
end
);
void
summarize_dense_prefix
(
HeapWord
*
beg
,
HeapWord
*
end
);
bool
summarize
(
HeapWord
*
target_beg
,
HeapWord
*
target_end
,
HeapWord
*
summarize_split_space
(
size_t
src_region
,
SplitInfo
&
split_info
,
HeapWord
*
destination
,
HeapWord
*
target_end
,
HeapWord
**
target_next
);
bool
summarize
(
SplitInfo
&
split_info
,
HeapWord
*
source_beg
,
HeapWord
*
source_end
,
HeapWord
*
source_beg
,
HeapWord
*
source_end
,
HeapWord
**
target_next
,
HeapWord
**
source_next
=
0
);
HeapWord
**
source_next
,
HeapWord
*
target_beg
,
HeapWord
*
target_end
,
HeapWord
**
target_next
);
void
clear
();
void
clear
();
void
clear_range
(
size_t
beg_region
,
size_t
end_region
);
void
clear_range
(
size_t
beg_region
,
size_t
end_region
);
...
@@ -838,13 +965,13 @@ class PSParallelCompact : AllStatic {
...
@@ -838,13 +965,13 @@ class PSParallelCompact : AllStatic {
// non-empty.
// non-empty.
static
void
fill_dense_prefix_end
(
SpaceId
id
);
static
void
fill_dense_prefix_end
(
SpaceId
id
);
// Clear the summary data source_region field for the specified addresses.
static
void
clear_source_region
(
HeapWord
*
beg_addr
,
HeapWord
*
end_addr
);
static
void
summarize_spaces_quick
();
static
void
summarize_spaces_quick
();
static
void
summarize_space
(
SpaceId
id
,
bool
maximum_compaction
);
static
void
summarize_space
(
SpaceId
id
,
bool
maximum_compaction
);
static
void
summary_phase
(
ParCompactionManager
*
cm
,
bool
maximum_compaction
);
static
void
summary_phase
(
ParCompactionManager
*
cm
,
bool
maximum_compaction
);
// The space that is compacted after space_id.
static
SpaceId
next_compaction_space_id
(
SpaceId
space_id
);
// Adjust addresses in roots. Does not adjust addresses in heap.
// Adjust addresses in roots. Does not adjust addresses in heap.
static
void
adjust_roots
();
static
void
adjust_roots
();
...
@@ -999,6 +1126,7 @@ class PSParallelCompact : AllStatic {
...
@@ -999,6 +1126,7 @@ class PSParallelCompact : AllStatic {
// Return the address of the word to be copied to dest_addr, which must be
// Return the address of the word to be copied to dest_addr, which must be
// aligned to a region boundary.
// aligned to a region boundary.
static
HeapWord
*
first_src_addr
(
HeapWord
*
const
dest_addr
,
static
HeapWord
*
first_src_addr
(
HeapWord
*
const
dest_addr
,
SpaceId
src_space_id
,
size_t
src_region_idx
);
size_t
src_region_idx
);
// Determine the next source region, set closure.source() to the start of the
// Determine the next source region, set closure.source() to the start of the
...
@@ -1081,6 +1209,10 @@ class PSParallelCompact : AllStatic {
...
@@ -1081,6 +1209,10 @@ class PSParallelCompact : AllStatic {
const
SpaceId
id
,
const
SpaceId
id
,
const
bool
maximum_compaction
,
const
bool
maximum_compaction
,
HeapWord
*
const
addr
);
HeapWord
*
const
addr
);
static
void
summary_phase_msg
(
SpaceId
dst_space_id
,
HeapWord
*
dst_beg
,
HeapWord
*
dst_end
,
SpaceId
src_space_id
,
HeapWord
*
src_beg
,
HeapWord
*
src_end
);
#endif // #ifndef PRODUCT
#endif // #ifndef PRODUCT
#ifdef ASSERT
#ifdef ASSERT
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录