# HG changeset patch # User zgu # Date 1537390282 14400 # Wed Sep 19 16:51:22 2018 -0400 # Node ID b7ac331c87d1a2c8f8aea8a8c23417ef6cd5e489 # Parent f671405d96879d2b90bc1ee92c125c0f1a7ca3fa [backport] 8210879: ClassLoaderStatsClosure does raw oop comparison Summary: Uses oopDesc::equals() for comparing oop equality Reviewed-by: shade diff --git a/src/share/vm/classfile/classLoaderStats.hpp b/src/share/vm/classfile/classLoaderStats.hpp --- a/src/share/vm/classfile/classLoaderStats.hpp +++ b/src/share/vm/classfile/classLoaderStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -28,6 +28,7 @@ #include "classfile/classLoaderData.hpp" #include "oops/klass.hpp" +#include "oops/oop.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/vm_operations.hpp" #include "services/diagnosticCommand.hpp" @@ -97,7 +98,7 @@ class ClassLoaderStatsClosure : public CLDClosure { protected: static bool oop_equals(oop const& s1, oop const& s2) { - return s1 == s2; + return oopDesc::equals(s1, s2); } static unsigned oop_hash(oop const& s1) { # HG changeset patch # User shade # Date 1552259206 -3600 # Mon Mar 11 00:06:46 2019 +0100 # Node ID 03448f15a87db4c1b08dc8a3144a8980bdca1b2f # Parent b7ac331c87d1a2c8f8aea8a8c23417ef6cd5e489 [backport] 8220350: Refactor ShenandoahHeap::initialize Reviewed-by: rkennke, zgu diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp @@ -82,15 +82,17 @@ class ShenandoahPretouchTask : public AbstractGangTask { private: ShenandoahRegionIterator _regions; + char* _bitmap_base; const size_t _bitmap_size; - const size_t _page_size; - char* _bitmap_base; + const size_t _heap_page_size; + const size_t _bitmap_page_size; public: - ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t page_size) : + ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t heap_page_size, size_t bitmap_page_size) : AbstractGangTask("Shenandoah PreTouch"), + _bitmap_base(bitmap_base), _bitmap_size(bitmap_size), - _page_size(page_size), - _bitmap_base(bitmap_base) {} + _heap_page_size(heap_page_size), + _bitmap_page_size(bitmap_page_size) {} virtual void work(uint worker_id) { ShenandoahHeapRegion* r = _regions.next(); @@ -115,77 +117,59 @@ initialize_heuristics(); + // + // Figure out heap sizing + // + size_t init_byte_size = collector_policy()->initial_heap_byte_size(); - size_t max_byte_size = collector_policy()->max_heap_byte_size(); + size_t max_byte_size = collector_policy()->max_heap_byte_size(); size_t heap_alignment = collector_policy()->heap_alignment(); + size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); + if (ShenandoahAlwaysPreTouch) { // Enabled pre-touch means the entire heap is committed right away. init_byte_size = max_byte_size; } - Universe::check_alignment(max_byte_size, - ShenandoahHeapRegion::region_size_bytes(), - "shenandoah heap"); - Universe::check_alignment(init_byte_size, - ShenandoahHeapRegion::region_size_bytes(), - "shenandoah heap"); - - ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, - heap_alignment); - + Universe::check_alignment(max_byte_size, reg_size_bytes, "Shenandoah heap"); + Universe::check_alignment(init_byte_size, reg_size_bytes, "Shenandoah heap"); + + _num_regions = ShenandoahHeapRegion::region_count(); + + size_t num_committed_regions = init_byte_size / reg_size_bytes; + num_committed_regions = MIN2(num_committed_regions, _num_regions); + assert(num_committed_regions <= _num_regions, "sanity"); + + _initial_size = num_committed_regions * reg_size_bytes; + _committed = _initial_size; + + size_t heap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + + // + // Reserve and commit memory for heap + // + + ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, heap_alignment); _reserved.set_word_size(0); _reserved.set_start((HeapWord*)heap_rs.base()); _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); - - set_barrier_set(new ShenandoahBarrierSet(this)); - ReservedSpace pgc_rs = heap_rs.first_part(max_byte_size); - - _num_regions = ShenandoahHeapRegion::region_count(); - - size_t num_committed_regions = init_byte_size / ShenandoahHeapRegion::region_size_bytes(); - num_committed_regions = MIN2(num_committed_regions, _num_regions); - assert(num_committed_regions <= _num_regions, "sanity"); - - _initial_size = num_committed_regions * ShenandoahHeapRegion::region_size_bytes(); - _committed = _initial_size; - - log_info(gc, heap)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s", - byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size)); - if (!os::commit_memory(pgc_rs.base(), _initial_size, false)) { - vm_exit_out_of_memory(_initial_size, OOM_MMAP_ERROR, "Shenandoah failed to initialize heap"); - } - - size_t reg_size_words = ShenandoahHeapRegion::region_size_words(); - size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); - - _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); - _free_set = new ShenandoahFreeSet(this, _num_regions); - - _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)pgc_rs.base()); - - if (ShenandoahPacing) { - _pacer = new ShenandoahPacer(this); - _pacer->setup_for_idle(); - } else { - _pacer = NULL; - } + _heap_region = MemRegion((HeapWord*)heap_rs.base(), heap_rs.size() / HeapWordSize); assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, - err_msg("misaligned heap: " PTR_FORMAT, p2i(base()))); - - // The call below uses stuff (the SATB* things) that are in G1, but probably - // belong into a shared location. - JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, - SATB_Q_FL_lock, - 20 /*G1SATBProcessCompletedThreshold */, - Shared_SATB_Q_lock); - - // Reserve space for prev and next bitmap. - size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + err_msg("Misaligned heap: " PTR_FORMAT, p2i(base()))); + + ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); + os::commit_memory_or_exit(sh_rs.base(), _initial_size, false, + "Cannot commit heap memory"); + + // + // Reserve and commit memory for bitmap(s) + // + _bitmap_size = MarkBitMap::compute_size(heap_rs.size()); _bitmap_size = align_size_up(_bitmap_size, bitmap_page_size); - _heap_region = MemRegion((HeapWord*) heap_rs.base(), heap_rs.size() / HeapWordSize); size_t bitmap_bytes_per_region = reg_size_bytes / MarkBitMap::heap_map_factor(); @@ -210,38 +194,51 @@ err_msg("Bitmap slices should be page-granular: bps = " SIZE_FORMAT ", page size = " SIZE_FORMAT, _bitmap_bytes_per_slice, bitmap_page_size)); - ReservedSpace bitmap0(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(bitmap0.base(), mtGC); - _bitmap_region = MemRegion((HeapWord*) bitmap0.base(), bitmap0.size() / HeapWordSize); + ReservedSpace bitmap(_bitmap_size, bitmap_page_size); + MemTracker::record_virtual_memory_type(bitmap.base(), mtGC); + _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); size_t bitmap_init_commit = _bitmap_bytes_per_slice * align_size_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); - os::commit_memory_or_exit((char *) (_bitmap_region.start()), bitmap_init_commit, false, - "couldn't allocate initial bitmap"); - - size_t page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, false, + "Cannot commit bitmap memory"); + + _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); if (ShenandoahVerify) { - ReservedSpace verify_bitmap(_bitmap_size, page_size); + ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false, - "couldn't allocate verification bitmap"); + "Cannot commit verification bitmap memory"); MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); _verification_bit_map.initialize(_heap_region, verify_bitmap_region); _verifier = new ShenandoahVerifier(this, &_verification_bit_map); } - _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); + // Reserve aux bitmap for use in object_iterate(). We don't commit it here. + ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); + MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC); + _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize); + _aux_bit_map.initialize(_heap_region, _aux_bitmap_region); + + // + // Create regions and region sets + // + + _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); + _free_set = new ShenandoahFreeSet(this, _num_regions); + _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)sh_rs.base()); { ShenandoahHeapLocker locker(lock()); + + size_t size_words = ShenandoahHeapRegion::region_size_words(); + for (size_t i = 0; i < _num_regions; i++) { - ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, - (HeapWord*) pgc_rs.base() + reg_size_words * i, - reg_size_words, - i, - i < num_committed_regions); + HeapWord* start = (HeapWord*)sh_rs.base() + size_words * i; + bool is_committed = i < num_committed_regions; + ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, start, size_words, i, is_committed); _marking_context->initialize_top_at_mark_start(r); _regions[i] = r; @@ -255,38 +252,24 @@ } if (ShenandoahAlwaysPreTouch) { - assert (!AlwaysPreTouch, "Should have been overridden"); + assert(!AlwaysPreTouch, "Should have been overridden"); // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads, // before initialize() below zeroes it with initializing thread. For any given region, // we touch the region and the corresponding bitmaps from the same thread. ShenandoahPushWorkerScope scope(workers(), _max_workers, false); - log_info(gc, heap)("Parallel pretouch " SIZE_FORMAT " regions with " SIZE_FORMAT " byte pages", - _num_regions, page_size); - ShenandoahPretouchTask cl(bitmap0.base(), _bitmap_size, page_size); + log_info(gc, init)("Pretouch " SIZE_FORMAT " regions; page sizes: " SIZE_FORMAT " heap, " SIZE_FORMAT " bitmap", + _num_regions, heap_page_size, bitmap_page_size); + ShenandoahPretouchTask cl(bitmap.base(), _bitmap_size, heap_page_size, bitmap_page_size); _workers->run_task(&cl); } - // Reserve aux bitmap for use in object_iterate(). We don't commit it here. - ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC); - _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize); - _aux_bit_map.initialize(_heap_region, _aux_bitmap_region); - - _monitoring_support = new ShenandoahMonitoringSupport(this); - - _phase_timings = new ShenandoahPhaseTimings(); - - if (ShenandoahAllocationTrace) { - _alloc_tracker = new ShenandoahAllocTracker(); - } - - ShenandoahStringDedup::initialize(); - - _control_thread = new ShenandoahControlThread(); - - ShenandoahCodeRoots::initialize(); + // + // Initialize the rest of GC subsystems + // + + set_barrier_set(new ShenandoahBarrierSet(this)); _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC); for (uint worker = 0; worker < _max_workers; worker++) { @@ -294,6 +277,34 @@ Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort)); } + // The call below uses stuff (the SATB* things) that are in G1, but probably + // belong into a shared location. + JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, + SATB_Q_FL_lock, + 20 /*G1SATBProcessCompletedThreshold */, + Shared_SATB_Q_lock); + + _monitoring_support = new ShenandoahMonitoringSupport(this); + _phase_timings = new ShenandoahPhaseTimings(); + ShenandoahStringDedup::initialize(); + ShenandoahCodeRoots::initialize(); + + if (ShenandoahAllocationTrace) { + _alloc_tracker = new ShenandoahAllocTracker(); + } + + if (ShenandoahPacing) { + _pacer = new ShenandoahPacer(this); + _pacer->setup_for_idle(); + } else { + _pacer = NULL; + } + + _control_thread = new ShenandoahControlThread(); + + log_info(gc, init)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s", + byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size)); + return JNI_OK; } @@ -346,6 +357,10 @@ _max_workers((uint)MAX2(ConcGCThreads, ParallelGCThreads)), _ref_processor(NULL), _marking_context(NULL), + _bitmap_size(0), + _bitmap_regions_per_slice(0), + _bitmap_bytes_per_slice(0), + _liveness_cache(NULL), _aux_bit_map(), _verifier(NULL), _pacer(NULL), @@ -2539,6 +2554,7 @@ jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) { #ifdef ASSERT + assert(_liveness_cache != NULL, "sanity"); assert(worker_id < _max_workers, "sanity"); for (uint i = 0; i < num_regions(); i++) { assert(_liveness_cache[worker_id][i] == 0, "liveness cache should be empty"); @@ -2549,6 +2565,7 @@ void ShenandoahHeap::flush_liveness_cache(uint worker_id) { assert(worker_id < _max_workers, "sanity"); + assert(_liveness_cache != NULL, "sanity"); jushort* ld = _liveness_cache[worker_id]; for (uint i = 0; i < num_regions(); i++) { ShenandoahHeapRegion* r = get_region(i); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp @@ -52,7 +52,6 @@ ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start, size_t size_words, size_t index, bool committed) : _heap(heap), - _pacer(ShenandoahPacing ? heap->pacer() : NULL), _reserved(MemRegion(start, size_words)), _region_number(index), _new_top(NULL), diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp @@ -210,7 +210,6 @@ // Never updated fields ShenandoahHeap* _heap; - ShenandoahPacer* _pacer; MemRegion _reserved; size_t _region_number; diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.inline.hpp @@ -71,7 +71,7 @@ inline void ShenandoahHeapRegion::increase_live_data_gc_words(size_t s) { internal_increase_live_data(s); if (ShenandoahPacing) { - _pacer->report_mark(s); + _heap->pacer()->report_mark(s); } } # HG changeset patch # User shade # Date 1552259207 -3600 # Mon Mar 11 00:06:47 2019 +0100 # Node ID 3a8f37171acae7eae47f3eba72062e89c0e4f94f # Parent 03448f15a87db4c1b08dc8a3144a8980bdca1b2f [backport] 8220153: Shenandoah does not work with TransparentHugePages properly Reviewed-by: rkennke, zgu diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp @@ -79,26 +79,40 @@ void ShenandoahAssertToSpaceClosure::do_oop(oop* p) { do_oop_nv(p); } #endif -class ShenandoahPretouchTask : public AbstractGangTask { +class ShenandoahPretouchHeapTask : public AbstractGangTask { private: ShenandoahRegionIterator _regions; - char* _bitmap_base; - const size_t _bitmap_size; - const size_t _heap_page_size; - const size_t _bitmap_page_size; + const size_t _page_size; public: - ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t heap_page_size, size_t bitmap_page_size) : - AbstractGangTask("Shenandoah PreTouch"), - _bitmap_base(bitmap_base), - _bitmap_size(bitmap_size), - _heap_page_size(heap_page_size), - _bitmap_page_size(bitmap_page_size) {} + ShenandoahPretouchHeapTask(size_t page_size) : + AbstractGangTask("Shenandoah Pretouch Heap"), + _page_size(page_size) {} virtual void work(uint worker_id) { ShenandoahHeapRegion* r = _regions.next(); while (r != NULL) { os::pretouch_memory((char*) r->bottom(), (char*) r->end()); - + r = _regions.next(); + } + } +}; + +class ShenandoahPretouchBitmapTask : public AbstractGangTask { +private: + ShenandoahRegionIterator _regions; + char* _bitmap_base; + const size_t _bitmap_size; + const size_t _page_size; +public: + ShenandoahPretouchBitmapTask(char* bitmap_base, size_t bitmap_size, size_t page_size) : + AbstractGangTask("Shenandoah Pretouch Bitmap"), + _bitmap_base(bitmap_base), + _bitmap_size(bitmap_size), + _page_size(page_size) {} + + virtual void work(uint worker_id) { + ShenandoahHeapRegion* r = _regions.next(); + while (r != NULL) { size_t start = r->region_number() * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); size_t end = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); assert (end <= _bitmap_size, err_msg("end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size)); @@ -161,7 +175,7 @@ err_msg("Misaligned heap: " PTR_FORMAT, p2i(base()))); ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); - os::commit_memory_or_exit(sh_rs.base(), _initial_size, false, + os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, "Cannot commit heap memory"); // @@ -201,14 +215,14 @@ size_t bitmap_init_commit = _bitmap_bytes_per_slice * align_size_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); - os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, false, + os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false, "Cannot commit bitmap memory"); _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); if (ShenandoahVerify) { ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); - os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false, + os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false, "Cannot commit verification bitmap memory"); MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); @@ -259,10 +273,31 @@ // we touch the region and the corresponding bitmaps from the same thread. ShenandoahPushWorkerScope scope(workers(), _max_workers, false); - log_info(gc, init)("Pretouch " SIZE_FORMAT " regions; page sizes: " SIZE_FORMAT " heap, " SIZE_FORMAT " bitmap", - _num_regions, heap_page_size, bitmap_page_size); - ShenandoahPretouchTask cl(bitmap.base(), _bitmap_size, heap_page_size, bitmap_page_size); - _workers->run_task(&cl); + size_t pretouch_heap_page_size = heap_page_size; + size_t pretouch_bitmap_page_size = bitmap_page_size; + +#ifdef LINUX + // UseTransparentHugePages would madvise that backing memory can be coalesced into huge + // pages. But, the kernel needs to know that every small page is used, in order to coalesce + // them into huge one. Therefore, we need to pretouch with smaller pages. + if (UseTransparentHugePages) { + pretouch_heap_page_size = (size_t)os::vm_page_size(); + pretouch_bitmap_page_size = (size_t)os::vm_page_size(); + } +#endif + + // OS memory managers may want to coalesce back-to-back pages. Make their jobs + // simpler by pre-touching continuous spaces (heap and bitmap) separately. + + log_info(gc, init)("Pretouch bitmap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", + _num_regions, pretouch_bitmap_page_size); + ShenandoahPretouchBitmapTask bcl(bitmap.base(), _bitmap_size, pretouch_bitmap_page_size); + _workers->run_task(&bcl); + + log_info(gc, init)("Pretouch heap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", + _num_regions, pretouch_heap_page_size); + ShenandoahPretouchHeapTask hcl(pretouch_heap_page_size); + _workers->run_task(&hcl); } // # HG changeset patch # User shade # Date 1552259208 -3600 # Mon Mar 11 00:06:48 2019 +0100 # Node ID bf9717f3e53beb81fb799b9aa30da68dd061d8c5 # Parent 3a8f37171acae7eae47f3eba72062e89c0e4f94f [backport] 8220162: Shenandoah should not commit HugeTLBFS memory Reviewed-by: rkennke, zgu diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp @@ -170,13 +170,16 @@ _reserved.set_start((HeapWord*)heap_rs.base()); _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); _heap_region = MemRegion((HeapWord*)heap_rs.base(), heap_rs.size() / HeapWordSize); + _heap_region_special = heap_rs.special(); assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, err_msg("Misaligned heap: " PTR_FORMAT, p2i(base()))); ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); - os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, - "Cannot commit heap memory"); + if (!_heap_region_special) { + os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, + "Cannot commit heap memory"); + } // // Reserve and commit memory for bitmap(s) @@ -211,19 +214,24 @@ ReservedSpace bitmap(_bitmap_size, bitmap_page_size); MemTracker::record_virtual_memory_type(bitmap.base(), mtGC); _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); + _bitmap_region_special = bitmap.special(); size_t bitmap_init_commit = _bitmap_bytes_per_slice * align_size_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); - os::commit_memory_or_exit((char *)_bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false, - "Cannot commit bitmap memory"); + if (!_bitmap_region_special) { + os::commit_memory_or_exit((char *) _bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false, + "Cannot commit bitmap memory"); + } _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); if (ShenandoahVerify) { ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); - os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false, - "Cannot commit verification bitmap memory"); + if (!verify_bitmap.special()) { + os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false, + "Cannot commit verification bitmap memory"); + } MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); _verification_bit_map.initialize(_heap_region, verify_bitmap_region); @@ -234,6 +242,7 @@ ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC); _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize); + _aux_bitmap_region_special = aux_bitmap.special(); _aux_bit_map.initialize(_heap_region, _aux_bitmap_region); // @@ -384,6 +393,7 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : SharedHeap(policy), _shenandoah_policy(policy), + _heap_region_special(false), _regions(NULL), _free_set(NULL), _collection_set(NULL), @@ -395,6 +405,8 @@ _bitmap_size(0), _bitmap_regions_per_slice(0), _bitmap_bytes_per_slice(0), + _bitmap_region_special(false), + _aux_bitmap_region_special(false), _liveness_cache(NULL), _aux_bit_map(), _verifier(NULL), @@ -1195,7 +1207,7 @@ */ void ShenandoahHeap::object_iterate(ObjectClosure* cl) { assert(SafepointSynchronize::is_at_safepoint(), "safe iteration is only available during safepoints"); - if (!os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) { + if (!_aux_bitmap_region_special && !os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) { log_warning(gc)("Could not commit native memory for auxiliary marking bitmap for heap iteration"); return; } @@ -1222,7 +1234,7 @@ assert(oop_stack.is_empty(), "should be empty"); - if (!os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) { + if (!_aux_bitmap_region_special && !os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) { log_warning(gc)("Could not uncommit native memory for auxiliary marking bitmap for heap iteration"); } } @@ -2148,6 +2160,11 @@ bool ShenandoahHeap::commit_bitmap_slice(ShenandoahHeapRegion* r) { assert_heaplock_owned_by_current_thread(); + // Bitmaps in special regions do not need commits + if (_bitmap_region_special) { + return true; + } + if (is_bitmap_slice_committed(r, true)) { // Some other region from the group is already committed, meaning the bitmap // slice is already committed, we exit right away. @@ -2167,6 +2184,11 @@ bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) { assert_heaplock_owned_by_current_thread(); + // Bitmaps in special regions do not need uncommits + if (_bitmap_region_special) { + return true; + } + if (is_bitmap_slice_committed(r, true)) { // Some other region from the group is still committed, meaning the bitmap // slice is should stay committed, exit right away. diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp @@ -234,12 +234,14 @@ // private: MemRegion _heap_region; + bool _heap_region_special; size_t _num_regions; ShenandoahHeapRegion** _regions; ShenandoahRegionIterator _update_refs_iterator; public: inline size_t num_regions() const { return _num_regions; } + inline bool is_heap_region_special() { return _heap_region_special; } inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const; inline size_t heap_region_index_containing(const void* addr) const; @@ -602,6 +604,9 @@ size_t _bitmap_regions_per_slice; size_t _bitmap_bytes_per_slice; + bool _bitmap_region_special; + bool _aux_bitmap_region_special; + // Used for buffering per-region liveness data. // Needed since ShenandoahHeapRegion uses atomics to update liveness. // diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp @@ -611,7 +611,7 @@ } void ShenandoahHeapRegion::do_commit() { - if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) { + if (!_heap->is_heap_region_special() && !os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) { report_java_out_of_memory("Unable to commit region"); } if (!_heap->commit_bitmap_slice(this)) { @@ -621,7 +621,7 @@ } void ShenandoahHeapRegion::do_uncommit() { - if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) { + if (!_heap->is_heap_region_special() && !os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) { report_java_out_of_memory("Unable to uncommit region"); } if (!_heap->uncommit_bitmap_slice(this)) {