aoqi@0: /* aoqi@0: * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@1: /* aoqi@1: * This file has been modified by Loongson Technology in 2015. These aoqi@1: * modifications are Copyright (c) 2015 Loongson Technology, and are made aoqi@1: * available on the same license terms set forth above. aoqi@1: */ aoqi@1: aoqi@0: #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLESPACE_HPP aoqi@0: #define SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLESPACE_HPP aoqi@0: aoqi@0: #include "gc_implementation/shared/immutableSpace.hpp" aoqi@0: #include "memory/memRegion.hpp" aoqi@0: #include "utilities/copy.hpp" aoqi@0: aoqi@0: // A MutableSpace is a subtype of ImmutableSpace that supports the aoqi@0: // concept of allocation. This includes the concepts that a space may aoqi@0: // be only partially full, and the querry methods that go with such aoqi@0: // an assumption. MutableSpace is also responsible for minimizing the aoqi@0: // page allocation time by having the memory pretouched (with aoqi@0: // AlwaysPretouch) and for optimizing page placement on NUMA systems aoqi@0: // by make the underlying region interleaved (with UseNUMA). aoqi@0: // aoqi@0: // Invariant: (ImmutableSpace +) bottom() <= top() <= end() aoqi@0: // top() is inclusive and end() is exclusive. aoqi@0: aoqi@0: class MutableSpaceMangler; aoqi@0: aoqi@0: class MutableSpace: public ImmutableSpace { aoqi@0: friend class VMStructs; aoqi@0: aoqi@0: // Helper for mangling unused space in debug builds aoqi@0: MutableSpaceMangler* _mangler; aoqi@0: // The last region which page had been setup to be interleaved. aoqi@0: MemRegion _last_setup_region; aoqi@0: size_t _alignment; aoqi@0: protected: aoqi@0: HeapWord* _top; aoqi@0: aoqi@0: MutableSpaceMangler* mangler() { return _mangler; } aoqi@0: aoqi@0: void numa_setup_pages(MemRegion mr, bool clear_space); aoqi@0: void pretouch_pages(MemRegion mr); aoqi@0: aoqi@0: void set_last_setup_region(MemRegion mr) { _last_setup_region = mr; } aoqi@0: MemRegion last_setup_region() const { return _last_setup_region; } aoqi@0: aoqi@0: public: aoqi@0: virtual ~MutableSpace(); aoqi@0: MutableSpace(size_t page_size); aoqi@0: aoqi@0: // Accessors aoqi@0: HeapWord* top() const { return _top; } aoqi@0: virtual void set_top(HeapWord* value) { _top = value; } aoqi@0: aoqi@0: HeapWord** top_addr() { return &_top; } aoqi@0: HeapWord** end_addr() { return &_end; } aoqi@0: aoqi@0: virtual void set_bottom(HeapWord* value) { _bottom = value; } aoqi@0: virtual void set_end(HeapWord* value) { _end = value; } aoqi@0: aoqi@0: size_t alignment() { return _alignment; } aoqi@0: aoqi@0: // Returns a subregion containing all objects in this space. aoqi@0: MemRegion used_region() { return MemRegion(bottom(), top()); } aoqi@0: aoqi@0: static const bool SetupPages = true; aoqi@0: static const bool DontSetupPages = false; aoqi@0: aoqi@0: // Initialization aoqi@0: virtual void initialize(MemRegion mr, aoqi@0: bool clear_space, aoqi@0: bool mangle_space, aoqi@0: bool setup_pages = SetupPages); aoqi@0: aoqi@0: virtual void clear(bool mangle_space); aoqi@0: // Does the usual initialization but optionally resets top to bottom. aoqi@0: #if 0 // MANGLE_SPACE aoqi@0: void initialize(MemRegion mr, bool clear_space, bool reset_top); aoqi@0: #endif aoqi@0: virtual void update() { } aoqi@0: virtual void accumulate_statistics() { } aoqi@0: aoqi@0: // Methods used in mangling. See descriptions under SpaceMangler. aoqi@0: virtual void mangle_unused_area() PRODUCT_RETURN; aoqi@0: virtual void mangle_unused_area_complete() PRODUCT_RETURN; aoqi@0: virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN; aoqi@0: virtual void check_mangled_unused_area_complete() PRODUCT_RETURN; aoqi@0: virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN; aoqi@0: aoqi@0: // Used to save the space's current top for later use during mangling. aoqi@0: virtual void set_top_for_allocations() PRODUCT_RETURN; aoqi@0: aoqi@0: virtual void ensure_parsability() { } aoqi@0: aoqi@0: virtual void mangle_region(MemRegion mr) PRODUCT_RETURN; aoqi@0: aoqi@0: // Boolean querries. aoqi@0: bool is_empty() const { return used_in_words() == 0; } aoqi@0: bool not_empty() const { return used_in_words() > 0; } aoqi@0: bool contains(const void* p) const { return _bottom <= p && p < _end; } aoqi@0: aoqi@0: // Size computations. Sizes are in bytes. aoqi@0: size_t used_in_bytes() const { return used_in_words() * HeapWordSize; } aoqi@0: size_t free_in_bytes() const { return free_in_words() * HeapWordSize; } aoqi@0: aoqi@0: // Size computations. Sizes are in heapwords. aoqi@0: virtual size_t used_in_words() const { return pointer_delta(top(), bottom()); } aoqi@0: virtual size_t free_in_words() const { return pointer_delta(end(), top()); } aoqi@0: virtual size_t tlab_capacity(Thread* thr) const { return capacity_in_bytes(); } aoqi@0: virtual size_t tlab_used(Thread* thr) const { return used_in_bytes(); } aoqi@0: virtual size_t unsafe_max_tlab_alloc(Thread* thr) const { return free_in_bytes(); } aoqi@0: aoqi@0: // Allocation (return NULL if full) aoqi@0: virtual HeapWord* allocate(size_t word_size); aoqi@0: virtual HeapWord* cas_allocate(size_t word_size); aoqi@1: aoqi@1: // Allocation for Old NUMA (return NULL if full) aoqi@1: virtual HeapWord* cas_allocate_oldnuma(size_t word_size, int node); aoqi@1: aoqi@0: // Optional deallocation. Used in NUMA-allocator. aoqi@0: bool cas_deallocate(HeapWord *obj, size_t size); aoqi@0: aoqi@0: // Iteration. aoqi@0: void oop_iterate(ExtendedOopClosure* cl); aoqi@0: void oop_iterate_no_header(OopClosure* cl); aoqi@0: void object_iterate(ObjectClosure* cl); aoqi@0: aoqi@0: // Debugging aoqi@0: virtual void print() const; aoqi@0: virtual void print_on(outputStream* st) const; aoqi@0: virtual void print_short() const; aoqi@0: virtual void print_short_on(outputStream* st) const; aoqi@0: virtual void verify(); aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLESPACE_HPP