Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
78c00a06
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看板
提交
78c00a06
编写于
9月 26, 2013
作者:
T
tschatzl
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
703693d2
259f62c7
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
534 addition
and
229 deletion
+534
-229
make/excludeSrc.make
make/excludeSrc.make
+1
-1
src/share/vm/classfile/symbolTable.cpp
src/share/vm/classfile/symbolTable.cpp
+2
-2
src/share/vm/gc_implementation/g1/g1BiasedArray.cpp
src/share/vm/gc_implementation/g1/g1BiasedArray.cpp
+141
-0
src/share/vm/gc_implementation/g1/g1BiasedArray.hpp
src/share/vm/gc_implementation/g1/g1BiasedArray.hpp
+181
-0
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+4
-2
src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
+19
-30
src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
+24
-35
src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
+5
-17
src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
+10
-2
src/share/vm/memory/gcLocker.cpp
src/share/vm/memory/gcLocker.cpp
+1
-1
src/share/vm/memory/gcLocker.hpp
src/share/vm/memory/gcLocker.hpp
+1
-1
src/share/vm/memory/metaspace.cpp
src/share/vm/memory/metaspace.cpp
+119
-134
src/share/vm/memory/metaspace.hpp
src/share/vm/memory/metaspace.hpp
+20
-2
src/share/vm/prims/jni.cpp
src/share/vm/prims/jni.cpp
+6
-2
未找到文件。
make/excludeSrc.make
浏览文件 @
78c00a06
...
...
@@ -88,7 +88,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp
\
g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp
\
g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp
\
heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp
\
g1BiasedArray.cpp
heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp
\
ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp
\
adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp
\
cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp
\
...
...
src/share/vm/classfile/symbolTable.cpp
浏览文件 @
78c00a06
...
...
@@ -341,7 +341,7 @@ Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
Symbol
*
SymbolTable
::
basic_add
(
int
index_arg
,
u1
*
name
,
int
len
,
unsigned
int
hashValue_arg
,
bool
c_heap
,
TRAPS
)
{
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
()
,
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
),
"proposed name of symbol must be stable"
);
// Don't allow symbols to be created which cannot fit in a Symbol*.
...
...
@@ -685,7 +685,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name,
if
(
found_string
!=
NULL
)
return
found_string
;
debug_only
(
StableMemoryChecker
smc
(
name
,
len
*
sizeof
(
name
[
0
])));
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
()
,
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
),
"proposed name of symbol must be stable"
);
Handle
string
;
...
...
src/share/vm/gc_implementation/g1/g1BiasedArray.cpp
0 → 100644
浏览文件 @
78c00a06
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "gc_implementation/g1/g1BiasedArray.hpp"
#ifndef PRODUCT
void
G1BiasedMappedArrayBase
::
verify_index
(
idx_t
index
)
const
{
guarantee
(
_base
!=
NULL
,
"Array not initialized"
);
guarantee
(
index
<
length
(),
err_msg
(
"Index out of bounds index: "
SIZE_FORMAT
" length: "
SIZE_FORMAT
,
index
,
length
()));
}
void
G1BiasedMappedArrayBase
::
verify_biased_index
(
idx_t
biased_index
)
const
{
guarantee
(
_biased_base
!=
NULL
,
"Array not initialized"
);
guarantee
(
biased_index
>=
bias
()
&&
biased_index
<
(
bias
()
+
length
()),
err_msg
(
"Biased index out of bounds, index: "
SIZE_FORMAT
" bias: "
SIZE_FORMAT
" length: "
SIZE_FORMAT
,
biased_index
,
bias
(),
length
()));
}
void
G1BiasedMappedArrayBase
::
verify_biased_index_inclusive_end
(
idx_t
biased_index
)
const
{
guarantee
(
_biased_base
!=
NULL
,
"Array not initialized"
);
guarantee
(
biased_index
>=
bias
()
&&
biased_index
<=
(
bias
()
+
length
()),
err_msg
(
"Biased index out of inclusive bounds, index: "
SIZE_FORMAT
" bias: "
SIZE_FORMAT
" length: "
SIZE_FORMAT
,
biased_index
,
bias
(),
length
()));
}
class
TestMappedArray
:
public
G1BiasedMappedArray
<
int
>
{
protected:
virtual
int
default_value
()
const
{
return
0xBAADBABE
;
}
public:
static
void
test_biasedarray
()
{
const
size_t
REGION_SIZE_IN_WORDS
=
512
;
const
size_t
NUM_REGIONS
=
20
;
HeapWord
*
fake_heap
=
(
HeapWord
*
)
LP64_ONLY
(
0xBAAA00000
)
NOT_LP64
(
0xBA000000
);
// Any value that is non-zero
TestMappedArray
array
;
array
.
initialize
(
fake_heap
,
fake_heap
+
REGION_SIZE_IN_WORDS
*
NUM_REGIONS
,
REGION_SIZE_IN_WORDS
*
HeapWordSize
);
// Check address calculation (bounds)
assert
(
array
.
bottom_address_mapped
()
==
fake_heap
,
err_msg
(
"bottom mapped address should be "
PTR_FORMAT
", but is "
PTR_FORMAT
,
fake_heap
,
array
.
bottom_address_mapped
()));
assert
(
array
.
end_address_mapped
()
==
(
fake_heap
+
REGION_SIZE_IN_WORDS
*
NUM_REGIONS
),
"must be"
);
int
*
bottom
=
array
.
address_mapped_to
(
fake_heap
);
assert
((
void
*
)
bottom
==
(
void
*
)
array
.
base
(),
"must be"
);
int
*
end
=
array
.
address_mapped_to
(
fake_heap
+
REGION_SIZE_IN_WORDS
*
NUM_REGIONS
);
assert
((
void
*
)
end
==
(
void
*
)(
array
.
base
()
+
array
.
length
()),
"must be"
);
// The entire array should contain default value elements
for
(
int
*
current
=
bottom
;
current
<
end
;
current
++
)
{
assert
(
*
current
==
array
.
default_value
(),
"must be"
);
}
// Test setting values in the table
HeapWord
*
region_start_address
=
fake_heap
+
REGION_SIZE_IN_WORDS
*
(
NUM_REGIONS
/
2
);
HeapWord
*
region_end_address
=
fake_heap
+
(
REGION_SIZE_IN_WORDS
*
(
NUM_REGIONS
/
2
)
+
REGION_SIZE_IN_WORDS
-
1
);
// Set/get by address tests: invert some value; first retrieve one
int
actual_value
=
array
.
get_by_index
(
NUM_REGIONS
/
2
);
array
.
set_by_index
(
NUM_REGIONS
/
2
,
~
actual_value
);
// Get the same value by address, should correspond to the start of the "region"
int
value
=
array
.
get_by_address
(
region_start_address
);
assert
(
value
==
~
actual_value
,
"must be"
);
// Get the same value by address, at one HeapWord before the start
value
=
array
.
get_by_address
(
region_start_address
-
1
);
assert
(
value
==
array
.
default_value
(),
"must be"
);
// Get the same value by address, at the end of the "region"
value
=
array
.
get_by_address
(
region_end_address
);
assert
(
value
==
~
actual_value
,
"must be"
);
// Make sure the next value maps to another index
value
=
array
.
get_by_address
(
region_end_address
+
1
);
assert
(
value
==
array
.
default_value
(),
"must be"
);
// Reset the value in the array
array
.
set_by_address
(
region_start_address
+
(
region_end_address
-
region_start_address
)
/
2
,
actual_value
);
// The entire array should have the default value again
for
(
int
*
current
=
bottom
;
current
<
end
;
current
++
)
{
assert
(
*
current
==
array
.
default_value
(),
"must be"
);
}
// Set/get by index tests: invert some value
idx_t
index
=
NUM_REGIONS
/
2
;
actual_value
=
array
.
get_by_index
(
index
);
array
.
set_by_index
(
index
,
~
actual_value
);
value
=
array
.
get_by_index
(
index
);
assert
(
value
==
~
actual_value
,
"must be"
);
value
=
array
.
get_by_index
(
index
-
1
);
assert
(
value
==
array
.
default_value
(),
"must be"
);
value
=
array
.
get_by_index
(
index
+
1
);
assert
(
value
==
array
.
default_value
(),
"must be"
);
array
.
set_by_index
(
0
,
0
);
value
=
array
.
get_by_index
(
0
);
assert
(
value
==
0
,
"must be"
);
array
.
set_by_index
(
array
.
length
()
-
1
,
0
);
value
=
array
.
get_by_index
(
array
.
length
()
-
1
);
assert
(
value
==
0
,
"must be"
);
array
.
set_by_index
(
index
,
0
);
// The array should have three zeros, and default values otherwise
size_t
num_zeros
=
0
;
for
(
int
*
current
=
bottom
;
current
<
end
;
current
++
)
{
assert
(
*
current
==
array
.
default_value
()
||
*
current
==
0
,
"must be"
);
if
(
*
current
==
0
)
{
num_zeros
++
;
}
}
assert
(
num_zeros
==
3
,
"must be"
);
}
};
void
TestG1BiasedArray_test
()
{
TestMappedArray
::
test_biasedarray
();
}
#endif
src/share/vm/gc_implementation/g1/g1BiasedArray.hpp
0 → 100644
浏览文件 @
78c00a06
/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP
#include "utilities/debug.hpp"
#include "memory/allocation.inline.hpp"
// Implements the common base functionality for arrays that contain provisions
// for accessing its elements using a biased index.
// The element type is defined by the instantiating the template.
class
G1BiasedMappedArrayBase
VALUE_OBJ_CLASS_SPEC
{
friend
class
VMStructs
;
public:
typedef
size_t
idx_t
;
protected:
address
_base
;
// the real base address
size_t
_length
;
// the length of the array
address
_biased_base
;
// base address biased by "bias" elements
size_t
_bias
;
// the bias, i.e. the offset biased_base is located to the right in elements
uint
_shift_by
;
// the amount of bits to shift right when mapping to an index of the array.
protected:
G1BiasedMappedArrayBase
()
:
_base
(
NULL
),
_length
(
0
),
_biased_base
(
NULL
),
_bias
(
0
),
_shift_by
(
0
)
{
}
// Allocate a new array, generic version.
static
address
create_new_base_array
(
size_t
length
,
size_t
elem_size
)
{
assert
(
length
>
0
,
"just checking"
);
assert
(
elem_size
>
0
,
"just checking"
);
return
NEW_C_HEAP_ARRAY
(
u_char
,
length
*
elem_size
,
mtGC
);
}
// Initialize the members of this class. The biased start address of this array
// is the bias (in elements) multiplied by the element size.
void
initialize_base
(
address
base
,
size_t
length
,
size_t
bias
,
size_t
elem_size
,
uint
shift_by
)
{
assert
(
base
!=
NULL
,
"just checking"
);
assert
(
length
>
0
,
"just checking"
);
assert
(
shift_by
<
sizeof
(
uintptr_t
)
*
8
,
err_msg
(
"Shifting by %zd, larger than word size?"
,
shift_by
));
_base
=
base
;
_length
=
length
;
_biased_base
=
base
-
(
bias
*
elem_size
);
_bias
=
bias
;
_shift_by
=
shift_by
;
}
// Allocate and initialize this array to cover the heap addresses in the range
// of [bottom, end).
void
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
,
size_t
target_elem_size_in_bytes
,
size_t
mapping_granularity_in_bytes
)
{
assert
(
mapping_granularity_in_bytes
>
0
,
"just checking"
);
assert
(
is_power_of_2
(
mapping_granularity_in_bytes
),
err_msg
(
"mapping granularity must be power of 2, is %zd"
,
mapping_granularity_in_bytes
));
assert
((
uintptr_t
)
bottom
%
mapping_granularity_in_bytes
==
0
,
err_msg
(
"bottom mapping area address must be a multiple of mapping granularity %zd, is "
PTR_FORMAT
,
mapping_granularity_in_bytes
,
bottom
));
assert
((
uintptr_t
)
end
%
mapping_granularity_in_bytes
==
0
,
err_msg
(
"end mapping area address must be a multiple of mapping granularity %zd, is "
PTR_FORMAT
,
mapping_granularity_in_bytes
,
end
));
size_t
num_target_elems
=
(
end
-
bottom
)
/
(
mapping_granularity_in_bytes
/
HeapWordSize
);
idx_t
bias
=
(
uintptr_t
)
bottom
/
mapping_granularity_in_bytes
;
address
base
=
create_new_base_array
(
num_target_elems
,
target_elem_size_in_bytes
);
initialize_base
(
base
,
num_target_elems
,
bias
,
target_elem_size_in_bytes
,
log2_intptr
(
mapping_granularity_in_bytes
));
}
size_t
bias
()
const
{
return
_bias
;
}
uint
shift_by
()
const
{
return
_shift_by
;
}
void
verify_index
(
idx_t
index
)
const
PRODUCT_RETURN
;
void
verify_biased_index
(
idx_t
biased_index
)
const
PRODUCT_RETURN
;
void
verify_biased_index_inclusive_end
(
idx_t
biased_index
)
const
PRODUCT_RETURN
;
public:
// Return the length of the array in elements.
size_t
length
()
const
{
return
_length
;
}
};
// Array that provides biased access and mapping from (valid) addresses in the
// heap into this array.
template
<
class
T
>
class
G1BiasedMappedArray
:
public
G1BiasedMappedArrayBase
{
public:
typedef
G1BiasedMappedArrayBase
::
idx_t
idx_t
;
T
*
base
()
const
{
return
(
T
*
)
G1BiasedMappedArrayBase
::
_base
;
}
// Return the element of the given array at the given index. Assume
// the index is valid. This is a convenience method that does sanity
// checking on the index.
T
get_by_index
(
idx_t
index
)
const
{
verify_index
(
index
);
return
this
->
base
()[
index
];
}
// Set the element of the given array at the given index to the
// given value. Assume the index is valid. This is a convenience
// method that does sanity checking on the index.
void
set_by_index
(
idx_t
index
,
T
value
)
{
verify_index
(
index
);
this
->
base
()[
index
]
=
value
;
}
// The raw biased base pointer.
T
*
biased_base
()
const
{
return
(
T
*
)
G1BiasedMappedArrayBase
::
_biased_base
;
}
// Return the element of the given array that covers the given word in the
// heap. Assumes the index is valid.
T
get_by_address
(
HeapWord
*
value
)
const
{
idx_t
biased_index
=
((
uintptr_t
)
value
)
>>
this
->
shift_by
();
this
->
verify_biased_index
(
biased_index
);
return
biased_base
()[
biased_index
];
}
// Set the value of the array entry that corresponds to the given array.
void
set_by_address
(
HeapWord
*
address
,
T
value
)
{
idx_t
biased_index
=
((
uintptr_t
)
address
)
>>
this
->
shift_by
();
this
->
verify_biased_index
(
biased_index
);
biased_base
()[
biased_index
]
=
value
;
}
protected:
// Returns the address of the element the given address maps to
T
*
address_mapped_to
(
HeapWord
*
address
)
{
idx_t
biased_index
=
((
uintptr_t
)
address
)
>>
this
->
shift_by
();
this
->
verify_biased_index_inclusive_end
(
biased_index
);
return
biased_base
()
+
biased_index
;
}
public:
// Return the smallest address (inclusive) in the heap that this array covers.
HeapWord
*
bottom_address_mapped
()
const
{
return
(
HeapWord
*
)
((
uintptr_t
)
this
->
bias
()
<<
this
->
shift_by
());
}
// Return the highest address (exclusive) in the heap that this array covers.
HeapWord
*
end_address_mapped
()
const
{
return
(
HeapWord
*
)
((
uintptr_t
)(
this
->
bias
()
+
this
->
length
())
<<
this
->
shift_by
());
}
protected:
virtual
T
default_value
()
const
=
0
;
// Set all elements of the given array to the given value.
void
clear
()
{
T
value
=
default_value
();
for
(
idx_t
i
=
0
;
i
<
length
();
i
++
)
{
set_by_index
(
i
,
value
);
}
}
public:
G1BiasedMappedArray
()
{}
// Allocate and initialize this array to cover the heap addresses in the range
// of [bottom, end).
void
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
,
size_t
mapping_granularity
)
{
G1BiasedMappedArrayBase
::
initialize
(
bottom
,
end
,
sizeof
(
T
),
mapping_granularity
);
this
->
clear
();
}
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
78c00a06
...
...
@@ -2069,8 +2069,10 @@ jint G1CollectedHeap::initialize() {
_g1_storage
.
initialize
(
g1_rs
,
0
);
_g1_committed
=
MemRegion
((
HeapWord
*
)
_g1_storage
.
low
(),
(
size_t
)
0
);
_hrs
.
initialize
((
HeapWord
*
)
_g1_reserved
.
start
(),
(
HeapWord
*
)
_g1_reserved
.
end
(),
_expansion_regions
);
(
HeapWord
*
)
_g1_reserved
.
end
());
assert
(
_hrs
.
max_length
()
==
_expansion_regions
,
err_msg
(
"max length: %u expansion regions: %u"
,
_hrs
.
max_length
(),
_expansion_regions
));
// Do later initialization work for concurrent refinement.
_cg1r
->
init
();
...
...
src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
浏览文件 @
78c00a06
...
...
@@ -71,27 +71,16 @@ uint HeapRegionSeq::find_contiguous_from(uint from, uint num) {
// Public
void
HeapRegionSeq
::
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
,
uint
max_length
)
{
void
HeapRegionSeq
::
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
)
{
assert
((
uintptr_t
)
bottom
%
HeapRegion
::
GrainBytes
==
0
,
"bottom should be heap region aligned"
);
assert
((
uintptr_t
)
end
%
HeapRegion
::
GrainBytes
==
0
,
"end should be heap region aligned"
);
_length
=
0
;
_heap_bottom
=
bottom
;
_heap_end
=
end
;
_region_shift
=
HeapRegion
::
LogOfHRGrainBytes
;
_next_search_index
=
0
;
_allocated_length
=
0
;
_max_length
=
max_length
;
_regions
=
NEW_C_HEAP_ARRAY
(
HeapRegion
*
,
max_length
,
mtGC
);
memset
(
_regions
,
0
,
(
size_t
)
max_length
*
sizeof
(
HeapRegion
*
));
_regions_biased
=
_regions
-
((
uintx
)
bottom
>>
_region_shift
);
assert
(
&
_regions
[
0
]
==
&
_regions_biased
[
addr_to_index_biased
(
bottom
)],
"bottom should be included in the region with index 0"
);
_regions
.
initialize
(
bottom
,
end
,
HeapRegion
::
GrainBytes
);
}
MemRegion
HeapRegionSeq
::
expand_by
(
HeapWord
*
old_end
,
...
...
@@ -101,15 +90,15 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
G1CollectedHeap
*
g1h
=
G1CollectedHeap
::
heap
();
HeapWord
*
next_bottom
=
old_end
;
assert
(
_heap_bottom
<=
next_bottom
,
"invariant"
);
assert
(
heap_bottom
()
<=
next_bottom
,
"invariant"
);
while
(
next_bottom
<
new_end
)
{
assert
(
next_bottom
<
_heap_end
,
"invariant"
);
assert
(
next_bottom
<
heap_end
()
,
"invariant"
);
uint
index
=
length
();
assert
(
index
<
_max_length
,
"otherwise we cannot expand further"
);
assert
(
index
<
max_length
()
,
"otherwise we cannot expand further"
);
if
(
index
==
0
)
{
// We have not allocated any regions so far
assert
(
next_bottom
==
_heap_bottom
,
"invariant"
);
assert
(
next_bottom
==
heap_bottom
()
,
"invariant"
);
}
else
{
// next_bottom should match the end of the last/previous region
assert
(
next_bottom
==
at
(
index
-
1
)
->
end
(),
"invariant"
);
...
...
@@ -122,8 +111,8 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end,
// allocation failed, we bail out and return what we have done so far
return
MemRegion
(
old_end
,
next_bottom
);
}
assert
(
_regions
[
index
]
==
NULL
,
"invariant"
);
_regions
[
index
]
=
new_hr
;
assert
(
_regions
.
get_by_index
(
index
)
==
NULL
,
"invariant"
);
_regions
.
set_by_index
(
index
,
new_hr
)
;
increment_allocated_length
();
}
// Have to increment the length first, otherwise we will get an
...
...
@@ -228,26 +217,26 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
#ifndef PRODUCT
void
HeapRegionSeq
::
verify_optional
()
{
guarantee
(
_length
<=
_allocated_length
,
guarantee
(
length
()
<=
_allocated_length
,
err_msg
(
"invariant: _length: %u _allocated_length: %u"
,
_length
,
_allocated_length
));
guarantee
(
_allocated_length
<=
_max_length
,
length
()
,
_allocated_length
));
guarantee
(
_allocated_length
<=
max_length
()
,
err_msg
(
"invariant: _allocated_length: %u _max_length: %u"
,
_allocated_length
,
_max_length
));
guarantee
(
_next_search_index
<=
_length
,
_allocated_length
,
max_length
()
));
guarantee
(
_next_search_index
<=
length
()
,
err_msg
(
"invariant: _next_search_index: %u _length: %u"
,
_next_search_index
,
_length
));
_next_search_index
,
length
()
));
HeapWord
*
prev_end
=
_heap_bottom
;
HeapWord
*
prev_end
=
heap_bottom
()
;
for
(
uint
i
=
0
;
i
<
_allocated_length
;
i
+=
1
)
{
HeapRegion
*
hr
=
_regions
[
i
]
;
HeapRegion
*
hr
=
_regions
.
get_by_index
(
i
)
;
guarantee
(
hr
!=
NULL
,
err_msg
(
"invariant: i: %u"
,
i
));
guarantee
(
hr
->
bottom
()
==
prev_end
,
err_msg
(
"invariant i: %u "
HR_FORMAT
" prev_end: "
PTR_FORMAT
,
i
,
HR_FORMAT_PARAMS
(
hr
),
prev_end
));
guarantee
(
hr
->
hrs_index
()
==
i
,
err_msg
(
"invariant: i: %u hrs_index(): %u"
,
i
,
hr
->
hrs_index
()));
if
(
i
<
_length
)
{
if
(
i
<
length
()
)
{
// Asserts will fire if i is >= _length
HeapWord
*
addr
=
hr
->
bottom
();
guarantee
(
addr_to_region
(
addr
)
==
hr
,
"sanity"
);
...
...
@@ -265,8 +254,8 @@ void HeapRegionSeq::verify_optional() {
prev_end
=
hr
->
end
();
}
}
for
(
uint
i
=
_allocated_length
;
i
<
_max_length
;
i
+=
1
)
{
guarantee
(
_regions
[
i
]
==
NULL
,
err_msg
(
"invariant i: %u"
,
i
));
for
(
uint
i
=
_allocated_length
;
i
<
max_length
()
;
i
+=
1
)
{
guarantee
(
_regions
.
get_by_index
(
i
)
==
NULL
,
err_msg
(
"invariant i: %u"
,
i
));
}
}
#endif // PRODUCT
src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
浏览文件 @
78c00a06
...
...
@@ -25,10 +25,17 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
#include "gc_implementation/g1/g1BiasedArray.hpp"
class
HeapRegion
;
class
HeapRegionClosure
;
class
FreeRegionList
;
class
G1HeapRegionTable
:
public
G1BiasedMappedArray
<
HeapRegion
*>
{
protected:
virtual
HeapRegion
*
default_value
()
const
{
return
NULL
;
}
};
// This class keeps track of the region metadata (i.e., HeapRegion
// instances). They are kept in the _regions array in address
// order. A region's index in the array corresponds to its index in
...
...
@@ -44,35 +51,21 @@ class FreeRegionList;
//
// We keep track of three lengths:
//
// * _length (returned by length()) is the number of currently
// * _
committed_
length (returned by length()) is the number of currently
// committed regions.
// * _allocated_length (not exposed outside this class) is the
// number of regions for which we have HeapRegions.
// * _max_length (returned by max_length()) is the maximum number of
// regions the heap can have.
// * max_length() returns the maximum number of regions the heap can have.
//
// and maintain that: _
length <= _allocated_length <= _max_length
// and maintain that: _
committed_length <= _allocated_length <= max_length()
class
HeapRegionSeq
:
public
CHeapObj
<
mtGC
>
{
friend
class
VMStructs
;
// The array that holds the HeapRegions.
HeapRegion
**
_regions
;
// Version of _regions biased to address 0
HeapRegion
**
_regions_biased
;
G1HeapRegionTable
_regions
;
// The number of regions committed in the heap.
uint
_length
;
// The address of the first reserved word in the heap.
HeapWord
*
_heap_bottom
;
// The address of the last reserved word in the heap - 1.
HeapWord
*
_heap_end
;
// The log of the region byte size.
uint
_region_shift
;
uint
_committed_length
;
// A hint for which index to start searching from for humongous
// allocations.
...
...
@@ -81,37 +74,33 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
// The number of regions for which we have allocated HeapRegions for.
uint
_allocated_length
;
// The maximum number of regions in the heap.
uint
_max_length
;
// Find a contiguous set of empty regions of length num, starting
// from the given index.
uint
find_contiguous_from
(
uint
from
,
uint
num
);
// Map a heap address to a biased region index. Assume that the
// address is valid.
inline
uintx
addr_to_index_biased
(
HeapWord
*
addr
)
const
;
void
increment_allocated_length
()
{
assert
(
_allocated_length
<
_max_length
,
"pre-condition"
);
assert
(
_allocated_length
<
max_length
()
,
"pre-condition"
);
_allocated_length
++
;
}
void
increment_length
()
{
assert
(
_length
<
_max_length
,
"pre-condition"
);
_length
++
;
assert
(
length
()
<
max_length
()
,
"pre-condition"
);
_
committed_
length
++
;
}
void
decrement_length
()
{
assert
(
_length
>
0
,
"pre-condition"
);
_length
--
;
assert
(
length
()
>
0
,
"pre-condition"
);
_
committed_
length
--
;
}
HeapWord
*
heap_bottom
()
const
{
return
_regions
.
bottom_address_mapped
();
}
HeapWord
*
heap_end
()
const
{
return
_regions
.
end_address_mapped
();
}
public:
// Empty contructor, we'll initialize it with the initialize() method.
HeapRegionSeq
()
{
}
HeapRegionSeq
()
:
_regions
(),
_committed_length
(
0
),
_next_search_index
(
0
),
_allocated_length
(
0
)
{
}
void
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
,
uint
max_length
);
void
initialize
(
HeapWord
*
bottom
,
HeapWord
*
end
);
// Return the HeapRegion at the given index. Assume that the index
// is valid.
...
...
@@ -126,10 +115,10 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
inline
HeapRegion
*
addr_to_region_unsafe
(
HeapWord
*
addr
)
const
;
// Return the number of regions that have been committed in the heap.
uint
length
()
const
{
return
_length
;
}
uint
length
()
const
{
return
_
committed_
length
;
}
// Return the maximum number of regions in the heap.
uint
max_length
()
const
{
return
_max_length
;
}
uint
max_length
()
const
{
return
(
uint
)
_regions
.
length
()
;
}
// Expand the sequence to reflect that the heap has grown from
// old_end to new_end. Either create new HeapRegions, or re-use
...
...
src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
浏览文件 @
78c00a06
...
...
@@ -28,28 +28,16 @@
#include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp"
inline
uintx
HeapRegionSeq
::
addr_to_index_biased
(
HeapWord
*
addr
)
const
{
assert
(
_heap_bottom
<=
addr
&&
addr
<
_heap_end
,
err_msg
(
"addr: "
PTR_FORMAT
" bottom: "
PTR_FORMAT
" end: "
PTR_FORMAT
,
addr
,
_heap_bottom
,
_heap_end
));
uintx
index
=
(
uintx
)
addr
>>
_region_shift
;
return
index
;
}
inline
HeapRegion
*
HeapRegionSeq
::
addr_to_region_unsafe
(
HeapWord
*
addr
)
const
{
assert
(
_heap_bottom
<=
addr
&&
addr
<
_heap_end
,
err_msg
(
"addr: "
PTR_FORMAT
" bottom: "
PTR_FORMAT
" end: "
PTR_FORMAT
,
addr
,
_heap_bottom
,
_heap_end
));
uintx
index_biased
=
addr_to_index_biased
(
addr
);
HeapRegion
*
hr
=
_regions_biased
[
index_biased
];
HeapRegion
*
hr
=
_regions
.
get_by_address
(
addr
);
assert
(
hr
!=
NULL
,
"invariant"
);
return
hr
;
}
inline
HeapRegion
*
HeapRegionSeq
::
addr_to_region
(
HeapWord
*
addr
)
const
{
if
(
addr
!=
NULL
&&
addr
<
_heap_end
)
{
assert
(
addr
>=
_heap_bottom
,
err_msg
(
"addr: "
PTR_FORMAT
" bottom: "
PTR_FORMAT
,
addr
,
_heap_bottom
));
if
(
addr
!=
NULL
&&
addr
<
heap_end
()
)
{
assert
(
addr
>=
heap_bottom
()
,
err_msg
(
"addr: "
PTR_FORMAT
" bottom: "
PTR_FORMAT
,
addr
,
heap_bottom
()
));
return
addr_to_region_unsafe
(
addr
);
}
return
NULL
;
...
...
@@ -57,7 +45,7 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
inline
HeapRegion
*
HeapRegionSeq
::
at
(
uint
index
)
const
{
assert
(
index
<
length
(),
"pre-condition"
);
HeapRegion
*
hr
=
_regions
[
index
]
;
HeapRegion
*
hr
=
_regions
.
get_by_index
(
index
)
;
assert
(
hr
!=
NULL
,
"sanity"
);
assert
(
hr
->
hrs_index
()
==
index
,
"sanity"
);
return
hr
;
...
...
src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
浏览文件 @
78c00a06
...
...
@@ -34,8 +34,14 @@
static_field(HeapRegion, GrainBytes, size_t) \
static_field(HeapRegion, LogOfHRGrainBytes, int) \
\
nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \
nonstatic_field(HeapRegionSeq, _length, uint) \
nonstatic_field(G1HeapRegionTable, _base, address) \
nonstatic_field(G1HeapRegionTable, _length, size_t) \
nonstatic_field(G1HeapRegionTable, _biased_base, address) \
nonstatic_field(G1HeapRegionTable, _bias, size_t) \
nonstatic_field(G1HeapRegionTable, _shift_by, uint) \
\
nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \
nonstatic_field(HeapRegionSeq, _committed_length, uint) \
\
nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \
nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \
...
...
@@ -58,6 +64,8 @@
#define VM_TYPES_G1(declare_type, declare_toplevel_type) \
\
declare_toplevel_type(G1HeapRegionTable) \
\
declare_type(G1CollectedHeap, SharedHeap) \
\
declare_type(HeapRegion, ContiguousSpace) \
...
...
src/share/vm/memory/gcLocker.cpp
浏览文件 @
78c00a06
...
...
@@ -122,7 +122,7 @@ void GC_locker::jni_unlock(JavaThread* thread) {
// strictly needed. It's added here to make it clear that
// the GC will NOT be performed if any other caller
// of GC_locker::lock() still needs GC locked.
if
(
!
is_active
())
{
if
(
!
is_active
_internal
())
{
_doing_gc
=
true
;
{
// Must give up the lock while at a safepoint
...
...
src/share/vm/memory/gcLocker.hpp
浏览文件 @
78c00a06
...
...
@@ -88,7 +88,7 @@ class GC_locker: public AllStatic {
public:
// Accessors
static
bool
is_active
()
{
assert
(
_needs_gc
||
SafepointSynchronize
::
is_at_safepoint
(),
"only read at safepoint"
);
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"only read at safepoint"
);
return
is_active_internal
();
}
static
bool
needs_gc
()
{
return
_needs_gc
;
}
...
...
src/share/vm/memory/metaspace.cpp
浏览文件 @
78c00a06
...
...
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/allocation.hpp"
#include "memory/binaryTreeDictionary.hpp"
#include "memory/freeList.hpp"
#include "memory/collectorPolicy.hpp"
...
...
@@ -111,7 +112,7 @@ typedef class FreeList<Metachunk> ChunkList;
// Has three lists of free chunks, and a total size and
// count that includes all three
class
ChunkManager
VALUE_OBJ_CLASS_SPEC
{
class
ChunkManager
:
public
CHeapObj
<
mtInternal
>
{
// Free list of chunks of different sizes.
// SpecializedChunk
...
...
@@ -158,7 +159,12 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
public:
ChunkManager
()
:
_free_chunks_total
(
0
),
_free_chunks_count
(
0
)
{}
ChunkManager
(
size_t
specialized_size
,
size_t
small_size
,
size_t
medium_size
)
:
_free_chunks_total
(
0
),
_free_chunks_count
(
0
)
{
_free_chunks
[
SpecializedIndex
].
set_size
(
specialized_size
);
_free_chunks
[
SmallIndex
].
set_size
(
small_size
);
_free_chunks
[
MediumIndex
].
set_size
(
medium_size
);
}
// add or delete (return) a chunk to the global freelist.
Metachunk
*
chunk_freelist_allocate
(
size_t
word_size
);
...
...
@@ -219,7 +225,7 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
void
locked_print_free_chunks
(
outputStream
*
st
);
void
locked_print_sum_free_chunks
(
outputStream
*
st
);
void
print_on
(
outputStream
*
st
);
void
print_on
(
outputStream
*
st
)
const
;
};
// Used to manage the free list of Metablocks (a block corresponds
...
...
@@ -276,11 +282,6 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
// VirtualSpace
Metachunk
*
first_chunk
()
{
return
(
Metachunk
*
)
bottom
();
}
void
inc_container_count
();
#ifdef ASSERT
uint
container_count_slow
();
#endif
public:
VirtualSpaceNode
(
size_t
byte_size
);
...
...
@@ -314,8 +315,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
void
inc_top
(
size_t
word_size
)
{
_top
+=
word_size
;
}
uintx
container_count
()
{
return
_container_count
;
}
void
inc_container_count
();
void
dec_container_count
();
#ifdef ASSERT
uint
container_count_slow
();
void
verify_container_count
();
#endif
...
...
@@ -421,8 +424,6 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
VirtualSpaceNode
*
_virtual_space_list
;
// virtual space currently being used for allocations
VirtualSpaceNode
*
_current_virtual_space
;
// Free chunk list for all other metadata
ChunkManager
_chunk_manager
;
// Can this virtual list allocate >1 spaces? Also, used to determine
// whether to allocate unlimited small chunks in this virtual space
...
...
@@ -475,7 +476,6 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
return
_current_virtual_space
;
}
ChunkManager
*
chunk_manager
()
{
return
&
_chunk_manager
;
}
bool
is_class
()
const
{
return
_is_class
;
}
// Allocate the first virtualspace.
...
...
@@ -494,14 +494,7 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
void
dec_virtual_space_count
();
// Unlink empty VirtualSpaceNodes and free it.
void
purge
();
// Used and capacity in the entire list of virtual spaces.
// These are global values shared by all Metaspaces
size_t
capacity_words_sum
();
size_t
capacity_bytes_sum
()
{
return
capacity_words_sum
()
*
BytesPerWord
;
}
size_t
used_words_sum
();
size_t
used_bytes_sum
()
{
return
used_words_sum
()
*
BytesPerWord
;
}
void
purge
(
ChunkManager
*
chunk_manager
);
bool
contains
(
const
void
*
ptr
);
...
...
@@ -582,18 +575,12 @@ class SpaceManager : public CHeapObj<mtClass> {
// Type of metadata allocated.
Metaspace
::
MetadataType
_mdtype
;
// Chunk related size
size_t
_medium_chunk_bunch
;
// List of chunks in use by this SpaceManager. Allocations
// are done from the current chunk. The list is used for deallocating
// chunks when the SpaceManager is freed.
Metachunk
*
_chunks_in_use
[
NumberOfInUseLists
];
Metachunk
*
_current_chunk
;
// Virtual space where allocation comes from.
VirtualSpaceList
*
_vs_list
;
// Number of small chunks to allocate to a manager
// If class space manager, small chunks are unlimited
static
uint
const
_small_chunk_limit
;
...
...
@@ -626,7 +613,9 @@ class SpaceManager : public CHeapObj<mtClass> {
}
Metaspace
::
MetadataType
mdtype
()
{
return
_mdtype
;
}
VirtualSpaceList
*
vs_list
()
const
{
return
_vs_list
;
}
VirtualSpaceList
*
vs_list
()
const
{
return
Metaspace
::
get_space_list
(
_mdtype
);
}
ChunkManager
*
chunk_manager
()
const
{
return
Metaspace
::
get_chunk_manager
(
_mdtype
);
}
Metachunk
*
current_chunk
()
const
{
return
_current_chunk
;
}
void
set_current_chunk
(
Metachunk
*
v
)
{
...
...
@@ -648,18 +637,19 @@ class SpaceManager : public CHeapObj<mtClass> {
public:
SpaceManager
(
Metaspace
::
MetadataType
mdtype
,
Mutex
*
lock
,
VirtualSpaceList
*
vs_list
);
Mutex
*
lock
);
~
SpaceManager
();
enum
ChunkMultiples
{
MediumChunkMultiple
=
4
};
bool
is_class
()
{
return
_mdtype
==
Metaspace
::
ClassType
;
}
// Accessors
size_t
specialized_chunk_size
()
{
return
SpecializedChunk
;
}
size_t
small_chunk_size
()
{
return
(
size_t
)
vs_list
()
->
is_class
()
?
ClassSmallChunk
:
SmallChunk
;
}
size_t
medium_chunk_size
()
{
return
(
size_t
)
vs_list
()
->
is_class
()
?
ClassMediumChunk
:
MediumChunk
;
}
size_t
small_chunk_size
()
{
return
(
size_t
)
is_class
()
?
ClassSmallChunk
:
SmallChunk
;
}
size_t
medium_chunk_size
()
{
return
(
size_t
)
is_class
()
?
ClassMediumChunk
:
MediumChunk
;
}
size_t
medium_chunk_bunch
()
{
return
medium_chunk_size
()
*
MediumChunkMultiple
;
}
size_t
allocated_blocks_words
()
const
{
return
_allocated_blocks_words
;
}
...
...
@@ -762,7 +752,7 @@ void VirtualSpaceNode::inc_container_count() {
_container_count
++
;
assert
(
_container_count
==
container_count_slow
(),
err_msg
(
"Inconsistency in countainer_count _container_count "
SIZE_FORMAT
"container_count_slow() "
SIZE_FORMAT
,
"
container_count_slow() "
SIZE_FORMAT
,
_container_count
,
container_count_slow
()));
}
...
...
@@ -775,7 +765,7 @@ void VirtualSpaceNode::dec_container_count() {
void
VirtualSpaceNode
::
verify_container_count
()
{
assert
(
_container_count
==
container_count_slow
(),
err_msg
(
"Inconsistency in countainer_count _container_count "
SIZE_FORMAT
"container_count_slow() "
SIZE_FORMAT
,
_container_count
,
container_count_slow
()));
"
container_count_slow() "
SIZE_FORMAT
,
_container_count
,
container_count_slow
()));
}
#endif
...
...
@@ -1020,7 +1010,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) {
// Walk the list of VirtualSpaceNodes and delete
// nodes with a 0 container_count. Remove Metachunks in
// the node from their respective freelists.
void
VirtualSpaceList
::
purge
()
{
void
VirtualSpaceList
::
purge
(
ChunkManager
*
chunk_manager
)
{
assert_lock_strong
(
SpaceManager
::
expand_lock
());
// Don't use a VirtualSpaceListIterator because this
// list is being changed and a straightforward use of an iterator is not safe.
...
...
@@ -1042,7 +1032,7 @@ void VirtualSpaceList::purge() {
prev_vsl
->
set_next
(
vsl
->
next
());
}
vsl
->
purge
(
chunk_manager
()
);
vsl
->
purge
(
chunk_manager
);
dec_reserved_words
(
vsl
->
reserved_words
());
dec_committed_words
(
vsl
->
committed_words
());
dec_virtual_space_count
();
...
...
@@ -1064,36 +1054,6 @@ void VirtualSpaceList::purge() {
#endif
}
size_t
VirtualSpaceList
::
used_words_sum
()
{
size_t
allocated_by_vs
=
0
;
VirtualSpaceListIterator
iter
(
virtual_space_list
());
while
(
iter
.
repeat
())
{
VirtualSpaceNode
*
vsl
=
iter
.
get_next
();
// Sum used region [bottom, top) in each virtualspace
allocated_by_vs
+=
vsl
->
used_words_in_vs
();
}
assert
(
allocated_by_vs
>=
chunk_manager
()
->
free_chunks_total_words
(),
err_msg
(
"Total in free chunks "
SIZE_FORMAT
" greater than total from virtual_spaces "
SIZE_FORMAT
,
allocated_by_vs
,
chunk_manager
()
->
free_chunks_total_words
()));
size_t
used
=
allocated_by_vs
-
chunk_manager
()
->
free_chunks_total_words
();
return
used
;
}
// Space available in all MetadataVirtualspaces allocated
// for metadata. This is the upper limit on the capacity
// of chunks allocated out of all the MetadataVirtualspaces.
size_t
VirtualSpaceList
::
capacity_words_sum
()
{
size_t
capacity
=
0
;
VirtualSpaceListIterator
iter
(
virtual_space_list
());
while
(
iter
.
repeat
())
{
VirtualSpaceNode
*
vsl
=
iter
.
get_next
();
capacity
+=
vsl
->
capacity_words_in_vs
();
}
return
capacity
;
}
VirtualSpaceList
::
VirtualSpaceList
(
size_t
word_size
)
:
_is_class
(
false
),
_virtual_space_list
(
NULL
),
...
...
@@ -1104,10 +1064,6 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
bool
initialization_succeeded
=
grow_vs
(
word_size
);
_chunk_manager
.
free_chunks
(
SpecializedIndex
)
->
set_size
(
SpecializedChunk
);
_chunk_manager
.
free_chunks
(
SmallIndex
)
->
set_size
(
SmallChunk
);
_chunk_manager
.
free_chunks
(
MediumIndex
)
->
set_size
(
MediumChunk
);
assert
(
initialization_succeeded
,
" VirtualSpaceList initialization should not fail"
);
}
...
...
@@ -1123,9 +1079,6 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
Mutex
::
_no_safepoint_check_flag
);
VirtualSpaceNode
*
class_entry
=
new
VirtualSpaceNode
(
rs
);
bool
succeeded
=
class_entry
->
initialize
();
_chunk_manager
.
free_chunks
(
SpecializedIndex
)
->
set_size
(
SpecializedChunk
);
_chunk_manager
.
free_chunks
(
SmallIndex
)
->
set_size
(
ClassSmallChunk
);
_chunk_manager
.
free_chunks
(
MediumIndex
)
->
set_size
(
ClassMediumChunk
);
assert
(
succeeded
,
" VirtualSpaceList initialization should not fail"
);
link_vs
(
class_entry
);
}
...
...
@@ -1142,7 +1095,7 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
}
// Reserve the space
size_t
vs_byte_size
=
vs_word_size
*
BytesPerWord
;
assert
(
vs_byte_size
%
os
::
vm_
page_size
()
==
0
,
"Not aligned"
);
assert
(
vs_byte_size
%
os
::
vm_
allocation_granularity
()
==
0
,
"Not aligned"
);
// Allocate the meta virtual space and initialize it.
VirtualSpaceNode
*
new_entry
=
new
VirtualSpaceNode
(
vs_byte_size
);
...
...
@@ -1195,15 +1148,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
size_t
grow_chunks_by_words
,
size_t
medium_chunk_bunch
)
{
// Get a chunk from the chunk freelist
Metachunk
*
next
=
chunk_manager
()
->
chunk_freelist_allocate
(
grow_chunks_by_words
);
if
(
next
!=
NULL
)
{
next
->
container
()
->
inc_container_count
();
}
else
{
// Allocate a chunk out of the current virtual space.
next
=
current_virtual_space
()
->
get_chunk_vs
(
grow_chunks_by_words
);
}
// Allocate a chunk out of the current virtual space.
Metachunk
*
next
=
current_virtual_space
()
->
get_chunk_vs
(
grow_chunks_by_words
);
if
(
next
==
NULL
)
{
// Not enough room in current virtual space. Try to commit
...
...
@@ -1221,12 +1167,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
// being used for CompressedHeaders, don't allocate a new virtualspace.
if
(
can_grow
()
&&
MetaspaceGC
::
should_expand
(
this
,
word_size
))
{
// Get another virtual space.
size_t
grow_vs_words
=
MAX2
((
size_t
)
VirtualSpaceSize
,
aligned_expand_vs_by_words
);
size_t
allocation_aligned_expand_words
=
align_size_up
(
aligned_expand_vs_by_words
,
os
::
vm_allocation_granularity
()
/
BytesPerWord
);
size_t
grow_vs_words
=
MAX2
((
size_t
)
VirtualSpaceSize
,
allocation_aligned_expand_words
);
if
(
grow_vs
(
grow_vs_words
))
{
// Got it. It's on the list now. Get a chunk from it.
assert
(
current_virtual_space
()
->
expanded_words
()
==
0
,
"New virtual
s
space nodes should not have expanded"
);
"New virtual space nodes should not have expanded"
);
size_t
grow_chunks_by_words_aligned
=
align_size_up
(
grow_chunks_by_words
,
page_size_words
);
...
...
@@ -1342,8 +1290,9 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
// reserved space, because this is a larger space prereserved for compressed
// class pointers.
if
(
!
FLAG_IS_DEFAULT
(
MaxMetaspaceSize
))
{
size_t
real_allocated
=
Metaspace
::
space_list
()
->
reserved_words
()
+
MetaspaceAux
::
allocated_capacity_bytes
(
Metaspace
::
ClassType
);
size_t
nonclass_allocated
=
MetaspaceAux
::
reserved_bytes
(
Metaspace
::
NonClassType
);
size_t
class_allocated
=
MetaspaceAux
::
allocated_capacity_bytes
(
Metaspace
::
ClassType
);
size_t
real_allocated
=
nonclass_allocated
+
class_allocated
;
if
(
real_allocated
>=
MaxMetaspaceSize
)
{
return
false
;
}
...
...
@@ -1536,15 +1485,15 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
if
(
dummy_chunk
==
NULL
)
{
break
;
}
vsl
->
chunk_manager
()
->
chunk_freelist_deallocate
(
dummy_chunk
);
sm
->
chunk_manager
()
->
chunk_freelist_deallocate
(
dummy_chunk
);
if
(
TraceMetadataChunkAllocation
&&
Verbose
)
{
gclog_or_tty
->
print
(
"Metadebug::deallocate_chunk_a_lot: %d) "
,
sm
->
sum_count_in_chunks_in_use
());
dummy_chunk
->
print_on
(
gclog_or_tty
);
gclog_or_tty
->
print_cr
(
" Free chunks total %d count %d"
,
vsl
->
chunk_manager
()
->
free_chunks_total_words
(),
vsl
->
chunk_manager
()
->
free_chunks_count
());
sm
->
chunk_manager
()
->
free_chunks_total_words
(),
sm
->
chunk_manager
()
->
free_chunks_count
());
}
}
}
else
{
...
...
@@ -1796,6 +1745,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
// work.
chunk
->
set_is_free
(
false
);
#endif
chunk
->
container
()
->
inc_container_count
();
slow_locked_verify
();
return
chunk
;
}
...
...
@@ -1830,9 +1781,9 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
return
chunk
;
}
void
ChunkManager
::
print_on
(
outputStream
*
out
)
{
void
ChunkManager
::
print_on
(
outputStream
*
out
)
const
{
if
(
PrintFLSStatistics
!=
0
)
{
humongous_dictionary
()
->
report_statistics
();
const_cast
<
ChunkManager
*>
(
this
)
->
humongous_dictionary
()
->
report_statistics
();
}
}
...
...
@@ -1979,8 +1930,8 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const {
}
}
vs_list
()
->
chunk_manager
()
->
locked_print_free_chunks
(
st
);
vs_list
()
->
chunk_manager
()
->
locked_print_sum_free_chunks
(
st
);
chunk_manager
()
->
locked_print_free_chunks
(
st
);
chunk_manager
()
->
locked_print_sum_free_chunks
(
st
);
}
size_t
SpaceManager
::
calc_chunk_size
(
size_t
word_size
)
{
...
...
@@ -2084,9 +2035,7 @@ void SpaceManager::print_on(outputStream* st) const {
}
SpaceManager
::
SpaceManager
(
Metaspace
::
MetadataType
mdtype
,
Mutex
*
lock
,
VirtualSpaceList
*
vs_list
)
:
_vs_list
(
vs_list
),
Mutex
*
lock
)
:
_mdtype
(
mdtype
),
_allocated_blocks_words
(
0
),
_allocated_chunks_words
(
0
),
...
...
@@ -2172,9 +2121,7 @@ SpaceManager::~SpaceManager() {
MutexLockerEx
fcl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
ChunkManager
*
chunk_manager
=
vs_list
()
->
chunk_manager
();
chunk_manager
->
slow_locked_verify
();
chunk_manager
()
->
slow_locked_verify
();
dec_total_from_size_metrics
();
...
...
@@ -2188,8 +2135,8 @@ SpaceManager::~SpaceManager() {
// Have to update before the chunks_in_use lists are emptied
// below.
chunk_manager
->
inc_free_chunks_total
(
allocated_chunks_words
(),
sum_count_in_chunks_in_use
());
chunk_manager
()
->
inc_free_chunks_total
(
allocated_chunks_words
(),
sum_count_in_chunks_in_use
());
// Add all the chunks in use by this space manager
// to the global list of free chunks.
...
...
@@ -2204,11 +2151,11 @@ SpaceManager::~SpaceManager() {
chunk_size_name
(
i
));
}
Metachunk
*
chunks
=
chunks_in_use
(
i
);
chunk_manager
->
return_chunks
(
i
,
chunks
);
chunk_manager
()
->
return_chunks
(
i
,
chunks
);
set_chunks_in_use
(
i
,
NULL
);
if
(
TraceMetadataChunkAllocation
&&
Verbose
)
{
gclog_or_tty
->
print_cr
(
"updated freelist count %d %s"
,
chunk_manager
->
free_chunks
(
i
)
->
count
(),
chunk_manager
()
->
free_chunks
(
i
)
->
count
(),
chunk_size_name
(
i
));
}
assert
(
i
!=
HumongousIndex
,
"Humongous chunks are handled explicitly later"
);
...
...
@@ -2245,16 +2192,16 @@ SpaceManager::~SpaceManager() {
humongous_chunks
->
word_size
(),
HumongousChunkGranularity
));
Metachunk
*
next_humongous_chunks
=
humongous_chunks
->
next
();
humongous_chunks
->
container
()
->
dec_container_count
();
chunk_manager
->
humongous_dictionary
()
->
return_chunk
(
humongous_chunks
);
chunk_manager
()
->
humongous_dictionary
()
->
return_chunk
(
humongous_chunks
);
humongous_chunks
=
next_humongous_chunks
;
}
if
(
TraceMetadataChunkAllocation
&&
Verbose
)
{
gclog_or_tty
->
print_cr
(
""
);
gclog_or_tty
->
print_cr
(
"updated dictionary count %d %s"
,
chunk_manager
->
humongous_dictionary
()
->
total_count
(),
chunk_manager
()
->
humongous_dictionary
()
->
total_count
(),
chunk_size_name
(
HumongousIndex
));
}
chunk_manager
->
slow_locked_verify
();
chunk_manager
()
->
slow_locked_verify
();
}
const
char
*
SpaceManager
::
chunk_size_name
(
ChunkIndex
index
)
const
{
...
...
@@ -2343,9 +2290,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
gclog_or_tty
->
print
(
"SpaceManager::add_chunk: %d) "
,
sum_count_in_chunks_in_use
());
new_chunk
->
print_on
(
gclog_or_tty
);
if
(
vs_list
()
!=
NULL
)
{
vs_list
()
->
chunk_manager
()
->
locked_print_free_chunks
(
gclog_or_tty
);
}
chunk_manager
()
->
locked_print_free_chunks
(
gclog_or_tty
);
}
}
...
...
@@ -2361,10 +2306,14 @@ void SpaceManager::retire_current_chunk() {
Metachunk
*
SpaceManager
::
get_new_chunk
(
size_t
word_size
,
size_t
grow_chunks_by_words
)
{
// Get a chunk from the chunk freelist
Metachunk
*
next
=
chunk_manager
()
->
chunk_freelist_allocate
(
grow_chunks_by_words
);
Metachunk
*
next
=
vs_list
()
->
get_new_chunk
(
word_size
,
grow_chunks_by_words
,
medium_chunk_bunch
());
if
(
next
==
NULL
)
{
next
=
vs_list
()
->
get_new_chunk
(
word_size
,
grow_chunks_by_words
,
medium_chunk_bunch
());
}
if
(
TraceMetadataHumongousAllocation
&&
next
!=
NULL
&&
SpaceManager
::
is_humongous
(
next
->
word_size
()))
{
...
...
@@ -2644,13 +2593,12 @@ size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) {
size_t
MetaspaceAux
::
min_chunk_size_words
()
{
return
Metaspace
::
first_chunk_word_size
();
}
size_t
MetaspaceAux
::
free_chunks_total_words
(
Metaspace
::
MetadataType
mdtype
)
{
VirtualSpaceList
*
list
=
Metaspace
::
get_space_list
(
mdtype
);
if
(
list
==
NULL
)
{
ChunkManager
*
chunk_manager
=
Metaspace
::
get_chunk_manager
(
mdtype
);
if
(
chunk_manager
==
NULL
)
{
return
0
;
}
ChunkManager
*
chunk
=
list
->
chunk_manager
();
chunk
->
slow_verify
();
return
chunk
->
free_chunks_total_words
();
chunk_manager
->
slow_verify
();
return
chunk_manager
->
free_chunks_total_words
();
}
size_t
MetaspaceAux
::
free_chunks_total_bytes
(
Metaspace
::
MetadataType
mdtype
)
{
...
...
@@ -2801,9 +2749,9 @@ void MetaspaceAux::dump(outputStream* out) {
}
void
MetaspaceAux
::
verify_free_chunks
()
{
Metaspace
::
space_list
()
->
chunk_manager
()
->
verify
();
Metaspace
::
chunk_manager_metadata
()
->
verify
();
if
(
Metaspace
::
using_class_space
())
{
Metaspace
::
c
lass_space_list
()
->
chunk_manager
()
->
verify
();
Metaspace
::
c
hunk_manager_class
()
->
verify
();
}
}
...
...
@@ -2874,6 +2822,9 @@ Metaspace::~Metaspace() {
VirtualSpaceList
*
Metaspace
::
_space_list
=
NULL
;
VirtualSpaceList
*
Metaspace
::
_class_space_list
=
NULL
;
ChunkManager
*
Metaspace
::
_chunk_manager_metadata
=
NULL
;
ChunkManager
*
Metaspace
::
_chunk_manager_class
=
NULL
;
#define VIRTUALSPACEMULTIPLIER 2
#ifdef _LP64
...
...
@@ -2981,6 +2932,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
err_msg
(
SIZE_FORMAT
" != "
UINTX_FORMAT
,
rs
.
size
(),
CompressedClassSpaceSize
));
assert
(
using_class_space
(),
"Must be using class space"
);
_class_space_list
=
new
VirtualSpaceList
(
rs
);
_chunk_manager_class
=
new
ChunkManager
(
SpecializedChunk
,
ClassSmallChunk
,
ClassMediumChunk
);
}
#endif
...
...
@@ -3006,6 +2958,7 @@ void Metaspace::global_initialize() {
// remainder is the misc code and data chunks.
cds_total
=
FileMapInfo
::
shared_spaces_size
();
_space_list
=
new
VirtualSpaceList
(
cds_total
/
wordSize
);
_chunk_manager_metadata
=
new
ChunkManager
(
SpecializedChunk
,
SmallChunk
,
MediumChunk
);
#ifdef _LP64
// Set the compressed klass pointer base so that decoding of these pointers works
...
...
@@ -3073,15 +3026,30 @@ void Metaspace::global_initialize() {
size_t
word_size
=
VIRTUALSPACEMULTIPLIER
*
first_chunk_word_size
();
// Initialize the list of virtual spaces.
_space_list
=
new
VirtualSpaceList
(
word_size
);
_chunk_manager_metadata
=
new
ChunkManager
(
SpecializedChunk
,
SmallChunk
,
MediumChunk
);
}
}
Metachunk
*
Metaspace
::
get_initialization_chunk
(
MetadataType
mdtype
,
size_t
chunk_word_size
,
size_t
chunk_bunch
)
{
// Get a chunk from the chunk freelist
Metachunk
*
chunk
=
get_chunk_manager
(
mdtype
)
->
chunk_freelist_allocate
(
chunk_word_size
);
if
(
chunk
!=
NULL
)
{
return
chunk
;
}
return
get_space_list
(
mdtype
)
->
get_initialization_chunk
(
chunk_word_size
,
chunk_bunch
);
}
void
Metaspace
::
initialize
(
Mutex
*
lock
,
MetaspaceType
type
)
{
assert
(
space_list
()
!=
NULL
,
"Metadata VirtualSpaceList has not been initialized"
);
assert
(
chunk_manager_metadata
()
!=
NULL
,
"Metadata ChunkManager has not been initialized"
);
_vsm
=
new
SpaceManager
(
NonClassType
,
lock
,
space_list
()
);
_vsm
=
new
SpaceManager
(
NonClassType
,
lock
);
if
(
_vsm
==
NULL
)
{
return
;
}
...
...
@@ -3090,11 +3058,13 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
vsm
()
->
get_initial_chunk_sizes
(
type
,
&
word_size
,
&
class_word_size
);
if
(
using_class_space
())
{
assert
(
class_space_list
()
!=
NULL
,
"Class VirtualSpaceList has not been initialized"
);
assert
(
class_space_list
()
!=
NULL
,
"Class VirtualSpaceList has not been initialized"
);
assert
(
chunk_manager_class
()
!=
NULL
,
"Class ChunkManager has not been initialized"
);
// Allocate SpaceManager for classes.
_class_vsm
=
new
SpaceManager
(
ClassType
,
lock
,
class_space_list
()
);
_class_vsm
=
new
SpaceManager
(
ClassType
,
lock
);
if
(
_class_vsm
==
NULL
)
{
return
;
}
...
...
@@ -3103,9 +3073,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
// Allocate chunk for metadata objects
Metachunk
*
new_chunk
=
space_list
()
->
get_initialization_chunk
(
word_size
,
vsm
()
->
medium_chunk_bunch
());
Metachunk
*
new_chunk
=
get_initialization_chunk
(
NonClassType
,
word_size
,
vsm
()
->
medium_chunk_bunch
());
assert
(
!
DumpSharedSpaces
||
new_chunk
!=
NULL
,
"should have enough space for both chunks"
);
if
(
new_chunk
!=
NULL
)
{
// Add to this manager's list of chunks in use and current_chunk().
...
...
@@ -3114,9 +3084,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
// Allocate chunk for class metadata objects
if
(
using_class_space
())
{
Metachunk
*
class_chunk
=
class_space_list
()
->
get_initialization_chunk
(
class_word_size
,
class_vsm
()
->
medium_chunk_bunch
());
Metachunk
*
class_chunk
=
get_initialization_chunk
(
ClassType
,
class_word_size
,
class_vsm
()
->
medium_chunk_bunch
());
if
(
class_chunk
!=
NULL
)
{
class_vsm
()
->
add_chunk
(
class_chunk
,
true
);
}
...
...
@@ -3333,12 +3303,16 @@ void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
}
}
void
Metaspace
::
purge
(
MetadataType
mdtype
)
{
get_space_list
(
mdtype
)
->
purge
(
get_chunk_manager
(
mdtype
));
}
void
Metaspace
::
purge
()
{
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
space_list
()
->
purge
(
);
purge
(
NonClassType
);
if
(
using_class_space
())
{
class_space_list
()
->
purge
(
);
purge
(
ClassType
);
}
}
...
...
@@ -3385,7 +3359,7 @@ void Metaspace::dump(outputStream* const out) const {
#ifndef PRODUCT
class
MetaspaceAuxTest
:
AllStatic
{
class
Test
MetaspaceAuxTest
:
AllStatic
{
public:
static
void
test_reserved
()
{
size_t
reserved
=
MetaspaceAux
::
reserved_bytes
();
...
...
@@ -3425,14 +3399,25 @@ class MetaspaceAuxTest : AllStatic {
}
}
static
void
test_virtual_space_list_large_chunk
()
{
VirtualSpaceList
*
vs_list
=
new
VirtualSpaceList
(
os
::
vm_allocation_granularity
());
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
// A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be
// vm_allocation_granularity aligned on Windows.
size_t
large_size
=
(
size_t
)(
2
*
256
*
K
+
(
os
::
vm_page_size
()
/
BytesPerWord
));
large_size
+=
(
os
::
vm_page_size
()
/
BytesPerWord
);
vs_list
->
get_new_chunk
(
large_size
,
large_size
,
0
);
}
static
void
test
()
{
test_reserved
();
test_committed
();
test_virtual_space_list_large_chunk
();
}
};
void
MetaspaceAux_test
()
{
MetaspaceAuxTest
::
test
();
void
Test
MetaspaceAux_test
()
{
Test
MetaspaceAuxTest
::
test
();
}
#endif
src/share/vm/memory/metaspace.hpp
浏览文件 @
78c00a06
...
...
@@ -56,12 +56,15 @@
// +-------------------+
//
class
ChunkManager
;
class
ClassLoaderData
;
class
Metablock
;
class
Metachunk
;
class
MetaWord
;
class
Mutex
;
class
outputStream
;
class
SpaceManager
;
class
VirtualSpaceList
;
// Metaspaces each have a SpaceManager and allocations
// are done by the SpaceManager. Allocations are done
...
...
@@ -76,8 +79,6 @@ class SpaceManager;
// allocate() method returns a block for use as a
// quantum of metadata.
class
VirtualSpaceList
;
class
Metaspace
:
public
CHeapObj
<
mtClass
>
{
friend
class
VMStructs
;
friend
class
SpaceManager
;
...
...
@@ -102,6 +103,10 @@ class Metaspace : public CHeapObj<mtClass> {
private:
void
initialize
(
Mutex
*
lock
,
MetaspaceType
type
);
Metachunk
*
get_initialization_chunk
(
MetadataType
mdtype
,
size_t
chunk_word_size
,
size_t
chunk_bunch
);
// Align up the word size to the allocation word size
static
size_t
align_word_size_up
(
size_t
);
...
...
@@ -134,6 +139,10 @@ class Metaspace : public CHeapObj<mtClass> {
static
VirtualSpaceList
*
_space_list
;
static
VirtualSpaceList
*
_class_space_list
;
static
ChunkManager
*
_chunk_manager_metadata
;
static
ChunkManager
*
_chunk_manager_class
;
public:
static
VirtualSpaceList
*
space_list
()
{
return
_space_list
;
}
static
VirtualSpaceList
*
class_space_list
()
{
return
_class_space_list
;
}
static
VirtualSpaceList
*
get_space_list
(
MetadataType
mdtype
)
{
...
...
@@ -141,6 +150,14 @@ class Metaspace : public CHeapObj<mtClass> {
return
mdtype
==
ClassType
?
class_space_list
()
:
space_list
();
}
static
ChunkManager
*
chunk_manager_metadata
()
{
return
_chunk_manager_metadata
;
}
static
ChunkManager
*
chunk_manager_class
()
{
return
_chunk_manager_class
;
}
static
ChunkManager
*
get_chunk_manager
(
MetadataType
mdtype
)
{
assert
(
mdtype
!=
MetadataTypeCount
,
"MetadaTypeCount can't be used as mdtype"
);
return
mdtype
==
ClassType
?
chunk_manager_class
()
:
chunk_manager_metadata
();
}
private:
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now.
void
record_allocation
(
void
*
ptr
,
MetaspaceObj
::
Type
type
,
size_t
word_size
);
...
...
@@ -199,6 +216,7 @@ class Metaspace : public CHeapObj<mtClass> {
void
dump
(
outputStream
*
const
out
)
const
;
// Free empty virtualspaces
static
void
purge
(
MetadataType
mdtype
);
static
void
purge
();
void
print_on
(
outputStream
*
st
)
const
;
...
...
src/share/vm/prims/jni.cpp
浏览文件 @
78c00a06
...
...
@@ -5046,7 +5046,10 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
void
TestReservedSpace_test
();
void
TestReserveMemorySpecial_test
();
void
TestVirtualSpace_test
();
void
MetaspaceAux_test
();
void
TestMetaspaceAux_test
();
#if INCLUDE_ALL_GCS
void
TestG1BiasedArray_test
();
#endif
void
execute_internal_vm_tests
()
{
if
(
ExecuteInternalVMTests
)
{
...
...
@@ -5054,7 +5057,7 @@ void execute_internal_vm_tests() {
run_unit_test
(
TestReservedSpace_test
());
run_unit_test
(
TestReserveMemorySpecial_test
());
run_unit_test
(
TestVirtualSpace_test
());
run_unit_test
(
MetaspaceAux_test
());
run_unit_test
(
Test
MetaspaceAux_test
());
run_unit_test
(
GlobalDefinitions
::
test_globals
());
run_unit_test
(
GCTimerAllTest
::
all
());
run_unit_test
(
arrayOopDesc
::
test_max_array_length
());
...
...
@@ -5066,6 +5069,7 @@ void execute_internal_vm_tests() {
run_unit_test
(
VMStructs
::
test
());
#endif
#if INCLUDE_ALL_GCS
run_unit_test
(
TestG1BiasedArray_test
());
run_unit_test
(
HeapRegionRemSet
::
test_prt
());
#endif
tty
->
print_cr
(
"All internal VM tests passed"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录