8054823: Add size_t as a valid VM flag type

Reviewed-by: kvn, vlivanov, sla
This commit is contained in:
Stefan Karlsson 2014-08-11 14:03:06 +02:00
parent dd95f0a0c2
commit 2880629908
12 changed files with 439 additions and 7 deletions

View file

@ -597,6 +597,15 @@ WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name))
return NULL; return NULL;
WB_END WB_END
WB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name))
uintx result;
if (GetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAt)) {
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return longBox(thread, env, result);
}
return NULL;
WB_END
WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))
double result; double result;
if (GetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAt)) { if (GetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAt)) {
@ -637,6 +646,11 @@ WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong va
SetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut); SetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut);
WB_END WB_END
WB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
size_t result = value;
SetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAtPut);
WB_END
WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value)) WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value))
double result = value; double result = value;
SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut); SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut);
@ -880,6 +894,7 @@ static JNINativeMethod methods[] = {
{CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
{CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag}, {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
{CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag}, {CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag},
{CC"setSizeTVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetSizeTVMFlag},
{CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag}, {CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag},
{CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V", {CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V",
(void*)&WB_SetStringVMFlag}, (void*)&WB_SetStringVMFlag},
@ -891,6 +906,8 @@ static JNINativeMethod methods[] = {
(void*)&WB_GetUintxVMFlag}, (void*)&WB_GetUintxVMFlag},
{CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", {CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
(void*)&WB_GetUint64VMFlag}, (void*)&WB_GetUint64VMFlag},
{CC"getSizeTVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
(void*)&WB_GetSizeTVMFlag},
{CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;", {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;",
(void*)&WB_GetDoubleVMFlag}, (void*)&WB_GetDoubleVMFlag},
{CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;", {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;",

View file

@ -686,6 +686,10 @@ static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) {
if (!is_neg && CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin)) { if (!is_neg && CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin)) {
return true; return true;
} }
size_t size_t_v = (size_t) v;
if (!is_neg && CommandLineFlags::size_tAtPut(name, &size_t_v, origin)) {
return true;
}
return false; return false;
} }

View file

@ -131,6 +131,19 @@ void Flag::set_uint64_t(uint64_t value) {
*((uint64_t*) _addr) = value; *((uint64_t*) _addr) = value;
} }
bool Flag::is_size_t() const {
return strcmp(_type, "size_t") == 0;
}
size_t Flag::get_size_t() const {
return *((size_t*) _addr);
}
void Flag::set_size_t(size_t value) {
check_writable();
*((size_t*) _addr) = value;
}
bool Flag::is_double() const { bool Flag::is_double() const {
return strcmp(_type, "double") == 0; return strcmp(_type, "double") == 0;
} }
@ -306,6 +319,9 @@ void Flag::print_on(outputStream* st, bool withComments) {
if (is_uint64_t()) { if (is_uint64_t()) {
st->print("%-16lu", get_uint64_t()); st->print("%-16lu", get_uint64_t());
} }
if (is_size_t()) {
st->print(SIZE_FORMAT_W(-16), get_size_t());
}
if (is_double()) { if (is_double()) {
st->print("%-16f", get_double()); st->print("%-16f", get_double());
} }
@ -395,6 +411,8 @@ void Flag::print_as_flag(outputStream* st) {
st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx()); st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
} else if (is_uint64_t()) { } else if (is_uint64_t()) {
st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t()); st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
} else if (is_size_t()) {
st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t());
} else if (is_double()) { } else if (is_double()) {
st->print("-XX:%s=%f", _name, get_double()); st->print("-XX:%s=%f", _name, get_double());
} else if (is_ccstr()) { } else if (is_ccstr()) {
@ -723,6 +741,34 @@ void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t va
faddr->set_origin(origin); faddr->set_origin(origin);
} }
bool CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return false;
if (!result->is_size_t()) return false;
*value = result->get_size_t();
return true;
}
bool CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
Flag* result = Flag::find_flag(name, len);
if (result == NULL) return false;
if (!result->is_size_t()) return false;
size_t old_value = result->get_size_t();
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
result->set_size_t(*value);
*value = old_value;
result->set_origin(origin);
return true;
}
void CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
Flag* faddr = address_of_flag(flag);
guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
faddr->set_size_t(value);
faddr->set_origin(origin);
}
bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) { bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) {
Flag* result = Flag::find_flag(name, len); Flag* result = Flag::find_flag(name, len);
if (result == NULL) return false; if (result == NULL) return false;

View file

@ -275,6 +275,10 @@ struct Flag {
uint64_t get_uint64_t() const; uint64_t get_uint64_t() const;
void set_uint64_t(uint64_t value); void set_uint64_t(uint64_t value);
bool is_size_t() const;
size_t get_size_t() const;
void set_size_t(size_t value);
bool is_double() const; bool is_double() const;
double get_double() const; double get_double() const;
void set_double(double value); void set_double(double value);
@ -350,7 +354,6 @@ class UIntFlagSetting {
~UIntFlagSetting() { *flag = val; } ~UIntFlagSetting() { *flag = val; }
}; };
class DoubleFlagSetting { class DoubleFlagSetting {
double val; double val;
double* flag; double* flag;
@ -359,6 +362,14 @@ class DoubleFlagSetting {
~DoubleFlagSetting() { *flag = val; } ~DoubleFlagSetting() { *flag = val; }
}; };
class SizeTFlagSetting {
size_t val;
size_t* flag;
public:
SizeTFlagSetting(size_t& fl, size_t newValue) { flag = &fl; val = fl; fl = newValue; }
~SizeTFlagSetting() { *flag = val; }
};
class CommandLineFlags { class CommandLineFlags {
public: public:
@ -377,6 +388,11 @@ class CommandLineFlags {
static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin); static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin);
static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); } static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
static bool size_tAt(const char* name, size_t len, size_t* value);
static bool size_tAt(const char* name, size_t* value) { return size_tAt(name, strlen(name), value); }
static bool size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin);
static bool size_tAtPut(const char* name, size_t* value, Flag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
static bool uint64_tAt(const char* name, size_t len, uint64_t* value); static bool uint64_tAt(const char* name, size_t len, uint64_t* value);
static bool uint64_tAt(const char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); } static bool uint64_tAt(const char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin); static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin);
@ -3883,8 +3899,8 @@ class CommandLineFlags {
diagnostic(ccstr, SharedArchiveFile, NULL, \ diagnostic(ccstr, SharedArchiveFile, NULL, \
"Override the default location of the CDS archive file") \ "Override the default location of the CDS archive file") \
\ \
experimental(uintx, ArrayAllocatorMallocLimit, \ experimental(size_t, ArrayAllocatorMallocLimit, \
SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \ SOLARIS_ONLY(64*K) NOT_SOLARIS((size_t)-1), \
"Allocation less than this value will be allocated " \ "Allocation less than this value will be allocated " \
"using malloc. Larger allocations will use mmap.") \ "using malloc. Larger allocations will use mmap.") \
\ \

View file

@ -200,6 +200,7 @@ class CommandLineFlagsEx : CommandLineFlags {
static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin); static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin); static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin); static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
static void size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin);
static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin); static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
// Contract: Flag will make private copy of the incoming value // Contract: Flag will make private copy of the incoming value
static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin); static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);

View file

