Skip to content

Commit

Permalink
8326065: Merge Space into ContiguousSpace
Browse files Browse the repository at this point in the history
Reviewed-by: cjplummer, sjohanss
  • Loading branch information
albertnetymk committed Feb 23, 2024
1 parent 11fdca0 commit ef2d5c4
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 351 deletions.
16 changes: 6 additions & 10 deletions src/hotspot/share/gc/shared/space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"

ContiguousSpace::ContiguousSpace(): Space(),
ContiguousSpace::ContiguousSpace():
_bottom(nullptr),
_end(nullptr),
_next_compaction_space(nullptr),
_top(nullptr) {
_mangler = new GenSpaceMangler(this);
Expand Down Expand Up @@ -101,20 +103,14 @@ void ContiguousSpace::mangle_unused_area_complete() {
#endif // NOT_PRODUCT


void Space::print_short() const { print_short_on(tty); }
void ContiguousSpace::print_short() const { print_short_on(tty); }

void Space::print_short_on(outputStream* st) const {
void ContiguousSpace::print_short_on(outputStream* st) const {
st->print(" space " SIZE_FORMAT "K, %3d%% used", capacity() / K,
(int) ((double) used() * 100 / capacity()));
}

void Space::print() const { print_on(tty); }

void Space::print_on(outputStream* st) const {
print_short_on(st);
st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(bottom()), p2i(end()));
}
void ContiguousSpace::print() const { print_on(tty); }

void ContiguousSpace::print_on(outputStream* st) const {
print_short_on(st);
Expand Down
124 changes: 41 additions & 83 deletions src/hotspot/share/gc/shared/space.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,45 @@
// for iterating over objects and free blocks, etc.

// Forward decls.
class Space;
class ContiguousSpace;
class Generation;
class ContiguousSpace;
class CardTableRS;
class DirtyCardToOopClosure;
class GenSpaceMangler;

// A Space describes a heap area. Class Space is an abstract
// base class.
//
// Space supports allocation, size computation and GC support is provided.
// A space in which the free area is contiguous. It therefore supports
// faster allocation, and compaction.
//
// Invariant: bottom() and end() are on page_size boundaries and
// bottom() <= top() <= end()
// top() is inclusive and end() is exclusive.

class Space: public CHeapObj<mtGC> {
class ContiguousSpace: public CHeapObj<mtGC> {
friend class VMStructs;
protected:

private:
HeapWord* _bottom;
HeapWord* _end;

// Used in support of save_marks()
HeapWord* _saved_mark_word;

Space():
_bottom(nullptr), _end(nullptr) { }
ContiguousSpace* _next_compaction_space;

HeapWord* _top;
// A helper for mangling the unused area of the space in debug builds.
GenSpaceMangler* _mangler;

GenSpaceMangler* mangler() { return _mangler; }

// Allocation helpers (return null if full).
inline HeapWord* allocate_impl(size_t word_size);
inline HeapWord* par_allocate_impl(size_t word_size);

public:
ContiguousSpace();
~ContiguousSpace();

public:
// Accessors
HeapWord* bottom() const { return _bottom; }
HeapWord* end() const { return _end; }
Expand All @@ -82,10 +92,6 @@ class Space: public CHeapObj<mtGC> {

HeapWord* saved_mark_word() const { return _saved_mark_word; }

// Returns a subregion of the space containing only the allocated objects in
// the space.
virtual MemRegion used_region() const = 0;

// Returns a region that is guaranteed to contain (at least) all objects
// allocated at the time of the last call to "save_marks". If the space
// initializes its DirtyCardToOopClosure's specifying the "contig" option
Expand All @@ -98,13 +104,6 @@ class Space: public CHeapObj<mtGC> {
return MemRegion(bottom(), saved_mark_word());
}

// For detecting GC bugs. Should only be called at GC boundaries, since
// some unused space may be used as scratch space during GC's.
// We also call this when expanding a space to satisfy an allocation
// request. See bug #4668531
virtual void mangle_unused_area() = 0;
virtual void mangle_unused_area_complete() = 0;

// Testers
bool is_empty() const { return used() == 0; }

Expand All @@ -123,53 +122,14 @@ class Space: public CHeapObj<mtGC> {
bool is_in_reserved(const void* p) const { return _bottom <= p && p < _end; }

// Size computations. Sizes are in bytes.
size_t capacity() const { return byte_size(bottom(), end()); }
virtual size_t used() const = 0;
virtual size_t free() const = 0;

// If "p" is in the space, returns the address of the start of the
// "block" that contains "p". We say "block" instead of "object" since
// some heaps may not pack objects densely; a chunk may either be an
// object or a non-object. If "p" is not in the space, return null.
virtual HeapWord* block_start_const(const void* p) const = 0;

// Allocation (return null if full). Assumes the caller has established
// mutually exclusive access to the space.
virtual HeapWord* allocate(size_t word_size) = 0;

// Allocation (return null if full). Enforces mutual exclusion internally.
virtual HeapWord* par_allocate(size_t word_size) = 0;
size_t capacity() const { return byte_size(bottom(), end()); }
size_t used() const { return byte_size(bottom(), top()); }
size_t free() const { return byte_size(top(), end()); }

void print() const;
virtual void print_on(outputStream* st) const;
void print_short() const;
void print_short_on(outputStream* st) const;
};

class GenSpaceMangler;

// A space in which the free area is contiguous. It therefore supports
// faster allocation, and compaction.
class ContiguousSpace: public Space {
friend class VMStructs;

private:
ContiguousSpace* _next_compaction_space;

protected:
HeapWord* _top;
// A helper for mangling the unused area of the space in debug builds.
GenSpaceMangler* _mangler;

GenSpaceMangler* mangler() { return _mangler; }

// Allocation helpers (return null if full).
inline HeapWord* allocate_impl(size_t word_size);
inline HeapWord* par_allocate_impl(size_t word_size);

public:
ContiguousSpace();
~ContiguousSpace();

// Initialization.
// "initialize" should be called once on a space, before it is used for
Expand Down Expand Up @@ -206,37 +166,34 @@ class ContiguousSpace: public Space {

bool saved_mark_at_top() const { return saved_mark_word() == top(); }

// In debug mode mangle (write it with a particular bit
// pattern) the unused part of a space.

// Used to save the address in a space for later use during mangling.
void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN;
// Used to save the space's current top for later use during mangling.
void set_top_for_allocations() PRODUCT_RETURN;

// For detecting GC bugs. Should only be called at GC boundaries, since
// some unused space may be used as scratch space during GC's.
// We also call this when expanding a space to satisfy an allocation
// request. See bug #4668531
// Mangle regions in the space from the current top up to the
// previously mangled part of the space.
void mangle_unused_area() override PRODUCT_RETURN;
void mangle_unused_area() PRODUCT_RETURN;
// Mangle [top, end)
void mangle_unused_area_complete() override PRODUCT_RETURN;
void mangle_unused_area_complete() PRODUCT_RETURN;

// Do some sparse checking on the area that should have been mangled.
void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
// Check the complete area that should have been mangled.
// This code may be null depending on the macro DEBUG_MANGLING.
void check_mangled_unused_area_complete() PRODUCT_RETURN;

// Size computations: sizes in bytes.
size_t used() const override { return byte_size(bottom(), top()); }
size_t free() const override { return byte_size(top(), end()); }

// In a contiguous space we have a more obvious bound on what parts
// contain objects.
MemRegion used_region() const override { return MemRegion(bottom(), top()); }
MemRegion used_region() const { return MemRegion(bottom(), top()); }

// Allocation (return null if full)
HeapWord* allocate(size_t word_size) override;
HeapWord* par_allocate(size_t word_size) override;
// Allocation (return null if full). Assumes the caller has established
// mutually exclusive access to the space.
virtual HeapWord* allocate(size_t word_size);
// Allocation (return null if full). Enforces mutual exclusion internally.
virtual HeapWord* par_allocate(size_t word_size);

// Iteration
void object_iterate(ObjectClosure* blk);
Expand All @@ -251,14 +208,15 @@ class ContiguousSpace: public Space {
template <typename OopClosureType>
void oop_since_save_marks_iterate(OopClosureType* blk);

// Very inefficient implementation.
HeapWord* block_start_const(const void* p) const override;
// If "p" is in the space, returns the address of the start of the
// "block" that contains "p". We say "block" instead of "object" since
// some heaps may not pack objects densely; a chunk may either be an
// object or a non-object. If "p" is not in the space, return null.
virtual HeapWord* block_start_const(const void* p) const;

// Addresses for inlined allocation
HeapWord** top_addr() { return &_top; }

void print_on(outputStream* st) const override;

// Debugging
void verify() const;
};
Expand Down
11 changes: 4 additions & 7 deletions src/hotspot/share/gc/shared/vmStructs_gc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,13 @@
nonstatic_field(CollectedHeap, _is_gc_active, bool) \
nonstatic_field(CollectedHeap, _total_collections, unsigned int) \
\
nonstatic_field(ContiguousSpace, _bottom, HeapWord*) \
nonstatic_field(ContiguousSpace, _end, HeapWord*) \
nonstatic_field(ContiguousSpace, _top, HeapWord*) \
nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \
\
nonstatic_field(MemRegion, _start, HeapWord*) \
nonstatic_field(MemRegion, _word_size, size_t) \
\
nonstatic_field(Space, _bottom, HeapWord*) \
nonstatic_field(Space, _end, HeapWord*)
nonstatic_field(MemRegion, _word_size, size_t)

#define VM_TYPES_GC(declare_type, \
declare_toplevel_type, \
Expand Down Expand Up @@ -135,8 +134,7 @@
/******************************************/ \
\
declare_toplevel_type(CollectedHeap) \
declare_toplevel_type(Space) \
declare_type(ContiguousSpace, Space) \
declare_toplevel_type(ContiguousSpace) \
declare_toplevel_type(BarrierSet) \
declare_type(ModRefBarrierSet, BarrierSet) \
declare_type(CardTableBarrierSet, ModRefBarrierSet) \
Expand Down Expand Up @@ -164,7 +162,6 @@
declare_toplevel_type(HeapWord*) \
declare_toplevel_type(HeapWord* volatile) \
declare_toplevel_type(MemRegion*) \
declare_toplevel_type(Space*) \
declare_toplevel_type(ThreadLocalAllocBuffer*) \
\
declare_toplevel_type(BarrierSet::FakeRtti)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ public CollectedHeapName kind() {
private static AddressField youngGenField;
private static AddressField oldGenField;

private static GenerationFactory genFactory;

static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
Expand All @@ -61,8 +59,6 @@ private static synchronized void initialize(TypeDataBase db) {

youngGenField = type.getAddressField("_young_gen");
oldGenField = type.getAddressField("_old_gen");

genFactory = new GenerationFactory();
}

public DefNewGeneration youngGen() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@
import sun.jvm.hotspot.utilities.Observable;
import sun.jvm.hotspot.utilities.Observer;

public class ContiguousSpace extends Space implements LiveRegionsProvider {
/** <P> A ContiguousSpace describes a heap area. </P>
<P> Invariant: bottom() and end() are on page_size boundaries and: </P>
<P> bottom() <= top() <= end() </P>
<P> top() is inclusive and end() is exclusive. </P> */

public class ContiguousSpace extends VMObject implements LiveRegionsProvider {
private static AddressField bottomField;
private static AddressField endField;
private static AddressField topField;

static {
Expand All @@ -48,31 +58,39 @@ public void update(Observable o, Object data) {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("ContiguousSpace");

bottomField = type.getAddressField("_bottom");
endField = type.getAddressField("_end");
topField = type.getAddressField("_top");
}

public ContiguousSpace(Address addr) {
super(addr);
}

public Address top() {
return topField.getValue(addr);
}
public Address bottom() { return bottomField.getValue(addr); }
public Address end() { return endField.getValue(addr); }
public Address top() { return topField.getValue(addr); }

/** In bytes */
public long capacity() {
return end().minus(bottom());
/** Support for iteration over heap -- not sure how this will
interact with GC in reflective system, but necessary for the
debugging mechanism */
public OopHandle bottomAsOopHandle() {
return bottomField.getOopHandle(addr);
}

/** In bytes */
public long used() {
return top().minus(bottom());
/** Support for iteration over heap -- not sure how this will
interact with GC in reflective system, but necessary for the
debugging mechanism */
public OopHandle nextOopHandle(OopHandle handle, long size) {
return handle.addOffsetToAsOopHandle(size);
}

/** In bytes */
public long free() {
return end().minus(top());
}
/** Returned value is in bytes */
public long capacity() { return end().minus(bottom()); }
public long used() { return top().minus(bottom()); }
public long free() { return end().minus(top()); }

public void print() { printOn(System.out); }

/** In a contiguous space we have a more obvious bound on what parts
contain objects. */
Expand All @@ -95,6 +113,10 @@ public boolean contains(Address p) {
public void printOn(PrintStream tty) {
tty.print(" [" + bottom() + "," +
top() + "," + end() + ")");
super.printOn(tty);
tty.print(" space capacity = ");
tty.print(capacity());
tty.print(", ");
tty.print((double) used() * 100.0/ capacity());
tty.print(" used");
}
}
Loading

1 comment on commit ef2d5c4

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.