xo-allod: + per-type stats + pretty printing
This commit is contained in:
parent
227b2e5cf7
commit
593dc064f9
16 changed files with 379 additions and 191 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "IAlloc.hpp"
|
||||
#include "ObjectStatistics.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
|
|
@ -48,6 +49,9 @@ namespace xo {
|
|||
std::byte * free_ptr() const { return free_ptr_; }
|
||||
void set_free_ptr(std::byte * x);
|
||||
|
||||
void capture_object_statistics(capture_phase phase,
|
||||
ObjectStatistics * p_dest) const;
|
||||
|
||||
// inherited from IAlloc...
|
||||
|
||||
virtual const std::string & name() const final override { return name_; }
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace xo {
|
|||
|
||||
// inherited from Object..
|
||||
virtual TaggedPtr self_tp() const final override;
|
||||
virtual void display(std::ostream & os) const final override;
|
||||
virtual bool _is_forwarded() const final override { return true; }
|
||||
virtual Object * _offset_destination(Object * src) const final override;
|
||||
virtual Object * _destination() final override;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ namespace xo {
|
|||
std::size_t initial_tenured_z_ = 0;
|
||||
/** true to permit incremental garbage collection **/
|
||||
bool allow_incremental_gc_ = true;
|
||||
/** true to report statistics **/
|
||||
bool stats_flag_ = false;
|
||||
/** true to enable debug logging **/
|
||||
bool debug_flag_ = false;
|
||||
};
|
||||
|
|
@ -207,6 +209,8 @@ namespace xo {
|
|||
void swap_mutation_log();
|
||||
/** swap roles of FromSpace/ToSpace **/
|
||||
void swap_spaces(generation g);
|
||||
/** scan to-space for object statistics before GC */
|
||||
void capture_object_statistics(generation upto, capture_phase phase);
|
||||
/** copy object **/
|
||||
void copy_object(Object ** addr, generation upto, ObjectStatistics * object_stats);
|
||||
/** copy everything reachable from global gc roots **/
|
||||
|
|
@ -273,6 +277,10 @@ namespace xo {
|
|||
|
||||
/** allocation/collection counters **/
|
||||
GcStatistics gc_statistics_;
|
||||
/** optional per-object-type counters. snapshot at beginning of collection cycle **/
|
||||
std::array<ObjectStatistics, gen2int(generation::N)> object_statistics_sab_;
|
||||
/** optional per-object-type counters. snapshot at end of collection cycle **/
|
||||
std::array<ObjectStatistics, gen2int(generation::N)> object_statistics_sae_;
|
||||
|
||||
/** trigger full GC whenever this much data arrives in tenured generation **/
|
||||
std::size_t full_gc_threshold_ = 0;
|
||||
|
|
|
|||
|
|
@ -6,20 +6,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "generation.hpp"
|
||||
#include "xo/reflect/TypeDescr.hpp"
|
||||
#include "xo/indentlog/print/pretty.hpp"
|
||||
#include <ostream>
|
||||
#include <array>
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
/** @class ObjectStatistics
|
||||
* @brief placeholder for type-driven allocation statistics
|
||||
*
|
||||
* Passed to @ref Object::deep_move for example
|
||||
**/
|
||||
class ObjectStatistics {
|
||||
};
|
||||
|
||||
/** @class PerGenerationStatistics
|
||||
* @brief garbage collection statistics for particular GC generation
|
||||
**/
|
||||
|
|
@ -103,9 +96,6 @@ namespace xo {
|
|||
* (N0 -> N1 when reported; cumulative across GCs)
|
||||
**/
|
||||
std::size_t n_xckp_mutation_ = 0;
|
||||
|
||||
/** per-type statistics (placeholder) **/
|
||||
ObjectStatistics per_type_stats_;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream & os, const GcStatistics & x) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "IAlloc.hpp"
|
||||
#include "ObjectStatistics.hpp"
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
|
@ -43,6 +44,14 @@ namespace xo {
|
|||
/** current free pointer **/
|
||||
std::byte * free_ptr() const;
|
||||
|
||||
/** scan space (must not contain forwarding pointers, because loses size info)
|
||||
* + gather stats by object type
|
||||
*
|
||||
* See @ref Object::self_tp
|
||||
**/
|
||||
void capture_object_statistics(capture_phase phase,
|
||||
ObjectStatistics * p_dest) const;
|
||||
|
||||
// inherited from IAlloc..
|
||||
|
||||
virtual const std::string & name() const final override;
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ namespace xo {
|
|||
**/
|
||||
virtual TaggedPtr self_tp() const = 0;
|
||||
|
||||
/** print on stream @p os **/
|
||||
virtual void display(std::ostream & os) const = 0;
|
||||
|
||||
// GC support
|
||||
|
||||
/** true iff this object represents a forwarding pointer.
|
||||
|
|
@ -244,6 +247,9 @@ namespace xo {
|
|||
rhs.ptr());
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<< (std::ostream & os, gp<Object> x);
|
||||
|
||||
/** @class Cpof
|
||||
* @brief argument to operator new used for garbage collector evacuation phase
|
||||
*
|
||||
|
|
|
|||
86
include/xo/alloc/ObjectStatistics.hpp
Normal file
86
include/xo/alloc/ObjectStatistics.hpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* file ObjectStatistics.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Aug 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xo/indentlog/print/pretty.hpp"
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
namespace reflect { class TypeDescrBase; }
|
||||
|
||||
namespace gc {
|
||||
enum class capture_phase {
|
||||
/** snapshot-at-beginning **/
|
||||
sab,
|
||||
/** snapshot-at-end **/
|
||||
sae,
|
||||
};
|
||||
|
||||
/** @class PerObjectTypeStatistics
|
||||
* @brief statistics for a particular object type
|
||||
*
|
||||
* Gathered for each leaf type descended from xo::obj::Object.
|
||||
* See @ref xo::obj::Object::self_tp
|
||||
*
|
||||
* See @ref GC::capture_object_statistics
|
||||
* (gathers @ref scanned_n_, @ref scanned_z_)
|
||||
**/
|
||||
struct PerObjectTypeStatistics {
|
||||
using TypeDescr = xo::reflect::TypeDescrBase const *;
|
||||
|
||||
void display(std::ostream & os) const;
|
||||
|
||||
/** stats here are for objects of this type **/
|
||||
TypeDescr td_ = nullptr;
|
||||
/** number of objects scanned **/
|
||||
std::size_t scanned_n_ = 0;
|
||||
/** number of bytes scanned **/
|
||||
std::size_t scanned_z_ = 0;
|
||||
/** number of objects surviving **/
|
||||
std::size_t survive_n_ = 0;
|
||||
/** number of bytes from surviving objects **/
|
||||
std::size_t survive_z_ = 0;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream & os, const PerObjectTypeStatistics & x) {
|
||||
x.display(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
/** @class ObjectStatistics
|
||||
* @brief placeholder for type-driven allocation statistics
|
||||
*
|
||||
* Passed to @ref Object::deep_move for example
|
||||
**/
|
||||
struct ObjectStatistics {
|
||||
void display(std::ostream & os) const;
|
||||
|
||||
/** per-object-type statistics, indexed by TypeId **/
|
||||
std::vector<PerObjectTypeStatistics> per_type_stats_v_;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream & os, const ObjectStatistics & x) {
|
||||
x.display(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} /*namespace gc*/
|
||||
|
||||
namespace print {
|
||||
template <>
|
||||
struct ppdetail<xo::gc::PerObjectTypeStatistics> {
|
||||
static bool print_pretty(const ppindentinfo &, const xo::gc::PerObjectTypeStatistics &);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ppdetail<xo::gc::ObjectStatistics> {
|
||||
static bool print_pretty(const ppindentinfo &, const xo::gc::ObjectStatistics &);
|
||||
};
|
||||
} /*namespace print*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end ObjectStatistics.hpp */
|
||||
Loading…
Add table
Add a link
Reference in a new issue