@ -320,6 +320,25 @@ static jint set_uint64_t_flag(const char* name, AttachOperation* op, outputStrea
return res? JNI_OK : JNI_ERR; return res? JNI_OK : JNI_ERR;
} }
// set a size_t global flag using value from AttachOperation
static jint set_size_t_flag(const char* name, AttachOperation* op, outputStream* out) {
size_t value;
const char* arg1;
if ((arg1 = op->arg(1)) != NULL) {
int n = sscanf(arg1, SIZE_FORMAT, &value);
if (n != 1) {
out->print_cr("flag value must be an unsigned integer");
return JNI_ERR;
}
}
bool res = CommandLineFlags::size_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
if (! res) {
out->print_cr("setting flag %s failed", name);
}
return res? JNI_OK : JNI_ERR;
}
// set a string global flag using value from AttachOperation // set a string global flag using value from AttachOperation
static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out) { static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out) {
const char* value; const char* value;
@ -356,6 +375,8 @@ static jint set_flag(AttachOperation* op, outputStream* out) {
return set_uintx_flag(name, op, out); return set_uintx_flag(name, op, out);
} else if (f->is_uint64_t()) { } else if (f->is_uint64_t()) {
return set_uint64_t_flag(name, op, out); return set_uint64_t_flag(name, op, out);
} else if (f->is_size_t()) {
return set_size_t_flag(name, op, out);
} else if (f->is_ccstr()) { } else if (f->is_ccstr()) {
return set_ccstr_flag(name, op, out); return set_ccstr_flag(name, op, out);
} else { } else {

View file

@ -1696,6 +1696,9 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag,
} else if (flag->is_uint64_t()) { } else if (flag->is_uint64_t()) {
global->value.j = (jlong)flag->get_uint64_t(); global->value.j = (jlong)flag->get_uint64_t();
global->type = JMM_VMGLOBAL_TYPE_JLONG; global->type = JMM_VMGLOBAL_TYPE_JLONG;
} else if (flag->is_size_t()) {
global->value.j = (jlong)flag->get_size_t();
global->type = JMM_VMGLOBAL_TYPE_JLONG;
} else if (flag->is_ccstr()) { } else if (flag->is_ccstr()) {
Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false); Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false);
global->value.l = (jobject)JNIHandles::make_local(env, str()); global->value.l = (jobject)JNIHandles::make_local(env, str());
@ -1851,6 +1854,9 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value
} else if (flag->is_uint64_t()) { } else if (flag->is_uint64_t()) {
uint64_t uvalue = (uint64_t)new_value.j; uint64_t uvalue = (uint64_t)new_value.j;
succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT); succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT);
} else if (flag->is_size_t()) {
size_t svalue = (size_t)new_value.j;
succeed = CommandLineFlags::size_tAtPut(name, &svalue, Flag::MANAGEMENT);
} else if (flag->is_ccstr()) { } else if (flag->is_ccstr()) {
oop str = JNIHandles::resolve_external_guard(new_value.l); oop str = JNIHandles::resolve_external_guard(new_value.l);
if (str == NULL) { if (str == NULL) {

View file

@ -567,7 +567,7 @@ class TestBitMap : public AllStatic {
} }
static void testResizeNonResource() { static void testResizeNonResource() {
const uintx bitmap_bytes = BITMAP_SIZE / BitsPerByte; const size_t bitmap_bytes = BITMAP_SIZE / BitsPerByte;
// Test the default behavior // Test the default behavior
testResize(false); testResize(false);
@ -575,13 +575,13 @@ class TestBitMap : public AllStatic {
{ {
// Make sure that AllocatorMallocLimit is larger than our allocation request // Make sure that AllocatorMallocLimit is larger than our allocation request
// forcing it to call standard malloc() // forcing it to call standard malloc()
UIntFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes * 4); SizeTFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes * 4);
testResize(false); testResize(false);
} }
{ {
// Make sure that AllocatorMallocLimit is smaller than our allocation request // Make sure that AllocatorMallocLimit is smaller than our allocation request
// forcing it to call mmap() (or equivalent) // forcing it to call mmap() (or equivalent)
UIntFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes / 4); SizeTFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes / 4);
testResize(false); testResize(false);
} }
} }

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2014, 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.
*/
/*
* @test TestArrayAllocatorMallocLimit
* @summary Sanity check that the ArrayAllocatorMallocLimit flag can be set.
* The test helps verifying that size_t flags can be set/read.
* @bug 8054823
* @key gc
* @library /testlibrary
* @run driver TestArrayAllocatorMallocLimit
*/
import com.oracle.java.testlibrary.Asserts;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
import java.math.BigInteger;
public class TestArrayAllocatorMallocLimit {
public static void main(String [] args) throws Exception {
testDefaultValue();
testSetValue();
}
private static final String flagName = "ArrayAllocatorMallocLimit";
// size_t ArrayAllocatorMallocLimit = 18446744073709551615{experimental}
private static final String printFlagsFinalPattern = " *size_t *" + flagName + " *:?= *(\\d+) *\\{experimental\\} *";
public static void testDefaultValue() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions", "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
String value = output.firstMatch(printFlagsFinalPattern, 1);
try {
Asserts.assertNotNull(value, "Couldn't find size_t flag " + flagName);
// A size_t is not always parseable with Long.parseValue,
// use BigInteger instead.
BigInteger biValue = new BigInteger(value);
// Sanity check that we got a non-zero value.
Asserts.assertNotEquals(biValue, "0");
output.shouldHaveExitValue(0);
} catch (Exception e) {
System.err.println(output.getOutput());
throw e;
}
}
public static void testSetValue() throws Exception {
long flagValue = 2048;
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions", "-XX:" + flagName + "=" + flagValue, "-XX:+PrintFlagsFinal", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
String value = output.firstMatch(printFlagsFinalPattern, 1);
try {
Asserts.assertNotNull("Couldn't find size_t flag " + flagName);
long longValue = Long.parseLong(value);
Asserts.assertEquals(longValue, flagValue);
output.shouldHaveExitValue(0);
} catch (Exception e) {
System.err.println(output.getOutput());
throw e;
}
}
}

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2014, 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.
*/
/*
* @test
* @bug 8054823
* @summary Tests the setFlag and printFlag attach command
* @library /testlibrary
* @build com.oracle.java.testlibrary.* AttachSetGetFlag
* @run driver AttachSetGetFlag
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import sun.tools.attach.HotSpotVirtualMachine;
import com.oracle.java.testlibrary.Asserts;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.ProcessTools;
import com.sun.tools.attach.VirtualMachine;
public class AttachSetGetFlag {
public static void main(String... args) throws Exception {
// Test a manageable uintx flag.
testGetFlag("MaxHeapFreeRatio", "60");
testSetFlag("MaxHeapFreeRatio", "50", "60");
// Test a non-manageable size_t flag.
// Since it is not manageable, we can't test the setFlag functionality.
testGetFlag("ArrayAllocatorMallocLimit", "128");
// testSetFlag("ArrayAllocatorMallocLimit", "64", "128");
}
public static ProcessBuilder runTarget(String flagName, String flagValue) throws Exception {
return ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockExperimentalVMOptions",
"-XX:" + flagName + "=" + flagValue,
"AttachSetGetFlag$Target");
}
public static void testGetFlag(String flagName, String flagValue) throws Exception {
ProcessBuilder pb = runTarget(flagName, flagValue);
Process target = pb.start();
try {
waitForReady(target);
int pid = (int)target.getPid();
HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString());
// Test Get
BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(
vm.printFlag(flagName)));
boolean foundExpectedLine = false;
String line = null;
while((line = remoteDataReader.readLine()) != null) {
System.out.println("printFlag: " + line);
if (line.equals("-XX:" + flagName + "=" + flagValue)) {
foundExpectedLine = true;
}
}
Asserts.assertTrue(foundExpectedLine, "Didn't get the expected output: '-XX:" + flagName + "=" + flagValue + "'");
vm.detach();
}
finally {
target.destroy();
target.waitFor();
}
}
public static void testSetFlag(String flagName, String initialFlagValue, String flagValue) throws Exception {
ProcessBuilder pb = runTarget(flagName, initialFlagValue);
Process target = pb.start();
try {
waitForReady(target);
int pid = (int)target.getPid();
HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString());
// First set the value.
BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(
vm.setFlag(flagName, flagValue)));
String line;
while((line = remoteDataReader.readLine()) != null) {
System.out.println("setFlag: " + line);
// Just empty the stream.
}
remoteDataReader.close();
// Then read and make sure we get back the set value.
remoteDataReader = new BufferedReader(new InputStreamReader(vm.printFlag(flagName)));
boolean foundExpectedLine = false;
line = null;
while((line = remoteDataReader.readLine()) != null) {
System.out.println("getFlag: " + line);
if (line.equals("-XX:" + flagName + "=" + flagValue)) {
foundExpectedLine = true;
}
}
Asserts.assertTrue(foundExpectedLine, "Didn't get the expected output: '-XX:" + flagName + "=" + flagValue + "'");
vm.detach();
} finally {
target.destroy();
target.waitFor();
}
}
private static void waitForReady(Process target) throws Exception {
InputStream os = target.getInputStream();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(os))) {
String line;
while ((line = reader.readLine()) != null) {
if ("Ready".equals(line)) {
return;
}
}
}
}
public static class Target {
public static void main(String [] args) throws Exception {
System.out.println("Ready");
System.out.flush();
while (true) {
Thread.sleep(1000);
}
}
}
}

View file

@ -167,17 +167,20 @@ public class WhiteBox {
public native void setIntxVMFlag(String name, long value); public native void setIntxVMFlag(String name, long value);
public native void setUintxVMFlag(String name, long value); public native void setUintxVMFlag(String name, long value);
public native void setUint64VMFlag(String name, long value); public native void setUint64VMFlag(String name, long value);
public native void setSizeTVMFlag(String name, long value);
public native void setStringVMFlag(String name, String value); public native void setStringVMFlag(String name, String value);
public native void setDoubleVMFlag(String name, double value); public native void setDoubleVMFlag(String name, double value);
public native Boolean getBooleanVMFlag(String name); public native Boolean getBooleanVMFlag(String name);
public native Long getIntxVMFlag(String name); public native Long getIntxVMFlag(String name);
public native Long getUintxVMFlag(String name); public native Long getUintxVMFlag(String name);
public native Long getUint64VMFlag(String name); public native Long getUint64VMFlag(String name);
public native Long getSizeTVMFlag(String name);
public native String getStringVMFlag(String name); public native String getStringVMFlag(String name);
public native Double getDoubleVMFlag(String name); public native Double getDoubleVMFlag(String name);
private final List<Function<String,Object>> flagsGetters = Arrays.asList( private final List<Function<String,Object>> flagsGetters = Arrays.asList(
this::getBooleanVMFlag, this::getIntxVMFlag, this::getUintxVMFlag, this::getBooleanVMFlag, this::getIntxVMFlag, this::getUintxVMFlag,
this::getUint64VMFlag, this::getStringVMFlag, this::getDoubleVMFlag); this::getUint64VMFlag, this::getSizeTVMFlag, this::getStringVMFlag,
this::getDoubleVMFlag);
public Object getVMFlag(String name) { public Object getVMFlag(String name) {
return flagsGetters.stream() return flagsGetters.stream()

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, 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.
*/
/*
* @test SizeTTest
* @bug 8054823
* @library /testlibrary /testlibrary/whitebox
* @build SizeTTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions SizeTTest
* @summary testing of WB::set/getSizeTVMFlag()
*/
import com.oracle.java.testlibrary.Platform;
public class SizeTTest {
private static final String FLAG_NAME = "ArrayAllocatorMallocLimit";
private static final Long[] TESTS = {0L, 100L, (long) Integer.MAX_VALUE,
(1L << 32L) - 1L, 1L << 32L};
private static final Long[] EXPECTED_64 = TESTS;
private static final Long[] EXPECTED_32 = {0L, 100L,
(long) Integer.MAX_VALUE, (1L << 32L) - 1L, 0L};
public static void main(String[] args) throws Exception {
VmFlagTest.runTest(FLAG_NAME, TESTS,
Platform.is64bit() ? EXPECTED_64 : EXPECTED_32,
VmFlagTest.WHITE_BOX::setSizeTVMFlag,
VmFlagTest.WHITE_BOX::getSizeTVMFlag);
}
}