Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8326065: Merge Space into ContiguousSpace #17891

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions src/hotspot/share/gc/shared/space.cpp
Original file line number Diff line number Diff line change
@@ -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);
@@ -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);
124 changes: 41 additions & 83 deletions src/hotspot/share/gc/shared/space.hpp
Original file line number Diff line number Diff line change
@@ -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; }
@@ -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
@@ -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; }

@@ -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
@@ -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);
@@ -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;
};
11 changes: 4 additions & 7 deletions src/hotspot/share/gc/shared/vmStructs_gc.hpp
Original file line number Diff line number Diff line change
@@ -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, \
@@ -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) \
@@ -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)
Original file line number Diff line number Diff line change
@@ -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) {
@@ -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() {
Original file line number Diff line number Diff line change
@@ -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 {
@@ -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. */
@@ -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");
}
}

This file was deleted.

This file was deleted.

This file was deleted.