7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26
27 #include "gc/shared/gcTimer.hpp"
28 #include "gc/shared/gcTraceTime.inline.hpp"
29 #include "gc/shared/parallelCleaning.hpp"
30
31 #include "gc/shenandoah/brooksPointer.hpp"
32 #include "gc/shenandoah/shenandoahAllocTracker.hpp"
33 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
34 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
35 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
36 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
37 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
38 #include "gc/shenandoah/shenandoahControlThread.hpp"
39 #include "gc/shenandoah/shenandoahFreeSet.hpp"
40 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
41 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
42 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
43 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
44 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
45 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
46 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
783
784 if (in_new_region) {
785 control_thread()->notify_heap_changed();
786 }
787
788 log_develop_trace(gc, alloc)("allocate memory chunk of size "SIZE_FORMAT" at addr "PTR_FORMAT " by thread %d ",
789 word_size, p2i(result), Thread::current()->osthread()->thread_id());
790
791 if (result != NULL) {
792 notify_alloc(word_size, false);
793 }
794
795 return result;
796 }
797
798 HeapWord* ShenandoahHeap::allocate_memory_under_lock(size_t word_size, AllocType type, bool& in_new_region) {
799 ShenandoahHeapLocker locker(lock());
800 return _free_set->allocate(word_size, type, in_new_region);
801 }
802
803 HeapWord* ShenandoahHeap::mem_allocate(size_t size,
804 bool* gc_overhead_limit_was_exceeded) {
805 HeapWord* filler = allocate_memory(size + BrooksPointer::word_size(), _alloc_shared);
806 HeapWord* result = filler + BrooksPointer::word_size();
807 if (filler != NULL) {
808 BrooksPointer::initialize(oop(result));
809
810 assert(! in_collection_set(result), "never allocate in targetted region");
811 return result;
812 } else {
813 return NULL;
814 }
815 }
816
817 class ShenandoahEvacuateUpdateRootsClosure: public ExtendedOopClosure {
818 private:
819 ShenandoahHeap* _heap;
820 Thread* _thread;
821 public:
822 ShenandoahEvacuateUpdateRootsClosure() :
823 _heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
824 }
825
826 private:
827 template <class T>
828 void do_oop_work(T* p) {
829 assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
830
831 T o = RawAccess<>::oop_load(p);
832 if (! CompressedOops::is_null(o)) {
833 oop obj = CompressedOops::decode_not_null(o);
834 if (_heap->in_collection_set(obj)) {
1843
1844 void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
1845 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should really be Shenandoah safepoint");
1846 _gc_state.set_cond(mask, value);
1847 set_gc_state_all_threads(_gc_state.raw_value());
1848 }
1849
1850 void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
1851 set_gc_state_mask(MARKING, in_progress);
1852 ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
1853 }
1854
1855 void ShenandoahHeap::set_concurrent_traversal_in_progress(bool in_progress) {
1856 set_gc_state_mask(TRAVERSAL | HAS_FORWARDED, in_progress);
1857 ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
1858 }
1859
1860 void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
1861 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
1862 set_gc_state_mask(EVACUATION, in_progress);
1863 }
1864
1865 HeapWord* ShenandoahHeap::tlab_post_allocation_setup(HeapWord* obj) {
1866 // Initialize Brooks pointer for the next object
1867 HeapWord* result = obj + BrooksPointer::word_size();
1868 BrooksPointer::initialize(oop(result));
1869 return result;
1870 }
1871
1872 uint ShenandoahHeap::oop_extra_words() {
1873 return BrooksPointer::word_size();
1874 }
1875
1876 ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
1877 _heap(ShenandoahHeap::heap_no_check()) {
1878 }
1879
1880 ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :
1881 _heap(ShenandoahHeap::heap_no_check()) {
1882 }
1883
1884 bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {
1885 if (CompressedOops::is_null(obj)) {
1886 return false;
1887 }
1888 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
1889 shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_mark_in_progress() || _heap->is_concurrent_traversal_in_progress())
|
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "memory/allocation.hpp"
26
27 #include "gc/shared/collectedHeap.inline.hpp"
28 #include "gc/shared/gcTimer.hpp"
29 #include "gc/shared/gcTraceTime.inline.hpp"
30 #include "gc/shared/parallelCleaning.hpp"
31
32 #include "gc/shenandoah/brooksPointer.hpp"
33 #include "gc/shenandoah/shenandoahAllocTracker.hpp"
34 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
35 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
36 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
37 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
38 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
39 #include "gc/shenandoah/shenandoahControlThread.hpp"
40 #include "gc/shenandoah/shenandoahFreeSet.hpp"
41 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
42 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
43 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
44 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
45 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
46 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
47 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
784
785 if (in_new_region) {
786 control_thread()->notify_heap_changed();
787 }
788
789 log_develop_trace(gc, alloc)("allocate memory chunk of size "SIZE_FORMAT" at addr "PTR_FORMAT " by thread %d ",
790 word_size, p2i(result), Thread::current()->osthread()->thread_id());
791
792 if (result != NULL) {
793 notify_alloc(word_size, false);
794 }
795
796 return result;
797 }
798
799 HeapWord* ShenandoahHeap::allocate_memory_under_lock(size_t word_size, AllocType type, bool& in_new_region) {
800 ShenandoahHeapLocker locker(lock());
801 return _free_set->allocate(word_size, type, in_new_region);
802 }
803
804 HeapWord* ShenandoahHeap::mem_allocate(size_t size, Klass* klass, Thread* thread,
805 bool* gc_overhead_limit_was_exceeded) {
806
807 size += BrooksPointer::word_size();
808 HeapWord* obj = allocate_from_tlab(klass, thread, size);
809 if (obj == NULL) {
810 obj = allocate_memory(size, _alloc_shared);
811 }
812
813 if (obj != NULL) {
814 obj = obj + BrooksPointer::word_size();
815 BrooksPointer::initialize(oop(obj));
816 assert(! in_collection_set(obj), "never allocate in targetted region");
817 }
818 return obj;
819 }
820
821 void ShenandoahHeap::fill_with_object_impl(HeapWord* start, size_t words, bool zap) {
822 if (words > 0) {
823 start += BrooksPointer::word_size();
824 words -= BrooksPointer::word_size();
825 }
826 CollectedHeap::fill_with_object_impl(start, words, zap);
827 BrooksPointer::initialize(oop(start));
828 }
829
830 class ShenandoahEvacuateUpdateRootsClosure: public ExtendedOopClosure {
831 private:
832 ShenandoahHeap* _heap;
833 Thread* _thread;
834 public:
835 ShenandoahEvacuateUpdateRootsClosure() :
836 _heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
837 }
838
839 private:
840 template <class T>
841 void do_oop_work(T* p) {
842 assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
843
844 T o = RawAccess<>::oop_load(p);
845 if (! CompressedOops::is_null(o)) {
846 oop obj = CompressedOops::decode_not_null(o);
847 if (_heap->in_collection_set(obj)) {
1856
1857 void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
1858 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should really be Shenandoah safepoint");
1859 _gc_state.set_cond(mask, value);
1860 set_gc_state_all_threads(_gc_state.raw_value());
1861 }
1862
1863 void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
1864 set_gc_state_mask(MARKING, in_progress);
1865 ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
1866 }
1867
1868 void ShenandoahHeap::set_concurrent_traversal_in_progress(bool in_progress) {
1869 set_gc_state_mask(TRAVERSAL | HAS_FORWARDED, in_progress);
1870 ShenandoahBarrierSet::satb_mark_queue_set().set_active_all_threads(in_progress, !in_progress);
1871 }
1872
1873 void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) {
1874 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint");
1875 set_gc_state_mask(EVACUATION, in_progress);
1876 }
1877
1878 uint ShenandoahHeap::oop_extra_words() {
1879 return BrooksPointer::word_size();
1880 }
1881
1882 ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
1883 _heap(ShenandoahHeap::heap_no_check()) {
1884 }
1885
1886 ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :
1887 _heap(ShenandoahHeap::heap_no_check()) {
1888 }
1889
1890 bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {
1891 if (CompressedOops::is_null(obj)) {
1892 return false;
1893 }
1894 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
1895 shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_mark_in_progress() || _heap->is_concurrent_traversal_in_progress())
|