#hotspotTag=jdk8u31-b13 | #hotspotTag=jdk8u31-b13 | ||||
#hotspotTag=jdk8u20-b22 | #hotspotTag=jdk8u20-b22 | ||||
#hotspotTag=jdk8u5-b13 | #hotspotTag=jdk8u5-b13 | ||||
hotspotTag=jdk7u71-b01 | |||||
#hotspotTag=jdk8u31-b13 | |||||
hotspotTag=jdk8u40-b25 | |||||
#hotspotTag=jdk7u71-b01 | |||||
#hotspotTag=jdk7u60-b09 | #hotspotTag=jdk7u60-b09 | ||||
#hotspotTag=jdk7u55-b13 | #hotspotTag=jdk7u55-b13 | ||||
#hotspotTag=jdk7u51-b13 | #hotspotTag=jdk7u51-b13 |
diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp | |||||
index 1565f88..5982b58 100644 | |||||
--- a/src/share/vm/runtime/arguments.cpp | |||||
+++ b/src/share/vm/runtime/arguments.cpp | |||||
@@ -62,8 +62,8 @@ | |||||
# HG changeset patch | |||||
# Parent 94dee6e9176e68ea1122af0dc98b6a5c152ea1e5 | |||||
diff -r 94dee6e9176e src/share/vm/runtime/arguments.cpp | |||||
--- a/src/share/vm/runtime/arguments.cpp Tue Mar 31 17:58:49 2015 -0700 | |||||
+++ b/src/share/vm/runtime/arguments.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
@@ -65,8 +65,8 @@ | |||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | ||||
#endif // INCLUDE_ALL_GCS | #endif // INCLUDE_ALL_GCS | ||||
#define DEFAULT_JAVA_LAUNCHER "generic" | #define DEFAULT_JAVA_LAUNCHER "generic" | ||||
// Disable options not supported in this release, with a warning if they | // Disable options not supported in this release, with a warning if they | ||||
@@ -1511,6 +1511,10 @@ | |||||
void Arguments::set_ergonomics_flags() { | |||||
@@ -1561,6 +1561,10 @@ | |||||
} | |||||
void Arguments::select_gc_ergonomically() { | |||||
+ if (AllowEnhancedClassRedefinition) { | + if (AllowEnhancedClassRedefinition) { | ||||
+ // (DCEVM) enforces serial GC | + // (DCEVM) enforces serial GC | ||||
+ FLAG_SET_ERGO(bool, UseSerialGC, true); | + FLAG_SET_ERGO(bool, UseSerialGC, true); | ||||
+ } | + } | ||||
if (os::is_server_class_machine()) { | if (os::is_server_class_machine()) { | ||||
// If no other collector is requested explicitly, | |||||
// let the VM select the collector based on | |||||
@@ -1988,6 +1992,17 @@ | |||||
if (should_auto_select_low_pause_collector()) { | |||||
FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true); | |||||
@@ -2082,6 +2086,17 @@ | |||||
if (UseConcMarkSweepGC || UseParNewGC) i++; | if (UseConcMarkSweepGC || UseParNewGC) i++; | ||||
if (UseParallelGC || UseParallelOldGC) i++; | if (UseParallelGC || UseParallelOldGC) i++; | ||||
if (UseG1GC) i++; | if (UseG1GC) i++; | ||||
if (i > 1) { | if (i > 1) { | ||||
jio_fprintf(defaultStream::error_stream(), | jio_fprintf(defaultStream::error_stream(), | ||||
"Conflicting collector combinations in option list; " | "Conflicting collector combinations in option list; " | ||||
diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp | |||||
index 63222af..7597eda 100644 | |||||
--- a/src/share/vm/runtime/globals.hpp | |||||
+++ b/src/share/vm/runtime/globals.hpp | |||||
@@ -1283,6 +1283,9 @@ | |||||
diff -r 94dee6e9176e src/share/vm/runtime/globals.hpp | |||||
--- a/src/share/vm/runtime/globals.hpp Tue Mar 31 17:58:49 2015 -0700 | |||||
+++ b/src/share/vm/runtime/globals.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
@@ -1305,6 +1305,9 @@ | |||||
product(intx, TraceRedefineClasses, 0, \ | product(intx, TraceRedefineClasses, 0, \ | ||||
"Trace level for JVMTI RedefineClasses") \ | "Trace level for JVMTI RedefineClasses") \ | ||||
\ | \ | ||||
+ \ | + \ | ||||
develop(bool, StressMethodComparator, false, \ | develop(bool, StressMethodComparator, false, \ | ||||
"Run the MethodComparator on all loaded methods") \ | "Run the MethodComparator on all loaded methods") \ | ||||
\ | |||||
\ |
# HG changeset patch | |||||
# Parent 94dee6e9176e68ea1122af0dc98b6a5c152ea1e5 | |||||
diff -r 94dee6e9176e src/share/vm/runtime/arguments.cpp | |||||
--- a/src/share/vm/runtime/arguments.cpp Tue Mar 31 17:58:49 2015 -0700 | |||||
+++ b/src/share/vm/runtime/arguments.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
@@ -65,8 +65,8 @@ | |||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | |||||
#endif // INCLUDE_ALL_GCS | |||||
-// Note: This is a special bug reporting site for the JVM | |||||
-#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp" | |||||
+// (DCEVM) The DCE VM has its own JIRA bug tracking system. | |||||
+#define DEFAULT_VENDOR_URL_BUG "https://github.com/Guidewire/DCEVM/issues" | |||||
#define DEFAULT_JAVA_LAUNCHER "generic" | |||||
// Disable options not supported in this release, with a warning if they | |||||
@@ -1561,6 +1561,10 @@ | |||||
} | |||||
void Arguments::select_gc_ergonomically() { | |||||
+ if (AllowEnhancedClassRedefinition) { | |||||
+ // (DCEVM) enforces serial GC | |||||
+ FLAG_SET_ERGO(bool, UseSerialGC, true); | |||||
+ } | |||||
if (os::is_server_class_machine()) { | |||||
if (should_auto_select_low_pause_collector()) { | |||||
FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true); | |||||
@@ -2082,6 +2086,17 @@ | |||||
if (UseConcMarkSweepGC || UseParNewGC) i++; | |||||
if (UseParallelGC || UseParallelOldGC) i++; | |||||
if (UseG1GC) i++; | |||||
+ | |||||
+ if (AllowEnhancedClassRedefinition) { | |||||
+ // (DCEVM) Must use serial GC. This limitation applies because the instance size changing GC modifications | |||||
+ // are only built into the mark and compact algorithm. | |||||
+ if (!UseSerialGC && i >= 1) { | |||||
+ jio_fprintf(defaultStream::error_stream(), | |||||
+ "Must use the serial GC in the DCEVM\n"); | |||||
+ status = false; | |||||
+ } | |||||
+ } | |||||
+ | |||||
if (i > 1) { | |||||
jio_fprintf(defaultStream::error_stream(), | |||||
"Conflicting collector combinations in option list; " | |||||
diff -r 94dee6e9176e src/share/vm/runtime/globals.hpp | |||||
--- a/src/share/vm/runtime/globals.hpp Tue Mar 31 17:58:49 2015 -0700 | |||||
+++ b/src/share/vm/runtime/globals.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
@@ -1305,6 +1305,9 @@ | |||||
product(intx, TraceRedefineClasses, 0, \ | |||||
"Trace level for JVMTI RedefineClasses") \ | |||||
\ | |||||
+ product(bool, AllowEnhancedClassRedefinition, true, \ | |||||
+ "Allow enhanced class redefinition beyond swapping method bodies")\ | |||||
+ \ | |||||
develop(bool, StressMethodComparator, false, \ | |||||
"Run the MethodComparator on all loaded methods") \ | |||||
\ |
During the redefinition run, these instances are updated to point to new field index location. | During the redefinition run, these instances are updated to point to new field index location. | ||||
# HG changeset patch | # HG changeset patch | ||||
# Parent 93419aa9be423015ad99c0e5fa53abca1939aa00 | |||||
# Parent a5d69314e0a8e05605ca678e31eeba92ec173400 | |||||
diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp | |||||
--- a/src/share/vm/classfile/javaClasses.cpp | |||||
+++ b/src/share/vm/classfile/javaClasses.cpp | |||||
@@ -2617,6 +2617,50 @@ | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/javaClasses.cpp | |||||
--- a/src/share/vm/classfile/javaClasses.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/javaClasses.cpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -2667,6 +2667,50 @@ | |||||
} | } | ||||
} | } | ||||
// Support for java_lang_invoke_MethodHandle | // Support for java_lang_invoke_MethodHandle | ||||
int java_lang_invoke_MethodHandle::_type_offset; | int java_lang_invoke_MethodHandle::_type_offset; | ||||
@@ -3269,6 +3313,9 @@ | |||||
@@ -3343,6 +3387,9 @@ | |||||
java_lang_invoke_LambdaForm::compute_offsets(); | java_lang_invoke_LambdaForm::compute_offsets(); | ||||
java_lang_invoke_MethodType::compute_offsets(); | java_lang_invoke_MethodType::compute_offsets(); | ||||
java_lang_invoke_CallSite::compute_offsets(); | java_lang_invoke_CallSite::compute_offsets(); | ||||
} | } | ||||
java_security_AccessControlContext::compute_offsets(); | java_security_AccessControlContext::compute_offsets(); | ||||
// Initialize reflection classes. The layouts of these classes | // Initialize reflection classes. The layouts of these classes | ||||
diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp | |||||
--- a/src/share/vm/classfile/javaClasses.hpp | |||||
+++ b/src/share/vm/classfile/javaClasses.hpp | |||||
@@ -1003,6 +1003,55 @@ | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/javaClasses.hpp | |||||
--- a/src/share/vm/classfile/javaClasses.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/javaClasses.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -1020,6 +1020,55 @@ | |||||
static int member_offset_in_bytes() { return _member_offset; } | static int member_offset_in_bytes() { return _member_offset; } | ||||
}; | }; | ||||
// Interface to java.lang.invoke.LambdaForm objects | // Interface to java.lang.invoke.LambdaForm objects | ||||
// (These are a private interface for managing adapter code generation.) | // (These are a private interface for managing adapter code generation.) | ||||
diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp | |||||
--- a/src/share/vm/classfile/systemDictionary.hpp | |||||
+++ b/src/share/vm/classfile/systemDictionary.hpp | |||||
@@ -151,6 +151,8 @@ | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/systemDictionary.hpp | |||||
--- a/src/share/vm/classfile/systemDictionary.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/systemDictionary.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -153,6 +153,8 @@ | |||||
\ | \ | ||||
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ | /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ | ||||
do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ | do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ | ||||
do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ | do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ | ||||
do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ | do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ | ||||
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ | do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ | ||||
diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp | |||||
--- a/src/share/vm/classfile/vmSymbols.hpp | |||||
+++ b/src/share/vm/classfile/vmSymbols.hpp | |||||
@@ -256,6 +256,8 @@ | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/vmSymbols.hpp | |||||
--- a/src/share/vm/classfile/vmSymbols.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -265,6 +265,8 @@ | |||||
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ | template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ | ||||
template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ | template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ | ||||
template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ | template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ | ||||
template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ | template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ | ||||
template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ | template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ | ||||
template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ | template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ | ||||
@@ -397,6 +399,10 @@ | |||||
template(signers_name, "signers_name") \ | |||||
template(loader_data_name, "loader_data") \ | |||||
template(dependencies_name, "dependencies") \ | |||||
@@ -414,6 +416,10 @@ | |||||
template(getProtectionDomain_name, "getProtectionDomain") \ | |||||
template(getProtectionDomain_signature, "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \ | |||||
template(url_code_signer_array_void_signature, "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \ | |||||
+ template(static_offset_name, "staticOffset") \ | + template(static_offset_name, "staticOffset") \ | ||||
+ template(static_base_name, "staticBase") \ | + template(static_base_name, "staticBase") \ | ||||
+ template(field_offset_name, "fieldOffset") \ | + template(field_offset_name, "fieldOffset") \ |
Add support for DirectMethodHandle field implementations (StaticAccessor/Accessor). | |||||
During the redefinition run, these instances are updated to point to new field index location. | |||||
# HG changeset patch | |||||
# Parent a5d69314e0a8e05605ca678e31eeba92ec173400 | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/javaClasses.cpp | |||||
--- a/src/share/vm/classfile/javaClasses.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/javaClasses.cpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -2667,6 +2667,50 @@ | |||||
} | |||||
} | |||||
+// Support for java_lang_invoke_DirectMethodHandle$StaticAccessor | |||||
+ | |||||
+int java_lang_invoke_DirectMethodHandle_StaticAccessor::_static_offset_offset; | |||||
+ | |||||
+long java_lang_invoke_DirectMethodHandle_StaticAccessor::static_offset(oop dmh) { | |||||
+ assert(_static_offset_offset != 0, ""); | |||||
+ return dmh->long_field(_static_offset_offset); | |||||
+} | |||||
+ | |||||
+void java_lang_invoke_DirectMethodHandle_StaticAccessor::set_static_offset(oop dmh, long static_offset) { | |||||
+ assert(_static_offset_offset != 0, ""); | |||||
+ dmh->long_field_put(_static_offset_offset, static_offset); | |||||
+} | |||||
+ | |||||
+ | |||||
+void java_lang_invoke_DirectMethodHandle_StaticAccessor::compute_offsets() { | |||||
+ Klass* klass_oop = SystemDictionary::DirectMethodHandle_StaticAccessor_klass(); | |||||
+ if (klass_oop != NULL && EnableInvokeDynamic) { | |||||
+ compute_offset(_static_offset_offset, klass_oop, vmSymbols::static_offset_name(), vmSymbols::long_signature()); | |||||
+ } | |||||
+} | |||||
+ | |||||
+// Support for java_lang_invoke_DirectMethodHandle$Accessor | |||||
+ | |||||
+int java_lang_invoke_DirectMethodHandle_Accessor::_field_offset_offset; | |||||
+ | |||||
+int java_lang_invoke_DirectMethodHandle_Accessor::field_offset(oop dmh) { | |||||
+ assert(_field_offset_offset != 0, ""); | |||||
+ return dmh->int_field(_field_offset_offset); | |||||
+} | |||||
+ | |||||
+void java_lang_invoke_DirectMethodHandle_Accessor::set_field_offset(oop dmh, int field_offset) { | |||||
+ assert(_field_offset_offset != 0, ""); | |||||
+ dmh->int_field_put(_field_offset_offset, field_offset); | |||||
+} | |||||
+ | |||||
+ | |||||
+void java_lang_invoke_DirectMethodHandle_Accessor::compute_offsets() { | |||||
+ Klass* klass_oop = SystemDictionary::DirectMethodHandle_Accessor_klass(); | |||||
+ if (klass_oop != NULL && EnableInvokeDynamic) { | |||||
+ compute_offset(_field_offset_offset, klass_oop, vmSymbols::field_offset_name(), vmSymbols::int_signature()); | |||||
+ } | |||||
+} | |||||
+ | |||||
// Support for java_lang_invoke_MethodHandle | |||||
int java_lang_invoke_MethodHandle::_type_offset; | |||||
@@ -3343,6 +3387,9 @@ | |||||
java_lang_invoke_LambdaForm::compute_offsets(); | |||||
java_lang_invoke_MethodType::compute_offsets(); | |||||
java_lang_invoke_CallSite::compute_offsets(); | |||||
+ | |||||
+ java_lang_invoke_DirectMethodHandle_StaticAccessor::compute_offsets(); | |||||
+ java_lang_invoke_DirectMethodHandle_Accessor::compute_offsets(); | |||||
} | |||||
java_security_AccessControlContext::compute_offsets(); | |||||
// Initialize reflection classes. The layouts of these classes | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/javaClasses.hpp | |||||
--- a/src/share/vm/classfile/javaClasses.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/javaClasses.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -1020,6 +1020,55 @@ | |||||
static int member_offset_in_bytes() { return _member_offset; } | |||||
}; | |||||
+// Interface to java.lang.invoke.DirectMethodHandle$StaticAccessor objects | |||||
+ | |||||
+class java_lang_invoke_DirectMethodHandle_StaticAccessor: AllStatic { | |||||
+ friend class JavaClasses; | |||||
+ | |||||
+ private: | |||||
+ static int _static_offset_offset; // offset to static field | |||||
+ | |||||
+ static void compute_offsets(); | |||||
+ | |||||
+ public: | |||||
+ // Accessors | |||||
+ static long static_offset(oop dmh); | |||||
+ static void set_static_offset(oop dmh, long value); | |||||
+ | |||||
+ // Testers | |||||
+ static bool is_subclass(Klass* klass) { | |||||
+ return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_StaticAccessor_klass()); | |||||
+ } | |||||
+ static bool is_instance(oop obj) { | |||||
+ return obj != NULL && is_subclass(obj->klass()); | |||||
+ } | |||||
+}; | |||||
+ | |||||
+// Interface to java.lang.invoke.DirectMethodHandle$Accessor objects | |||||
+ | |||||
+class java_lang_invoke_DirectMethodHandle_Accessor: AllStatic { | |||||
+ friend class JavaClasses; | |||||
+ | |||||
+ private: | |||||
+ static int _field_offset_offset; // offset to field | |||||
+ | |||||
+ static void compute_offsets(); | |||||
+ | |||||
+ public: | |||||
+ // Accessors | |||||
+ static int field_offset(oop dmh); | |||||
+ static void set_field_offset(oop dmh, int value); | |||||
+ | |||||
+ // Testers | |||||
+ static bool is_subclass(Klass* klass) { | |||||
+ return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_Accessor_klass()); | |||||
+ } | |||||
+ static bool is_instance(oop obj) { | |||||
+ return obj != NULL && is_subclass(obj->klass()); | |||||
+ } | |||||
+}; | |||||
+ | |||||
+ | |||||
// Interface to java.lang.invoke.LambdaForm objects | |||||
// (These are a private interface for managing adapter code generation.) | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/systemDictionary.hpp | |||||
--- a/src/share/vm/classfile/systemDictionary.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/systemDictionary.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -153,6 +153,8 @@ | |||||
\ | |||||
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ | |||||
do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ | |||||
+ do_klass(DirectMethodHandle_StaticAccessor_klass, java_lang_invoke_DirectMethodHandle_StaticAccessor, Opt ) \ | |||||
+ do_klass(DirectMethodHandle_Accessor_klass, java_lang_invoke_DirectMethodHandle_Accessor, Opt ) \ | |||||
do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ | |||||
do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ | |||||
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ | |||||
diff -r a5d69314e0a8 src/share/vm/classfile/vmSymbols.hpp | |||||
--- a/src/share/vm/classfile/vmSymbols.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
+++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 31 18:06:35 2015 -0700 | |||||
@@ -265,6 +265,8 @@ | |||||
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ | |||||
template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ | |||||
template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ | |||||
+ template(java_lang_invoke_DirectMethodHandle_StaticAccessor, "java/lang/invoke/DirectMethodHandle$StaticAccessor") \ | |||||
+ template(java_lang_invoke_DirectMethodHandle_Accessor, "java/lang/invoke/DirectMethodHandle$Accessor") \ | |||||
template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ | |||||
template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ | |||||
template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ | |||||
@@ -414,6 +416,10 @@ | |||||
template(getProtectionDomain_name, "getProtectionDomain") \ | |||||
template(getProtectionDomain_signature, "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \ | |||||
template(url_code_signer_array_void_signature, "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \ | |||||
+ template(static_offset_name, "staticOffset") \ | |||||
+ template(static_base_name, "staticBase") \ | |||||
+ template(field_offset_name, "fieldOffset") \ | |||||
+ template(field_type_name, "fieldType") \ | |||||
\ | |||||
/* non-intrinsic name/signature pairs: */ \ | |||||
template(register_method_name, "register") \ |
# HG changeset patch | |||||
# Parent 8f44f8a7e50563e6c9a82fb0ed6c7bce4925bd3b | |||||
Change MarkAndSweep garbage collector to allow changing instances during redefinition. | Change MarkAndSweep garbage collector to allow changing instances during redefinition. | ||||
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp | |||||
@@ -161,6 +161,12 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -163,6 +163,12 @@ | |||||
} | } | ||||
} | } | ||||
// Like CompactibleSpace forward() but always calls cross_threshold() to | // Like CompactibleSpace forward() but always calls cross_threshold() to | ||||
// update the block offset table. Removed initialize_threshold call because | // update the block offset table. Removed initialize_threshold call because | ||||
// CFLS does not use a block offset array for contiguous spaces. | // CFLS does not use a block offset array for contiguous spaces. | ||||
@@ -2098,7 +2104,7 @@ | |||||
@@ -2097,7 +2103,7 @@ | |||||
// Support for compaction | // Support for compaction | ||||
void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { | void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { | ||||
// prepare_for_compaction() uses the space between live objects | // prepare_for_compaction() uses the space between live objects | ||||
// so that later phase can skip dead space quickly. So verification | // so that later phase can skip dead space quickly. So verification | ||||
// of the free lists doesn't work after. | // of the free lists doesn't work after. | ||||
@@ -2119,7 +2125,7 @@ | |||||
@@ -2118,7 +2124,7 @@ | |||||
} | } | ||||
void CompactibleFreeListSpace::compact() { | void CompactibleFreeListSpace::compact() { | ||||
} | } | ||||
// fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2] | // fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2] | ||||
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -150,6 +150,7 @@ | @@ -150,6 +150,7 @@ | ||||
// Support for compacting cms | // Support for compacting cms | ||||
HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); | HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); | ||||
// Initialization helpers. | // Initialization helpers. | ||||
diff --git a/src/share/vm/gc_implementation/shared/markSweep.cpp b/src/share/vm/gc_implementation/shared/markSweep.cpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp | |||||
@@ -46,6 +46,8 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/shared/markSweep.cpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -48,6 +48,8 @@ | |||||
STWGCTimer* MarkSweep::_gc_timer = NULL; | STWGCTimer* MarkSweep::_gc_timer = NULL; | ||||
SerialOldTracer* MarkSweep::_gc_tracer = NULL; | SerialOldTracer* MarkSweep::_gc_tracer = NULL; | ||||
+GrowableArray<HeapWord*>* MarkSweep::_rescued_oops = NULL; | +GrowableArray<HeapWord*>* MarkSweep::_rescued_oops = NULL; | ||||
+ | + | ||||
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; | MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; | ||||
CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); | |||||
@@ -171,3 +173,100 @@ | |||||
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } | |||||
@@ -165,3 +167,100 @@ | |||||
} | } | ||||
#endif | #endif | ||||
+ } | + } | ||||
+ } | + } | ||||
+} | +} | ||||
diff --git a/src/share/vm/gc_implementation/shared/markSweep.hpp b/src/share/vm/gc_implementation/shared/markSweep.hpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.hpp | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.hpp | |||||
@@ -107,8 +107,12 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/shared/markSweep.hpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -96,8 +96,12 @@ | |||||
friend class AdjustPointerClosure; | friend class AdjustPointerClosure; | ||||
friend class KeepAliveClosure; | friend class KeepAliveClosure; | ||||
friend class VM_MarkSweep; | friend class VM_MarkSweep; | ||||
// | // | ||||
// Vars | // Vars | ||||
// | // | ||||
@@ -169,6 +173,9 @@ | |||||
@@ -157,6 +161,9 @@ | |||||
static inline void push_objarray(oop obj, size_t index); | static inline void push_objarray(oop obj, size_t index); | ||||
static void follow_stack(); // Empty marking stack. | static void follow_stack(); // Empty marking stack. | ||||
static void follow_klass(Klass* klass); | static void follow_klass(Klass* klass); | ||||
diff --git a/src/share/vm/memory/genMarkSweep.cpp b/src/share/vm/memory/genMarkSweep.cpp | |||||
--- a/src/share/vm/memory/genMarkSweep.cpp | |||||
+++ b/src/share/vm/memory/genMarkSweep.cpp | |||||
@@ -334,11 +334,16 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/genMarkSweep.cpp | |||||
--- a/src/share/vm/memory/genMarkSweep.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/genMarkSweep.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -327,11 +327,16 @@ | |||||
// in the same order in phase2, phase3 and phase4. We don't quite do that | // in the same order in phase2, phase3 and phase4. We don't quite do that | ||||
// here (perm_gen first rather than last), so we tell the validate code | // here (perm_gen first rather than last), so we tell the validate code | ||||
// to use a higher index (saved from phase2) when verifying perm_gen. | // to use a higher index (saved from phase2) when verifying perm_gen. | ||||
+ assert(_rescued_oops == NULL, "must be empty before processing"); | + assert(_rescued_oops == NULL, "must be empty before processing"); | ||||
GenCollectedHeap* gch = GenCollectedHeap::heap(); | GenCollectedHeap* gch = GenCollectedHeap::heap(); | ||||
GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer); | |||||
GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id()); | |||||
trace("4"); | trace("4"); | ||||
+ MarkSweep::copy_rescued_objects_back(); | + MarkSweep::copy_rescued_objects_back(); | ||||
+ | + | ||||
+ MarkSweep::copy_rescued_objects_back(); | + MarkSweep::copy_rescued_objects_back(); | ||||
} | } | ||||
diff --git a/src/share/vm/memory/space.cpp b/src/share/vm/memory/space.cpp | |||||
--- a/src/share/vm/memory/space.cpp | |||||
+++ b/src/share/vm/memory/space.cpp | |||||
@@ -379,9 +379,8 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.cpp | |||||
--- a/src/share/vm/memory/space.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -377,9 +377,8 @@ | |||||
_compaction_top = bottom(); | _compaction_top = bottom(); | ||||
} | } | ||||
// First check if we should switch compaction space | // First check if we should switch compaction space | ||||
assert(this == cp->space, "'this' should be current compaction space."); | assert(this == cp->space, "'this' should be current compaction space."); | ||||
size_t compaction_max_size = pointer_delta(end(), compact_top); | size_t compaction_max_size = pointer_delta(end(), compact_top); | ||||
@@ -401,8 +400,15 @@ | |||||
@@ -399,8 +398,15 @@ | |||||
compaction_max_size = pointer_delta(cp->space->end(), compact_top); | compaction_max_size = pointer_delta(cp->space->end(), compact_top); | ||||
} | } | ||||
q->forward_to(oop(compact_top)); | q->forward_to(oop(compact_top)); | ||||
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark"); | assert(q->is_gc_marked(), "encoding the pointer should preserve the mark"); | ||||
} else { | } else { | ||||
@@ -423,6 +429,58 @@ | |||||
@@ -421,6 +427,58 @@ | |||||
return compact_top; | return compact_top; | ||||
} | } | ||||
bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words, | bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words, | ||||
HeapWord* q, size_t deadlength) { | HeapWord* q, size_t deadlength) { | ||||
@@ -444,12 +502,17 @@ | |||||
@@ -442,12 +500,17 @@ | |||||
#define adjust_obj_size(s) s | #define adjust_obj_size(s) s | ||||
void CompactibleSpace::prepare_for_compaction(CompactPoint* cp) { | void CompactibleSpace::prepare_for_compaction(CompactPoint* cp) { | ||||
} | } | ||||
void Space::adjust_pointers() { | void Space::adjust_pointers() { | ||||
@@ -487,6 +550,111 @@ | |||||
@@ -485,6 +548,111 @@ | |||||
assert(q == t, "just checking"); | assert(q == t, "just checking"); | ||||
} | } | ||||
void CompactibleSpace::adjust_pointers() { | void CompactibleSpace::adjust_pointers() { | ||||
// Check first is there is any work to do. | // Check first is there is any work to do. | ||||
if (used() == 0) { | if (used() == 0) { | ||||
@@ -497,7 +665,12 @@ | |||||
@@ -495,7 +663,12 @@ | |||||
} | } | ||||
void CompactibleSpace::compact() { | void CompactibleSpace::compact() { | ||||
} | } | ||||
void Space::print_short() const { print_short_on(tty); } | void Space::print_short() const { print_short_on(tty); } | ||||
diff --git a/src/share/vm/memory/space.hpp b/src/share/vm/memory/space.hpp | |||||
--- a/src/share/vm/memory/space.hpp | |||||
+++ b/src/share/vm/memory/space.hpp | |||||
@@ -450,6 +450,9 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.hpp | |||||
--- a/src/share/vm/memory/space.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -392,6 +392,9 @@ | |||||
// indicates when the next such action should be taken. | // indicates when the next such action should be taken. | ||||
virtual void prepare_for_compaction(CompactPoint* cp); | virtual void prepare_for_compaction(CompactPoint* cp); | ||||
// MarkSweep support phase3 | // MarkSweep support phase3 | ||||
virtual void adjust_pointers(); | virtual void adjust_pointers(); | ||||
// MarkSweep support phase4 | // MarkSweep support phase4 | ||||
virtual void compact(); | virtual void compact(); | ||||
@@ -479,6 +482,15 @@ | |||||
@@ -421,6 +424,15 @@ | |||||
// accordingly". | // accordingly". | ||||
virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp, | virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp, | ||||
HeapWord* compact_top); | HeapWord* compact_top); | ||||
// Return a size with adjusments as required of the space. | // Return a size with adjusments as required of the space. | ||||
virtual size_t adjust_object_size_v(size_t size) const { return size; } | virtual size_t adjust_object_size_v(size_t size) const { return size; } | ||||
@@ -509,7 +521,7 @@ | |||||
size_t word_len); | |||||
}; | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.inline.hpp | |||||
--- a/src/share/vm/memory/space.inline.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.inline.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -35,7 +35,7 @@ | |||||
return block_start_const(p); | |||||
} | |||||
-#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ | -#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ | ||||
+#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size,redefinition_run) { \ | +#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size,redefinition_run) { \ | ||||
/* Compute the new addresses for the live objects and store it in the mark \ | /* Compute the new addresses for the live objects and store it in the mark \ | ||||
* Used by universe::mark_sweep_phase2() \ | * Used by universe::mark_sweep_phase2() \ | ||||
*/ \ | */ \ | ||||
@@ -567,7 +579,17 @@ | |||||
@@ -93,7 +93,17 @@ | |||||
/* prefetch beyond q */ \ | /* prefetch beyond q */ \ | ||||
Prefetch::write(q, interval); \ | Prefetch::write(q, interval); \ | ||||
size_t size = block_size(q); \ | size_t size = block_size(q); \ | ||||
q += size; \ | q += size; \ | ||||
end_of_live = q; \ | end_of_live = q; \ | ||||
} else { \ | } else { \ | ||||
@@ -616,6 +638,8 @@ | |||||
@@ -142,6 +152,8 @@ | |||||
} \ | } \ | ||||
} \ | } \ | ||||
\ | \ | ||||
assert(q == t, "just checking"); \ | assert(q == t, "just checking"); \ | ||||
if (liveRange != NULL) { \ | if (liveRange != NULL) { \ | ||||
liveRange->set_end(q); \ | liveRange->set_end(q); \ | ||||
@@ -662,13 +686,8 @@ | |||||
@@ -188,13 +200,8 @@ | |||||
q += size; \ | q += size; \ | ||||
} \ | } \ | ||||
\ | \ | ||||
} \ | } \ | ||||
\ | \ | ||||
const intx interval = PrefetchScanIntervalInBytes; \ | const intx interval = PrefetchScanIntervalInBytes; \ | ||||
@@ -696,7 +715,7 @@ | |||||
@@ -222,7 +229,7 @@ | |||||
assert(q == t, "just checking"); \ | assert(q == t, "just checking"); \ | ||||
} | } | ||||
/* Copy all live objects to their new location \ | /* Copy all live objects to their new location \ | ||||
* Used by MarkSweep::mark_sweep_phase4() */ \ | * Used by MarkSweep::mark_sweep_phase4() */ \ | ||||
\ | \ | ||||
@@ -721,13 +740,9 @@ | |||||
@@ -247,13 +254,9 @@ | |||||
} \ | } \ | ||||
) /* debug_only */ \ | ) /* debug_only */ \ | ||||
\ | \ | ||||
\ | \ | ||||
const intx scan_interval = PrefetchScanIntervalInBytes; \ | const intx scan_interval = PrefetchScanIntervalInBytes; \ | ||||
const intx copy_interval = PrefetchCopyIntervalInBytes; \ | const intx copy_interval = PrefetchCopyIntervalInBytes; \ | ||||
@@ -745,11 +760,34 @@ | |||||
@@ -271,11 +274,34 @@ | |||||
size_t size = obj_size(q); \ | size_t size = obj_size(q); \ | ||||
HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ | HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ | ||||
\ | \ | ||||
Copy::aligned_conjoint_words(q, compaction_top, size); \ | Copy::aligned_conjoint_words(q, compaction_top, size); \ | ||||
oop(compaction_top)->init_mark(); \ | oop(compaction_top)->init_mark(); \ | ||||
assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ | assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ | ||||
diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp | |||||
--- a/src/share/vm/memory/universe.cpp | |||||
+++ b/src/share/vm/memory/universe.cpp | |||||
@@ -78,6 +78,8 @@ | |||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | |||||
#endif // INCLUDE_ALL_GCS | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/universe.cpp | |||||
--- a/src/share/vm/memory/universe.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/universe.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -84,6 +84,8 @@ | |||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC | |||||
+bool Universe::_is_redefining_gc_run = false; | +bool Universe::_is_redefining_gc_run = false; | ||||
+ | + | ||||
// Known objects | // Known objects | ||||
Klass* Universe::_boolArrayKlassObj = NULL; | Klass* Universe::_boolArrayKlassObj = NULL; | ||||
Klass* Universe::_byteArrayKlassObj = NULL; | Klass* Universe::_byteArrayKlassObj = NULL; | ||||
diff --git a/src/share/vm/memory/universe.hpp b/src/share/vm/memory/universe.hpp | |||||
--- a/src/share/vm/memory/universe.hpp | |||||
+++ b/src/share/vm/memory/universe.hpp | |||||
@@ -248,7 +248,13 @@ | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/universe.hpp | |||||
--- a/src/share/vm/memory/universe.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/universe.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -251,7 +251,13 @@ | |||||
static void compute_verify_oop_data(); | static void compute_verify_oop_data(); | ||||
# HG changeset patch | |||||
# Parent 8f44f8a7e50563e6c9a82fb0ed6c7bce4925bd3b | |||||
Change MarkAndSweep garbage collector to allow changing instances during redefinition. | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -163,6 +163,12 @@ | |||||
} | |||||
} | |||||
+HeapWord* CompactibleFreeListSpace::forward_compact_top(size_t size, | |||||
+ CompactPoint* cp, HeapWord* compact_top) { | |||||
+ ShouldNotReachHere(); | |||||
+ return NULL; | |||||
+} | |||||
+ | |||||
// Like CompactibleSpace forward() but always calls cross_threshold() to | |||||
// update the block offset table. Removed initialize_threshold call because | |||||
// CFLS does not use a block offset array for contiguous spaces. | |||||
@@ -2097,7 +2103,7 @@ | |||||
// Support for compaction | |||||
void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { | |||||
- SCAN_AND_FORWARD(cp,end,block_is_obj,block_size); | |||||
+ SCAN_AND_FORWARD(cp,end,block_is_obj,block_size,false); | |||||
// prepare_for_compaction() uses the space between live objects | |||||
// so that later phase can skip dead space quickly. So verification | |||||
// of the free lists doesn't work after. | |||||
@@ -2118,7 +2124,7 @@ | |||||
} | |||||
void CompactibleFreeListSpace::compact() { | |||||
- SCAN_AND_COMPACT(obj_size); | |||||
+ SCAN_AND_COMPACT(obj_size, false); | |||||
} | |||||
// fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2] | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp | |||||
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -150,6 +150,7 @@ | |||||
// Support for compacting cms | |||||
HeapWord* cross_threshold(HeapWord* start, HeapWord* end); | |||||
+ HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top); | |||||
HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); | |||||
// Initialization helpers. | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/shared/markSweep.cpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -48,6 +48,8 @@ | |||||
STWGCTimer* MarkSweep::_gc_timer = NULL; | |||||
SerialOldTracer* MarkSweep::_gc_tracer = NULL; | |||||
+GrowableArray<HeapWord*>* MarkSweep::_rescued_oops = NULL; | |||||
+ | |||||
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; | |||||
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } | |||||
@@ -165,3 +167,100 @@ | |||||
} | |||||
#endif | |||||
+ | |||||
+// (DCEVM) Copy the rescued objects to their destination address after compaction. | |||||
+void MarkSweep::copy_rescued_objects_back() { | |||||
+ | |||||
+ if (_rescued_oops != NULL) { | |||||
+ | |||||
+ for (int i=0; i<_rescued_oops->length(); i++) { | |||||
+ HeapWord* rescued_ptr = _rescued_oops->at(i); | |||||
+ oop rescued_obj = (oop) rescued_ptr; | |||||
+ | |||||
+ int size = rescued_obj->size(); | |||||
+ oop new_obj = rescued_obj->forwardee(); | |||||
+ | |||||
+ assert(rescued_obj->klass()->new_version() != NULL, "just checking"); | |||||
+ | |||||
+ if (rescued_obj->klass()->new_version()->update_information() != NULL) { | |||||
+ MarkSweep::update_fields(rescued_obj, new_obj); | |||||
+ } else { | |||||
+ rescued_obj->set_klass(rescued_obj->klass()->new_version()); | |||||
+ Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size); | |||||
+ } | |||||
+ | |||||
+ FREE_RESOURCE_ARRAY(HeapWord, rescued_ptr, size); | |||||
+ | |||||
+ new_obj->init_mark(); | |||||
+ assert(new_obj->is_oop(), "must be a valid oop"); | |||||
+ } | |||||
+ _rescued_oops->clear(); | |||||
+ _rescued_oops = NULL; | |||||
+ } | |||||
+} | |||||
+ | |||||
+// (DCEVM) Update instances of a class whose fields changed. | |||||
+void MarkSweep::update_fields(oop q, oop new_location) { | |||||
+ | |||||
+ assert(q->klass()->new_version() != NULL, "class of old object must have new version"); | |||||
+ | |||||
+ Klass* old_klass_oop = q->klass(); | |||||
+ Klass* new_klass_oop = q->klass()->new_version(); | |||||
+ | |||||
+ InstanceKlass *old_klass = InstanceKlass::cast(old_klass_oop); | |||||
+ InstanceKlass *new_klass = InstanceKlass::cast(new_klass_oop); | |||||
+ | |||||
+ int size = q->size_given_klass(old_klass); | |||||
+ int new_size = q->size_given_klass(new_klass); | |||||
+ | |||||
+ HeapWord* tmp = NULL; | |||||
+ oop tmp_obj = q; | |||||
+ | |||||
+ // Save object somewhere, there is an overlap in fields | |||||
+ if (new_klass_oop->is_copying_backwards()) { | |||||
+ if (((HeapWord *)q >= (HeapWord *)new_location && (HeapWord *)q < (HeapWord *)new_location + new_size) || | |||||
+ ((HeapWord *)new_location >= (HeapWord *)q && (HeapWord *)new_location < (HeapWord *)q + size)) { | |||||
+ tmp = NEW_RESOURCE_ARRAY(HeapWord, size); | |||||
+ q = (oop) tmp; | |||||
+ Copy::aligned_disjoint_words((HeapWord*)q, (HeapWord*)tmp_obj, size); | |||||
+ } | |||||
+ } | |||||
+ | |||||
+ q->set_klass(new_klass_oop); | |||||
+ int *cur = new_klass_oop->update_information(); | |||||
+ assert(cur != NULL, "just checking"); | |||||
+ MarkSweep::update_fields(new_location, q, cur); | |||||
+ | |||||
+ if (tmp != NULL) { | |||||
+ FREE_RESOURCE_ARRAY(HeapWord, tmp, size); | |||||
+ } | |||||
+} | |||||
+ | |||||
+void MarkSweep::update_fields(oop new_location, oop tmp_obj, int *cur) { | |||||
+ assert(cur != NULL, "just checking"); | |||||
+ char* to = (char*)(HeapWord*)new_location; | |||||
+ while (*cur != 0) { | |||||
+ int size = *cur; | |||||
+ if (size > 0) { | |||||
+ cur++; | |||||
+ int offset = *cur; | |||||
+ HeapWord* from = (HeapWord*)(((char *)(HeapWord*)tmp_obj) + offset); | |||||
+ if (size == HeapWordSize) { | |||||
+ *((HeapWord*)to) = *from; | |||||
+ } else if (size == HeapWordSize * 2) { | |||||
+ *((HeapWord*)to) = *from; | |||||
+ *(((HeapWord*)to) + 1) = *(from + 1); | |||||
+ } else { | |||||
+ Copy::conjoint_jbytes(from, to, size); | |||||
+ } | |||||
+ to += size; | |||||
+ cur++; | |||||
+ } else { | |||||
+ assert(size < 0, ""); | |||||
+ int skip = -*cur; | |||||
+ Copy::fill_to_bytes(to, skip, 0); | |||||
+ to += skip; | |||||
+ cur++; | |||||
+ } | |||||
+ } | |||||
+} | |||||
diff -r 8f44f8a7e505 src/share/vm/gc_implementation/shared/markSweep.hpp | |||||
--- a/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -96,8 +96,12 @@ | |||||
friend class AdjustPointerClosure; | |||||
friend class KeepAliveClosure; | |||||
friend class VM_MarkSweep; | |||||
+ friend class GenMarkSweep; | |||||
friend void marksweep_init(); | |||||
+public: | |||||
+ static GrowableArray<HeapWord*>* _rescued_oops; | |||||
+ | |||||
// | |||||
// Vars | |||||
// | |||||
@@ -157,6 +161,9 @@ | |||||
static inline void push_objarray(oop obj, size_t index); | |||||
+ static void copy_rescued_objects_back(); | |||||
+ static void update_fields(oop q, oop new_location); | |||||
+ static void update_fields(oop new_location, oop tmp_obj, int *cur); | |||||
static void follow_stack(); // Empty marking stack. | |||||
static void follow_klass(Klass* klass); | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/genMarkSweep.cpp | |||||
--- a/src/share/vm/memory/genMarkSweep.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/genMarkSweep.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -327,11 +327,16 @@ | |||||
// in the same order in phase2, phase3 and phase4. We don't quite do that | |||||
// here (perm_gen first rather than last), so we tell the validate code | |||||
// to use a higher index (saved from phase2) when verifying perm_gen. | |||||
+ assert(_rescued_oops == NULL, "must be empty before processing"); | |||||
GenCollectedHeap* gch = GenCollectedHeap::heap(); | |||||
GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id()); | |||||
trace("4"); | |||||
+ MarkSweep::copy_rescued_objects_back(); | |||||
+ | |||||
GenCompactClosure blk; | |||||
gch->generation_iterate(&blk, true); | |||||
+ | |||||
+ MarkSweep::copy_rescued_objects_back(); | |||||
} | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.cpp | |||||
--- a/src/share/vm/memory/space.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -377,9 +377,8 @@ | |||||
_compaction_top = bottom(); | |||||
} | |||||
-HeapWord* CompactibleSpace::forward(oop q, size_t size, | |||||
- CompactPoint* cp, HeapWord* compact_top) { | |||||
- // q is alive | |||||
+// (DCEVM) Calculates the compact_top that will be used for placing the next object with the giving size on the heap. | |||||
+HeapWord* CompactibleSpace::forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top) { | |||||
// First check if we should switch compaction space | |||||
assert(this == cp->space, "'this' should be current compaction space."); | |||||
size_t compaction_max_size = pointer_delta(end(), compact_top); | |||||
@@ -399,8 +398,15 @@ | |||||
compaction_max_size = pointer_delta(cp->space->end(), compact_top); | |||||
} | |||||
+ return compact_top; | |||||
+} | |||||
+ | |||||
+HeapWord* CompactibleSpace::forward(oop q, size_t size, | |||||
+ CompactPoint* cp, HeapWord* compact_top) { | |||||
+ compact_top = forward_compact_top(size, cp, compact_top); | |||||
+ | |||||
// store the forwarding pointer into the mark word | |||||
- if ((HeapWord*)q != compact_top) { | |||||
+ if ((HeapWord*)q != compact_top || (size_t)q->size() != size) { | |||||
q->forward_to(oop(compact_top)); | |||||
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark"); | |||||
} else { | |||||
@@ -421,6 +427,58 @@ | |||||
return compact_top; | |||||
} | |||||
+// Compute the forward sizes and leave out objects whose position could | |||||
+// possibly overlap other objects. | |||||
+HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size, | |||||
+ CompactPoint* cp, HeapWord* compact_top) { | |||||
+ size_t forward_size = size; | |||||
+ | |||||
+ // (DCEVM) There is a new version of the class of q => different size | |||||
+ if (oop(q)->klass()->new_version() != NULL && oop(q)->klass()->new_version()->update_information() != NULL) { | |||||
+ | |||||
+ size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version()); | |||||
+ assert(size != new_size, "instances without changed size have to be updated prior to GC run"); | |||||
+ forward_size = new_size; | |||||
+ } | |||||
+ | |||||
+ compact_top = forward_compact_top(forward_size, cp, compact_top); | |||||
+ | |||||
+ if (must_rescue(oop(q), oop(compact_top))) { | |||||
+ if (MarkSweep::_rescued_oops == NULL) { | |||||
+ MarkSweep::_rescued_oops = new GrowableArray<HeapWord*>(128); | |||||
+ } | |||||
+ MarkSweep::_rescued_oops->append(q); | |||||
+ return compact_top; | |||||
+ } | |||||
+ | |||||
+ return forward(oop(q), forward_size, cp, compact_top); | |||||
+} | |||||
+ | |||||
+// Compute the forwarding addresses for the objects that need to be rescued. | |||||
+HeapWord* CompactibleSpace::forward_rescued(CompactPoint* cp, HeapWord* compact_top) { | |||||
+ // TODO: empty the _rescued_oops after ALL spaces are compacted! | |||||
+ if (MarkSweep::_rescued_oops != NULL) { | |||||
+ for (int i=0; i<MarkSweep::_rescued_oops->length(); i++) { | |||||
+ HeapWord* q = MarkSweep::_rescued_oops->at(i); | |||||
+ | |||||
+ /* size_t size = oop(q)->size(); changing this for cms for perm gen */ | |||||
+ size_t size = block_size(q); | |||||
+ | |||||
+ // (DCEVM) There is a new version of the class of q => different size | |||||
+ if (oop(q)->klass()->new_version() != NULL) { | |||||
+ size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version()); | |||||
+ assert(size != new_size, "instances without changed size have to be updated prior to GC run"); | |||||
+ size = new_size; | |||||
+ } | |||||
+ | |||||
+ compact_top = cp->space->forward(oop(q), size, cp, compact_top); | |||||
+ assert(compact_top <= end(), "must not write over end of space!"); | |||||
+ } | |||||
+ MarkSweep::_rescued_oops->clear(); | |||||
+ MarkSweep::_rescued_oops = NULL; | |||||
+ } | |||||
+ return compact_top; | |||||
+} | |||||
bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words, | |||||
HeapWord* q, size_t deadlength) { | |||||
@@ -442,12 +500,17 @@ | |||||
#define adjust_obj_size(s) s | |||||
void CompactibleSpace::prepare_for_compaction(CompactPoint* cp) { | |||||
- SCAN_AND_FORWARD(cp, end, block_is_obj, block_size); | |||||
+ SCAN_AND_FORWARD(cp, end, block_is_obj, block_size, false); | |||||
} | |||||
// Faster object search. | |||||
void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) { | |||||
- SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size); | |||||
+ if (!Universe::is_redefining_gc_run()) { | |||||
+ SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size, false); | |||||
+ } else { | |||||
+ // Redefinition run | |||||
+ SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size, true); | |||||
+ } | |||||
} | |||||
void Space::adjust_pointers() { | |||||
@@ -485,6 +548,111 @@ | |||||
assert(q == t, "just checking"); | |||||
} | |||||
+ | |||||
+#ifdef ASSERT | |||||
+ | |||||
+int CompactibleSpace::space_index(oop obj) { | |||||
+ GenCollectedHeap* heap = GenCollectedHeap::heap(); | |||||
+ | |||||
+ //if (heap->is_in_permanent(obj)) { | |||||
+ // return -1; | |||||
+ //} | |||||
+ | |||||
+ int index = 0; | |||||
+ for (int i = heap->n_gens() - 1; i >= 0; i--) { | |||||
+ Generation* gen = heap->get_gen(i); | |||||
+ CompactibleSpace* space = gen->first_compaction_space(); | |||||
+ while (space != NULL) { | |||||
+ if (space->is_in_reserved(obj)) { | |||||
+ return index; | |||||
+ } | |||||
+ space = space->next_compaction_space(); | |||||
+ index++; | |||||
+ } | |||||
+ } | |||||
+ | |||||
+ tty->print_cr("could not compute space_index for %08xh", (HeapWord*)obj); | |||||
+ index = 0; | |||||
+ for (int i = heap->n_gens() - 1; i >= 0; i--) { | |||||
+ Generation* gen = heap->get_gen(i); | |||||
+ tty->print_cr(" generation %s: %08xh - %08xh", gen->name(), gen->reserved().start(), gen->reserved().end()); | |||||
+ | |||||
+ CompactibleSpace* space = gen->first_compaction_space(); | |||||
+ while (space != NULL) { | |||||
+ tty->print_cr(" %2d space %08xh - %08xh", index, space->bottom(), space->end()); | |||||
+ space = space->next_compaction_space(); | |||||
+ index++; | |||||
+ } | |||||
+ } | |||||
+ | |||||
+ ShouldNotReachHere(); | |||||
+ return 0; | |||||
+} | |||||
+#endif | |||||
+ | |||||
+bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) { | |||||
+ // Only redefined objects can have the need to be rescued. | |||||
+ if (oop(old_obj)->klass()->new_version() == NULL) return false; | |||||
+ | |||||
+ //if (old_obj->is_perm()) { | |||||
+ // // This object is in perm gen: Always rescue to satisfy invariant obj->klass() <= obj. | |||||
+ // return true; | |||||
+ //} | |||||
+ | |||||
+ int new_size = old_obj->size_given_klass(oop(old_obj)->klass()->new_version()); | |||||
+ int original_size = old_obj->size(); | |||||
+ | |||||
+ Generation* tenured_gen = GenCollectedHeap::heap()->get_gen(1); | |||||
+ bool old_in_tenured = tenured_gen->is_in_reserved(old_obj); | |||||
+ bool new_in_tenured = tenured_gen->is_in_reserved(new_obj); | |||||
+ if (old_in_tenured == new_in_tenured) { | |||||
+ // Rescue if object may overlap with a higher memory address. | |||||
+ bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size); | |||||
+ if (old_in_tenured) { | |||||
+ // Old and new address are in same space, so just compare the address. | |||||
+ // Must rescue if object moves towards the top of the space. | |||||
+ assert(space_index(old_obj) == space_index(new_obj), "old_obj and new_obj must be in same space"); | |||||
+ } else { | |||||
+ // In the new generation, eden is located before the from space, so a | |||||
+ // simple pointer comparison is sufficient. | |||||
+ assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration"); | |||||
+ assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration"); | |||||
+ assert(overlap == (space_index(old_obj) < space_index(new_obj)), "slow and fast computation must yield same result"); | |||||
+ } | |||||
+ return overlap; | |||||
+ | |||||
+ } else { | |||||
+ assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces"); | |||||
+ if (tenured_gen->is_in_reserved(new_obj)) { | |||||
+ // Must never rescue when moving from the new into the old generation. | |||||
+ assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration"); | |||||
+ assert(space_index(old_obj) > space_index(new_obj), "must be"); | |||||
+ return false; | |||||
+ | |||||
+ } else /* if (tenured_gen->is_in_reserved(old_obj)) */ { | |||||
+ // Must always rescue when moving from the old into the new generation. | |||||
+ assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration"); | |||||
+ assert(space_index(old_obj) < space_index(new_obj), "must be"); | |||||
+ return true; | |||||
+ } | |||||
+ } | |||||
+} | |||||
+ | |||||
+HeapWord* CompactibleSpace::rescue(HeapWord* old_obj) { | |||||
+ assert(must_rescue(oop(old_obj), oop(old_obj)->forwardee()), "do not call otherwise"); | |||||
+ | |||||
+ int size = oop(old_obj)->size(); | |||||
+ HeapWord* rescued_obj = NEW_RESOURCE_ARRAY(HeapWord, size); | |||||
+ Copy::aligned_disjoint_words(old_obj, rescued_obj, size); | |||||
+ | |||||
+ if (MarkSweep::_rescued_oops == NULL) { | |||||
+ MarkSweep::_rescued_oops = new GrowableArray<HeapWord*>(128); | |||||
+ } | |||||
+ | |||||
+ MarkSweep::_rescued_oops->append(rescued_obj); | |||||
+ return rescued_obj; | |||||
+} | |||||
+ | |||||
void CompactibleSpace::adjust_pointers() { | |||||
// Check first is there is any work to do. | |||||
if (used() == 0) { | |||||
@@ -495,7 +663,12 @@ | |||||
} | |||||
void CompactibleSpace::compact() { | |||||
- SCAN_AND_COMPACT(obj_size); | |||||
+ if(!Universe::is_redefining_gc_run()) { | |||||
+ SCAN_AND_COMPACT(obj_size, false); | |||||
+ } else { | |||||
+ // Redefinition run | |||||
+ SCAN_AND_COMPACT(obj_size, true) | |||||
+ } | |||||
} | |||||
void Space::print_short() const { print_short_on(tty); } | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.hpp | |||||
--- a/src/share/vm/memory/space.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -392,6 +392,9 @@ | |||||
// indicates when the next such action should be taken. | |||||
virtual void prepare_for_compaction(CompactPoint* cp); | |||||
// MarkSweep support phase3 | |||||
+ DEBUG_ONLY(int space_index(oop obj)); | |||||
+ bool must_rescue(oop old_obj, oop new_obj); | |||||
+ HeapWord* rescue(HeapWord* old_obj); | |||||
virtual void adjust_pointers(); | |||||
// MarkSweep support phase4 | |||||
virtual void compact(); | |||||
@@ -421,6 +424,15 @@ | |||||
// accordingly". | |||||
virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp, | |||||
HeapWord* compact_top); | |||||
+ // (DCEVM) same as forwad, but can rescue objects. Invoked only during | |||||
+ // redefinition runs | |||||
+ HeapWord* forward_with_rescue(HeapWord* q, size_t size, CompactPoint* cp, | |||||
+ HeapWord* compact_top); | |||||
+ | |||||
+ HeapWord* forward_rescued(CompactPoint* cp, HeapWord* compact_top); | |||||
+ | |||||
+ // (tw) Compute new compact top without actually forwarding the object. | |||||
+ virtual HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top); | |||||
// Return a size with adjusments as required of the space. | |||||
virtual size_t adjust_object_size_v(size_t size) const { return size; } | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/space.inline.hpp | |||||
--- a/src/share/vm/memory/space.inline.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/space.inline.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -35,7 +35,7 @@ | |||||
return block_start_const(p); | |||||
} | |||||
-#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \ | |||||
+#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size,redefinition_run) { \ | |||||
/* Compute the new addresses for the live objects and store it in the mark \ | |||||
* Used by universe::mark_sweep_phase2() \ | |||||
*/ \ | |||||
@@ -93,7 +93,17 @@ | |||||
/* prefetch beyond q */ \ | |||||
Prefetch::write(q, interval); \ | |||||
size_t size = block_size(q); \ | |||||
+ if (redefinition_run) { \ | |||||
+ compact_top = cp->space->forward_with_rescue(q, size, \ | |||||
+ cp, compact_top); \ | |||||
+ if (q < first_dead && oop(q)->is_gc_marked()) { \ | |||||
+ /* Was moved (otherwise, forward would reset mark), \ | |||||
+ set first_dead to here */ \ | |||||
+ first_dead = q; \ | |||||
+ } \ | |||||
+ } else { \ | |||||
compact_top = cp->space->forward(oop(q), size, cp, compact_top); \ | |||||
+ } \ | |||||
q += size; \ | |||||
end_of_live = q; \ | |||||
} else { \ | |||||
@@ -142,6 +152,8 @@ | |||||
} \ | |||||
} \ | |||||
\ | |||||
+ if (redefinition_run) { compact_top = forward_rescued(cp, compact_top); } \ | |||||
+ \ | |||||
assert(q == t, "just checking"); \ | |||||
if (liveRange != NULL) { \ | |||||
liveRange->set_end(q); \ | |||||
@@ -188,13 +200,8 @@ | |||||
q += size; \ | |||||
} \ | |||||
\ | |||||
- if (_first_dead == t) { \ | |||||
- q = t; \ | |||||
- } else { \ | |||||
- /* $$$ This is funky. Using this to read the previously written \ | |||||
- * LiveRange. See also use below. */ \ | |||||
- q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \ | |||||
- } \ | |||||
+ /* (DCEVM) first_dead can be live object if we move/rescue resized objects */ \ | |||||
+ q = _first_dead; \ | |||||
} \ | |||||
\ | |||||
const intx interval = PrefetchScanIntervalInBytes; \ | |||||
@@ -222,7 +229,7 @@ | |||||
assert(q == t, "just checking"); \ | |||||
} | |||||
-#define SCAN_AND_COMPACT(obj_size) { \ | |||||
+#define SCAN_AND_COMPACT(obj_size, redefinition_run) { \ | |||||
/* Copy all live objects to their new location \ | |||||
* Used by MarkSweep::mark_sweep_phase4() */ \ | |||||
\ | |||||
@@ -247,13 +254,9 @@ | |||||
} \ | |||||
) /* debug_only */ \ | |||||
\ | |||||
- if (_first_dead == t) { \ | |||||
- q = t; \ | |||||
- } else { \ | |||||
- /* $$$ Funky */ \ | |||||
- q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \ | |||||
+ /* (DCEVM) first_dead can be live object if we move/rescue resized objects */ \ | |||||
+ q = _first_dead; \ | |||||
} \ | |||||
- } \ | |||||
\ | |||||
const intx scan_interval = PrefetchScanIntervalInBytes; \ | |||||
const intx copy_interval = PrefetchCopyIntervalInBytes; \ | |||||
@@ -271,11 +274,34 @@ | |||||
size_t size = obj_size(q); \ | |||||
HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \ | |||||
\ | |||||
+ if (redefinition_run && must_rescue(oop(q), oop(q)->forwardee())) { \ | |||||
+ rescue(q); \ | |||||
+ debug_only(Copy::fill_to_words(q, size, 0)); \ | |||||
+ q += size; \ | |||||
+ continue; \ | |||||
+ } \ | |||||
+ \ | |||||
/* prefetch beyond compaction_top */ \ | |||||
Prefetch::write(compaction_top, copy_interval); \ | |||||
\ | |||||
/* copy object and reinit its mark */ \ | |||||
- assert(q != compaction_top, "everything in this pass should be moving"); \ | |||||
+ assert(q != compaction_top || oop(q)->klass()->new_version() != NULL, \ | |||||
+ "everything in this pass should be moving"); \ | |||||
+ if (redefinition_run && oop(q)->klass()->new_version() != NULL) { \ | |||||
+ Klass* new_version = oop(q)->klass()->new_version(); \ | |||||
+ if (new_version->update_information() == NULL) { \ | |||||
+ Copy::aligned_conjoint_words(q, compaction_top, size); \ | |||||
+ oop(compaction_top)->set_klass(new_version); \ | |||||
+ } else { \ | |||||
+ MarkSweep::update_fields(oop(q), oop(compaction_top)); \ | |||||
+ } \ | |||||
+ oop(compaction_top)->init_mark(); \ | |||||
+ assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ | |||||
+ \ | |||||
+ debug_only(prev_q = q); \ | |||||
+ q += size; \ | |||||
+ continue; \ | |||||
+ } \ | |||||
Copy::aligned_conjoint_words(q, compaction_top, size); \ | |||||
oop(compaction_top)->init_mark(); \ | |||||
assert(oop(compaction_top)->klass() != NULL, "should have a class"); \ | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/universe.cpp | |||||
--- a/src/share/vm/memory/universe.cpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/universe.cpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -84,6 +84,8 @@ | |||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC | |||||
+bool Universe::_is_redefining_gc_run = false; | |||||
+ | |||||
// Known objects | |||||
Klass* Universe::_boolArrayKlassObj = NULL; | |||||
Klass* Universe::_byteArrayKlassObj = NULL; | |||||
diff -r 8f44f8a7e505 src/share/vm/memory/universe.hpp | |||||
--- a/src/share/vm/memory/universe.hpp Tue Mar 31 18:01:20 2015 -0700 | |||||
+++ b/src/share/vm/memory/universe.hpp Tue Mar 31 18:05:19 2015 -0700 | |||||
@@ -251,7 +251,13 @@ | |||||
static void compute_verify_oop_data(); | |||||
+ static bool _is_redefining_gc_run; | |||||
+ | |||||
public: | |||||
+ | |||||
+ static bool is_redefining_gc_run() { return _is_redefining_gc_run; } | |||||
+ static void set_redefining_gc_run(bool b) { _is_redefining_gc_run = b; } | |||||
+ | |||||
// Known classes in the VM | |||||
static Klass* boolArrayKlassObj() { return _boolArrayKlassObj; } | |||||
static Klass* byteArrayKlassObj() { return _byteArrayKlassObj; } |
# Add AllowEnhancedRedefinition argument | # Add AllowEnhancedRedefinition argument | ||||
arguments-java8.patch #+light-jdk8u5-b13 #+light-jdk8u20-b22 | arguments-java8.patch #+light-jdk8u5-b13 #+light-jdk8u20-b22 | ||||
arguments-java8u31.patch #+light-jdk8u31-b13 | arguments-java8u31.patch #+light-jdk8u31-b13 | ||||
arguments-java8u40.patch #+light-jdk8u40-b25 | |||||
# GC changes to allow modifying instances during redefinition run | # GC changes to allow modifying instances during redefinition run | ||||
gc-java8.patch #+jdk8 | |||||
gc-java8.patch #+light-jdk8u5-b13 #+light-jdk8u20-b22 #+light-jdk8u31-b13 | |||||
gc-java8u40.patch #+light-jdk8u40-b25 | |||||
# Add support for certain DMH implementations | # Add support for certain DMH implementations | ||||
dmh-field-accessors-java8.patch #+jdk8 | |||||
dmh-field-accessors-java8.patch #+light-jdk8u5-b13 #+light-jdk8u20-b22 #+light-jdk8u31-b13 | |||||
dmh-field-accessors-java8u40.patch #+light-jdk8u40-b25 | |||||
# Rest of the changes | # Rest of the changes | ||||
full-jdk7u11-b21.patch #+full-jdk7u11-b21 | full-jdk7u11-b21.patch #+full-jdk7u11-b21 | ||||
light-jdk8u5-b13.patch #+light-jdk8u5-b13 | light-jdk8u5-b13.patch #+light-jdk8u5-b13 | ||||
light-jdk8u20-b22.patch #+light-jdk8u20-b22 #+light-jdk8u31-b13 | light-jdk8u20-b22.patch #+light-jdk8u20-b22 #+light-jdk8u31-b13 | ||||
light-jdk8u20-deopt-cp.patch #+light-jdk8u20-b22 #+light-jdk8u31-b13 | |||||
light-jdk8u40-b25.patch #+light-jdk8u40-b25 | |||||
light-jdk8u20-deopt-cp.patch #+light-jdk8u20-b22 #+light-jdk8u31-b13 #+light-jdk8u40-b25 | |||||