aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hotspot/share/gc/g1/g1CollectedHeap.cpp20
-rw-r--r--src/hotspot/share/gc/g1/g1CollectedHeap.hpp2
-rw-r--r--src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp46
-rw-r--r--src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp5
4 files changed, 58 insertions, 15 deletions
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index dea8d9fdb0e..33664a30519 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -2108,6 +2108,21 @@ public:
}
};
+class G1IterateObjectClosureTask : public AbstractGangTask {
+ private:
+ ObjectClosure* _cl;
+ G1CollectedHeap* _g1h;
+ HeapRegionClaimer _hrclaimer;
+ public:
+ G1IterateObjectClosureTask(ObjectClosure* cl, G1CollectedHeap* g1h) : AbstractGangTask("IterateObject Closure"),
+ _cl(cl), _g1h(g1h), _hrclaimer(g1h->workers()->active_workers()) { }
+
+ virtual void work(uint worker_id) {
+ IterateObjectClosureRegionClosure blk(_cl);
+ _g1h->heap_region_par_iterate_from_worker_offset(&blk, &_hrclaimer, worker_id);
+ }
+};
+
void G1CollectedHeap::object_iterate(ObjectClosure* cl) {
IterateObjectClosureRegionClosure blk(cl);
heap_region_iterate(&blk);
@@ -2117,6 +2132,11 @@ void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
_hrm.iterate(cl);
}
+void G1CollectedHeap::object_par_iterate(ObjectClosure* cl) {
+ G1IterateObjectClosureTask iocl_task(cl, this);
+ workers()->run_task(&iocl_task);
+}
+
void G1CollectedHeap::heap_region_par_iterate_from_worker_offset(HeapRegionClosure* cl,
HeapRegionClaimer *hrclaimer,
uint worker_id) const {
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
index 0735eef0da8..05a068bb2e0 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -1117,6 +1117,8 @@ public:
// Iteration functions.
+ void object_par_iterate(ObjectClosure* cl);
+
// Iterate over all objects, calling "cl.do_object" on each.
virtual void object_iterate(ObjectClosure* cl);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 32929b3d7a0..5be9bb74305 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -54,6 +54,7 @@
#include "utilities/events.hpp"
#include "oops/constantPool.inline.hpp"
#include "gc/cms/cmsHeap.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/shared/dcevmSharedGC.hpp"
Array<Method*>* VM_EnhancedRedefineClasses::_old_methods = NULL;
@@ -459,6 +460,10 @@ public:
void VM_EnhancedRedefineClasses::doit() {
Thread *thread = Thread::current();
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_vm_op_doit.start();
+ }
+
#if INCLUDE_CDS
if (UseSharedSpaces) {
// Sharing is enabled so we remap the shared readonly space to
@@ -523,8 +528,22 @@ void VM_EnhancedRedefineClasses::doit() {
}
Universe::heap()->ensure_parsability(false);
- Universe::heap()->object_iterate(&objectClosure);
+ if (UseG1GC) {
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_heap_iterate.start();
+ }
+ G1CollectedHeap::heap()->object_par_iterate(&objectClosure);
+ _timer_heap_iterate.stop();
+ } else {
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_heap_iterate.start();
+ }
+ Universe::heap()->object_iterate(&objectClosure);
+ _timer_heap_iterate.stop();
+ }
+
Universe::root_oops_do(&oopClosureNoBarrier);
+
}
log_trace(redefine, class, obsolete, metadata)("After updating instances");
@@ -577,12 +596,19 @@ void VM_EnhancedRedefineClasses::doit() {
if (objectClosure.needs_instance_update()) {
// Do a full garbage collection to update the instance sizes accordingly
+
+ if (log_is_enabled(Info, redefine, class, timer)) {
+ _timer_heap_full_gc.start();
+ }
+
Universe::set_redefining_gc_run(true);
notify_gc_begin(true);
// TODO: check _metadata_GC_clear_soft_refs with ScavengeRootsInCode
Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
notify_gc_end();
Universe::set_redefining_gc_run(false);
+
+ _timer_heap_full_gc.stop();
}
// Unmark Klass*s as "redefining"
@@ -630,6 +656,7 @@ void VM_EnhancedRedefineClasses::doit() {
}
#endif
+ _timer_vm_op_doit.stop();
}
// Cleanup - runs in JVM thread
@@ -653,16 +680,14 @@ void VM_EnhancedRedefineClasses::doit_epilogue() {
if (log_is_enabled(Info, redefine, class, timer)) {
// Used to have separate timers for "doit" and "all", but the timer
// overhead skewed the measurements.
- jlong doit_time = _timer_rsc_phase1.milliseconds() +
- _timer_rsc_phase2.milliseconds();
- jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
+ jlong all_time = _timer_vm_op_prologue.milliseconds() + _timer_vm_op_doit.milliseconds();
log_info(redefine, class, timer)
("vm_op: all=" JLONG_FORMAT " prologue=" JLONG_FORMAT " doit=" JLONG_FORMAT,
- all_time, _timer_vm_op_prologue.milliseconds(), doit_time);
+ all_time, _timer_vm_op_prologue.milliseconds(), _timer_vm_op_doit.milliseconds());
log_info(redefine, class, timer)
- ("redefine_single_class: phase1=" JLONG_FORMAT " phase2=" JLONG_FORMAT,
- _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds());
+ ("doit: heap iterate=" JLONG_FORMAT " fullgc=" JLONG_FORMAT,
+ _timer_heap_iterate.milliseconds(), _timer_heap_full_gc.milliseconds());
}
}
@@ -1411,7 +1436,7 @@ void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
// arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp.
void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
if (!k->is_instance_klass()) {
- return;
+ return;
}
HandleMark hm(_thread);
@@ -1829,10 +1854,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
HandleMark hm(THREAD); // make sure handles from this call are freed
- if (log_is_enabled(Info, redefine, class, timer)) {
- _timer_rsc_phase1.start();
- }
-
InstanceKlass* new_class = new_class_oop;
InstanceKlass* the_class = InstanceKlass::cast(new_class_oop->old_version());
assert(the_class != NULL, "must have old version");
@@ -1887,7 +1908,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
new_class->external_name(),
java_lang_Class::classRedefinedCount(new_class->java_mirror()));
}
- _timer_rsc_phase2.stop();
} // end redefine_single_class()
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 030852b160a..9755944d70b 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -86,9 +86,10 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// Performance measurement support. These timers do not cover all
// the work done for JVM/TI RedefineClasses() but they do cover
// the heavy lifting.
- elapsedTimer _timer_rsc_phase1;
- elapsedTimer _timer_rsc_phase2;
+ elapsedTimer _timer_vm_op_doit;
elapsedTimer _timer_vm_op_prologue;
+ elapsedTimer _timer_heap_iterate;
+ elapsedTimer _timer_heap_full_gc;
// These routines are roughly in call order unless otherwise noted.