This commit is contained in:
Coleen Phillimore 2015-10-28 15:03:40 +01:00
commit b046110ab7
41 changed files with 620 additions and 426 deletions

View file

@ -315,6 +315,7 @@ inline Symbol* check_symbol_at(constantPoolHandle cp, int index) {
return NULL; return NULL;
} }
#ifdef ASSERT
PRAGMA_DIAG_PUSH PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED PRAGMA_FORMAT_NONLITERAL_IGNORED
void ClassFileParser::report_assert_property_failure(const char* msg, TRAPS) { 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()); fatal(msg, index, _class_name->as_C_string());
} }
PRAGMA_DIAG_POP PRAGMA_DIAG_POP
#endif
constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ClassFileStream* cfs = stream(); ClassFileStream* cfs = stream();

View file

@ -319,8 +319,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
if (!b) { classfile_parse_error(msg, CHECK); } if (!b) { classfile_parse_error(msg, CHECK); }
} }
void report_assert_property_failure(const char* msg, TRAPS); void report_assert_property_failure(const char* msg, TRAPS) PRODUCT_RETURN;
void report_assert_property_failure(const char* msg, int index, TRAPS); void report_assert_property_failure(const char* msg, int index, TRAPS) PRODUCT_RETURN;
inline void assert_property(bool b, const char* msg, TRAPS) { inline void assert_property(bool b, const char* msg, TRAPS) {
#ifdef ASSERT #ifdef ASSERT

View file

@ -1967,7 +1967,8 @@ void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
instanceKlassHandle k, instanceKlassHandle k,
Handle class_loader, bool defining, Handle class_loader, bool defining,
TRAPS) { TRAPS) {
const char *linkage_error = NULL; const char *linkage_error1 = NULL;
const char *linkage_error2 = NULL;
{ {
Symbol* name = k->name(); Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader); 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"); assert(check->is_instance_klass(), "noninstance in systemdictionary");
if ((defining == true) || (k() != check)) { if ((defining == true) || (k() != check)) {
linkage_error = "loader (instance of %s): attempted duplicate class " linkage_error1 = "loader (instance of ";
"definition for name: \"%s\""; linkage_error2 = "): attempted duplicate class definition for name: \"";
} else { } else {
return; 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"); assert(ph_check == NULL || ph_check == name, "invalid symbol");
#endif #endif
if (linkage_error == NULL) { if (linkage_error1 == NULL) {
if (constraints()->check_or_update(k, class_loader, name) == false) { if (constraints()->check_or_update(k, class_loader, name) == false) {
linkage_error = "loader constraint violation: loader (instance of %s)" linkage_error1 = "loader constraint violation: loader (instance of ";
" previously initiated loading for a different type with name \"%s\""; 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 // Throw error now if needed (cannot throw while holding
// SystemDictionary_lock because of rank ordering) // SystemDictionary_lock because of rank ordering)
if (linkage_error) { if (linkage_error1) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
const char* class_loader_name = loader_name(class_loader()); const char* class_loader_name = loader_name(class_loader());
char* type_name = k->name()->as_C_string(); char* type_name = k->name()->as_C_string();
size_t buflen = strlen(linkage_error) + strlen(class_loader_name) + size_t buflen = strlen(linkage_error1) + strlen(class_loader_name) +
strlen(type_name); strlen(linkage_error2) + strlen(type_name) + 2; // +2 for '"' and null byte.
char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); 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); THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
} }
} }

View file

@ -168,7 +168,7 @@ class Ticks;
\ \
do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \ do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \
do_klass(StringBuilder_klass, java_lang_StringBuilder, 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 */ \ /* support for CDS */ \
do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream, Pre ) \ do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream, Pre ) \

View file

@ -938,22 +938,23 @@
do_intrinsic(_updateByteBufferAdler32, java_util_zip_Adler32, updateByteBuffer_A_name, updateByteBuffer_signature, F_SN) \ do_intrinsic(_updateByteBufferAdler32, java_util_zip_Adler32, updateByteBuffer_A_name, updateByteBuffer_signature, F_SN) \
do_name( updateByteBuffer_A_name, "updateByteBuffer") \ do_name( updateByteBuffer_A_name, "updateByteBuffer") \
\ \
/* support for sun.misc.Unsafe */ \ /* support for Unsafe */ \
do_class(sun_misc_Unsafe, "sun/misc/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_intrinsic(_allocateInstance, jdk_internal_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
do_name( allocateInstance_name, "allocateInstance") \ do_name( allocateInstance_name, "allocateInstance") \
do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \ do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \
do_intrinsic(_copyMemory, sun_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \ do_intrinsic(_copyMemory, jdk_internal_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
do_name( copyMemory_name, "copyMemory") \ do_name( copyMemory_name, "copyMemory") \
do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \ 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_intrinsic(_loadFence, jdk_internal_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
do_name( loadFence_name, "loadFence") \ do_name( loadFence_name, "loadFence") \
do_alias( loadFence_signature, void_method_signature) \ do_alias( loadFence_signature, void_method_signature) \
do_intrinsic(_storeFence, sun_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \ do_intrinsic(_storeFence, jdk_internal_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
do_name( storeFence_name, "storeFence") \ do_name( storeFence_name, "storeFence") \
do_alias( storeFence_signature, void_method_signature) \ do_alias( storeFence_signature, void_method_signature) \
do_intrinsic(_fullFence, sun_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \ do_intrinsic(_fullFence, jdk_internal_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
do_name( fullFence_name, "fullFence") \ do_name( fullFence_name, "fullFence") \
do_alias( fullFence_signature, void_method_signature) \ do_alias( fullFence_signature, void_method_signature) \
\ \
@ -996,24 +997,24 @@
do_name(getFloat_name,"getFloat") do_name(putFloat_name,"putFloat") \ do_name(getFloat_name,"getFloat") do_name(putFloat_name,"putFloat") \
do_name(getDouble_name,"getDouble") do_name(putDouble_name,"putDouble") \ do_name(getDouble_name,"getDouble") do_name(putDouble_name,"putDouble") \
\ \
do_intrinsic(_getObject, sun_misc_Unsafe, getObject_name, getObject_signature, F_RN) \ do_intrinsic(_getObject, jdk_internal_misc_Unsafe, getObject_name, getObject_signature, F_RN) \
do_intrinsic(_getBoolean, sun_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \ do_intrinsic(_getBoolean, jdk_internal_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \
do_intrinsic(_getByte, sun_misc_Unsafe, getByte_name, getByte_signature, F_RN) \ do_intrinsic(_getByte, jdk_internal_misc_Unsafe, getByte_name, getByte_signature, F_RN) \
do_intrinsic(_getShort, sun_misc_Unsafe, getShort_name, getShort_signature, F_RN) \ do_intrinsic(_getShort, jdk_internal_misc_Unsafe, getShort_name, getShort_signature, F_RN) \
do_intrinsic(_getChar, sun_misc_Unsafe, getChar_name, getChar_signature, F_RN) \ do_intrinsic(_getChar, jdk_internal_misc_Unsafe, getChar_name, getChar_signature, F_RN) \
do_intrinsic(_getInt, sun_misc_Unsafe, getInt_name, getInt_signature, F_RN) \ do_intrinsic(_getInt, jdk_internal_misc_Unsafe, getInt_name, getInt_signature, F_RN) \
do_intrinsic(_getLong, sun_misc_Unsafe, getLong_name, getLong_signature, F_RN) \ do_intrinsic(_getLong, jdk_internal_misc_Unsafe, getLong_name, getLong_signature, F_RN) \
do_intrinsic(_getFloat, sun_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \ do_intrinsic(_getFloat, jdk_internal_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \
do_intrinsic(_getDouble, sun_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \ do_intrinsic(_getDouble, jdk_internal_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \
do_intrinsic(_putObject, sun_misc_Unsafe, putObject_name, putObject_signature, F_RN) \ do_intrinsic(_putObject, jdk_internal_misc_Unsafe, putObject_name, putObject_signature, F_RN) \
do_intrinsic(_putBoolean, sun_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \ do_intrinsic(_putBoolean, jdk_internal_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \
do_intrinsic(_putByte, sun_misc_Unsafe, putByte_name, putByte_signature, F_RN) \ do_intrinsic(_putByte, jdk_internal_misc_Unsafe, putByte_name, putByte_signature, F_RN) \
do_intrinsic(_putShort, sun_misc_Unsafe, putShort_name, putShort_signature, F_RN) \ do_intrinsic(_putShort, jdk_internal_misc_Unsafe, putShort_name, putShort_signature, F_RN) \
do_intrinsic(_putChar, sun_misc_Unsafe, putChar_name, putChar_signature, F_RN) \ do_intrinsic(_putChar, jdk_internal_misc_Unsafe, putChar_name, putChar_signature, F_RN) \
do_intrinsic(_putInt, sun_misc_Unsafe, putInt_name, putInt_signature, F_RN) \ do_intrinsic(_putInt, jdk_internal_misc_Unsafe, putInt_name, putInt_signature, F_RN) \
do_intrinsic(_putLong, sun_misc_Unsafe, putLong_name, putLong_signature, F_RN) \ do_intrinsic(_putLong, jdk_internal_misc_Unsafe, putLong_name, putLong_signature, F_RN) \
do_intrinsic(_putFloat, sun_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \ do_intrinsic(_putFloat, jdk_internal_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \
do_intrinsic(_putDouble, sun_misc_Unsafe, putDouble_name, putDouble_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(getObjectVolatile_name,"getObjectVolatile") do_name(putObjectVolatile_name,"putObjectVolatile") \
do_name(getBooleanVolatile_name,"getBooleanVolatile") do_name(putBooleanVolatile_name,"putBooleanVolatile") \ 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(getFloatVolatile_name,"getFloatVolatile") do_name(putFloatVolatile_name,"putFloatVolatile") \
do_name(getDoubleVolatile_name,"getDoubleVolatile") do_name(putDoubleVolatile_name,"putDoubleVolatile") \ do_name(getDoubleVolatile_name,"getDoubleVolatile") do_name(putDoubleVolatile_name,"putDoubleVolatile") \
\ \
do_intrinsic(_getObjectVolatile, sun_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \ do_intrinsic(_getObjectVolatile, jdk_internal_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \
do_intrinsic(_getBooleanVolatile, sun_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \ do_intrinsic(_getBooleanVolatile, jdk_internal_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \
do_intrinsic(_getByteVolatile, sun_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \ do_intrinsic(_getByteVolatile, jdk_internal_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \
do_intrinsic(_getShortVolatile, sun_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \ do_intrinsic(_getShortVolatile, jdk_internal_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \
do_intrinsic(_getCharVolatile, sun_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \ do_intrinsic(_getCharVolatile, jdk_internal_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \
do_intrinsic(_getIntVolatile, sun_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \ do_intrinsic(_getIntVolatile, jdk_internal_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \
do_intrinsic(_getLongVolatile, sun_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \ do_intrinsic(_getLongVolatile, jdk_internal_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \
do_intrinsic(_getFloatVolatile, sun_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \ do_intrinsic(_getFloatVolatile, jdk_internal_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \
do_intrinsic(_getDoubleVolatile, sun_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \ do_intrinsic(_getDoubleVolatile, jdk_internal_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \
do_intrinsic(_putObjectVolatile, sun_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \ do_intrinsic(_putObjectVolatile, jdk_internal_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \
do_intrinsic(_putBooleanVolatile, sun_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \ do_intrinsic(_putBooleanVolatile, jdk_internal_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \
do_intrinsic(_putByteVolatile, sun_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \ do_intrinsic(_putByteVolatile, jdk_internal_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \
do_intrinsic(_putShortVolatile, sun_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \ do_intrinsic(_putShortVolatile, jdk_internal_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \
do_intrinsic(_putCharVolatile, sun_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \ do_intrinsic(_putCharVolatile, jdk_internal_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \
do_intrinsic(_putIntVolatile, sun_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \ do_intrinsic(_putIntVolatile, jdk_internal_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \
do_intrinsic(_putLongVolatile, sun_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \ do_intrinsic(_putLongVolatile, jdk_internal_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \
do_intrinsic(_putFloatVolatile, sun_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \ do_intrinsic(_putFloatVolatile, jdk_internal_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
do_intrinsic(_putDoubleVolatile, sun_misc_Unsafe, putDoubleVolatile_name, putDouble_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(getShortUnaligned_name,"getShortUnaligned") do_name(putShortUnaligned_name,"putShortUnaligned") \
do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \ do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \
do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \ do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \
do_name(getLongUnaligned_name,"getLongUnaligned") do_name(putLongUnaligned_name,"putLongUnaligned") \ do_name(getLongUnaligned_name,"getLongUnaligned") do_name(putLongUnaligned_name,"putLongUnaligned") \
\ \
do_intrinsic(_getShortUnaligned, sun_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \ do_intrinsic(_getShortUnaligned, jdk_internal_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \
do_intrinsic(_getCharUnaligned, sun_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \ do_intrinsic(_getCharUnaligned, jdk_internal_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \
do_intrinsic(_getIntUnaligned, sun_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \ do_intrinsic(_getIntUnaligned, jdk_internal_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \
do_intrinsic(_getLongUnaligned, sun_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \ do_intrinsic(_getLongUnaligned, jdk_internal_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \
do_intrinsic(_putShortUnaligned, sun_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \ do_intrinsic(_putShortUnaligned, jdk_internal_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \
do_intrinsic(_putCharUnaligned, sun_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \ do_intrinsic(_putCharUnaligned, jdk_internal_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \
do_intrinsic(_putIntUnaligned, sun_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \ do_intrinsic(_putIntUnaligned, jdk_internal_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
do_intrinsic(_putLongUnaligned, sun_misc_Unsafe, putLongUnaligned_name, putLong_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 */ \ /* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */ \
do_signature(getByte_raw_signature, "(J)B") \ do_signature(getByte_raw_signature, "(J)B") \
@ -1078,66 +1079,67 @@
do_name( getAddress_name, "getAddress") \ do_name( getAddress_name, "getAddress") \
do_name( putAddress_name, "putAddress") \ do_name( putAddress_name, "putAddress") \
\ \
do_intrinsic(_getByte_raw, sun_misc_Unsafe, getByte_name, getByte_raw_signature, F_RN) \ do_intrinsic(_getByte_raw, jdk_internal_misc_Unsafe, getByte_name, getByte_raw_signature, F_R) \
do_intrinsic(_getShort_raw, sun_misc_Unsafe, getShort_name, getShort_raw_signature, F_RN) \ do_intrinsic(_getShort_raw, jdk_internal_misc_Unsafe, getShort_name, getShort_raw_signature, F_R) \
do_intrinsic(_getChar_raw, sun_misc_Unsafe, getChar_name, getChar_raw_signature, F_RN) \ do_intrinsic(_getChar_raw, jdk_internal_misc_Unsafe, getChar_name, getChar_raw_signature, F_R) \
do_intrinsic(_getInt_raw, sun_misc_Unsafe, getInt_name, long_int_signature, F_RN) \ do_intrinsic(_getInt_raw, jdk_internal_misc_Unsafe, getInt_name, long_int_signature, F_R) \
do_intrinsic(_getLong_raw, sun_misc_Unsafe, getLong_name, getLong_raw_signature, F_RN) \ do_intrinsic(_getLong_raw, jdk_internal_misc_Unsafe, getLong_name, getLong_raw_signature, F_R) \
do_intrinsic(_getFloat_raw, sun_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_RN) \ do_intrinsic(_getFloat_raw, jdk_internal_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_R) \
do_intrinsic(_getDouble_raw, sun_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_RN) \ do_intrinsic(_getDouble_raw, jdk_internal_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_R) \
do_intrinsic(_getAddress_raw, sun_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_RN) \ do_intrinsic(_getAddress_raw, jdk_internal_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_R) \
do_intrinsic(_putByte_raw, sun_misc_Unsafe, putByte_name, putByte_raw_signature, F_RN) \ do_intrinsic(_putByte_raw, jdk_internal_misc_Unsafe, putByte_name, putByte_raw_signature, F_R) \
do_intrinsic(_putShort_raw, sun_misc_Unsafe, putShort_name, putShort_raw_signature, F_RN) \ do_intrinsic(_putShort_raw, jdk_internal_misc_Unsafe, putShort_name, putShort_raw_signature, F_R) \
do_intrinsic(_putChar_raw, sun_misc_Unsafe, putChar_name, putChar_raw_signature, F_RN) \ do_intrinsic(_putChar_raw, jdk_internal_misc_Unsafe, putChar_name, putChar_raw_signature, F_R) \
do_intrinsic(_putInt_raw, sun_misc_Unsafe, putInt_name, putInt_raw_signature, F_RN) \ do_intrinsic(_putInt_raw, jdk_internal_misc_Unsafe, putInt_name, putInt_raw_signature, F_R) \
do_intrinsic(_putLong_raw, sun_misc_Unsafe, putLong_name, putLong_raw_signature, F_RN) \ do_intrinsic(_putLong_raw, jdk_internal_misc_Unsafe, putLong_name, putLong_raw_signature, F_R) \
do_intrinsic(_putFloat_raw, sun_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_RN) \ do_intrinsic(_putFloat_raw, jdk_internal_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_R) \
do_intrinsic(_putDouble_raw, sun_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_RN) \ do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \
do_intrinsic(_putAddress_raw, sun_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_RN) \ 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_intrinsic(_compareAndSwapObject, jdk_internal_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_R) \
do_name( compareAndSwapObject_name, "compareAndSwapObject") \ do_name( compareAndSwapObject_name, "compareAndSwapObject") \
do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \ 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_intrinsic(_compareAndSwapLong, jdk_internal_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_R) \
do_name( compareAndSwapLong_name, "compareAndSwapLong") \ do_name( compareAndSwapLong_name, "compareAndSwapLong") \
do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \ do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
do_intrinsic(_compareAndSwapInt, sun_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_RN) \ do_intrinsic(_compareAndSwapInt, jdk_internal_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_R) \
do_name( compareAndSwapInt_name, "compareAndSwapInt") \ do_name( compareAndSwapInt_name, "compareAndSwapInt") \
do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \ do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
do_intrinsic(_putOrderedObject, sun_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \ do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_R) \
do_name( putOrderedObject_name, "putOrderedObject") \ do_name( putOrderedObject_name, "putOrderedObject") \
do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \ do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
do_intrinsic(_putOrderedLong, sun_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \ do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_R) \
do_name( putOrderedLong_name, "putOrderedLong") \ do_name( putOrderedLong_name, "putOrderedLong") \
do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \ do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
do_intrinsic(_putOrderedInt, sun_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \ do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_R) \
do_name( putOrderedInt_name, "putOrderedInt") \ do_name( putOrderedInt_name, "putOrderedInt") \
do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \ do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
\ \
do_intrinsic(_getAndAddInt, sun_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \ do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
do_name( getAndAddInt_name, "getAndAddInt") \ do_name( getAndAddInt_name, "getAndAddInt") \
do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \ do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \
do_intrinsic(_getAndAddLong, sun_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \ do_intrinsic(_getAndAddLong, jdk_internal_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \
do_name( getAndAddLong_name, "getAndAddLong") \ do_name( getAndAddLong_name, "getAndAddLong") \
do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \ do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \
do_intrinsic(_getAndSetInt, sun_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \ do_intrinsic(_getAndSetInt, jdk_internal_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \
do_name( getAndSetInt_name, "getAndSetInt") \ do_name( getAndSetInt_name, "getAndSetInt") \
do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \ do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \
do_intrinsic(_getAndSetLong, sun_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \ do_intrinsic(_getAndSetLong, jdk_internal_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \
do_name( getAndSetLong_name, "getAndSetLong") \ do_name( getAndSetLong_name, "getAndSetLong") \
do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \ do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \
do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\ do_intrinsic(_getAndSetObject, jdk_internal_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
do_name( getAndSetObject_name, "getAndSetObject") \ do_name( getAndSetObject_name, "getAndSetObject") \
do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \ do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
\ \
/* (2) Bytecode intrinsics */ \ /* (2) Bytecode intrinsics */ \
\ \
do_intrinsic(_park, sun_misc_Unsafe, park_name, park_signature, F_RN) \ do_intrinsic(_park, jdk_internal_misc_Unsafe, park_name, park_signature, F_R) \
do_name( park_name, "park") \ do_name( park_name, "park") \
do_signature(park_signature, "(ZJ)V") \ do_signature(park_signature, "(ZJ)V") \
do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \ do_intrinsic(_unpark, jdk_internal_misc_Unsafe, unpark_name, unpark_signature, F_R) \
do_name( unpark_name, "unpark") \ do_name( unpark_name, "unpark") \
do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \ 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_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_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) \ do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \

View file

@ -79,9 +79,6 @@ class ConcurrentMarkSweepThread: public ConcurrentGCThread {
static void makeSurrogateLockerThread(TRAPS); static void makeSurrogateLockerThread(TRAPS);
static SurrogateLockerThread* slt() { return _slt; } static SurrogateLockerThread* slt() { return _slt; }
// Tester
bool is_ConcurrentGC_thread() const { return true; }
static void threads_do(ThreadClosure* tc); static void threads_do(ThreadClosure* tc);
// Printing // Printing

View file

@ -30,7 +30,8 @@
#include "runtime/java.hpp" #include "runtime/java.hpp"
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) : ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
_threads(NULL), _n_threads(0), _threads(NULL),
_sample_thread(NULL),
_hot_card_cache(g1h) _hot_card_cache(g1h)
{ {
// Ergonomically select initial concurrent refinement parameters // Ergonomically select initial concurrent refinement parameters
@ -58,12 +59,10 @@ ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEn
return NULL; return NULL;
} }
cg1r->_n_worker_threads = thread_num(); 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->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) { if (cg1r->_threads == NULL) {
*ecode = JNI_ENOMEM; *ecode = JNI_ENOMEM;
vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread"); 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(); uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
ConcurrentG1RefineThread *next = NULL; 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); ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
assert(t != NULL, "Conc refine should have been created"); assert(t != NULL, "Conc refine should have been created");
if (t->osthread() == NULL) { if (t->osthread() == NULL) {
@ -86,6 +85,14 @@ ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEn
cg1r->_threads[i] = t; cg1r->_threads[i] = t;
next = 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; *ecode = JNI_OK;
return cg1r; return cg1r;
} }
@ -103,45 +110,37 @@ void ConcurrentG1Refine::init(G1RegionToSpaceMapper* card_counts_storage) {
} }
void ConcurrentG1Refine::stop() { void ConcurrentG1Refine::stop() {
if (_threads != NULL) { for (uint i = 0; i < _n_worker_threads; i++) {
for (uint i = 0; i < _n_threads; i++) {
_threads[i]->stop(); _threads[i]->stop();
} }
} _sample_thread->stop();
} }
void ConcurrentG1Refine::reinitialize_threads() { void ConcurrentG1Refine::reinitialize_threads() {
reset_threshold_step(); reset_threshold_step();
if (_threads != NULL) { for (uint i = 0; i < _n_worker_threads; i++) {
for (uint i = 0; i < _n_threads; i++) {
_threads[i]->initialize(); _threads[i]->initialize();
} }
}
} }
ConcurrentG1Refine::~ConcurrentG1Refine() { ConcurrentG1Refine::~ConcurrentG1Refine() {
if (_threads != NULL) { for (uint i = 0; i < _n_worker_threads; i++) {
for (uint i = 0; i < _n_threads; i++) {
delete _threads[i]; delete _threads[i];
} }
FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads); FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
}
delete _sample_thread;
} }
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) { void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
if (_threads != NULL) { worker_threads_do(tc);
for (uint i = 0; i < _n_threads; i++) { tc->do_thread(_sample_thread);
tc->do_thread(_threads[i]);
}
}
} }
void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) { void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
if (_threads != NULL) {
for (uint i = 0; i < worker_thread_num(); i++) { for (uint i = 0; i < worker_thread_num(); i++) {
tc->do_thread(_threads[i]); tc->do_thread(_threads[i]);
} }
}
} }
uint ConcurrentG1Refine::thread_num() { uint ConcurrentG1Refine::thread_num() {
@ -149,12 +148,10 @@ uint ConcurrentG1Refine::thread_num() {
} }
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const { 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); _threads[i]->print_on(st);
st->cr(); st->cr();
} }
} _sample_thread->print_on(st);
st->cr();
ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
return _threads[worker_thread_num()];
} }

View file

@ -26,6 +26,7 @@
#define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP #define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
#include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
@ -39,8 +40,9 @@ class G1RemSet;
class DirtyCardQueue; class DirtyCardQueue;
class ConcurrentG1Refine: public CHeapObj<mtGC> { class ConcurrentG1Refine: public CHeapObj<mtGC> {
G1YoungRemSetSamplingThread* _sample_thread;
ConcurrentG1RefineThread** _threads; ConcurrentG1RefineThread** _threads;
uint _n_threads;
uint _n_worker_threads; uint _n_worker_threads;
/* /*
* The value of the update buffer queue length falls into one of 3 zones: * 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 // Iterate over all worker refinement threads
void worker_threads_do(ThreadClosure * tc); void worker_threads_do(ThreadClosure * tc);
// The RS sampling thread // The RS sampling thread has nothing to do with refinement, but is here for now.
ConcurrentG1RefineThread * sampling_thread() const; G1YoungRemSetSamplingThread * sampling_thread() const { return _sample_thread; }
static uint thread_num(); static uint thread_num();
@ -106,7 +108,6 @@ class ConcurrentG1Refine: public CHeapObj<mtGC> {
int yellow_zone() const { return _yellow_zone; } int yellow_zone() const { return _yellow_zone; }
int red_zone() const { return _red_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; } uint worker_thread_num() const { return _n_worker_threads; }
int thread_threshold_step() const { return _thread_threshold_step; } int thread_threshold_step() const { return _thread_threshold_step; }

View file

@ -50,9 +50,8 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
// Each thread has its own monitor. The i-th thread is responsible for signaling // 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 // 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. // 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 0th (primary) worker is notified by mutator threads and has a special monitor.
// The last worker is used for young gen rset size sampling. if (!is_primary()) {
if (worker_id > 0) {
_monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true, _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
Monitor::_safepoint_check_never); Monitor::_safepoint_check_never);
} else { } else {
@ -66,61 +65,11 @@ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *nex
} }
void ConcurrentG1RefineThread::initialize() { void ConcurrentG1RefineThread::initialize() {
if (_worker_id < cg1r()->worker_thread_num()) {
// Current thread activation threshold // Current thread activation threshold
_threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(), _threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
cg1r()->yellow_zone()); cg1r()->yellow_zone());
// A thread deactivates once the number of buffer reached a deactivation threshold // A thread deactivates once the number of buffer reached a deactivation threshold
_deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone()); _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);
}
} }
void ConcurrentG1RefineThread::wait_for_completed_buffers() { void ConcurrentG1RefineThread::wait_for_completed_buffers() {
@ -133,12 +82,12 @@ void ConcurrentG1RefineThread::wait_for_completed_buffers() {
bool ConcurrentG1RefineThread::is_active() { bool ConcurrentG1RefineThread::is_active() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); 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() { void ConcurrentG1RefineThread::activate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (_worker_id > 0) { if (!is_primary()) {
if (G1TraceConcRefinement) { if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d", 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() { void ConcurrentG1RefineThread::deactivate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (_worker_id > 0) { if (!is_primary()) {
if (G1TraceConcRefinement) { if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d", 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(); initialize_in_thread();
wait_for_universe_init(); wait_for_universe_init();
if (_worker_id >= cg1r()->worker_thread_num()) { run_service();
run_young_rs_sampling();
terminate(); terminate();
return; }
}
void ConcurrentG1RefineThread::run_service() {
_vtime_start = os::elapsedVTime(); _vtime_start = os::elapsedVTime();
while (!_should_terminate) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
while (!_should_terminate) {
// Wait for work // Wait for work
wait_for_completed_buffers(); wait_for_completed_buffers();
if (_should_terminate) { if (_should_terminate) {
break; break;
} }
{ {
SuspendibleThreadSetJoiner sts_join; SuspendibleThreadSetJoiner sts_join;
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
do { do {
int curr_buffer_num = (int)dcqs.completed_buffers_num(); int curr_buffer_num = (int)dcqs.completed_buffers_num();
@ -199,7 +147,7 @@ void ConcurrentG1RefineThread::run() {
dcqs.set_completed_queue_padding(0); 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 // If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this // we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again. // thread should the number of the buffers cross the threshold again.
@ -225,8 +173,10 @@ void ConcurrentG1RefineThread::run() {
_vtime_accum = 0.0; _vtime_accum = 0.0;
} }
} }
assert(_should_terminate, "just checking");
terminate(); if (G1TraceConcRefinement) {
gclog_or_tty->print_cr("G1-Refine-stop");
}
} }
void ConcurrentG1RefineThread::stop() { void ConcurrentG1RefineThread::stop() {
@ -236,10 +186,7 @@ void ConcurrentG1RefineThread::stop() {
_should_terminate = true; _should_terminate = true;
} }
{ stop_service();
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
_monitor->notify();
}
{ {
MutexLockerEx mu(Terminator_lock); MutexLockerEx mu(Terminator_lock);
@ -247,8 +194,9 @@ void ConcurrentG1RefineThread::stop() {
Terminator_lock->wait(); 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();
}

View file

@ -31,14 +31,14 @@
class CardTableEntryClosure; class CardTableEntryClosure;
class ConcurrentG1Refine; 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 { class ConcurrentG1RefineThread: public ConcurrentGCThread {
friend class VMStructs; friend class VMStructs;
friend class G1CollectedHeap; friend class G1CollectedHeap;
double _vtime_start; // Initial virtual time. double _vtime_start; // Initial virtual time.
double _vtime_accum; // Initial virtual time. double _vtime_accum; // Accumulated virtual time.
uint _worker_id; uint _worker_id;
uint _worker_id_offset; uint _worker_id_offset;
@ -59,8 +59,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
// This thread deactivation threshold // This thread deactivation threshold
int _deactivation_threshold; int _deactivation_threshold;
void sample_young_list_rs_lengths();
void run_young_rs_sampling();
void wait_for_completed_buffers(); void wait_for_completed_buffers();
void set_active(bool x) { _active = x; } void set_active(bool x) { _active = x; }
@ -68,6 +66,11 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
void activate(); void activate();
void deactivate(); void deactivate();
bool is_primary() { return (_worker_id == 0); }
void run_service();
void stop_service();
public: public:
virtual void run(); virtual void run();
// Constructor // Constructor

View file

@ -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() { void ConcurrentMarkThread::run() {
initialize_in_thread(); initialize_in_thread();
_vtime_start = os::elapsedVTime();
wait_for_universe_init(); wait_for_universe_init();
run_service();
terminate();
}
void ConcurrentMarkThread::run_service() {
_vtime_start = os::elapsedVTime();
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1_policy = g1h->g1_policy(); G1CollectorPolicy* g1_policy = g1h->g1_policy();
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
Thread *current_thread = Thread::current();
while (!_should_terminate) { while (!_should_terminate) {
// wait until started is set. // wait until started is set.
@ -141,12 +157,7 @@ void ConcurrentMarkThread::run() {
double mark_end_sec = os::elapsedTime(); double mark_end_sec = os::elapsedTime();
_vtime_mark_accum += (mark_end_time - cycle_start); _vtime_mark_accum += (mark_end_time - cycle_start);
if (!cm()->has_aborted()) { if (!cm()->has_aborted()) {
if (g1_policy->adaptive_young_list_length()) { delay_to_keep_mmu(g1_policy, true /* remark */);
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);
}
cm_log(G1Log::fine(), true, "[GC concurrent-mark-end, %1.7lf secs]", mark_end_sec - mark_start_sec); 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); _vtime_accum = (end_time - _vtime_start);
if (!cm()->has_aborted()) { if (!cm()->has_aborted()) {
if (g1_policy->adaptive_young_list_length()) { delay_to_keep_mmu(g1_policy, false /* cleanup */);
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);
}
CMCleanUp cl_cl(_cm); CMCleanUp cl_cl(_cm);
VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */); VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
@ -272,9 +278,6 @@ void ConcurrentMarkThread::run() {
g1h->register_concurrent_cycle_end(); g1h->register_concurrent_cycle_end();
} }
} }
assert(_should_terminate, "just checking");
terminate();
} }
void ConcurrentMarkThread::stop() { void ConcurrentMarkThread::stop() {
@ -283,10 +286,7 @@ void ConcurrentMarkThread::stop() {
_should_terminate = true; _should_terminate = true;
} }
{ stop_service();
MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
CGC_lock->notify_all();
}
{ {
MutexLockerEx ml(Terminator_lock); 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() { void ConcurrentMarkThread::sleepBeforeNextCycle() {
// We join here because we don't want to do the "shouldConcurrentMark()" // We join here because we don't want to do the "shouldConcurrentMark()"
// below while the world is otherwise stopped. // below while the world is otherwise stopped.

View file

@ -27,11 +27,11 @@
#include "gc/shared/concurrentGCThread.hpp" #include "gc/shared/concurrentGCThread.hpp"
// The Concurrent Mark GC Thread (could be several in the future). // The Concurrent Mark GC Thread triggers the parallel CMConcurrentMarkingTasks
// This is copied from the Concurrent Mark Sweep GC Thread // as well as handling various marking cleanup.
// Still under construction.
class ConcurrentMark; class ConcurrentMark;
class G1CollectorPolicy;
class ConcurrentMarkThread: public ConcurrentGCThread { class ConcurrentMarkThread: public ConcurrentGCThread {
friend class VMStructs; friend class VMStructs;
@ -57,6 +57,10 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
volatile State _state; volatile State _state;
void sleepBeforeNextCycle(); void sleepBeforeNextCycle();
void delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark);
void run_service();
void stop_service();
static SurrogateLockerThread* _slt; static SurrogateLockerThread* _slt;
@ -67,9 +71,9 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
static void makeSurrogateLockerThread(TRAPS); static void makeSurrogateLockerThread(TRAPS);
static SurrogateLockerThread* slt() { return _slt; } 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(); double vtime_accum();
// Marking virtual time so far // Marking virtual time so far this thread and concurrent marking tasks.
double vtime_mark_accum(); double vtime_mark_accum();
ConcurrentMark* cm() { return _cm; } ConcurrentMark* cm() { return _cm; }

View file

@ -3934,9 +3934,13 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
_allocator->init_gc_alloc_regions(evacuation_info); _allocator->init_gc_alloc_regions(evacuation_info);
G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length()); G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length());
pre_evacuate_collection_set();
// Actually do the work... // Actually do the work...
evacuate_collection_set(evacuation_info, &per_thread_states); 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(); const size_t* surviving_young_words = per_thread_states.surviving_young_words();
free_collection_set(g1_policy()->collection_set(), evacuation_info, 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); 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; _expand_heap_after_alloc_failure = true;
_evacuation_failed = false; _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. // Disable the hot card cache.
G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache(); G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
hot_card_cache->reset_hot_cache_claimed_index(); hot_card_cache->reset_hot_cache_claimed_index();
hot_card_cache->set_use_cache(false); 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"); assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
double start_par_time_sec = os::elapsedTime(); double start_par_time_sec = os::elapsedTime();
double end_par_time_sec; double end_par_time_sec;
{ {
const uint n_workers = workers()->active_workers();
G1RootProcessor root_processor(this, n_workers); G1RootProcessor root_processor(this, n_workers);
G1ParTask g1_par_task(this, per_thread_states, _task_queues, &root_processor, 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. // 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); 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(); 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()) { if (evacuation_failed()) {
remove_self_forwarding_pointers(); 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 // cards). We need these updates logged to update any
// RSets. // RSets.
enqueue_discovered_references(per_thread_states); 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(); redirty_logged_cards();
#if defined(COMPILER2) || INCLUDE_JVMCI #if defined(COMPILER2) || INCLUDE_JVMCI

View file

@ -728,7 +728,10 @@ protected:
bool do_collection_pause_at_safepoint(double target_pause_time_ms); bool do_collection_pause_at_safepoint(double target_pause_time_ms);
// Actually do the work of evacuating the collection set. // 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. // Print the header for the per-thread termination statistics.
static void print_termination_stats_hdr(outputStream* const st); static void print_termination_stats_hdr(outputStream* const st);

View file

@ -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->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
} }
} }
if (PrintPLAB) {
gclog_or_tty->cr(); gclog_or_tty->cr();
}
// Clear accumulators for next round. // Clear accumulators for next round.
reset(); reset();
} }

View file

@ -29,11 +29,23 @@
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "utilities/debug.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. // 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" // this is the "interface"
class G1MMUTracker: public CHeapObj<mtGC> { class G1MMUTracker: public CHeapObj<mtGC> {
protected: protected:

View 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();
}
}

View 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 */

View file

@ -66,6 +66,7 @@ void ConcurrentGCThread::wait_for_universe_init() {
} }
void ConcurrentGCThread::terminate() { void ConcurrentGCThread::terminate() {
assert(_should_terminate, "Should only be called on terminate request.");
// Signal that it is terminated // Signal that it is terminated
{ {
MutexLockerEx mu(Terminator_lock, MutexLockerEx mu(Terminator_lock,

View file

@ -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) { void BytecodePrinter::print_attributes(int bci, outputStream* st) {
// Show attributes of pre-rewritten codes // Show attributes of pre-rewritten codes
Bytecodes::Code code = Bytecodes::java_code(raw_code()); 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 " ", st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
default_dest, lo, hi); default_dest, lo, hi);
int first = true; const char *comma = "";
for (int ll = lo; ll <= hi; ll++, first = false) { for (int ll = lo; ll <= hi; ll++) {
int idx = ll - lo; int idx = ll - lo;
const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : st->print("%s %d:" INT32_FORMAT " (delta: %d)", comma, ll, dest[idx], dest[idx]-bci);
", %d:" INT32_FORMAT " (delta: %d)"; comma = ",";
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
st->print(format, ll, dest[idx], dest[idx]-bci);
PRAGMA_DIAG_POP
} }
st->cr(); st->cr();
} }
@ -536,14 +531,10 @@ PRAGMA_DIAG_POP
dest[i] = bci + get_int(); dest[i] = bci + get_int();
}; };
st->print(" %d %d ", default_dest, len); st->print(" %d %d ", default_dest, len);
bool first = true; const char *comma = "";
for (int ll = 0; ll < len; ll++, first = false) { for (int ll = 0; ll < len; ll++) {
const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : st->print("%s " INT32_FORMAT ":" INT32_FORMAT, comma, key[ll], dest[ll]);
", " INT32_FORMAT ":" INT32_FORMAT ; comma = ",";
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
st->print(format, key[ll], dest[ll]);
PRAGMA_DIAG_POP
} }
st->cr(); st->cr();
} }

View file

@ -286,7 +286,6 @@ bool KlassInfoHisto::is_selected(const char *col_name) {
return true; return true;
} }
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void KlassInfoHisto::print_title(outputStream* st, bool csv_format, void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
bool selected[], int width_table[], bool selected[], int width_table[],
const char *name_table[]) { const char *name_table[]) {
@ -298,11 +297,10 @@ void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
st->print(",ClassName"); st->print(",ClassName");
} else { } else {
st->print("Index Super"); st->print("Index Super");
for (int c=0; c<KlassSizeStats::_num_columns; c++) { for (int c = 0; c < KlassSizeStats::_num_columns; c++) {
PRAGMA_DIAG_PUSH if (selected[c]) {
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print("%*s", width_table[c], name_table[c]);
if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);} }
PRAGMA_DIAG_POP
} }
st->print(" ClassName"); st->print(" ClassName");
} }
@ -607,18 +605,12 @@ void KlassInfoHisto::print_class_stats(outputStream* st,
case KlassSizeStats::_index_inst_size: case KlassSizeStats::_index_inst_size:
case KlassSizeStats::_index_inst_count: case KlassSizeStats::_index_inst_count:
case KlassSizeStats::_index_method_count: case KlassSizeStats::_index_method_count:
PRAGMA_DIAG_PUSH st->print("%*s", width_table[c], "-");
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
st->print(str_fmt(width_table[c]), "-");
PRAGMA_DIAG_POP
break; break;
default: default:
{ {
double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
PRAGMA_DIAG_PUSH st->print("%*.1f%%", width_table[c]-1, perc);
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
st->print(perc_fmt(width_table[c]), perc);
PRAGMA_DIAG_POP
} }
} }
} }

View file

@ -313,32 +313,13 @@ class KlassInfoHisto : public StackObj {
return HeapWordSize * x->size(); 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) { static void print_julong(outputStream* st, int width, julong n) {
int num_spaces = width - julong_width(n); int num_spaces = width - julong_width(n);
if (num_spaces > 0) { if (num_spaces > 0) {
st->print(str_fmt(num_spaces), ""); st->print("%*s", num_spaces, "");
} }
st->print(JULONG_FORMAT, n); 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) { static int julong_width(julong n) {
if (n == 0) { if (n == 0) {

View file

@ -1008,8 +1008,8 @@ bool universe_post_init() {
Universe::_finalizer_register_cache->init( Universe::_finalizer_register_cache->init(
SystemDictionary::Finalizer_klass(), m); SystemDictionary::Finalizer_klass(), m);
SystemDictionary::misc_Unsafe_klass()->link_class(CHECK_false); SystemDictionary::internal_Unsafe_klass()->link_class(CHECK_false);
m = SystemDictionary::misc_Unsafe_klass()->find_method( m = SystemDictionary::internal_Unsafe_klass()->find_method(
vmSymbols::throwIllegalAccessError_name(), vmSymbols::throwIllegalAccessError_name(),
vmSymbols::void_method_signature()); vmSymbols::void_method_signature());
if (m != NULL && !m->is_static()) { if (m != NULL && !m->is_static()) {
@ -1019,7 +1019,7 @@ bool universe_post_init() {
return false; // initialization failed (cannot throw exception yet) return false; // initialization failed (cannot throw exception yet)
} }
Universe::_throw_illegal_access_error_cache->init( 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 // Setup method for registering loaded classes in class loader vector
SystemDictionary::ClassLoader_klass()->link_class(CHECK_false); SystemDictionary::ClassLoader_klass()->link_class(CHECK_false);

View file

@ -1302,6 +1302,73 @@ vmSymbols::SID Method::klass_id_for_intrinsics(Klass* holder) {
return vmSymbols::find_sid(klass_name); 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() { void Method::init_intrinsic_id() {
assert(_intrinsic_id == vmIntrinsics::_none, "do this just once"); assert(_intrinsic_id == vmIntrinsics::_none, "do this just once");
const uintptr_t max_id_uint = right_n_bits((int)(sizeof(_intrinsic_id) * BitsPerByte)); 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)) if (is_static() != MethodHandles::is_signature_polymorphic_static(id))
id = vmIntrinsics::_none; id = vmIntrinsics::_none;
break; 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) { if (id != vmIntrinsics::_none) {

View file

@ -2779,9 +2779,9 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind
} }
//----------------------------inline_unsafe_ordered_store---------------------- //----------------------------inline_unsafe_ordered_store----------------------
// public native void sun.misc.Unsafe.putOrderedObject(Object o, long offset, Object x); // public native void Unsafe.putOrderedObject(Object o, long offset, Object x);
// public native void sun.misc.Unsafe.putOrderedInt(Object o, long offset, int x); // public native void 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.putOrderedLong(Object o, long offset, long x);
bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) { bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
// This is another variant of inline_unsafe_access, differing in // This is another variant of inline_unsafe_access, differing in
// that it always issues store-store ("release") barrier and ensures // 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--------------------------- //----------------------------inline_unsafe_allocate---------------------------
// public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls); // public native Object Unsafe.allocateInstance(Class<?> cls);
bool LibraryCallKit::inline_unsafe_allocate() { bool LibraryCallKit::inline_unsafe_allocate() {
if (callee()->is_static()) return false; // caller must have the capability! 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 #endif //_LP64
//----------------------inline_unsafe_copyMemory------------------------- //----------------------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() { bool LibraryCallKit::inline_unsafe_copyMemory() {
if (callee()->is_static()) return false; // caller must have the capability! if (callee()->is_static()) return false; // caller must have the capability!
null_check_receiver(); // null-check receiver null_check_receiver(); // null-check receiver

View file

@ -997,7 +997,7 @@ public:
// "Acquire" - no following ref can move before (but earlier refs can // "Acquire" - no following ref can move before (but earlier refs can
// follow, like an early Load stalled in cache). Requires multi-cpu // follow, like an early Load stalled in cache). Requires multi-cpu
// visibility. Inserted independ of any load, as required // visibility. Inserted independ of any load, as required
// for intrinsic sun.misc.Unsafe.loadFence(). // for intrinsic Unsafe.loadFence().
class LoadFenceNode: public MemBarNode { class LoadFenceNode: public MemBarNode {
public: public:
LoadFenceNode(Compile* C, int alias_idx, Node* precedent) 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 // "Release" - no earlier ref can move after (but later refs can move
// up, like a speculative pipelined cache-hitting Load). Requires // up, like a speculative pipelined cache-hitting Load). Requires
// multi-cpu visibility. Inserted independent of any store, as required // multi-cpu visibility. Inserted independent of any store, as required
// for intrinsic sun.misc.Unsafe.storeFence(). // for intrinsic Unsafe.storeFence().
class StoreFenceNode: public MemBarNode { class StoreFenceNode: public MemBarNode {
public: public:
StoreFenceNode(Compile* C, int alias_idx, Node* precedent) StoreFenceNode(Compile* C, int alias_idx, Node* precedent)

View file

@ -4061,6 +4061,10 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
OrderAccess::release_store(&vm_created, 0); OrderAccess::release_store(&vm_created, 0);
} }
// Flush stdout and stderr before exit.
fflush(stdout);
fflush(stderr);
return result; return result;
} }

View file

@ -1892,7 +1892,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct(
} }
u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray, 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) u2 num_element_value_pairs = Bytes::get_Java_u2((address)
annotations_typeArray->adr_at(byte_i_ref)); 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( u2 element_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref, annotations_typeArray, byte_i_ref,
"mapped old element_name_index=%d", THREAD); "element_name_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD, RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("element_name_index=%d", element_name_index)); ("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 // 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 not needed or the new constant
// pool reference if a rewrite was needed. // pool reference if a rewrite was needed.
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED
u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data( u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data(
AnnotationArray* annotations_typeArray, int &byte_i_ref, AnnotationArray* annotations_typeArray, int &byte_i_ref,
const char * trace_mesg, TRAPS) { 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 old_cp_index = Bytes::get_Java_u2(cp_index_addr);
u2 new_cp_index = find_new_index(old_cp_index); u2 new_cp_index = find_new_index(old_cp_index);
if (new_cp_index != 0) { 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); Bytes::put_Java_u2(cp_index_addr, new_cp_index);
old_cp_index = new_cp_index; old_cp_index = new_cp_index;
} }
byte_i_ref += 2; byte_i_ref += 2;
return old_cp_index; return old_cp_index;
} }
PRAGMA_DIAG_POP
// Rewrite constant pool references in the element_value portion of an // 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( u2 const_value_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref, annotations_typeArray, byte_i_ref,
"mapped old const_value_index=%d", THREAD); "const_value_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD, RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("const_value_index=%d", const_value_index)); ("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( u2 type_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref, 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( u2 const_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref, annotations_typeArray, byte_i_ref,
"mapped old const_name_index=%d", THREAD); "const_name_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD, RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("type_name_index=%d const_name_index=%d", type_name_index, ("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( u2 class_info_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref, annotations_typeArray, byte_i_ref,
"mapped old class_info_index=%d", THREAD); "class_info_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD, RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("class_info_index=%d", class_info_index)); ("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. // default_vtable_indices for methods already in the vtable.
// If redefining Unsafe, walk all the vtables looking for entries. // If redefining Unsafe, walk all the vtables looking for entries.
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface() 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->is_subtype_of(_the_class_oop))) {
// ik->vtable() creates a wrapper object; rm cleans it up // ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread); ResourceMark rm(_thread);
@ -3396,7 +3393,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// subclass relationship between an interface and an InstanceKlass. // subclass relationship between an interface and an InstanceKlass.
// If redefining Unsafe, walk all the itables looking for entries. // If redefining Unsafe, walk all the itables looking for entries.
if (ik->itable_length() > 0 && (_the_class_oop->is_interface() 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->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up // ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread); ResourceMark rm(_thread);

View file

@ -121,6 +121,7 @@ extern "C" {
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
static JNINativeMethod lookup_special_native_methods[] = { 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_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
{ CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },

View file

@ -45,7 +45,7 @@
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
/* /*
* Implementation of class sun.misc.Unsafe * Implementation of class Unsafe
*/ */

View file

@ -416,7 +416,6 @@ nmethod* NonTieredCompPolicy::event(const methodHandle& method, const methodHand
} }
#ifndef PRODUCT #ifndef PRODUCT
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) { void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
if (TraceInvocationCounterOverflow) { if (TraceInvocationCounterOverflow) {
MethodCounters* mcs = m->method_counters(); MethodCounters* mcs = m->method_counters();
@ -424,14 +423,11 @@ void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m
InvocationCounter* ic = mcs->invocation_counter(); InvocationCounter* ic = mcs->invocation_counter();
InvocationCounter* bc = mcs->backedge_counter(); InvocationCounter* bc = mcs->backedge_counter();
ResourceMark rm; ResourceMark rm;
const char* msg = if (bci == InvocationEntryBci) {
bci == InvocationEntryBci tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
? "comp-policy cntr ovfl @ %d in entry of " } else {
: "comp-policy cntr ovfl @ %d in loop of "; tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
PRAGMA_DIAG_PUSH }
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
tty->print(msg, bci);
PRAGMA_DIAG_POP
m->print_value(); m->print_value();
tty->cr(); tty->cr();
ic->print(); ic->print();

View file

@ -349,11 +349,6 @@ bool Flag::is_external() const {
return is_manageable() || is_external_ext(); 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) { void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
// Don't print notproduct and develop flags in a product build. // Don't print notproduct and develop flags in a product build.
if (is_constant_in_binary()) { if (is_constant_in_binary()) {
@ -385,14 +380,8 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
if (cp != NULL) { if (cp != NULL) {
const char* eol; const char* eol;
while ((eol = strchr(cp, '\n')) != NULL) { while ((eol = strchr(cp, '\n')) != NULL) {
char format_buffer[FORMAT_BUFFER_LEN];
size_t llen = pointer_delta(eol, cp, sizeof(char)); size_t llen = pointer_delta(eol, cp, sizeof(char));
jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, st->print("%.*s", (int)llen, cp);
"%%." SIZE_FORMAT "s", llen);
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
st->print(format_buffer, cp);
PRAGMA_DIAG_POP
st->cr(); st->cr();
cp = eol+1; cp = eol+1;
st->print("%5s %-35s += ", "", _name); st->print("%5s %-35s += ", "", _name);

View file

@ -812,7 +812,7 @@ public:
"Inline Thread.currentThread, etc") \ "Inline Thread.currentThread, etc") \
\ \
develop(bool, InlineUnsafeOps, true, \ develop(bool, InlineUnsafeOps, true, \
"Inline memory ops (native methods) from sun.misc.Unsafe") \ "Inline memory ops (native methods) from Unsafe") \
\ \
product(bool, CriticalJNINatives, true, \ product(bool, CriticalJNINatives, true, \
"Check for critical JNI entry points") \ "Check for critical JNI entry points") \
@ -4241,7 +4241,7 @@ public:
"Use locked-tracing when doing event-based tracing") \ "Use locked-tracing when doing event-based tracing") \
\ \
diagnostic(bool, UseUnalignedAccesses, false, \ diagnostic(bool, UseUnalignedAccesses, false, \
"Use unaligned memory accesses in sun.misc.Unsafe") \ "Use unaligned memory accesses in Unsafe") \
\ \
product_pd(bool, PreserveFramePointer, \ product_pd(bool, PreserveFramePointer, \
"Use the FP register for holding the frame pointer " \ "Use the FP register for holding the frame pointer " \

View file

@ -575,6 +575,11 @@ void vm_shutdown()
void vm_abort(bool dump_core) { void vm_abort(bool dump_core) {
vm_perform_shutdown_actions(); vm_perform_shutdown_actions();
os::wait_for_keypress_at_exit(); os::wait_for_keypress_at_exit();
// Flush stdout and stderr before abort.
fflush(stdout);
fflush(stderr);
os::abort(dump_core); os::abort(dump_core);
ShouldNotReachHere(); ShouldNotReachHere();
} }

View file

@ -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" // Output will be of the form "YYYY-MM-DDThh:mm:ss.mmm+zzzz\0"
// 1 2 // 1 2
// 12345678901234567890123456789 // 12345678901234567890123456789
static const char* iso8601_format = // format string: "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d"
"%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d";
static const size_t needed_buffer = 29; static const size_t needed_buffer = 29;
// Sanity check the arguments // 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 // Print an ISO 8601 date and time stamp into the buffer
const int year = 1900 + time_struct.tm_year; const int year = 1900 + time_struct.tm_year;
const int month = 1 + time_struct.tm_mon; 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, year,
month, month,
time_struct.tm_mday, time_struct.tm_mday,

View file

@ -722,7 +722,7 @@ void DumperSupport::dump_field_value(DumpWriter* writer, char type, address addr
o = oopDesc::load_decode_heap_oop((oop*)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. // Klass* so filter it out.
assert(o->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(o)); assert(o->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
writer->write_objectID(o); writer->write_objectID(o);
@ -1848,7 +1848,6 @@ void VM_HeapDumper::dump_stack_traces() {
} }
// dump the heap to given path. // dump the heap to given path.
PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
int HeapDumper::dump(const char* path) { int HeapDumper::dump(const char* path) {
assert(path != NULL && strlen(path) > 0, "path missing"); assert(path != NULL && strlen(path) > 0, "path missing");
@ -1886,13 +1885,8 @@ int HeapDumper::dump(const char* path) {
if (print_to_tty()) { if (print_to_tty()) {
timer()->stop(); timer()->stop();
if (error() == NULL) { if (error() == NULL) {
char msg[256]; tty->print_cr("Heap dump file created [" JLONG_FORMAT " bytes in %3.3f secs]",
sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", writer.bytes_written(), timer()->seconds());
JLONG_FORMAT, timer()->seconds());
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
tty->print_cr(msg, writer.bytes_written());
PRAGMA_DIAG_POP
} else { } else {
tty->print_cr("Dump file is incomplete: %s", writer.error()); tty->print_cr("Dump file is incomplete: %s", writer.error());
} }

View file

@ -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) { static void print_flag_error_message_if_needed(Flag::Error error, const char* name, FormatBuffer<80>& err_msg) {
if (error == Flag::SUCCESS) { if (error == Flag::SUCCESS) {
return; return;

View file

@ -65,7 +65,7 @@ bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
case vmIntrinsics::_currentThread: case vmIntrinsics::_currentThread:
return true; return true;
// sun.misc.Unsafe // Unsafe
case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapInt:
return true; return true;
@ -139,7 +139,7 @@ void SharkIntrinsics::do_intrinsic() {
do_Thread_currentThread(); do_Thread_currentThread();
break; break;
// sun.misc.Unsafe // Unsafe
case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapInt:
do_Unsafe_compareAndSwapInt(); do_Unsafe_compareAndSwapInt();
break; break;

View file

@ -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. // Tested to work with clang version 3.1 and better.
#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push") #define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push")
#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop") #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 // Hack to deal with gcc yammering about non-security format stuff
#else #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. // versions of the macro-pragma to obtain better checking with newer compilers.
#define PRAGMA_DIAG_PUSH #define PRAGMA_DIAG_PUSH
#define PRAGMA_DIAG_POP #define PRAGMA_DIAG_POP
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
#endif #endif
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) #if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)

View file

@ -340,6 +340,7 @@ void xmlStream::done_raw(const char* kind) {
print_raw_cr(">"); print_raw_cr(">");
} }
// If you remove the PRAGMA, this fails to compile with clang-503.0.40.
PRAGMA_DIAG_PUSH PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED PRAGMA_FORMAT_NONLITERAL_IGNORED
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View file

@ -43,13 +43,13 @@ package java.lang.invoke;
import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.*;
import jdk.test.lib.Asserts; import jdk.test.lib.Asserts;
import jdk.test.lib.Utils; import jdk.test.lib.Utils;
import sun.misc.Unsafe; import jdk.internal.misc.Unsafe;
import static jdk.internal.org.objectweb.asm.Opcodes.*; import static jdk.internal.org.objectweb.asm.Opcodes.*;
public class UnsafeGetConstantField { public class UnsafeGetConstantField {
static final Class<?> THIS_CLASS = UnsafeGetConstantField.class; 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) { public static void main(String[] args) {
testUnsafeGetAddress(); testUnsafeGetAddress();