8138983: Runtime: implement ranges for Shared*** flags
Implement ranges. Reviewed-by: ddmitriev, dholmes, jiangli
This commit is contained in:
parent
dcd4a03963
commit
97470c5146
@ -137,7 +137,7 @@ juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p,
|
||||
if (_type == CompactHashtable<Symbol*, char>::_symbol_table) {
|
||||
base_address = uintx(MetaspaceShared::shared_rs()->base());
|
||||
max_delta = uintx(MetaspaceShared::shared_rs()->size());
|
||||
assert(max_delta <= 0x7fffffff, "range check");
|
||||
assert(max_delta <= MAX_SHARED_DELTA, "range check");
|
||||
} else {
|
||||
assert((_type == CompactHashtable<oop, char>::_string_table), "unknown table");
|
||||
assert(UseCompressedOops, "UseCompressedOops is required");
|
||||
|
@ -3230,36 +3230,6 @@ void Metaspace::global_initialize() {
|
||||
SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment);
|
||||
SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment);
|
||||
|
||||
// make sure SharedReadOnlySize and SharedReadWriteSize are not less than
|
||||
// the minimum values.
|
||||
if (SharedReadOnlySize < MetaspaceShared::min_ro_size){
|
||||
report_out_of_shared_space(SharedReadOnly);
|
||||
}
|
||||
|
||||
if (SharedReadWriteSize < MetaspaceShared::min_rw_size){
|
||||
report_out_of_shared_space(SharedReadWrite);
|
||||
}
|
||||
|
||||
// the min_misc_data_size and min_misc_code_size estimates are based on
|
||||
// MetaspaceShared::generate_vtable_methods().
|
||||
// The minimum size only accounts for the vtable methods. Any size less than the
|
||||
// minimum required size would cause vm crash when allocating the vtable methods.
|
||||
uint min_misc_data_size = align_size_up(
|
||||
MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size * sizeof(void*), max_alignment);
|
||||
|
||||
if (SharedMiscDataSize < min_misc_data_size) {
|
||||
report_out_of_shared_space(SharedMiscData);
|
||||
}
|
||||
|
||||
uintx min_misc_code_size = align_size_up(
|
||||
(MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) *
|
||||
(sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size,
|
||||
max_alignment);
|
||||
|
||||
if (SharedMiscCodeSize < min_misc_code_size) {
|
||||
report_out_of_shared_space(SharedMiscCode);
|
||||
}
|
||||
|
||||
// Initialize with the sum of the shared space sizes. The read-only
|
||||
// and read write metaspace chunks will be allocated out of this and the
|
||||
// remainder is the misc code and data chunks.
|
||||
|
@ -32,14 +32,55 @@
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#define LargeSharedArchiveSize (300*M)
|
||||
#define HugeSharedArchiveSize (800*M)
|
||||
#define ReadOnlyRegionPercentage 0.4
|
||||
#define ReadWriteRegionPercentage 0.55
|
||||
#define MiscDataRegionPercentage 0.03
|
||||
#define MiscCodeRegionPercentage 0.02
|
||||
#define LargeThresholdClassCount 5000
|
||||
#define HugeThresholdClassCount 40000
|
||||
#define DEFAULT_VTBL_LIST_SIZE (17) // number of entries in the shared space vtable list.
|
||||
#define DEFAULT_VTBL_VIRTUALS_COUNT (200) // maximum number of virtual functions
|
||||
// If virtual functions are added to Metadata,
|
||||
// this number needs to be increased. Also,
|
||||
// SharedMiscCodeSize will need to be increased.
|
||||
// The following 2 sizes were based on
|
||||
// MetaspaceShared::generate_vtable_methods()
|
||||
#define DEFAULT_VTBL_METHOD_SIZE (16) // conservative size of the mov1 and jmp instructions
|
||||
// for the x64 platform
|
||||
#define DEFAULT_VTBL_COMMON_CODE_SIZE (1*K) // conservative size of the "common_code" for the x64 platform
|
||||
|
||||
#define DEFAULT_SHARED_READ_WRITE_SIZE (NOT_LP64(12*M) LP64_ONLY(16*M))
|
||||
#define MIN_SHARED_READ_WRITE_SIZE (NOT_LP64(7*M) LP64_ONLY(12*M))
|
||||
|
||||
#define DEFAULT_SHARED_READ_ONLY_SIZE (NOT_LP64(12*M) LP64_ONLY(16*M))
|
||||
#define MIN_SHARED_READ_ONLY_SIZE (NOT_LP64(8*M) LP64_ONLY(9*M))
|
||||
|
||||
// the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
|
||||
// MetaspaceShared::generate_vtable_methods().
|
||||
// The minimum size only accounts for the vtable methods. Any size less than the
|
||||
// minimum required size would cause vm crash when allocating the vtable methods.
|
||||
#define SHARED_MISC_SIZE_FOR(size) (DEFAULT_VTBL_VIRTUALS_COUNT*DEFAULT_VTBL_LIST_SIZE*size)
|
||||
|
||||
#define DEFAULT_SHARED_MISC_DATA_SIZE (NOT_LP64(2*M) LP64_ONLY(4*M))
|
||||
#define MIN_SHARED_MISC_DATA_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*)))
|
||||
|
||||
#define DEFAULT_SHARED_MISC_CODE_SIZE (120*K)
|
||||
#define MIN_SHARED_MISC_CODE_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*))+SHARED_MISC_SIZE_FOR(DEFAULT_VTBL_METHOD_SIZE)+DEFAULT_VTBL_COMMON_CODE_SIZE)
|
||||
|
||||
#define DEFAULT_COMBINED_SIZE (DEFAULT_SHARED_READ_WRITE_SIZE+DEFAULT_SHARED_READ_ONLY_SIZE+DEFAULT_SHARED_MISC_DATA_SIZE+DEFAULT_SHARED_MISC_CODE_SIZE)
|
||||
|
||||
// the max size is the MAX size (ie. 0x7FFFFFFF) - the total size of
|
||||
// the other 3 sections - page size (to avoid overflow in case the final
|
||||
// size will get aligned up on page size)
|
||||
#define SHARED_PAGE ((size_t)os::vm_page_size())
|
||||
#define MAX_SHARED_DELTA (0x7FFFFFFF)
|
||||
#define MAX_SHARED_READ_WRITE_SIZE (MAX_SHARED_DELTA-(MIN_SHARED_READ_ONLY_SIZE+MIN_SHARED_MISC_DATA_SIZE+MIN_SHARED_MISC_CODE_SIZE)-SHARED_PAGE)
|
||||
#define MAX_SHARED_READ_ONLY_SIZE (MAX_SHARED_DELTA-(MIN_SHARED_READ_WRITE_SIZE+MIN_SHARED_MISC_DATA_SIZE+MIN_SHARED_MISC_CODE_SIZE)-SHARED_PAGE)
|
||||
#define MAX_SHARED_MISC_DATA_SIZE (MAX_SHARED_DELTA-(MIN_SHARED_READ_WRITE_SIZE+MIN_SHARED_READ_ONLY_SIZE+MIN_SHARED_MISC_CODE_SIZE)-SHARED_PAGE)
|
||||
#define MAX_SHARED_MISC_CODE_SIZE (MAX_SHARED_DELTA-(MIN_SHARED_READ_WRITE_SIZE+MIN_SHARED_READ_ONLY_SIZE+MIN_SHARED_MISC_DATA_SIZE)-SHARED_PAGE)
|
||||
|
||||
#define LargeSharedArchiveSize (300*M)
|
||||
#define HugeSharedArchiveSize (800*M)
|
||||
#define ReadOnlyRegionPercentage 0.4
|
||||
#define ReadWriteRegionPercentage 0.55
|
||||
#define MiscDataRegionPercentage 0.03
|
||||
#define MiscCodeRegionPercentage 0.02
|
||||
#define LargeThresholdClassCount 5000
|
||||
#define HugeThresholdClassCount 40000
|
||||
|
||||
#define SET_ESTIMATED_SIZE(type, region) \
|
||||
Shared ##region## Size = FLAG_IS_DEFAULT(Shared ##region## Size) ? \
|
||||
@ -69,21 +110,10 @@ class MetaspaceShared : AllStatic {
|
||||
static bool _archive_loading_failed;
|
||||
public:
|
||||
enum {
|
||||
vtbl_list_size = 17, // number of entries in the shared space vtable list.
|
||||
num_virtuals = 200, // maximum number of virtual functions
|
||||
// If virtual functions are added to Metadata,
|
||||
// this number needs to be increased. Also,
|
||||
// SharedMiscCodeSize will need to be increased.
|
||||
// The following 2 sizes were based on
|
||||
// MetaspaceShared::generate_vtable_methods()
|
||||
vtbl_method_size = 16, // conservative size of the mov1 and jmp instructions
|
||||
// for the x64 platform
|
||||
vtbl_common_code_size = (1*K) // conservative size of the "common_code" for the x64 platform
|
||||
};
|
||||
|
||||
enum {
|
||||
min_ro_size = NOT_LP64(8*M) LP64_ONLY(9*M), // minimum ro and rw regions sizes based on dumping
|
||||
min_rw_size = NOT_LP64(7*M) LP64_ONLY(12*M) // of a shared archive using the default classlist
|
||||
vtbl_list_size = DEFAULT_VTBL_LIST_SIZE,
|
||||
num_virtuals = DEFAULT_VTBL_VIRTUALS_COUNT,
|
||||
vtbl_method_size = DEFAULT_VTBL_METHOD_SIZE,
|
||||
vtbl_common_code_size = DEFAULT_VTBL_COMMON_CODE_SIZE
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -223,7 +223,7 @@ void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_doub
|
||||
#define EMIT_CONSTRAINT_CHECK(func, type) , func, CommandLineFlagConstraint::type
|
||||
|
||||
// the "name" argument must be a string literal
|
||||
#define INITIAL_CONSTRAINTS_SIZE 45
|
||||
#define INITIAL_CONSTRAINTS_SIZE 69
|
||||
GrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL;
|
||||
CommandLineFlagConstraint::ConstraintType CommandLineFlagConstraintList::_validating_type = CommandLineFlagConstraint::AtParse;
|
||||
|
||||
|
@ -279,7 +279,7 @@ void emit_range_double(const char* name, double min, double max) {
|
||||
// Generate func argument to pass into emit_range_xxx functions
|
||||
#define EMIT_RANGE_CHECK(a, b) , a, b
|
||||
|
||||
#define INITIAL_RANGES_SIZE 205
|
||||
#define INITIAL_RANGES_SIZE 320
|
||||
GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
|
||||
|
||||
// Check the ranges of all flags that have them
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGRANGELIST_HPP
|
||||
#define SHARE_VM_RUNTIME_COMMANDLINEFLAGRANGELIST_HPP
|
||||
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
|
@ -4110,21 +4110,26 @@ public:
|
||||
"If PrintSharedArchiveAndExit is true, also print the shared " \
|
||||
"dictionary") \
|
||||
\
|
||||
product(size_t, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(16*M), \
|
||||
product(size_t, SharedReadWriteSize, DEFAULT_SHARED_READ_WRITE_SIZE, \
|
||||
"Size of read-write space for metadata (in bytes)") \
|
||||
range(MIN_SHARED_READ_WRITE_SIZE, MAX_SHARED_READ_WRITE_SIZE) \
|
||||
\
|
||||
product(size_t, SharedReadOnlySize, NOT_LP64(12*M) LP64_ONLY(16*M), \
|
||||
product(size_t, SharedReadOnlySize, DEFAULT_SHARED_READ_ONLY_SIZE, \
|
||||
"Size of read-only space for metadata (in bytes)") \
|
||||
range(MIN_SHARED_READ_ONLY_SIZE, MAX_SHARED_READ_ONLY_SIZE) \
|
||||
\
|
||||
product(uintx, SharedMiscDataSize, NOT_LP64(2*M) LP64_ONLY(4*M), \
|
||||
product(size_t, SharedMiscDataSize, DEFAULT_SHARED_MISC_DATA_SIZE, \
|
||||
"Size of the shared miscellaneous data area (in bytes)") \
|
||||
range(MIN_SHARED_MISC_DATA_SIZE, MAX_SHARED_MISC_DATA_SIZE) \
|
||||
\
|
||||
product(uintx, SharedMiscCodeSize, 120*K, \
|
||||
product(size_t, SharedMiscCodeSize, DEFAULT_SHARED_MISC_CODE_SIZE, \
|
||||
"Size of the shared miscellaneous code area (in bytes)") \
|
||||
range(MIN_SHARED_MISC_CODE_SIZE, MAX_SHARED_MISC_CODE_SIZE) \
|
||||
\
|
||||
product(uintx, SharedBaseAddress, LP64_ONLY(32*G) \
|
||||
product(size_t, SharedBaseAddress, LP64_ONLY(32*G) \
|
||||
NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \
|
||||
"Address to allocate shared memory region for class data") \
|
||||
range(0, SIZE_MAX) \
|
||||
\
|
||||
product(uintx, SharedSymbolTableBucketSize, 4, \
|
||||
"Average number of symbols per bucket in shared table") \
|
||||
|
@ -55,9 +55,28 @@ public class TestOptionsWithRanges {
|
||||
* JDK-8136766
|
||||
* Temporarily remove ThreadStackSize from testing because Windows can set it to 0
|
||||
* (for default OS size) but other platforms insist it must be greater than 0
|
||||
*/
|
||||
*/
|
||||
allOptionsAsMap.remove("ThreadStackSize");
|
||||
|
||||
/*
|
||||
* JDK-8141650
|
||||
* Temporarily exclude SharedMiscDataSize as it will exit the VM with exit code 2 and
|
||||
* "The shared miscellaneous data space is not large enough to preload requested classes."
|
||||
* message at min value.
|
||||
*/
|
||||
allOptionsAsMap.remove("SharedMiscDataSize");
|
||||
|
||||
/*
|
||||
* JDK-8142874
|
||||
* Temporarily exclude Shared* flagse as they will exit the VM with exit code 2 and
|
||||
* "The shared miscellaneous data space is not large enough to preload requested classes."
|
||||
* message at max values.
|
||||
*/
|
||||
allOptionsAsMap.remove("SharedReadWriteSize");
|
||||
allOptionsAsMap.remove("SharedReadOnlySize");
|
||||
allOptionsAsMap.remove("SharedMiscDataSize");
|
||||
allOptionsAsMap.remove("SharedMiscCodeSize");
|
||||
|
||||
/*
|
||||
* Exclude MallocMaxTestWords as it is expected to exit VM at small values (>=0)
|
||||
*/
|
||||
|
@ -223,7 +223,7 @@ public class IntJVMOption extends JVMOption {
|
||||
validValues.add("1");
|
||||
}
|
||||
|
||||
if (max.compareTo(MAX_4_BYTE_INT_PLUS_ONE) == 1) {
|
||||
if ((min.compareTo(MAX_4_BYTE_INT_PLUS_ONE) == -1) && (max.compareTo(MAX_4_BYTE_INT_PLUS_ONE) == 1)) {
|
||||
/*
|
||||
* Check for overflow when flag is assigned to the
|
||||
* 4 byte int variable
|
||||
@ -231,7 +231,7 @@ public class IntJVMOption extends JVMOption {
|
||||
validValues.add(MAX_4_BYTE_INT_PLUS_ONE.toString());
|
||||
}
|
||||
|
||||
if (max.compareTo(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE) == 1) {
|
||||
if ((min.compareTo(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE) == -1) && (max.compareTo(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE) == 1)) {
|
||||
/*
|
||||
* Check for overflow when flag is assigned to the
|
||||
* 4 byte unsigned int variable
|
||||
|
@ -27,6 +27,7 @@ import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -49,6 +50,8 @@ public class JVMOptionsUtils {
|
||||
/* Used to start the JVM with the same type as current */
|
||||
static String VMType;
|
||||
|
||||
private static Map<String, JVMOption> optionsAsMap;
|
||||
|
||||
static {
|
||||
if (Platform.isServer()) {
|
||||
VMType = "-server";
|
||||
@ -63,6 +66,84 @@ public class JVMOptionsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean fitsRange(String optionName, BigDecimal number) throws Exception {
|
||||
JVMOption option;
|
||||
String minRangeString = null;
|
||||
String maxRangeString = null;
|
||||
boolean fits = true;
|
||||
|
||||
if (optionsAsMap == null) {
|
||||
optionsAsMap = getOptionsWithRangeAsMap();
|
||||
}
|
||||
|
||||
option = optionsAsMap.get(optionName);
|
||||
if (option != null) {
|
||||
minRangeString = option.getMin();
|
||||
if (minRangeString != null) {
|
||||
fits = (number.compareTo(new BigDecimal(minRangeString)) >= 0);
|
||||
}
|
||||
maxRangeString = option.getMax();
|
||||
if (maxRangeString != null) {
|
||||
fits &= (number.compareTo(new BigDecimal(maxRangeString)) <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
return fits;
|
||||
}
|
||||
|
||||
public static boolean fitsRange(String optionName, String number) throws Exception {
|
||||
String lowerCase = number.toLowerCase();
|
||||
String multiplier = "1";
|
||||
if (lowerCase.endsWith("k")) {
|
||||
multiplier = "1024";
|
||||
lowerCase = lowerCase.substring(0, lowerCase.length()-1);
|
||||
} else if (lowerCase.endsWith("m")) {
|
||||
multiplier = "1048576"; //1024*1024
|
||||
lowerCase = lowerCase.substring(0, lowerCase.length()-1);
|
||||
} else if (lowerCase.endsWith("g")) {
|
||||
multiplier = "1073741824"; //1024*1024*1024
|
||||
lowerCase = lowerCase.substring(0, lowerCase.length()-1);
|
||||
} else if (lowerCase.endsWith("t")) {
|
||||
multiplier = "1099511627776"; //1024*1024*1024*1024
|
||||
lowerCase = lowerCase.substring(0, lowerCase.length()-1);
|
||||
}
|
||||
BigDecimal valueBig = new BigDecimal(lowerCase);
|
||||
BigDecimal multiplierBig = new BigDecimal(multiplier);
|
||||
return fitsRange(optionName, valueBig.multiply(multiplierBig));
|
||||
}
|
||||
|
||||
public static String getMinOptionRange(String optionName) throws Exception {
|
||||
JVMOption option;
|
||||
String minRange = null;
|
||||
|
||||
if (optionsAsMap == null) {
|
||||
optionsAsMap = getOptionsWithRangeAsMap();
|
||||
}
|
||||
|
||||
option = optionsAsMap.get(optionName);
|
||||
if (option != null) {
|
||||
minRange = option.getMin();
|
||||
}
|
||||
|
||||
return minRange;
|
||||
}
|
||||
|
||||
public static String getMaxOptionRange(String optionName) throws Exception {
|
||||
JVMOption option;
|
||||
String maxRange = null;
|
||||
|
||||
if (optionsAsMap == null) {
|
||||
optionsAsMap = getOptionsWithRangeAsMap();
|
||||
}
|
||||
|
||||
option = optionsAsMap.get(optionName);
|
||||
if (option != null) {
|
||||
maxRange = option.getMax();
|
||||
}
|
||||
|
||||
return maxRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dependency for option depending on it's name. E.g. enable G1 GC for
|
||||
* G1 options or add prepend options to not hit constraints.
|
||||
@ -80,6 +161,13 @@ public class JVMOptionsUtils {
|
||||
option.addPrepend("-XX:+UseConcMarkSweepGC");
|
||||
}
|
||||
|
||||
if (name.startsWith("Shared")) {
|
||||
option.addPrepend("-XX:+UnlockDiagnosticVMOptions");
|
||||
String fileName = "Test" + name + ".jsa";
|
||||
option.addPrepend("-XX:SharedArchiveFile=" + fileName);
|
||||
option.addPrepend("-Xshare:dump");
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "MinHeapFreeRatio":
|
||||
option.addPrepend("-XX:MaxHeapFreeRatio=100");
|
||||
@ -112,7 +200,6 @@ public class JVMOptionsUtils {
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,50 +23,72 @@
|
||||
|
||||
/* @test LimitSharedSizes
|
||||
* @summary Test handling of limits on shared space size
|
||||
* @library /testlibrary
|
||||
* @library /testlibrary /runtime/CommandLine/OptionsValidation/common
|
||||
* @modules java.base/sun.misc
|
||||
* java.management
|
||||
* @run main LimitSharedSizes
|
||||
*/
|
||||
|
||||
import jdk.test.lib.*;
|
||||
import optionsvalidation.JVMOptionsUtils;
|
||||
|
||||
public class LimitSharedSizes {
|
||||
static enum Result {
|
||||
OUT_OF_RANGE,
|
||||
TOO_SMALL,
|
||||
VALID,
|
||||
VALID_ARCHIVE
|
||||
}
|
||||
|
||||
static enum Region {
|
||||
RO, RW, MD, MC
|
||||
}
|
||||
|
||||
private static final boolean fitsRange(String name, String value) throws RuntimeException {
|
||||
boolean fits = true;
|
||||
try {
|
||||
fits = JVMOptionsUtils.fitsRange(name, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
return fits;
|
||||
}
|
||||
|
||||
private static class SharedSizeTestData {
|
||||
public String optionName;
|
||||
public String optionValue;
|
||||
public String expectedErrorMsg;
|
||||
public Result optionResult;
|
||||
|
||||
public SharedSizeTestData(Region region, String value, String msg) {
|
||||
optionName = getName(region);
|
||||
public SharedSizeTestData(Region region, String value) {
|
||||
optionName = "-XX:"+getName(region);
|
||||
optionValue = value;
|
||||
expectedErrorMsg = msg;
|
||||
if (fitsRange(getName(region), value) == false) {
|
||||
optionResult = Result.OUT_OF_RANGE;
|
||||
} else {
|
||||
optionResult = Result.TOO_SMALL;
|
||||
}
|
||||
}
|
||||
|
||||
public SharedSizeTestData(Region region, String msg) {
|
||||
optionName = getName(region);
|
||||
optionValue = getValue(region);
|
||||
expectedErrorMsg = msg;
|
||||
public SharedSizeTestData(Region region, String value, Result result) {
|
||||
optionName = "-XX:"+getName(region);
|
||||
optionValue = value;
|
||||
optionResult = result;
|
||||
}
|
||||
|
||||
private String getName(Region region) {
|
||||
String name;
|
||||
switch (region) {
|
||||
case RO:
|
||||
name = "-XX:SharedReadOnlySize";
|
||||
name = "SharedReadOnlySize";
|
||||
break;
|
||||
case RW:
|
||||
name = "-XX:SharedReadWriteSize";
|
||||
name = "SharedReadWriteSize";
|
||||
break;
|
||||
case MD:
|
||||
name = "-XX:SharedMiscDataSize";
|
||||
name = "SharedMiscDataSize";
|
||||
break;
|
||||
case MC:
|
||||
name = "-XX:SharedMiscCodeSize";
|
||||
name = "SharedMiscCodeSize";
|
||||
break;
|
||||
default:
|
||||
name = "Unknown";
|
||||
@ -75,53 +97,37 @@ public class LimitSharedSizes {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getValue(Region region) {
|
||||
String value;
|
||||
switch (region) {
|
||||
case RO:
|
||||
value = Platform.is64bit() ? "9M" : "8M";
|
||||
break;
|
||||
case RW:
|
||||
value = Platform.is64bit() ? "12M" : "7M";
|
||||
break;
|
||||
case MD:
|
||||
value = Platform.is64bit() ? "4M" : "2M";
|
||||
break;
|
||||
case MC:
|
||||
value = "120k";
|
||||
break;
|
||||
default:
|
||||
value = "0M";
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
public Result getResult() {
|
||||
return optionResult;
|
||||
}
|
||||
}
|
||||
|
||||
private static final SharedSizeTestData[] testTable = {
|
||||
// Too small of a region size should not cause a vm crash.
|
||||
// It should result in an error message like the following:
|
||||
// It should result in an error message either like the following #1:
|
||||
// The shared miscellaneous code space is not large enough
|
||||
// to preload requested classes. Use -XX:SharedMiscCodeSize=
|
||||
// to increase the initial size of shared miscellaneous code space.
|
||||
new SharedSizeTestData(Region.RO, "4M", "read only"),
|
||||
new SharedSizeTestData(Region.RW, "4M", "read write"),
|
||||
new SharedSizeTestData(Region.MD, "50k", "miscellaneous data"),
|
||||
new SharedSizeTestData(Region.MC, "20k", "miscellaneous code"),
|
||||
// or #2:
|
||||
// The shared miscellaneous code space is outside the allowed range
|
||||
new SharedSizeTestData(Region.RO, "4M"),
|
||||
new SharedSizeTestData(Region.RW, "4M"),
|
||||
new SharedSizeTestData(Region.MD, "50k"),
|
||||
new SharedSizeTestData(Region.MC, "20k"),
|
||||
|
||||
// these values are larger than default ones, but should
|
||||
// these values are larger than default ones, and should
|
||||
// be acceptable and not cause failure
|
||||
new SharedSizeTestData(Region.RO, "20M", null),
|
||||
new SharedSizeTestData(Region.RW, "20M", null),
|
||||
new SharedSizeTestData(Region.MD, "20M", null),
|
||||
new SharedSizeTestData(Region.MC, "20M", null),
|
||||
new SharedSizeTestData(Region.RO, "20M", Result.VALID),
|
||||
new SharedSizeTestData(Region.RW, "20M", Result.VALID),
|
||||
new SharedSizeTestData(Region.MD, "20M", Result.VALID),
|
||||
new SharedSizeTestData(Region.MC, "20M", Result.VALID),
|
||||
|
||||
// test with sizes which just meet the minimum required sizes
|
||||
// the following tests also attempt to use the shared archive
|
||||
new SharedSizeTestData(Region.RO, "UseArchive"),
|
||||
new SharedSizeTestData(Region.RW, "UseArchive"),
|
||||
new SharedSizeTestData(Region.MD, "UseArchive"),
|
||||
new SharedSizeTestData(Region.MC, "UseArchive")
|
||||
new SharedSizeTestData(Region.RO, Platform.is64bit() ? "9M":"8M", Result.VALID_ARCHIVE),
|
||||
new SharedSizeTestData(Region.RW, Platform.is64bit() ? "12M":"7M", Result.VALID_ARCHIVE),
|
||||
new SharedSizeTestData(Region.MD, Platform.is64bit() ? "4M":"2M", Result.VALID_ARCHIVE),
|
||||
new SharedSizeTestData(Region.MC, "120k", Result.VALID_ARCHIVE),
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -131,6 +137,7 @@ public class LimitSharedSizes {
|
||||
counter++;
|
||||
|
||||
String option = td.optionName + "=" + td.optionValue;
|
||||
System.out.println("testing option number <" + counter + ">");
|
||||
System.out.println("testing option <" + option + ">");
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
@ -141,43 +148,52 @@ public class LimitSharedSizes {
|
||||
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
|
||||
if (td.expectedErrorMsg != null) {
|
||||
if (!td.expectedErrorMsg.equals("UseArchive")) {
|
||||
output.shouldContain("The shared " + td.expectedErrorMsg
|
||||
+ " space is not large enough");
|
||||
switch (td.getResult()) {
|
||||
case VALID:
|
||||
case VALID_ARCHIVE:
|
||||
{
|
||||
output.shouldNotContain("space is not large enough");
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
output.shouldHaveExitValue(2);
|
||||
} else {
|
||||
output.shouldNotContain("space is not large enough");
|
||||
output.shouldHaveExitValue(0);
|
||||
if (td.getResult() == Result.VALID_ARCHIVE) {
|
||||
// try to use the archive
|
||||
pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:SharedArchiveFile=./" + fileName,
|
||||
"-XX:+PrintSharedArchiveAndExit",
|
||||
"-version");
|
||||
|
||||
// try to use the archive
|
||||
pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:SharedArchiveFile=./" + fileName,
|
||||
"-XX:+PrintSharedArchiveAndExit",
|
||||
"-version");
|
||||
|
||||
try {
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("archive is valid");
|
||||
} catch (RuntimeException e) {
|
||||
// if sharing failed due to ASLR or similar reasons,
|
||||
// check whether sharing was attempted at all (UseSharedSpaces)
|
||||
if ((output.getOutput().contains("Unable to use shared archive") ||
|
||||
output.getOutput().contains("Unable to map ReadOnly shared space at required address.") ||
|
||||
output.getOutput().contains("Unable to map ReadWrite shared space at required address.") ||
|
||||
output.getOutput().contains("Unable to reserve shared space at required address")) &&
|
||||
output.getExitValue() == 1) {
|
||||
System.out.println("Unable to use shared archive: test not executed; assumed passed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
output.shouldHaveExitValue(0);
|
||||
try {
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("archive is valid");
|
||||
} catch (RuntimeException e) {
|
||||
// if sharing failed due to ASLR or similar reasons,
|
||||
// check whether sharing was attempted at all (UseSharedSpaces)
|
||||
if ((output.getOutput().contains("Unable to use shared archive") ||
|
||||
output.getOutput().contains("Unable to map ReadOnly shared space at required address.") ||
|
||||
output.getOutput().contains("Unable to map ReadWrite shared space at required address.") ||
|
||||
output.getOutput().contains("Unable to reserve shared space at required address")) &&
|
||||
output.getExitValue() == 1) {
|
||||
System.out.println("Unable to use shared archive: test not executed; assumed passed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output.shouldNotContain("space is not large enough");
|
||||
output.shouldHaveExitValue(0);
|
||||
break;
|
||||
case TOO_SMALL:
|
||||
{
|
||||
output.shouldContain("space is not large enough");
|
||||
output.shouldHaveExitValue(2);
|
||||
}
|
||||
break;
|
||||
case OUT_OF_RANGE:
|
||||
{
|
||||
output.shouldContain("outside the allowed range");
|
||||
output.shouldHaveExitValue(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user