# HG changeset patch # User rkennke # Date 1489669171 -3600 # Thu Mar 16 13:59:31 2017 +0100 # Node ID 57584c2a18bf1698abbbabac7b80b90a7050cec6 # Parent 366a99d8bd1b78e7ebdb852335e060d5a373f9e5 Add humongous regions support to partial GC. diff --git a/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp b/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp --- a/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp @@ -49,6 +49,7 @@ reserved(MemRegion(start, regionSizeWords)), _humongous_start(false), _humongous_continuation(false), + _humongous_obj_array(false), _recycled(true), _root(false), _new_top(NULL), @@ -215,6 +216,18 @@ void ShenandoahHeapRegion::oop_iterate(ExtendedOopClosure* blk) { if (is_empty()) return; + if (is_humongous_obj_array()) { + oop_iterate_humongous(blk); + } else { + oop_iterate_objects(blk); + } +} + +void ShenandoahHeapRegion::oop_iterate_objects(ExtendedOopClosure* blk) { + assert(! is_humongous_obj_array(), "no humongous obj array here"); + assert(! is_humongous_continuation(), "no humongous continuation here"); + // Note: it is ok to have a humongous start region here, e.g. in the case + // of an int[]. We might want to visit its header. HeapWord* obj_addr = bottom() + BrooksPointer::word_size(); HeapWord* t = top(); // Could call objects iterate, but this is easier. @@ -224,6 +237,21 @@ } } +void ShenandoahHeapRegion::oop_iterate_humongous(ExtendedOopClosure* blk) { + assert(is_humongous_obj_array(), "only humongous obj array here"); + // Find head. + ShenandoahHeapRegionSet* regions = _heap->regions(); + uint idx = region_number(); + ShenandoahHeapRegion* r = regions->get(idx); + while (! r->is_humongous_start()) { + idx--; + r = regions->get(idx); + } + assert(r->is_humongous_start(), "need humongous head here"); + objArrayOop array = objArrayOop(r->bottom() + BrooksPointer::word_size()); + array->oop_iterate(blk, MemRegion(bottom(), top())); +} + void ShenandoahHeapRegion::fill_region() { ShenandoahHeap* sh = (ShenandoahHeap*) Universe::heap(); @@ -243,6 +271,10 @@ _humongous_continuation = continuation; } +void ShenandoahHeapRegion::set_humongous_obj_array(bool obj_array) { + _humongous_obj_array = obj_array; +} + bool ShenandoahHeapRegion::is_humongous() const { return _humongous_start || _humongous_continuation; } @@ -255,11 +287,16 @@ return _humongous_continuation; } +bool ShenandoahHeapRegion::is_humongous_obj_array() const { + return _humongous_continuation; +} + void ShenandoahHeapRegion::recycle() { ContiguousSpace::initialize(reserved, true, false); clear_live_data(); _humongous_start = false; _humongous_continuation = false; + _humongous_obj_array = false; _recycled = true; _root = false; set_in_collection_set(false); diff --git a/src/share/vm/gc/shenandoah/shenandoahHeapRegion.hpp b/src/share/vm/gc/shenandoah/shenandoahHeapRegion.hpp --- a/src/share/vm/gc/shenandoah/shenandoahHeapRegion.hpp +++ b/src/share/vm/gc/shenandoah/shenandoahHeapRegion.hpp @@ -44,6 +44,7 @@ bool _humongous_start; bool _humongous_continuation; + bool _humongous_obj_array; bool _recycled; bool _root; @@ -92,6 +93,11 @@ HeapWord* object_iterate_careful(ObjectClosureCareful* cl); void oop_iterate(ExtendedOopClosure* cl); +private: + void oop_iterate_objects(ExtendedOopClosure* cl); + void oop_iterate_humongous(ExtendedOopClosure* cl); + +public: HeapWord* block_start_const(const void* p) const; // Just before GC we need to fill the current region. @@ -103,10 +109,12 @@ void set_humongous_start(bool start); void set_humongous_continuation(bool continuation); + void set_humongous_obj_array(bool obj_array); bool is_humongous() const; bool is_humongous_start() const; bool is_humongous_continuation() const; + bool is_humongous_obj_array() const; #ifdef ASSERT void memProtectionOn(); diff --git a/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp b/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp --- a/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp +++ b/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp @@ -194,11 +194,6 @@ if (matrix->is_connected(from_idx, to_idx)) { ShenandoahHeapRegion* r = regions->get(from_idx); if (! r->is_root() && ! _heap->region_in_collection_set(from_idx)) { - // TODO: Implement support for humongous roots: - // - quick impl: rewind to the head of the humongous object and use that - // - better impl: support scanning of humongous continuation regions - // and potentially avoid scanning the whole obj - guarantee(! r->is_humongous_continuation(), "unimplemented"); _root_regions->add_region(r); r->set_root(true); }