< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.cpp

Print this page
rev 10654 : [backport] Disable ShHeapUncommit on too-large large-pages
rev 10658 : [backport] Single marking bitmap
rev 10660 : [backport] Refactor bitmap cleaning
rev 10673 : [backport] Homogenize unimplemented stubs handling
rev 10676 : [backport] Remove ShHeap::region_in_collection_set in favor of SHR::in_cset
rev 10690 : [backport] Cleanup header files and forward declarations
rev 10712 : [backport] Fix compilation errors due to missing spaces between string literal and macro
rev 10740 : [backport] Protect more internal code from false sharing
rev 10747 : [backport] Fix Windows build failure
rev 10764 : [backport] Rename BrooksPointer to ShenandoahBrooksPointer
rev 10766 : Cast Shenandoah{Min,Max}RegionSize to size_t
rev 10772 : [backport] Update copyrights

*** 1,7 **** /* ! * Copyright (c) 2013, 2015, Red Hat, Inc. and/or its affiliates. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * --- 1,7 ---- /* ! * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. *
*** 20,36 **** * questions. * */ #include "precompiled.hpp" #include "memory/allocation.hpp" ! #include "gc_implementation/shenandoah/brooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "memory/space.inline.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" --- 20,38 ---- * questions. * */ #include "precompiled.hpp" + #include "memory/allocation.hpp" ! #include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.hpp" #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "memory/space.inline.hpp" + #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp"
*** 49,69 **** size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0; ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start, size_t size_words, size_t index, bool committed) : _heap(heap), ! _region_number(index), ! _live_data(0), _reserved(MemRegion(start, size_words)), ! _tlab_allocs(0), ! _gclab_allocs(0), ! _shared_allocs(0), _new_top(NULL), _critical_pins(0), - _state(committed ? _empty_committed : _empty_uncommitted), _empty_time(os::elapsedTime()), ! _pacer(ShenandoahPacing ? heap->pacer() : NULL) { ContiguousSpace::initialize(_reserved, true, committed); } size_t ShenandoahHeapRegion::region_number() const { --- 51,71 ---- size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0; 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), _critical_pins(0), _empty_time(os::elapsedTime()), ! _state(committed ? _empty_committed : _empty_uncommitted), ! _tlab_allocs(0), ! _gclab_allocs(0), ! _shared_allocs(0), ! _live_data(0) { ContiguousSpace::initialize(_reserved, true, committed); } size_t ShenandoahHeapRegion::region_number() const {
*** 263,272 **** --- 265,282 ---- default: report_illegal_transition("trashing"); } } + void ShenandoahHeapRegion::make_trash_immediate() { + make_trash(); + + // On this path, we know there are no marked objects in the region, + // tell marking context about it to bypass bitmap resets. + _heap->complete_marking_context()->reset_top_bitmap(this); + } + void ShenandoahHeapRegion::make_empty() { _heap->assert_heaplock_owned_by_current_thread(); switch (_state) { case _trash: _state = _empty_committed;
*** 301,315 **** default: report_illegal_transition("commit bypass"); } } - bool ShenandoahHeapRegion::rollback_allocation(uint size) { - set_top(top() - size); - return true; - } - void ShenandoahHeapRegion::clear_live_data() { OrderAccess::release_store_fence((volatile jint*)&_live_data, 0); } void ShenandoahHeapRegion::reset_alloc_metadata() { --- 311,320 ----
*** 360,379 **** bool ShenandoahHeapRegion::has_live() const { return get_live_data_words() != 0; } size_t ShenandoahHeapRegion::garbage() const { ! assert(used() >= get_live_data_bytes(), err_msg("Live Data must be a subset of used() live: "SIZE_FORMAT" used: "SIZE_FORMAT, get_live_data_bytes(), used())); size_t result = used() - get_live_data_bytes(); return result; } - bool ShenandoahHeapRegion::in_collection_set() const { - return _heap->region_in_collection_set(_region_number); - } - void ShenandoahHeapRegion::print_on(outputStream* st) const { st->print("|"); st->print(SIZE_FORMAT_W(5), this->_region_number); switch (_state) { --- 365,380 ---- bool ShenandoahHeapRegion::has_live() const { return get_live_data_words() != 0; } size_t ShenandoahHeapRegion::garbage() const { ! assert(used() >= get_live_data_bytes(), err_msg("Live Data must be a subset of used() live: " SIZE_FORMAT " used: " SIZE_FORMAT, get_live_data_bytes(), used())); size_t result = used() - get_live_data_bytes(); return result; } void ShenandoahHeapRegion::print_on(outputStream* st) const { st->print("|"); st->print(SIZE_FORMAT_W(5), this->_region_number); switch (_state) {
*** 410,441 **** default: ShouldNotReachHere(); } st->print("|BTE " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12), p2i(bottom()), p2i(top()), p2i(end())); ! st->print("|TAMS " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12), ! p2i(_heap->complete_marking_context()->top_at_mark_start(region_number())), ! p2i(_heap->next_marking_context()->top_at_mark_start(region_number()))); st->print("|U " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); st->print("|T " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_tlab_allocs()), proper_unit_for_byte_size(get_tlab_allocs())); st->print("|G " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs())); st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs())); st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes())); st->print("|CP " SIZE_FORMAT_W(3), _critical_pins); st->cr(); } - void ShenandoahHeapRegion::fill_region() { - if (free() > (BrooksPointer::word_size() + CollectedHeap::min_fill_size())) { - HeapWord* filler = allocate(BrooksPointer::word_size(), ShenandoahHeap::_alloc_shared); - HeapWord* obj = allocate(end() - top(), ShenandoahHeap::_alloc_shared); - _heap->fill_with_object(obj, end() - obj); - BrooksPointer::initialize(oop(obj)); - } - } - ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const { assert(is_humongous(), "Must be a part of the humongous region"); size_t reg_num = region_number(); ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this); while (!r->is_humongous_start()) { --- 411,432 ---- default: ShouldNotReachHere(); } st->print("|BTE " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12), p2i(bottom()), p2i(top()), p2i(end())); ! st->print("|TAMS " INTPTR_FORMAT_W(12), ! p2i(_heap->marking_context()->top_at_mark_start(const_cast<ShenandoahHeapRegion*>(this)))); st->print("|U " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(used()), proper_unit_for_byte_size(used())); st->print("|T " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_tlab_allocs()), proper_unit_for_byte_size(get_tlab_allocs())); st->print("|G " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_gclab_allocs()), proper_unit_for_byte_size(get_gclab_allocs())); st->print("|S " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_shared_allocs()), proper_unit_for_byte_size(get_shared_allocs())); st->print("|L " SIZE_FORMAT_W(5) "%1s", byte_size_in_proper_unit(get_live_data_bytes()), proper_unit_for_byte_size(get_live_data_bytes())); st->print("|CP " SIZE_FORMAT_W(3), _critical_pins); st->cr(); } ShenandoahHeapRegion* ShenandoahHeapRegion::humongous_start_region() const { assert(is_humongous(), "Must be a part of the humongous region"); size_t reg_num = region_number(); ShenandoahHeapRegion* r = const_cast<ShenandoahHeapRegion*>(this); while (!r->is_humongous_start()) {
*** 454,496 **** ContiguousSpace::mangle_unused_area_complete(); } clear_live_data(); reset_alloc_metadata(); ! ShenandoahMarkingContext* const compl_ctx = _heap->complete_marking_context(); ! ! // Reset C-TAMS pointer to ensure size-based iteration, everything ! // in that regions is going to be new objects. ! compl_ctx->set_top_at_mark_start(region_number(), bottom()); ! // We can only safely reset the C-TAMS pointer if the bitmap is clear for that region. ! assert(compl_ctx->is_bitmap_clear_range(bottom(), end()), "must be clear"); make_empty(); } HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const { assert(MemRegion(bottom(), end()).contains(p), ! err_msg("p ("PTR_FORMAT") not in space ["PTR_FORMAT", "PTR_FORMAT")", p2i(p), p2i(bottom()), p2i(end()))); if (p >= top()) { return top(); } else { ! HeapWord* last = bottom() + BrooksPointer::word_size(); HeapWord* cur = last; while (cur <= p) { last = cur; ! cur += oop(cur)->size() + BrooksPointer::word_size(); } shenandoah_assert_correct(NULL, oop(last)); return last; } } void ShenandoahHeapRegion::setup_sizes(size_t initial_heap_size, size_t max_heap_size) { // Absolute minimums we should not ever break: static const size_t MIN_REGION_SIZE = 256*K; - static const size_t MIN_NUM_REGIONS = 10; size_t region_size; if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) { if (ShenandoahMinRegionSize > initial_heap_size / MIN_NUM_REGIONS) { err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number " --- 445,480 ---- ContiguousSpace::mangle_unused_area_complete(); } clear_live_data(); reset_alloc_metadata(); ! _heap->marking_context()->reset_top_at_mark_start(this); make_empty(); } HeapWord* ShenandoahHeapRegion::block_start_const(const void* p) const { assert(MemRegion(bottom(), end()).contains(p), ! err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(p), p2i(bottom()), p2i(end()))); if (p >= top()) { return top(); } else { ! HeapWord* last = bottom() + ShenandoahBrooksPointer::word_size(); HeapWord* cur = last; while (cur <= p) { last = cur; ! cur += oop(cur)->size() + ShenandoahBrooksPointer::word_size(); } shenandoah_assert_correct(NULL, oop(last)); return last; } } void ShenandoahHeapRegion::setup_sizes(size_t initial_heap_size, size_t max_heap_size) { // Absolute minimums we should not ever break: static const size_t MIN_REGION_SIZE = 256*K; size_t region_size; if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) { if (ShenandoahMinRegionSize > initial_heap_size / MIN_NUM_REGIONS) { err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
*** 522,533 **** // We rapidly expand to max_heap_size in most scenarios, so that is the measure // for usual heap sizes. Do not depend on initial_heap_size here. region_size = max_heap_size / ShenandoahTargetNumRegions; // Now make sure that we don't go over or under our limits. ! region_size = MAX2(ShenandoahMinRegionSize, region_size); ! region_size = MIN2(ShenandoahMaxRegionSize, region_size); } else { if (ShenandoahHeapRegionSize > initial_heap_size / MIN_NUM_REGIONS) { err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number " "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "K).", --- 506,517 ---- // We rapidly expand to max_heap_size in most scenarios, so that is the measure // for usual heap sizes. Do not depend on initial_heap_size here. region_size = max_heap_size / ShenandoahTargetNumRegions; // Now make sure that we don't go over or under our limits. ! region_size = MAX2<size_t>(ShenandoahMinRegionSize, region_size); ! region_size = MIN2<size_t>(ShenandoahMaxRegionSize, region_size); } else { if (ShenandoahHeapRegionSize > initial_heap_size / MIN_NUM_REGIONS) { err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number " "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "K).",
*** 550,570 **** if (1 > ShenandoahHumongousThreshold || ShenandoahHumongousThreshold > 100) { vm_exit_during_initialization("Invalid -XX:ShenandoahHumongousThreshold option, should be within [1..100]"); } // Make sure region size is at least one large page, if enabled. ! // Otherwise, mem-protecting one region may falsely protect the adjacent // regions too. ! if (UseLargePages) { region_size = MAX2(region_size, os::large_page_size()); } int region_size_log = log2_long((jlong) region_size); // Recalculate the region size to make sure it's a power of // 2. This means that region_size is the largest power of 2 that's // <= what we've calculated so far. ! region_size = (size_t(1) << region_size_log); // Now, set up the globals. guarantee(RegionSizeBytesShift == 0, "we should only set it once"); RegionSizeBytesShift = (size_t)region_size_log; --- 534,555 ---- if (1 > ShenandoahHumongousThreshold || ShenandoahHumongousThreshold > 100) { vm_exit_during_initialization("Invalid -XX:ShenandoahHumongousThreshold option, should be within [1..100]"); } // Make sure region size is at least one large page, if enabled. ! // Otherwise, uncommitting one region may falsely uncommit the adjacent // regions too. ! // Also see shenandoahArguments.cpp, where it handles UseLargePages. ! if (UseLargePages && ShenandoahUncommit) { region_size = MAX2(region_size, os::large_page_size()); } int region_size_log = log2_long((jlong) region_size); // Recalculate the region size to make sure it's a power of // 2. This means that region_size is the largest power of 2 that's // <= what we've calculated so far. ! region_size = size_t(1) << region_size_log; // Now, set up the globals. guarantee(RegionSizeBytesShift == 0, "we should only set it once"); RegionSizeBytesShift = (size_t)region_size_log;
< prev index next >