mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
Merge
This commit is contained in:
commit
b046110ab7
41 changed files with 620 additions and 426 deletions
|
@ -315,6 +315,7 @@ inline Symbol* check_symbol_at(constantPoolHandle cp, int index) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
void ClassFileParser::report_assert_property_failure(const char* msg, TRAPS) {
|
||||
|
@ -327,6 +328,7 @@ void ClassFileParser::report_assert_property_failure(const char* msg, int index,
|
|||
fatal(msg, index, _class_name->as_C_string());
|
||||
}
|
||||
PRAGMA_DIAG_POP
|
||||
#endif
|
||||
|
||||
constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
ClassFileStream* cfs = stream();
|
||||
|
|
|
@ -319,8 +319,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
|||
if (!b) { classfile_parse_error(msg, CHECK); }
|
||||
}
|
||||
|
||||
void report_assert_property_failure(const char* msg, TRAPS);
|
||||
void report_assert_property_failure(const char* msg, int index, TRAPS);
|
||||
void report_assert_property_failure(const char* msg, TRAPS) PRODUCT_RETURN;
|
||||
void report_assert_property_failure(const char* msg, int index, TRAPS) PRODUCT_RETURN;
|
||||
|
||||
inline void assert_property(bool b, const char* msg, TRAPS) {
|
||||
#ifdef ASSERT
|
||||
|
|
|
@ -1967,7 +1967,8 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
|
|||
instanceKlassHandle k,
|
||||
Handle class_loader, bool defining,
|
||||
TRAPS) {
|
||||
const char *linkage_error = NULL;
|
||||
const char *linkage_error1 = NULL;
|
||||
const char *linkage_error2 = NULL;
|
||||
{
|
||||
Symbol* name = k->name();
|
||||
ClassLoaderData *loader_data = class_loader_data(class_loader);
|
||||
|
@ -1984,8 +1985,8 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
|
|||
|
||||
assert(check->is_instance_klass(), "noninstance in systemdictionary");
|
||||
if ((defining == true) || (k() != check)) {
|
||||
linkage_error = "loader (instance of %s): attempted duplicate class "
|
||||
"definition for name: \"%s\"";
|
||||
linkage_error1 = "loader (instance of ";
|
||||
linkage_error2 = "): attempted duplicate class definition for name: \"";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -1996,10 +1997,10 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
|
|||
assert(ph_check == NULL || ph_check == name, "invalid symbol");
|
||||
#endif
|
||||
|
||||
if (linkage_error == NULL) {
|
||||
if (linkage_error1 == NULL) {
|
||||
if (constraints()->check_or_update(k, class_loader, name) == false) {
|
||||
linkage_error = "loader constraint violation: loader (instance of %s)"
|
||||
" previously initiated loading for a different type with name \"%s\"";
|
||||
linkage_error1 = "loader constraint violation: loader (instance of ";
|
||||
linkage_error2 = ") previously initiated loading for a different type with name \"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2007,14 +2008,14 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
|
|||
// Throw error now if needed (cannot throw while holding
|
||||
// SystemDictionary_lock because of rank ordering)
|
||||
|
||||
if (linkage_error) {
|
||||
if (linkage_error1) {
|
||||
ResourceMark rm(THREAD);
|
||||
const char* class_loader_name = loader_name(class_loader());
|
||||
char* type_name = k->name()->as_C_string();
|
||||
size_t buflen = strlen(linkage_error) + strlen(class_loader_name) +
|
||||
strlen(type_name);
|
||||
size_t buflen = strlen(linkage_error1) + strlen(class_loader_name) +
|
||||
strlen(linkage_error2) + strlen(type_name) + 2; // +2 for '"' and null byte.
|
||||
char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
|
||||
jio_snprintf(buf, buflen, linkage_error, class_loader_name, type_name);
|
||||
jio_snprintf(buf, buflen, "%s%s%s%s\"", linkage_error1, class_loader_name, linkage_error2, type_name);
|
||||
THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ class Ticks;
|
|||
\
|
||||
do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \
|
||||
do_klass(StringBuilder_klass, java_lang_StringBuilder, Pre ) \
|
||||
do_klass(misc_Unsafe_klass, sun_misc_Unsafe, Pre ) \
|
||||
do_klass(internal_Unsafe_klass, jdk_internal_misc_Unsafe, Pre ) \
|
||||
\
|
||||
/* support for CDS */ \
|
||||
do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream, Pre ) \
|
||||
|
|
|
@ -938,24 +938,25 @@
|
|||
do_intrinsic(_updateByteBufferAdler32, java_util_zip_Adler32, updateByteBuffer_A_name, updateByteBuffer_signature, F_SN) \
|
||||
do_name( updateByteBuffer_A_name, "updateByteBuffer") \
|
||||
\
|
||||
/* support for sun.misc.Unsafe */ \
|
||||
do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
|
||||
/* support for Unsafe */ \
|
||||
do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
|
||||
do_class(jdk_internal_misc_Unsafe, "jdk/internal/misc/Unsafe") \
|
||||
\
|
||||
do_intrinsic(_allocateInstance, sun_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
|
||||
do_name( allocateInstance_name, "allocateInstance") \
|
||||
do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \
|
||||
do_intrinsic(_copyMemory, sun_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
|
||||
do_name( copyMemory_name, "copyMemory") \
|
||||
do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \
|
||||
do_intrinsic(_loadFence, sun_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
|
||||
do_name( loadFence_name, "loadFence") \
|
||||
do_alias( loadFence_signature, void_method_signature) \
|
||||
do_intrinsic(_storeFence, sun_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
|
||||
do_name( storeFence_name, "storeFence") \
|
||||
do_alias( storeFence_signature, void_method_signature) \
|
||||
do_intrinsic(_fullFence, sun_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
|
||||
do_name( fullFence_name, "fullFence") \
|
||||
do_alias( fullFence_signature, void_method_signature) \
|
||||
do_intrinsic(_allocateInstance, jdk_internal_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
|
||||
do_name( allocateInstance_name, "allocateInstance") \
|
||||
do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \
|
||||
do_intrinsic(_copyMemory, jdk_internal_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
|
||||
do_name( copyMemory_name, "copyMemory") \
|
||||
do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \
|
||||
do_intrinsic(_loadFence, jdk_internal_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
|
||||
do_name( loadFence_name, "loadFence") \
|
||||
do_alias( loadFence_signature, void_method_signature) \
|
||||
do_intrinsic(_storeFence, jdk_internal_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
|
||||
do_name( storeFence_name, "storeFence") \
|
||||
do_alias( storeFence_signature, void_method_signature) \
|
||||
do_intrinsic(_fullFence, jdk_internal_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
|
||||
do_name( fullFence_name, "fullFence") \
|
||||
do_alias( fullFence_signature, void_method_signature) \
|
||||
\
|
||||
/* Custom branch frequencies profiling support for JSR292 */ \
|
||||
do_class(java_lang_invoke_MethodHandleImpl, "java/lang/invoke/MethodHandleImpl") \
|
||||
|
@ -996,24 +997,24 @@
|
|||
do_name(getFloat_name,"getFloat") do_name(putFloat_name,"putFloat") \
|
||||
do_name(getDouble_name,"getDouble") do_name(putDouble_name,"putDouble") \
|
||||
\
|
||||
do_intrinsic(_getObject, sun_misc_Unsafe, getObject_name, getObject_signature, F_RN) \
|
||||
do_intrinsic(_getBoolean, sun_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \
|
||||
do_intrinsic(_getByte, sun_misc_Unsafe, getByte_name, getByte_signature, F_RN) \
|
||||
do_intrinsic(_getShort, sun_misc_Unsafe, getShort_name, getShort_signature, F_RN) \
|
||||
do_intrinsic(_getChar, sun_misc_Unsafe, getChar_name, getChar_signature, F_RN) \
|
||||
do_intrinsic(_getInt, sun_misc_Unsafe, getInt_name, getInt_signature, F_RN) \
|
||||
do_intrinsic(_getLong, sun_misc_Unsafe, getLong_name, getLong_signature, F_RN) \
|
||||
do_intrinsic(_getFloat, sun_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \
|
||||
do_intrinsic(_getDouble, sun_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \
|
||||
do_intrinsic(_putObject, sun_misc_Unsafe, putObject_name, putObject_signature, F_RN) \
|
||||
do_intrinsic(_putBoolean, sun_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \
|
||||
do_intrinsic(_putByte, sun_misc_Unsafe, putByte_name, putByte_signature, F_RN) \
|
||||
do_intrinsic(_putShort, sun_misc_Unsafe, putShort_name, putShort_signature, F_RN) \
|
||||
do_intrinsic(_putChar, sun_misc_Unsafe, putChar_name, putChar_signature, F_RN) \
|
||||
do_intrinsic(_putInt, sun_misc_Unsafe, putInt_name, putInt_signature, F_RN) \
|
||||
do_intrinsic(_putLong, sun_misc_Unsafe, putLong_name, putLong_signature, F_RN) \
|
||||
do_intrinsic(_putFloat, sun_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \
|
||||
do_intrinsic(_putDouble, sun_misc_Unsafe, putDouble_name, putDouble_signature, F_RN) \
|
||||
do_intrinsic(_getObject, jdk_internal_misc_Unsafe, getObject_name, getObject_signature, F_RN) \
|
||||
do_intrinsic(_getBoolean, jdk_internal_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \
|
||||
do_intrinsic(_getByte, jdk_internal_misc_Unsafe, getByte_name, getByte_signature, F_RN) \
|
||||
do_intrinsic(_getShort, jdk_internal_misc_Unsafe, getShort_name, getShort_signature, F_RN) \
|
||||
do_intrinsic(_getChar, jdk_internal_misc_Unsafe, getChar_name, getChar_signature, F_RN) \
|
||||
do_intrinsic(_getInt, jdk_internal_misc_Unsafe, getInt_name, getInt_signature, F_RN) \
|
||||
do_intrinsic(_getLong, jdk_internal_misc_Unsafe, getLong_name, getLong_signature, F_RN) \
|
||||
do_intrinsic(_getFloat, jdk_internal_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \
|
||||
do_intrinsic(_getDouble, jdk_internal_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \
|
||||
do_intrinsic(_putObject, jdk_internal_misc_Unsafe, putObject_name, putObject_signature, F_RN) \
|
||||
do_intrinsic(_putBoolean, jdk_internal_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \
|
||||
do_intrinsic(_putByte, jdk_internal_misc_Unsafe, putByte_name, putByte_signature, F_RN) \
|
||||
do_intrinsic(_putShort, jdk_internal_misc_Unsafe, putShort_name, putShort_signature, F_RN) \
|
||||
do_intrinsic(_putChar, jdk_internal_misc_Unsafe, putChar_name, putChar_signature, F_RN) \
|
||||
do_intrinsic(_putInt, jdk_internal_misc_Unsafe, putInt_name, putInt_signature, F_RN) \
|
||||
do_intrinsic(_putLong, jdk_internal_misc_Unsafe, putLong_name, putLong_signature, F_RN) \
|
||||
do_intrinsic(_putFloat, jdk_internal_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \
|
||||
do_intrinsic(_putDouble, jdk_internal_misc_Unsafe, putDouble_name, putDouble_signature, F_RN) \
|
||||
\
|
||||
do_name(getObjectVolatile_name,"getObjectVolatile") do_name(putObjectVolatile_name,"putObjectVolatile") \
|
||||
do_name(getBooleanVolatile_name,"getBooleanVolatile") do_name(putBooleanVolatile_name,"putBooleanVolatile") \
|
||||
|
@ -1025,38 +1026,38 @@
|
|||
do_name(getFloatVolatile_name,"getFloatVolatile") do_name(putFloatVolatile_name,"putFloatVolatile") \
|
||||
do_name(getDoubleVolatile_name,"getDoubleVolatile") do_name(putDoubleVolatile_name,"putDoubleVolatile") \
|
||||
\
|
||||
do_intrinsic(_getObjectVolatile, sun_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \
|
||||
do_intrinsic(_getBooleanVolatile, sun_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \
|
||||
do_intrinsic(_getByteVolatile, sun_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \
|
||||
do_intrinsic(_getShortVolatile, sun_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \
|
||||
do_intrinsic(_getCharVolatile, sun_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \
|
||||
do_intrinsic(_getIntVolatile, sun_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \
|
||||
do_intrinsic(_getLongVolatile, sun_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \
|
||||
do_intrinsic(_getFloatVolatile, sun_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \
|
||||
do_intrinsic(_getDoubleVolatile, sun_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \
|
||||
do_intrinsic(_putObjectVolatile, sun_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \
|
||||
do_intrinsic(_putBooleanVolatile, sun_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \
|
||||
do_intrinsic(_putByteVolatile, sun_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \
|
||||
do_intrinsic(_putShortVolatile, sun_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \
|
||||
do_intrinsic(_putCharVolatile, sun_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \
|
||||
do_intrinsic(_putIntVolatile, sun_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \
|
||||
do_intrinsic(_putLongVolatile, sun_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \
|
||||
do_intrinsic(_putFloatVolatile, sun_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
|
||||
do_intrinsic(_putDoubleVolatile, sun_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \
|
||||
do_intrinsic(_getObjectVolatile, jdk_internal_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \
|
||||
do_intrinsic(_getBooleanVolatile, jdk_internal_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \
|
||||
do_intrinsic(_getByteVolatile, jdk_internal_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \
|
||||
do_intrinsic(_getShortVolatile, jdk_internal_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \
|
||||
do_intrinsic(_getCharVolatile, jdk_internal_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \
|
||||
do_intrinsic(_getIntVolatile, jdk_internal_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \
|
||||
do_intrinsic(_getLongVolatile, jdk_internal_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \
|
||||
do_intrinsic(_getFloatVolatile, jdk_internal_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \
|
||||
do_intrinsic(_getDoubleVolatile, jdk_internal_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \
|
||||
do_intrinsic(_putObjectVolatile, jdk_internal_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \
|
||||
do_intrinsic(_putBooleanVolatile, jdk_internal_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \
|
||||
do_intrinsic(_putByteVolatile, jdk_internal_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \
|
||||
do_intrinsic(_putShortVolatile, jdk_internal_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \
|
||||
do_intrinsic(_putCharVolatile, jdk_internal_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \
|
||||
do_intrinsic(_putIntVolatile, jdk_internal_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \
|
||||
do_intrinsic(_putLongVolatile, jdk_internal_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \
|
||||
do_intrinsic(_putFloatVolatile, jdk_internal_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
|
||||
do_intrinsic(_putDoubleVolatile, jdk_internal_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \
|
||||
\
|
||||
do_name(getShortUnaligned_name,"getShortUnaligned") do_name(putShortUnaligned_name,"putShortUnaligned") \
|
||||
do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \
|
||||
do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \
|
||||
do_name(getLongUnaligned_name,"getLongUnaligned") do_name(putLongUnaligned_name,"putLongUnaligned") \
|
||||
\
|
||||
do_intrinsic(_getShortUnaligned, sun_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \
|
||||
do_intrinsic(_getCharUnaligned, sun_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \
|
||||
do_intrinsic(_getIntUnaligned, sun_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \
|
||||
do_intrinsic(_getLongUnaligned, sun_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \
|
||||
do_intrinsic(_putShortUnaligned, sun_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \
|
||||
do_intrinsic(_putCharUnaligned, sun_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \
|
||||
do_intrinsic(_putIntUnaligned, sun_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
|
||||
do_intrinsic(_putLongUnaligned, sun_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \
|
||||
do_intrinsic(_getShortUnaligned, jdk_internal_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \
|
||||
do_intrinsic(_getCharUnaligned, jdk_internal_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \
|
||||
do_intrinsic(_getIntUnaligned, jdk_internal_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \
|
||||
do_intrinsic(_getLongUnaligned, jdk_internal_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \
|
||||
do_intrinsic(_putShortUnaligned, jdk_internal_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \
|
||||
do_intrinsic(_putCharUnaligned, jdk_internal_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \
|
||||
do_intrinsic(_putIntUnaligned, jdk_internal_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
|
||||
do_intrinsic(_putLongUnaligned, jdk_internal_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \
|
||||
\
|
||||
/* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */ \
|
||||
do_signature(getByte_raw_signature, "(J)B") \
|
||||
|
@ -1078,66 +1079,67 @@
|
|||
do_name( getAddress_name, "getAddress") \
|
||||
do_name( putAddress_name, "putAddress") \
|
||||
\
|
||||
do_intrinsic(_getByte_raw, sun_misc_Unsafe, getByte_name, getByte_raw_signature, F_RN) \
|
||||
do_intrinsic(_getShort_raw, sun_misc_Unsafe, getShort_name, getShort_raw_signature, F_RN) \
|
||||
do_intrinsic(_getChar_raw, sun_misc_Unsafe, getChar_name, getChar_raw_signature, F_RN) \
|
||||
do_intrinsic(_getInt_raw, sun_misc_Unsafe, getInt_name, long_int_signature, F_RN) \
|
||||
do_intrinsic(_getLong_raw, sun_misc_Unsafe, getLong_name, getLong_raw_signature, F_RN) \
|
||||
do_intrinsic(_getFloat_raw, sun_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_RN) \
|
||||
do_intrinsic(_getDouble_raw, sun_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_RN) \
|
||||
do_intrinsic(_getAddress_raw, sun_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_RN) \
|
||||
do_intrinsic(_putByte_raw, sun_misc_Unsafe, putByte_name, putByte_raw_signature, F_RN) \
|
||||
do_intrinsic(_putShort_raw, sun_misc_Unsafe, putShort_name, putShort_raw_signature, F_RN) \
|
||||
do_intrinsic(_putChar_raw, sun_misc_Unsafe, putChar_name, putChar_raw_signature, F_RN) \
|
||||
do_intrinsic(_putInt_raw, sun_misc_Unsafe, putInt_name, putInt_raw_signature, F_RN) \
|
||||
do_intrinsic(_putLong_raw, sun_misc_Unsafe, putLong_name, putLong_raw_signature, F_RN) \
|
||||
do_intrinsic(_putFloat_raw, sun_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_RN) \
|
||||
do_intrinsic(_putDouble_raw, sun_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_RN) \
|
||||
do_intrinsic(_putAddress_raw, sun_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_RN) \
|
||||
do_intrinsic(_getByte_raw, jdk_internal_misc_Unsafe, getByte_name, getByte_raw_signature, F_R) \
|
||||
do_intrinsic(_getShort_raw, jdk_internal_misc_Unsafe, getShort_name, getShort_raw_signature, F_R) \
|
||||
do_intrinsic(_getChar_raw, jdk_internal_misc_Unsafe, getChar_name, getChar_raw_signature, F_R) \
|
||||
do_intrinsic(_getInt_raw, jdk_internal_misc_Unsafe, getInt_name, long_int_signature, F_R) \
|
||||
do_intrinsic(_getLong_raw, jdk_internal_misc_Unsafe, getLong_name, getLong_raw_signature, F_R) \
|
||||
do_intrinsic(_getFloat_raw, jdk_internal_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_R) \
|
||||
do_intrinsic(_getDouble_raw, jdk_internal_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_R) \
|
||||
do_intrinsic(_getAddress_raw, jdk_internal_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_R) \
|
||||
do_intrinsic(_putByte_raw, jdk_internal_misc_Unsafe, putByte_name, putByte_raw_signature, F_R) \
|
||||
do_intrinsic(_putShort_raw, jdk_internal_misc_Unsafe, putShort_name, putShort_raw_signature, F_R) \
|
||||
do_intrinsic(_putChar_raw, jdk_internal_misc_Unsafe, putChar_name, putChar_raw_signature, F_R) \
|
||||
do_intrinsic(_putInt_raw, jdk_internal_misc_Unsafe, putInt_name, putInt_raw_signature, F_R) \
|
||||
do_intrinsic(_putLong_raw, jdk_internal_misc_Unsafe, putLong_name, putLong_raw_signature, F_R) \
|
||||
do_intrinsic(_putFloat_raw, jdk_internal_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_R) \
|
||||
do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \
|
||||
do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \
|
||||
\
|
||||
do_intrinsic(_compareAndSwapObject, sun_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_RN) \
|
||||
do_name( compareAndSwapObject_name, "compareAndSwapObject") \
|
||||
do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
|
||||
do_intrinsic(_compareAndSwapLong, sun_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_RN) \
|
||||
do_name( compareAndSwapLong_name, "compareAndSwapLong") \
|
||||
do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
|
||||
do_intrinsic(_compareAndSwapInt, sun_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_RN) \
|
||||
do_name( compareAndSwapInt_name, "compareAndSwapInt") \
|
||||
do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
|
||||
do_intrinsic(_putOrderedObject, sun_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \
|
||||
do_name( putOrderedObject_name, "putOrderedObject") \
|
||||
do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
|
||||
do_intrinsic(_putOrderedLong, sun_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \
|
||||
do_name( putOrderedLong_name, "putOrderedLong") \
|
||||
do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
|
||||
do_intrinsic(_putOrderedInt, sun_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \
|
||||
do_name( putOrderedInt_name, "putOrderedInt") \
|
||||
do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
|
||||
do_intrinsic(_compareAndSwapObject, jdk_internal_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_R) \
|
||||
do_name( compareAndSwapObject_name, "compareAndSwapObject") \
|
||||
do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
|
||||
do_intrinsic(_compareAndSwapLong, jdk_internal_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_R) \
|
||||
do_name( compareAndSwapLong_name, "compareAndSwapLong") \
|
||||
do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
|
||||
do_intrinsic(_compareAndSwapInt, jdk_internal_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_R) \
|
||||
do_name( compareAndSwapInt_name, "compareAndSwapInt") \
|
||||
do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
|
||||
do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_R) \
|
||||
do_name( putOrderedObject_name, "putOrderedObject") \
|
||||
do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
|
||||
do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_R) \
|
||||
do_name( putOrderedLong_name, "putOrderedLong") \
|
||||
do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
|
||||
do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_R) \
|
||||
do_name( putOrderedInt_name, "putOrderedInt") \
|
||||
do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
|
||||
\
|
||||
do_intrinsic(_getAndAddInt, sun_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
|
||||
do_name( getAndAddInt_name, "getAndAddInt") \
|
||||
do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \
|
||||
do_intrinsic(_getAndAddLong, sun_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \
|
||||
do_name( getAndAddLong_name, "getAndAddLong") \
|
||||
do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \
|
||||
do_intrinsic(_getAndSetInt, sun_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \
|
||||
do_name( getAndSetInt_name, "getAndSetInt") \
|
||||
do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \
|
||||
do_intrinsic(_getAndSetLong, sun_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \
|
||||
do_name( getAndSetLong_name, "getAndSetLong") \
|
||||
do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \
|
||||
do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
|
||||
do_name( getAndSetObject_name, "getAndSetObject") \
|
||||
do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
|
||||
\
|
||||
/* (2) Bytecode intrinsics */ \
|
||||
\
|
||||
do_intrinsic(_park, sun_misc_Unsafe, park_name, park_signature, F_RN) \
|
||||
do_name( park_name, "park") \
|
||||
do_signature(park_signature, "(ZJ)V") \
|
||||
do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \
|
||||
do_name( unpark_name, "unpark") \
|
||||
do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
|
||||
do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
|
||||
do_name( getAndAddInt_name, "getAndAddInt") \
|
||||
do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \
|
||||
do_intrinsic(_getAndAddLong, jdk_internal_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \
|
||||
do_name( getAndAddLong_name, "getAndAddLong") \
|
||||
do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \
|
||||
do_intrinsic(_getAndSetInt, jdk_internal_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \
|
||||
do_name( getAndSetInt_name, "getAndSetInt") \
|
||||
do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \
|
||||
do_intrinsic(_getAndSetLong, jdk_internal_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \
|
||||
do_name( getAndSetLong_name, "getAndSetLong") \
|
||||
do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \
|
||||
do_intrinsic(_getAndSetObject, jdk_internal_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
|
||||
do_name( getAndSetObject_name, "getAndSetObject") \
|
||||
do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
|
||||
\
|
||||
/* (2) Bytecode intrinsics */ \
|
||||
\
|
||||
do_intrinsic(_park, jdk_internal_misc_Unsafe, park_name, park_signature, F_R) \
|
||||
do_name( park_name, "park") \
|
||||
do_signature(park_signature, "(ZJ)V") \
|
||||
do_intrinsic(_unpark, jdk_internal_misc_Unsafe, unpark_name, unpark_signature, F_R) \
|
||||
do_name( unpark_name, "unpark") \
|
||||
do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
|
||||
\
|
||||
do_intrinsic(_StringBuilder_void, java_lang_StringBuilder, object_initializer_name, void_method_signature, F_R) \
|
||||
do_intrinsic(_StringBuilder_int, java_lang_StringBuilder, object_initializer_name, int_void_signature, F_R) \
|
||||
do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \
|
||||
|
|
|
@ -79,9 +79,6 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread {
|
|||
static void makeSurrogateLockerThread(TRAPS);
|
||||
static SurrogateLockerThread* slt() { return _slt; }
|
||||
|
||||
// Tester
|
||||
bool is_ConcurrentGC_thread() const { return true; }
|
||||
|
||||
static void threads_do(ThreadClosure* tc);
|
||||
|
||||
// Printing
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#include "runtime/java.hpp"
|
||||
|
||||
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
|
||||
_threads(NULL), _n_threads(0),
|
||||
_threads(NULL),
|
||||
_sample_thread(NULL),
|
||||
_hot_card_cache(g1h)
|
||||
{
|
||||
// Ergonomically select initial concurrent refinement parameters
|
||||
|
@ -58,12 +59,10 @@ ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEn
|
|||
return NULL;
|
||||
}
|
||||
cg1r->_n_worker_threads = thread_num();
|
||||
// We need one extra thread to do the young gen rset size sampling.
|
||||
cg1r->_n_threads = cg1r->_n_worker_threads + 1;
|
||||
|
||||
cg1r->reset_threshold_step();
|
||||
|
||||
cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_threads, mtGC);
|
||||
cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC);
|
||||
if (cg1r->_threads == NULL) {
|
||||
*ecode = JNI_ENOMEM;
|
||||
vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread");
|
||||
|
@ -73,7 +72,7 @@ ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEn
|
|||
uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
|
||||
|
||||
ConcurrentG1RefineThread *next = NULL;
|
||||
for (uint i = cg1r->_n_threads - 1; i != UINT_MAX; i--) {
|
||||
for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) {
|
||||
ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
|
||||
assert(t != NULL, "Conc refine should have been created");
|
||||
if (t->osthread() == NULL) {
|
||||
|
@ -86,6 +85,14 @@ ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEn
|
|||
cg1r->_threads[i] = t;
|
||||
next = t;
|
||||
}
|
||||
|
||||
cg1r->_sample_thread = new G1YoungRemSetSamplingThread();
|
||||
if (cg1r->_sample_thread->osthread() == NULL) {
|
||||
*ecode = JNI_ENOMEM;
|
||||
vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ecode = JNI_OK;
|
||||
return cg1r;
|
||||
}
|
||||
|
@ -103,44 +110,36 @@ void ConcurrentG1Refine::init(G1RegionToSpaceMapper* card_counts_storage) {
|
|||
}
|
||||
|
||||
void ConcurrentG1Refine::stop() {
|
||||
if (_threads != NULL) {
|
||||
for (uint i = 0; i < _n_threads; i++) {
|
||||
_threads[i]->stop();
|
||||
}
|
||||
for (uint i = 0; i < _n_worker_threads; i++) {
|
||||
_threads[i]->stop();
|
||||
}
|
||||
_sample_thread->stop();
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::reinitialize_threads() {
|
||||
reset_threshold_step();
|
||||
if (_threads != NULL) {
|
||||
for (uint i = 0; i < _n_threads; i++) {
|
||||
_threads[i]->initialize();
|
||||
}
|
||||
for (uint i = 0; i < _n_worker_threads; i++) {
|
||||
_threads[i]->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
ConcurrentG1Refine::~ConcurrentG1Refine() {
|
||||
if (_threads != NULL) {
|
||||
for (uint i = 0; i < _n_threads; i++) {
|
||||
delete _threads[i];
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
|
||||
for (uint i = 0; i < _n_worker_threads; i++) {
|
||||
delete _threads[i];
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
|
||||
|
||||
delete _sample_thread;
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
|
||||
if (_threads != NULL) {
|
||||
for (uint i = 0; i < _n_threads; i++) {
|
||||
tc->do_thread(_threads[i]);
|
||||
}
|
||||
}
|
||||
worker_threads_do(tc);
|
||||
tc->do_thread(_sample_thread);
|
||||
}
|
||||
|
||||
void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
|
||||
if (_threads != NULL) {
|
||||
for (uint i = 0; i < worker_thread_num(); i++) {
|
||||
tc->do_thread(_threads[i]);
|
||||
}
|
||||
for (uint i = 0; i < worker_thread_num(); i++) {
|
||||
tc->do_thread(_threads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,12 +148,10 @@ uint ConcurrentG1Refine::thread_num() {
|
|||
}
|
||||
|
||||
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
|
||||
for (uint i = 0; i < _n_threads; ++i) {
|
||||
for (uint i = 0; i < _n_worker_threads; ++i) {
|
||||
_threads[i]->print_on(st);
|
||||
st->cr();
|
||||
}
|
||||
}
|
||||
|
||||
ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
|
||||
return _threads[worker_thread_num()];
|
||||
_sample_thread->print_on(st);
|
||||
st->cr();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
|
||||
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
@ -39,8 +40,9 @@ class G1RemSet;
|
|||
class DirtyCardQueue;
|
||||
|
||||
class ConcurrentG1Refine: public CHeapObj<mtGC> {
|
||||
G1YoungRemSetSamplingThread* _sample_thread;
|
||||
|
||||
ConcurrentG1RefineThread** _threads;
|
||||
uint _n_threads;
|
||||
uint _n_worker_threads;
|
||||
/*
|
||||
* The value of the update buffer queue length falls into one of 3 zones:
|
||||
|
@ -91,8 +93,8 @@ class ConcurrentG1Refine: public CHeapObj<mtGC> {
|
|||
// Iterate over all worker refinement threads
|
||||
void worker_threads_do(ThreadClosure * tc);
|
||||
|
||||
// The RS sampling thread
|
||||
ConcurrentG1RefineThread * sampling_thread() const;
|
||||
// The RS sampling thread has nothing to do with refinement, but is here for now.
|
||||
G1YoungRemSetSamplingThread * sampling_thread() const { return _sample_thread; }
|
||||
|
||||
static uint thread_num();
|
||||
|
||||
|
@ -106,7 +108,6 @@ class ConcurrentG1Refine: public CHeapObj<mtGC> {
|
|||
int yellow_zone() const { return _yellow_zone; }
|
||||
int red_zone() const { return _red_zone; }
|
||||
|
||||
uint total_thread_num() const { return _n_threads; }
|
||||
uint worker_thread_num() const { return _n_worker_threads; }
|
||||
|
||||
int thread_threshold_step() const { return _thread_threshold_step; }
|
||||
|
|
|
@ -50,9 +50,8 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
|
|||
// Each thread has its own monitor. The i-th thread is responsible for signaling
|
||||
// to thread i+1 if the number of buffers in the queue exceeds a threshold for this
|
||||
// thread. Monitors are also used to wake up the threads during termination.
|
||||
// The 0th worker in notified by mutator threads and has a special monitor.
|
||||
// The last worker is used for young gen rset size sampling.
|
||||
if (worker_id > 0) {
|
||||
// The 0th (primary) worker is notified by mutator threads and has a special monitor.
|
||||
if (!is_primary()) {
|
||||
_monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
|
||||
Monitor::_safepoint_check_never);
|
||||
} else {
|
||||
|
@ -66,61 +65,11 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
|
|||
}
|
||||
|
||||
void ConcurrentG1RefineThread::initialize() {
|
||||
if (_worker_id < cg1r()->worker_thread_num()) {
|
||||
// Current thread activation threshold
|
||||
_threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
|
||||
cg1r()->yellow_zone());
|
||||
// A thread deactivates once the number of buffer reached a deactivation threshold
|
||||
_deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
|
||||
} else {
|
||||
set_active(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
G1CollectorPolicy* g1p = g1h->g1_policy();
|
||||
if (g1p->adaptive_young_list_length()) {
|
||||
int regions_visited = 0;
|
||||
g1h->young_list()->rs_length_sampling_init();
|
||||
while (g1h->young_list()->rs_length_sampling_more()) {
|
||||
g1h->young_list()->rs_length_sampling_next();
|
||||
++regions_visited;
|
||||
|
||||
// we try to yield every time we visit 10 regions
|
||||
if (regions_visited == 10) {
|
||||
if (sts_join.should_yield()) {
|
||||
sts_join.yield();
|
||||
// we just abandon the iteration
|
||||
break;
|
||||
}
|
||||
regions_visited = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g1p->revise_young_list_target_length_if_necessary();
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::run_young_rs_sampling() {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
_vtime_start = os::elapsedVTime();
|
||||
while(!_should_terminate) {
|
||||
sample_young_list_rs_lengths();
|
||||
|
||||
if (os::supports_vtime()) {
|
||||
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
||||
} else {
|
||||
_vtime_accum = 0.0;
|
||||
}
|
||||
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
if (_should_terminate) {
|
||||
break;
|
||||
}
|
||||
_monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefinementServiceIntervalMillis);
|
||||
}
|
||||
// Current thread activation threshold
|
||||
_threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
|
||||
cg1r()->yellow_zone());
|
||||
// A thread deactivates once the number of buffer reached a deactivation threshold
|
||||
_deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::wait_for_completed_buffers() {
|
||||
|
@ -133,12 +82,12 @@ void ConcurrentG1RefineThread::wait_for_completed_buffers() {
|
|||
|
||||
bool ConcurrentG1RefineThread::is_active() {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
return _worker_id > 0 ? _active : dcqs.process_completed_buffers();
|
||||
return is_primary() ? dcqs.process_completed_buffers() : _active;
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::activate() {
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
if (_worker_id > 0) {
|
||||
if (!is_primary()) {
|
||||
if (G1TraceConcRefinement) {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
|
||||
|
@ -154,7 +103,7 @@ void ConcurrentG1RefineThread::activate() {
|
|||
|
||||
void ConcurrentG1RefineThread::deactivate() {
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
if (_worker_id > 0) {
|
||||
if (!is_primary()) {
|
||||
if (G1TraceConcRefinement) {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
|
||||
|
@ -171,25 +120,24 @@ void ConcurrentG1RefineThread::run() {
|
|||
initialize_in_thread();
|
||||
wait_for_universe_init();
|
||||
|
||||
if (_worker_id >= cg1r()->worker_thread_num()) {
|
||||
run_young_rs_sampling();
|
||||
terminate();
|
||||
return;
|
||||
}
|
||||
run_service();
|
||||
|
||||
terminate();
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::run_service() {
|
||||
_vtime_start = os::elapsedVTime();
|
||||
while (!_should_terminate) {
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
|
||||
while (!_should_terminate) {
|
||||
// Wait for work
|
||||
wait_for_completed_buffers();
|
||||
|
||||
if (_should_terminate) {
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||
|
||||
do {
|
||||
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
||||
|
@ -199,7 +147,7 @@ void ConcurrentG1RefineThread::run() {
|
|||
dcqs.set_completed_queue_padding(0);
|
||||
}
|
||||
|
||||
if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
|
||||
if (!is_primary() && curr_buffer_num <= _deactivation_threshold) {
|
||||
// If the number of the buffer has fallen below our threshold
|
||||
// we should deactivate. The predecessor will reactivate this
|
||||
// thread should the number of the buffers cross the threshold again.
|
||||
|
@ -225,8 +173,10 @@ void ConcurrentG1RefineThread::run() {
|
|||
_vtime_accum = 0.0;
|
||||
}
|
||||
}
|
||||
assert(_should_terminate, "just checking");
|
||||
terminate();
|
||||
|
||||
if (G1TraceConcRefinement) {
|
||||
gclog_or_tty->print_cr("G1-Refine-stop");
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::stop() {
|
||||
|
@ -236,10 +186,7 @@ void ConcurrentG1RefineThread::stop() {
|
|||
_should_terminate = true;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
_monitor->notify();
|
||||
}
|
||||
stop_service();
|
||||
|
||||
{
|
||||
MutexLockerEx mu(Terminator_lock);
|
||||
|
@ -247,8 +194,9 @@ void ConcurrentG1RefineThread::stop() {
|
|||
Terminator_lock->wait();
|
||||
}
|
||||
}
|
||||
if (G1TraceConcRefinement) {
|
||||
gclog_or_tty->print_cr("G1-Refine-stop");
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentG1RefineThread::stop_service() {
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
_monitor->notify();
|
||||
}
|
|
@ -31,14 +31,14 @@
|
|||
class CardTableEntryClosure;
|
||||
class ConcurrentG1Refine;
|
||||
|
||||
// The G1 Concurrent Refinement Thread (could be several in the future).
|
||||
|
||||
// One or more G1 Concurrent Refinement Threads may be active if concurrent
|
||||
// refinement is in progress.
|
||||
class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
||||
friend class VMStructs;
|
||||
friend class G1CollectedHeap;
|
||||
|
||||
double _vtime_start; // Initial virtual time.
|
||||
double _vtime_accum; // Initial virtual time.
|
||||
double _vtime_accum; // Accumulated virtual time.
|
||||
uint _worker_id;
|
||||
uint _worker_id_offset;
|
||||
|
||||
|
@ -59,8 +59,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
|||
// This thread deactivation threshold
|
||||
int _deactivation_threshold;
|
||||
|
||||
void sample_young_list_rs_lengths();
|
||||
void run_young_rs_sampling();
|
||||
void wait_for_completed_buffers();
|
||||
|
||||
void set_active(bool x) { _active = x; }
|
||||
|
@ -68,6 +66,11 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
|||
void activate();
|
||||
void deactivate();
|
||||
|
||||
bool is_primary() { return (_worker_id == 0); }
|
||||
|
||||
void run_service();
|
||||
void stop_service();
|
||||
|
||||
public:
|
||||
virtual void run();
|
||||
// Constructor
|
||||
|
|
|
@ -92,15 +92,31 @@ void ConcurrentMarkThread::cm_log(bool doit, bool join_sts, const char* fmt, ...
|
|||
}
|
||||
}
|
||||
|
||||
// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
|
||||
void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) {
|
||||
if (g1_policy->adaptive_young_list_length()) {
|
||||
double now = os::elapsedTime();
|
||||
double prediction_ms = remark ? g1_policy->predict_remark_time_ms()
|
||||
: g1_policy->predict_cleanup_time_ms();
|
||||
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
|
||||
jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms);
|
||||
os::sleep(this, sleep_time_ms, false);
|
||||
}
|
||||
}
|
||||
void ConcurrentMarkThread::run() {
|
||||
initialize_in_thread();
|
||||
_vtime_start = os::elapsedVTime();
|
||||
wait_for_universe_init();
|
||||
|
||||
run_service();
|
||||
|
||||
terminate();
|
||||
}
|
||||
|
||||
void ConcurrentMarkThread::run_service() {
|
||||
_vtime_start = os::elapsedVTime();
|
||||
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
G1CollectorPolicy* g1_policy = g1h->g1_policy();
|
||||
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
|
||||
Thread *current_thread = Thread::current();
|
||||
|
||||
while (!_should_terminate) {
|
||||
// wait until started is set.
|
||||
|
@ -141,12 +157,7 @@ void ConcurrentMarkThread::run() {
|
|||
double mark_end_sec = os::elapsedTime();
|
||||
_vtime_mark_accum += (mark_end_time - cycle_start);
|
||||
if (!cm()->has_aborted()) {
|
||||
if (g1_policy->adaptive_young_list_length()) {
|
||||
double now = os::elapsedTime();
|
||||
double remark_prediction_ms = g1_policy->predict_remark_time_ms();
|
||||
jlong sleep_time_ms = mmu_tracker->when_ms(now, remark_prediction_ms);
|
||||
os::sleep(current_thread, sleep_time_ms, false);
|
||||
}
|
||||
delay_to_keep_mmu(g1_policy, true /* remark */);
|
||||
|
||||
cm_log(G1Log::fine(), true, "[GC concurrent-mark-end, %1.7lf secs]", mark_end_sec - mark_start_sec);
|
||||
|
||||
|
@ -167,12 +178,7 @@ void ConcurrentMarkThread::run() {
|
|||
_vtime_accum = (end_time - _vtime_start);
|
||||
|
||||
if (!cm()->has_aborted()) {
|
||||
if (g1_policy->adaptive_young_list_length()) {
|
||||
double now = os::elapsedTime();
|
||||
double cleanup_prediction_ms = g1_policy->predict_cleanup_time_ms();
|
||||
jlong sleep_time_ms = mmu_tracker->when_ms(now, cleanup_prediction_ms);
|
||||
os::sleep(current_thread, sleep_time_ms, false);
|
||||
}
|
||||
delay_to_keep_mmu(g1_policy, false /* cleanup */);
|
||||
|
||||
CMCleanUp cl_cl(_cm);
|
||||
VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
|
||||
|
@ -272,9 +278,6 @@ void ConcurrentMarkThread::run() {
|
|||
g1h->register_concurrent_cycle_end();
|
||||
}
|
||||
}
|
||||
assert(_should_terminate, "just checking");
|
||||
|
||||
terminate();
|
||||
}
|
||||
|
||||
void ConcurrentMarkThread::stop() {
|
||||
|
@ -283,10 +286,7 @@ void ConcurrentMarkThread::stop() {
|
|||
_should_terminate = true;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
|
||||
CGC_lock->notify_all();
|
||||
}
|
||||
stop_service();
|
||||
|
||||
{
|
||||
MutexLockerEx ml(Terminator_lock);
|
||||
|
@ -296,6 +296,11 @@ void ConcurrentMarkThread::stop() {
|
|||
}
|
||||
}
|
||||
|
||||
void ConcurrentMarkThread::stop_service() {
|
||||
MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
|
||||
CGC_lock->notify_all();
|
||||
}
|
||||
|
||||
void ConcurrentMarkThread::sleepBeforeNextCycle() {
|
||||
// We join here because we don't want to do the "shouldConcurrentMark()"
|
||||
// below while the world is otherwise stopped.
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
#include "gc/shared/concurrentGCThread.hpp"
|
||||
|
||||
// The Concurrent Mark GC Thread (could be several in the future).
|
||||
// This is copied from the Concurrent Mark Sweep GC Thread
|
||||
// Still under construction.
|
||||
// The Concurrent Mark GC Thread triggers the parallel CMConcurrentMarkingTasks
|
||||
// as well as handling various marking cleanup.
|
||||
|
||||
class ConcurrentMark;
|
||||
class G1CollectorPolicy;
|
||||
|
||||
class ConcurrentMarkThread: public ConcurrentGCThread {
|
||||
friend class VMStructs;
|
||||
|
@ -57,6 +57,10 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
|
|||
volatile State _state;
|
||||
|
||||
void sleepBeforeNextCycle();
|
||||
void delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark);
|
||||
|
||||
void run_service();
|
||||
void stop_service();
|
||||
|
||||
static SurrogateLockerThread* _slt;
|
||||
|
||||
|
@ -67,9 +71,9 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
|
|||
static void makeSurrogateLockerThread(TRAPS);
|
||||
static SurrogateLockerThread* slt() { return _slt; }
|
||||
|
||||
// Total virtual time so far.
|
||||
// Total virtual time so far for this thread and concurrent marking tasks.
|
||||
double vtime_accum();
|
||||
// Marking virtual time so far
|
||||
// Marking virtual time so far this thread and concurrent marking tasks.
|
||||
double vtime_mark_accum();
|
||||
|
||||
ConcurrentMark* cm() { return _cm; }
|
||||
|
|
|
@ -3934,9 +3934,13 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
|||
_allocator->init_gc_alloc_regions(evacuation_info);
|
||||
|
||||
G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length());
|
||||
pre_evacuate_collection_set();
|
||||
|
||||
// Actually do the work...
|
||||
evacuate_collection_set(evacuation_info, &per_thread_states);
|
||||
|
||||
post_evacuate_collection_set(evacuation_info, &per_thread_states);
|
||||
|
||||
const size_t* surviving_young_words = per_thread_states.surviving_young_words();
|
||||
free_collection_set(g1_policy()->collection_set(), evacuation_info, surviving_young_words);
|
||||
|
||||
|
@ -5166,27 +5170,29 @@ void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadStateSet* per
|
|||
g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
|
||||
}
|
||||
|
||||
void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
|
||||
void G1CollectedHeap::pre_evacuate_collection_set() {
|
||||
_expand_heap_after_alloc_failure = true;
|
||||
_evacuation_failed = false;
|
||||
|
||||
// Should G1EvacuationFailureALot be in effect for this GC?
|
||||
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
|
||||
|
||||
g1_rem_set()->prepare_for_oops_into_collection_set_do();
|
||||
|
||||
// Disable the hot card cache.
|
||||
G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
|
||||
hot_card_cache->reset_hot_cache_claimed_index();
|
||||
hot_card_cache->set_use_cache(false);
|
||||
|
||||
const uint n_workers = workers()->active_workers();
|
||||
}
|
||||
|
||||
void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
|
||||
g1_rem_set()->prepare_for_oops_into_collection_set_do();
|
||||
|
||||
// Should G1EvacuationFailureALot be in effect for this GC?
|
||||
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
|
||||
|
||||
assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
|
||||
double start_par_time_sec = os::elapsedTime();
|
||||
double end_par_time_sec;
|
||||
|
||||
{
|
||||
const uint n_workers = workers()->active_workers();
|
||||
G1RootProcessor root_processor(this, n_workers);
|
||||
G1ParTask g1_par_task(this, per_thread_states, _task_queues, &root_processor, n_workers);
|
||||
// InitialMark needs claim bits to keep track of the marked-through CLDs.
|
||||
|
@ -5236,21 +5242,8 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G
|
|||
phase_times->record_string_dedup_fixup_time(fixup_time_ms);
|
||||
}
|
||||
|
||||
_allocator->release_gc_alloc_regions(evacuation_info);
|
||||
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
|
||||
|
||||
per_thread_states->flush();
|
||||
|
||||
record_obj_copy_mem_stats();
|
||||
|
||||
// Reset and re-enable the hot card cache.
|
||||
// Note the counts for the cards in the regions in the
|
||||
// collection set are reset when the collection set is freed.
|
||||
hot_card_cache->reset_hot_cache();
|
||||
hot_card_cache->set_use_cache(true);
|
||||
|
||||
purge_code_root_memory();
|
||||
|
||||
if (evacuation_failed()) {
|
||||
remove_self_forwarding_pointers();
|
||||
|
||||
|
@ -5268,6 +5261,23 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G
|
|||
// cards). We need these updates logged to update any
|
||||
// RSets.
|
||||
enqueue_discovered_references(per_thread_states);
|
||||
}
|
||||
|
||||
void G1CollectedHeap::post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
|
||||
_allocator->release_gc_alloc_regions(evacuation_info);
|
||||
|
||||
per_thread_states->flush();
|
||||
|
||||
record_obj_copy_mem_stats();
|
||||
|
||||
// Reset and re-enable the hot card cache.
|
||||
// Note the counts for the cards in the regions in the
|
||||
// collection set are reset when the collection set is freed.
|
||||
G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
|
||||
hot_card_cache->reset_hot_cache();
|
||||
hot_card_cache->set_use_cache(true);
|
||||
|
||||
purge_code_root_memory();
|
||||
|
||||
redirty_logged_cards();
|
||||
#if defined(COMPILER2) || INCLUDE_JVMCI
|
||||
|
|
|
@ -728,7 +728,10 @@ protected:
|
|||
bool do_collection_pause_at_safepoint(double target_pause_time_ms);
|
||||
|
||||
// Actually do the work of evacuating the collection set.
|
||||
void evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states);
|
||||
virtual void evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states);
|
||||
|
||||
void pre_evacuate_collection_set();
|
||||
void post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
|
||||
|
||||
// Print the header for the per-thread termination statistics.
|
||||
static void print_termination_stats_hdr(outputStream* const st);
|
||||
|
|
|
@ -107,7 +107,9 @@ void G1EvacStats::adjust_desired_plab_sz() {
|
|||
gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
|
||||
}
|
||||
}
|
||||
gclog_or_tty->cr();
|
||||
if (PrintPLAB) {
|
||||
gclog_or_tty->cr();
|
||||
}
|
||||
// Clear accumulators for next round.
|
||||
reset();
|
||||
}
|
||||
|
|
|
@ -29,11 +29,23 @@
|
|||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
// Keeps track of the GC work and decides when it is OK to do GC work
|
||||
// Two major user controls over G1 behavior are setting a pause time goal (MaxGCPauseMillis),
|
||||
// over a time slice (GCPauseIntervalMillis). This defines the Minimum Mutator
|
||||
// Utilisation (MMU) goal.
|
||||
//
|
||||
// * Definitions *
|
||||
// Mutator Utilisation:
|
||||
// - for a given time slice duration "ts",
|
||||
// - mutator utilisation is the following fraction:
|
||||
// non_gc_time / ts
|
||||
//
|
||||
// Minimum Mutator Utilisation (MMU):
|
||||
// - the worst mutator utilisation across all time slices.
|
||||
//
|
||||
// G1MMUTracker keeps track of the GC work and decides when it is OK to do GC work
|
||||
// and for how long so that the MMU invariants are maintained.
|
||||
|
||||
/***** ALL TIMES ARE IN SECS!!!!!!! *****/
|
||||
|
||||
//
|
||||
// ***** ALL TIMES ARE IN SECS!!!!!!! *****
|
||||
// this is the "interface"
|
||||
class G1MMUTracker: public CHeapObj<mtGC> {
|
||||
protected:
|
||||
|
|
122
hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp
Normal file
122
hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc/g1/g1CollectorPolicy.hpp"
|
||||
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
|
||||
#include "gc/g1/suspendibleThreadSet.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
|
||||
void G1YoungRemSetSamplingThread::run() {
|
||||
initialize_in_thread();
|
||||
wait_for_universe_init();
|
||||
|
||||
run_service();
|
||||
|
||||
terminate();
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::stop() {
|
||||
// it is ok to take late safepoints here, if needed
|
||||
{
|
||||
MutexLockerEx mu(Terminator_lock);
|
||||
_should_terminate = true;
|
||||
}
|
||||
|
||||
stop_service();
|
||||
|
||||
{
|
||||
MutexLockerEx mu(Terminator_lock);
|
||||
while (!_has_terminated) {
|
||||
Terminator_lock->wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() : ConcurrentGCThread() {
|
||||
_monitor = new Monitor(Mutex::nonleaf,
|
||||
"G1YoungRemSetSamplingThread monitor",
|
||||
true,
|
||||
Monitor::_safepoint_check_never);
|
||||
|
||||
create_and_start();
|
||||
|
||||
set_name("G1 Young RemSet Sampling");
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
if (!_should_terminate) {
|
||||
intx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
|
||||
_monitor->wait(Mutex::_no_safepoint_check_flag, waitms);
|
||||
}
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::run_service() {
|
||||
double vtime_start = os::elapsedVTime();
|
||||
|
||||
while (!_should_terminate) {
|
||||
sample_young_list_rs_lengths();
|
||||
|
||||
if (os::supports_vtime()) {
|
||||
_vtime_accum = (os::elapsedVTime() - vtime_start);
|
||||
} else {
|
||||
_vtime_accum = 0.0;
|
||||
}
|
||||
|
||||
sleep_before_next_cycle();
|
||||
}
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::stop_service() {
|
||||
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
|
||||
_monitor->notify();
|
||||
}
|
||||
|
||||
void G1YoungRemSetSamplingThread::sample_young_list_rs_lengths() {
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
G1CollectorPolicy* g1p = g1h->g1_policy();
|
||||
if (g1p->adaptive_young_list_length()) {
|
||||
int regions_visited = 0;
|
||||
g1h->young_list()->rs_length_sampling_init();
|
||||
while (g1h->young_list()->rs_length_sampling_more()) {
|
||||
g1h->young_list()->rs_length_sampling_next();
|
||||
++regions_visited;
|
||||
|
||||
// we try to yield every time we visit 10 regions
|
||||
if (regions_visited == 10) {
|
||||
if (sts.should_yield()) {
|
||||
sts.yield();
|
||||
// we just abandon the iteration
|
||||
break;
|
||||
}
|
||||
regions_visited = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g1p->revise_young_list_target_length_if_necessary();
|
||||
}
|
||||
}
|
63
hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.hpp
Normal file
63
hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP
|
||||
#define SHARE_VM_GC_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP
|
||||
|
||||
#include "gc/shared/concurrentGCThread.hpp"
|
||||
|
||||
// The G1YoungRemSetSamplingThread is used to re-assess the validity of
|
||||
// the prediction for the remembered set lengths of the young generation.
|
||||
//
|
||||
// At the end of the GC G1 determines the length of the young gen based on
|
||||
// how much time the next GC can take, and when the next GC may occur
|
||||
// according to the MMU.
|
||||
//
|
||||
// The assumption is that a significant part of the GC is spent on scanning
|
||||
// the remembered sets (and many other components), so this thread constantly
|
||||
// reevaluates the prediction for the remembered set scanning costs, and potentially
|
||||
// G1CollectorPolicy resizes the young gen. This may do a premature GC or even
|
||||
// increase the young gen size to keep pause time length goal.
|
||||
class G1YoungRemSetSamplingThread: public ConcurrentGCThread {
|
||||
private:
|
||||
Monitor* _monitor;
|
||||
|
||||
void sample_young_list_rs_lengths();
|
||||
|
||||
void run_service();
|
||||
void stop_service();
|
||||
|
||||
void sleep_before_next_cycle();
|
||||
|
||||
double _vtime_accum; // Accumulated virtual time.
|
||||
|
||||
public:
|
||||
G1YoungRemSetSamplingThread();
|
||||
double vtime_accum() { return _vtime_accum; }
|
||||
|
||||
virtual void run();
|
||||
void stop();
|
||||
};
|
||||
|
||||
#endif /* SHARE_VM_GC_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP */
|
|
@ -66,6 +66,7 @@ void ConcurrentGCThread::wait_for_universe_init() {
|
|||
}
|
||||
|
||||
void ConcurrentGCThread::terminate() {
|
||||
assert(_should_terminate, "Should only be called on terminate request.");
|
||||
// Signal that it is terminated
|
||||
{
|
||||
MutexLockerEx mu(Terminator_lock,
|
||||
|
|
|
@ -390,7 +390,6 @@ void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st)
|
|||
}
|
||||
|
||||
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
void BytecodePrinter::print_attributes(int bci, outputStream* st) {
|
||||
// Show attributes of pre-rewritten codes
|
||||
Bytecodes::Code code = Bytecodes::java_code(raw_code());
|
||||
|
@ -512,15 +511,11 @@ void BytecodePrinter::print_attributes(int bci, outputStream* st) {
|
|||
}
|
||||
st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
|
||||
default_dest, lo, hi);
|
||||
int first = true;
|
||||
for (int ll = lo; ll <= hi; ll++, first = false) {
|
||||
const char *comma = "";
|
||||
for (int ll = lo; ll <= hi; ll++) {
|
||||
int idx = ll - lo;
|
||||
const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
|
||||
", %d:" INT32_FORMAT " (delta: %d)";
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
st->print(format, ll, dest[idx], dest[idx]-bci);
|
||||
PRAGMA_DIAG_POP
|
||||
st->print("%s %d:" INT32_FORMAT " (delta: %d)", comma, ll, dest[idx], dest[idx]-bci);
|
||||
comma = ",";
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
@ -536,14 +531,10 @@ PRAGMA_DIAG_POP
|
|||
dest[i] = bci + get_int();
|
||||
};
|
||||
st->print(" %d %d ", default_dest, len);
|
||||
bool first = true;
|
||||
for (int ll = 0; ll < len; ll++, first = false) {
|
||||
const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
|
||||
", " INT32_FORMAT ":" INT32_FORMAT ;
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
st->print(format, key[ll], dest[ll]);
|
||||
PRAGMA_DIAG_POP
|
||||
const char *comma = "";
|
||||
for (int ll = 0; ll < len; ll++) {
|
||||
st->print("%s " INT32_FORMAT ":" INT32_FORMAT, comma, key[ll], dest[ll]);
|
||||
comma = ",";
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
|
|
@ -286,7 +286,6 @@ bool KlassInfoHisto::is_selected(const char *col_name) {
|
|||
return true;
|
||||
}
|
||||
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
|
||||
bool selected[], int width_table[],
|
||||
const char *name_table[]) {
|
||||
|
@ -298,11 +297,10 @@ void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
|
|||
st->print(",ClassName");
|
||||
} else {
|
||||
st->print("Index Super");
|
||||
for (int c=0; c<KlassSizeStats::_num_columns; c++) {
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
|
||||
PRAGMA_DIAG_POP
|
||||
for (int c = 0; c < KlassSizeStats::_num_columns; c++) {
|
||||
if (selected[c]) {
|
||||
st->print("%*s", width_table[c], name_table[c]);
|
||||
}
|
||||
}
|
||||
st->print(" ClassName");
|
||||
}
|
||||
|
@ -607,18 +605,12 @@ void KlassInfoHisto::print_class_stats(outputStream* st,
|
|||
case KlassSizeStats::_index_inst_size:
|
||||
case KlassSizeStats::_index_inst_count:
|
||||
case KlassSizeStats::_index_method_count:
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
st->print(str_fmt(width_table[c]), "-");
|
||||
PRAGMA_DIAG_POP
|
||||
st->print("%*s", width_table[c], "-");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
st->print(perc_fmt(width_table[c]), perc);
|
||||
PRAGMA_DIAG_POP
|
||||
st->print("%*.1f%%", width_table[c]-1, perc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,32 +313,13 @@ class KlassInfoHisto : public StackObj {
|
|||
return HeapWordSize * x->size();
|
||||
}
|
||||
|
||||
// returns a format string to print a julong with the given width. E.g,
|
||||
// printf(num_fmt(6), julong(10)) would print out the number 10 with 4
|
||||
// leading spaces.
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
|
||||
static void print_julong(outputStream* st, int width, julong n) {
|
||||
int num_spaces = width - julong_width(n);
|
||||
if (num_spaces > 0) {
|
||||
st->print(str_fmt(num_spaces), "");
|
||||
st->print("%*s", num_spaces, "");
|
||||
}
|
||||
st->print(JULONG_FORMAT, n);
|
||||
}
|
||||
PRAGMA_DIAG_POP
|
||||
|
||||
static char* perc_fmt(int width) {
|
||||
static char buf[32];
|
||||
jio_snprintf(buf, sizeof(buf), "%%%d.1f%%%%", width-1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char* str_fmt(int width) {
|
||||
static char buf[32];
|
||||
jio_snprintf(buf, sizeof(buf), "%%%ds", width);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int julong_width(julong n) {
|
||||
if (n == 0) {
|
||||
|
|
|
@ -1008,8 +1008,8 @@ bool universe_post_init() {
|
|||
Universe::_finalizer_register_cache->init(
|
||||
SystemDictionary::Finalizer_klass(), m);
|
||||
|
||||
SystemDictionary::misc_Unsafe_klass()->link_class(CHECK_false);
|
||||
m = SystemDictionary::misc_Unsafe_klass()->find_method(
|
||||
SystemDictionary::internal_Unsafe_klass()->link_class(CHECK_false);
|
||||
m = SystemDictionary::internal_Unsafe_klass()->find_method(
|
||||
vmSymbols::throwIllegalAccessError_name(),
|
||||
vmSymbols::void_method_signature());
|
||||
if (m != NULL && !m->is_static()) {
|
||||
|
@ -1019,7 +1019,7 @@ bool universe_post_init() {
|
|||
return false; // initialization failed (cannot throw exception yet)
|
||||
}
|
||||
Universe::_throw_illegal_access_error_cache->init(
|
||||
SystemDictionary::misc_Unsafe_klass(), m);
|
||||
SystemDictionary::internal_Unsafe_klass(), m);
|
||||
|
||||
// Setup method for registering loaded classes in class loader vector
|
||||
SystemDictionary::ClassLoader_klass()->link_class(CHECK_false);
|
||||
|
|
|
@ -1302,6 +1302,73 @@ vmSymbols::SID Method::klass_id_for_intrinsics(Klass* holder) {
|
|||
return vmSymbols::find_sid(klass_name);
|
||||
}
|
||||
|
||||
static bool is_unsafe_alias(vmSymbols::SID name_id) {
|
||||
// All 70 intrinsic candidate methods from sun.misc.Unsafe in 1.8.
|
||||
// Some have the same method name but different signature, e.g.
|
||||
// getByte(long), getByte(Object,long)
|
||||
switch (name_id) {
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(allocateInstance_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(copyMemory_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(loadFence_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(storeFence_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(fullFence_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getObject_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getBoolean_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getByte_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getShort_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getChar_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getFloat_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getDouble_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putObject_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putBoolean_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putByte_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putShort_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putChar_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putFloat_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putDouble_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getObjectVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getBooleanVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getByteVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getShortVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getCharVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getIntVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getLongVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getFloatVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getDoubleVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putObjectVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putBooleanVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putByteVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putShortVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putCharVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putIntVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putLongVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putFloatVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putDoubleVolatile_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAddress_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putAddress_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapObject_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedObject_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndAddInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndAddLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetInt_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetLong_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetObject_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(park_name):
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(unpark_name):
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Method::init_intrinsic_id() {
|
||||
assert(_intrinsic_id == vmIntrinsics::_none, "do this just once");
|
||||
const uintptr_t max_id_uint = right_n_bits((int)(sizeof(_intrinsic_id) * BitsPerByte));
|
||||
|
@ -1354,6 +1421,14 @@ void Method::init_intrinsic_id() {
|
|||
if (is_static() != MethodHandles::is_signature_polymorphic_static(id))
|
||||
id = vmIntrinsics::_none;
|
||||
break;
|
||||
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Unsafe):
|
||||
// Map sun.misc.Unsafe to jdk.internal.misc.Unsafe
|
||||
if (!is_unsafe_alias(name_id)) break;
|
||||
// pretend it is the corresponding method in the internal Unsafe class:
|
||||
klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_misc_Unsafe);
|
||||
id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
if (id != vmIntrinsics::_none) {
|
||||
|
|
|
@ -2779,9 +2779,9 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind
|
|||
}
|
||||
|
||||
//----------------------------inline_unsafe_ordered_store----------------------
|
||||
// public native void sun.misc.Unsafe.putOrderedObject(Object o, long offset, Object x);
|
||||
// public native void sun.misc.Unsafe.putOrderedInt(Object o, long offset, int x);
|
||||
// public native void sun.misc.Unsafe.putOrderedLong(Object o, long offset, long x);
|
||||
// public native void Unsafe.putOrderedObject(Object o, long offset, Object x);
|
||||
// public native void Unsafe.putOrderedInt(Object o, long offset, int x);
|
||||
// public native void Unsafe.putOrderedLong(Object o, long offset, long x);
|
||||
bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
|
||||
// This is another variant of inline_unsafe_access, differing in
|
||||
// that it always issues store-store ("release") barrier and ensures
|
||||
|
@ -2875,7 +2875,7 @@ bool LibraryCallKit::klass_needs_init_guard(Node* kls) {
|
|||
}
|
||||
|
||||
//----------------------------inline_unsafe_allocate---------------------------
|
||||
// public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls);
|
||||
// public native Object Unsafe.allocateInstance(Class<?> cls);
|
||||
bool LibraryCallKit::inline_unsafe_allocate() {
|
||||
if (callee()->is_static()) return false; // caller must have the capability!
|
||||
|
||||
|
@ -4194,7 +4194,7 @@ bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
|
|||
#endif //_LP64
|
||||
|
||||
//----------------------inline_unsafe_copyMemory-------------------------
|
||||
// public native void sun.misc.Unsafe.copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
|
||||
// public native void Unsafe.copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
|
||||
bool LibraryCallKit::inline_unsafe_copyMemory() {
|
||||
if (callee()->is_static()) return false; // caller must have the capability!
|
||||
null_check_receiver(); // null-check receiver
|
||||
|
|
|
@ -997,7 +997,7 @@ public:
|
|||
// "Acquire" - no following ref can move before (but earlier refs can
|
||||
// follow, like an early Load stalled in cache). Requires multi-cpu
|
||||
// visibility. Inserted independ of any load, as required
|
||||
// for intrinsic sun.misc.Unsafe.loadFence().
|
||||
// for intrinsic Unsafe.loadFence().
|
||||
class LoadFenceNode: public MemBarNode {
|
||||
public:
|
||||
LoadFenceNode(Compile* C, int alias_idx, Node* precedent)
|
||||
|
@ -1018,7 +1018,7 @@ public:
|
|||
// "Release" - no earlier ref can move after (but later refs can move
|
||||
// up, like a speculative pipelined cache-hitting Load). Requires
|
||||
// multi-cpu visibility. Inserted independent of any store, as required
|
||||
// for intrinsic sun.misc.Unsafe.storeFence().
|
||||
// for intrinsic Unsafe.storeFence().
|
||||
class StoreFenceNode: public MemBarNode {
|
||||
public:
|
||||
StoreFenceNode(Compile* C, int alias_idx, Node* precedent)
|
||||
|
|
|
@ -4061,6 +4061,10 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
|
|||
OrderAccess::release_store(&vm_created, 0);
|
||||
}
|
||||
|
||||
// Flush stdout and stderr before exit.
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
|
|
@ -1892,7 +1892,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct(
|
|||
}
|
||||
|
||||
u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray,
|
||||
byte_i_ref, "mapped old type_index=%d", THREAD);
|
||||
byte_i_ref, "type_index", THREAD);
|
||||
|
||||
u2 num_element_value_pairs = Bytes::get_Java_u2((address)
|
||||
annotations_typeArray->adr_at(byte_i_ref));
|
||||
|
@ -1915,7 +1915,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct(
|
|||
|
||||
u2 element_name_index = rewrite_cp_ref_in_annotation_data(
|
||||
annotations_typeArray, byte_i_ref,
|
||||
"mapped old element_name_index=%d", THREAD);
|
||||
"element_name_index", THREAD);
|
||||
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
|
||||
("element_name_index=%d", element_name_index));
|
||||
|
@ -1939,8 +1939,6 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct(
|
|||
// annotations_typeArray if needed. Returns the original constant
|
||||
// pool reference if a rewrite was not needed or the new constant
|
||||
// pool reference if a rewrite was needed.
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data(
|
||||
AnnotationArray* annotations_typeArray, int &byte_i_ref,
|
||||
const char * trace_mesg, TRAPS) {
|
||||
|
@ -1950,14 +1948,13 @@ u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data(
|
|||
u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr);
|
||||
u2 new_cp_index = find_new_index(old_cp_index);
|
||||
if (new_cp_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD, (trace_mesg, old_cp_index));
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("mapped old %s=%d", trace_mesg, old_cp_index));
|
||||
Bytes::put_Java_u2(cp_index_addr, new_cp_index);
|
||||
old_cp_index = new_cp_index;
|
||||
}
|
||||
byte_i_ref += 2;
|
||||
return old_cp_index;
|
||||
}
|
||||
PRAGMA_DIAG_POP
|
||||
|
||||
|
||||
// Rewrite constant pool references in the element_value portion of an
|
||||
|
@ -2022,7 +2019,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_element_value(
|
|||
|
||||
u2 const_value_index = rewrite_cp_ref_in_annotation_data(
|
||||
annotations_typeArray, byte_i_ref,
|
||||
"mapped old const_value_index=%d", THREAD);
|
||||
"const_value_index", THREAD);
|
||||
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
|
||||
("const_value_index=%d", const_value_index));
|
||||
|
@ -2041,11 +2038,11 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_element_value(
|
|||
|
||||
u2 type_name_index = rewrite_cp_ref_in_annotation_data(
|
||||
annotations_typeArray, byte_i_ref,
|
||||
"mapped old type_name_index=%d", THREAD);
|
||||
"type_name_index", THREAD);
|
||||
|
||||
u2 const_name_index = rewrite_cp_ref_in_annotation_data(
|
||||
annotations_typeArray, byte_i_ref,
|
||||
"mapped old const_name_index=%d", THREAD);
|
||||
"const_name_index", THREAD);
|
||||
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
|
||||
("type_name_index=%d const_name_index=%d", type_name_index,
|
||||
|
@ -2065,7 +2062,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_element_value(
|
|||
|
||||
u2 class_info_index = rewrite_cp_ref_in_annotation_data(
|
||||
annotations_typeArray, byte_i_ref,
|
||||
"mapped old class_info_index=%d", THREAD);
|
||||
"class_info_index", THREAD);
|
||||
|
||||
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
|
||||
("class_info_index=%d", class_info_index));
|
||||
|
@ -3379,7 +3376,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
|
|||
// default_vtable_indices for methods already in the vtable.
|
||||
// If redefining Unsafe, walk all the vtables looking for entries.
|
||||
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
|
||||
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|
||||
|| _the_class_oop == SystemDictionary::internal_Unsafe_klass()
|
||||
|| ik->is_subtype_of(_the_class_oop))) {
|
||||
// ik->vtable() creates a wrapper object; rm cleans it up
|
||||
ResourceMark rm(_thread);
|
||||
|
@ -3396,7 +3393,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
|
|||
// subclass relationship between an interface and an InstanceKlass.
|
||||
// If redefining Unsafe, walk all the itables looking for entries.
|
||||
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|
||||
|| _the_class_oop == SystemDictionary::misc_Unsafe_klass()
|
||||
|| _the_class_oop == SystemDictionary::internal_Unsafe_klass()
|
||||
|| ik->is_subclass_of(_the_class_oop))) {
|
||||
// ik->itable() creates a wrapper object; rm cleans it up
|
||||
ResourceMark rm(_thread);
|
||||
|
|
|
@ -121,6 +121,7 @@ extern "C" {
|
|||
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
|
||||
|
||||
static JNINativeMethod lookup_special_native_methods[] = {
|
||||
{ CC"Java_jdk_internal_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
|
||||
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
/*
|
||||
* Implementation of class sun.misc.Unsafe
|
||||
* Implementation of class Unsafe
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -416,7 +416,6 @@ nmethod* NonTieredCompPolicy::event(const methodHandle& method, const methodHand
|
|||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
|
||||
if (TraceInvocationCounterOverflow) {
|
||||
MethodCounters* mcs = m->method_counters();
|
||||
|
@ -424,14 +423,11 @@ void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m
|
|||
InvocationCounter* ic = mcs->invocation_counter();
|
||||
InvocationCounter* bc = mcs->backedge_counter();
|
||||
ResourceMark rm;
|
||||
const char* msg =
|
||||
bci == InvocationEntryBci
|
||||
? "comp-policy cntr ovfl @ %d in entry of "
|
||||
: "comp-policy cntr ovfl @ %d in loop of ";
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
tty->print(msg, bci);
|
||||
PRAGMA_DIAG_POP
|
||||
if (bci == InvocationEntryBci) {
|
||||
tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
|
||||
} else {
|
||||
tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
|
||||
}
|
||||
m->print_value();
|
||||
tty->cr();
|
||||
ic->print();
|
||||
|
|
|
@ -349,11 +349,6 @@ bool Flag::is_external() const {
|
|||
return is_manageable() || is_external_ext();
|
||||
}
|
||||
|
||||
|
||||
// Length of format string (e.g. "%.1234s") for printing ccstr below
|
||||
#define FORMAT_BUFFER_LEN 16
|
||||
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
|
||||
// Don't print notproduct and develop flags in a product build.
|
||||
if (is_constant_in_binary()) {
|
||||
|
@ -385,14 +380,8 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
|
|||
if (cp != NULL) {
|
||||
const char* eol;
|
||||
while ((eol = strchr(cp, '\n')) != NULL) {
|
||||
char format_buffer[FORMAT_BUFFER_LEN];
|
||||
size_t llen = pointer_delta(eol, cp, sizeof(char));
|
||||
jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
|
||||
"%%." SIZE_FORMAT "s", llen);
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
st->print(format_buffer, cp);
|
||||
PRAGMA_DIAG_POP
|
||||
st->print("%.*s", (int)llen, cp);
|
||||
st->cr();
|
||||
cp = eol+1;
|
||||
st->print("%5s %-35s += ", "", _name);
|
||||
|
|
|
@ -812,7 +812,7 @@ public:
|
|||
"Inline Thread.currentThread, etc") \
|
||||
\
|
||||
develop(bool, InlineUnsafeOps, true, \
|
||||
"Inline memory ops (native methods) from sun.misc.Unsafe") \
|
||||
"Inline memory ops (native methods) from Unsafe") \
|
||||
\
|
||||
product(bool, CriticalJNINatives, true, \
|
||||
"Check for critical JNI entry points") \
|
||||
|
@ -4241,7 +4241,7 @@ public:
|
|||
"Use locked-tracing when doing event-based tracing") \
|
||||
\
|
||||
diagnostic(bool, UseUnalignedAccesses, false, \
|
||||
"Use unaligned memory accesses in sun.misc.Unsafe") \
|
||||
"Use unaligned memory accesses in Unsafe") \
|
||||
\
|
||||
product_pd(bool, PreserveFramePointer, \
|
||||
"Use the FP register for holding the frame pointer " \
|
||||
|
|
|
@ -575,6 +575,11 @@ void vm_shutdown()
|
|||
void vm_abort(bool dump_core) {
|
||||
vm_perform_shutdown_actions();
|
||||
os::wait_for_keypress_at_exit();
|
||||
|
||||
// Flush stdout and stderr before abort.
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
os::abort(dump_core);
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
|
|
@ -96,8 +96,7 @@ char* os::iso8601_time(char* buffer, size_t buffer_length) {
|
|||
// Output will be of the form "YYYY-MM-DDThh:mm:ss.mmm+zzzz\0"
|
||||
// 1 2
|
||||
// 12345678901234567890123456789
|
||||
static const char* iso8601_format =
|
||||
"%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d";
|
||||
// format string: "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d"
|
||||
static const size_t needed_buffer = 29;
|
||||
|
||||
// Sanity check the arguments
|
||||
|
@ -158,7 +157,8 @@ char* os::iso8601_time(char* buffer, size_t buffer_length) {
|
|||
// Print an ISO 8601 date and time stamp into the buffer
|
||||
const int year = 1900 + time_struct.tm_year;
|
||||
const int month = 1 + time_struct.tm_mon;
|
||||
const int printed = jio_snprintf(buffer, buffer_length, iso8601_format,
|
||||
const int printed = jio_snprintf(buffer, buffer_length,
|
||||
"%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d",
|
||||
year,
|
||||
month,
|
||||
time_struct.tm_mday,
|
||||
|
|
|
@ -722,7 +722,7 @@ void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr
|
|||
o = oopDesc::load_decode_heap_oop((oop*)addr);
|
||||
}
|
||||
|
||||
// reflection and sun.misc.Unsafe classes may have a reference to a
|
||||
// reflection and Unsafe classes may have a reference to a
|
||||
// Klass* so filter it out.
|
||||
assert(o->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
|
||||
writer->write_objectID(o);
|
||||
|
@ -1848,7 +1848,6 @@ void VM_HeapDumper::dump_stack_traces() {
|
|||
}
|
||||
|
||||
// dump the heap to given path.
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
int HeapDumper::dump(const char* path) {
|
||||
assert(path != NULL && strlen(path) > 0, "path missing");
|
||||
|
||||
|
@ -1886,13 +1885,8 @@ int HeapDumper::dump(const char* path) {
|
|||
if (print_to_tty()) {
|
||||
timer()->stop();
|
||||
if (error() == NULL) {
|
||||
char msg[256];
|
||||
sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
|
||||
JLONG_FORMAT, timer()->seconds());
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
tty->print_cr(msg, writer.bytes_written());
|
||||
PRAGMA_DIAG_POP
|
||||
tty->print_cr("Heap dump file created [" JLONG_FORMAT " bytes in %3.3f secs]",
|
||||
writer.bytes_written(), timer()->seconds());
|
||||
} else {
|
||||
tty->print_cr("Dump file is incomplete: %s", writer.error());
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ static void print_flag_error_message_bounds(const char* name, char* buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
static void print_flag_error_message_if_needed(Flag::Error error, const char* name, FormatBuffer<80>& err_msg) {
|
||||
if (error == Flag::SUCCESS) {
|
||||
return;
|
||||
|
|
|
@ -65,7 +65,7 @@ bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
|
|||
case vmIntrinsics::_currentThread:
|
||||
return true;
|
||||
|
||||
// sun.misc.Unsafe
|
||||
// Unsafe
|
||||
case vmIntrinsics::_compareAndSwapInt:
|
||||
return true;
|
||||
|
||||
|
@ -139,7 +139,7 @@ void SharkIntrinsics::do_intrinsic() {
|
|||
do_Thread_currentThread();
|
||||
break;
|
||||
|
||||
// sun.misc.Unsafe
|
||||
// Unsafe
|
||||
case vmIntrinsics::_compareAndSwapInt:
|
||||
do_Unsafe_compareAndSwapInt();
|
||||
break;
|
||||
|
|
|
@ -287,8 +287,6 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
|
|||
// Tested to work with clang version 3.1 and better.
|
||||
#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push")
|
||||
#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop")
|
||||
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
|
||||
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
|
||||
// Hack to deal with gcc yammering about non-security format stuff
|
||||
#else
|
||||
|
@ -297,8 +295,6 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
|
|||
// versions of the macro-pragma to obtain better checking with newer compilers.
|
||||
#define PRAGMA_DIAG_PUSH
|
||||
#define PRAGMA_DIAG_POP
|
||||
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
|
||||
|
|
|
@ -340,6 +340,7 @@ void xmlStream::done_raw(const char* kind) {
|
|||
print_raw_cr(">");
|
||||
}
|
||||
|
||||
// If you remove the PRAGMA, this fails to compile with clang-503.0.40.
|
||||
PRAGMA_DIAG_PUSH
|
||||
PRAGMA_FORMAT_NONLITERAL_IGNORED
|
||||
// ------------------------------------------------------------------
|
||||
|
|
|
@ -43,13 +43,13 @@ package java.lang.invoke;
|
|||
import jdk.internal.org.objectweb.asm.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.Utils;
|
||||
import sun.misc.Unsafe;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class UnsafeGetConstantField {
|
||||
static final Class<?> THIS_CLASS = UnsafeGetConstantField.class;
|
||||
|
||||
static final Unsafe U = Utils.getUnsafe();
|
||||
static final Unsafe U = Unsafe.getUnsafe();
|
||||
|
||||
public static void main(String[] args) {
|
||||
testUnsafeGetAddress();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue