143 lines
5.3 KiB
C++
143 lines
5.3 KiB
C++
/* AppState.cpp */
|
|
|
|
#include "AppState.hpp"
|
|
#include "xo/object/Integer.hpp"
|
|
#include "xo/object/List.hpp"
|
|
|
|
using xo::obj::Integer;
|
|
using xo::obj::List;
|
|
using xo::gp;
|
|
|
|
AppState::AppState()
|
|
{
|
|
this->gc_ = (GC::make
|
|
(
|
|
{.initial_nursery_z_ = 1024*1024,
|
|
.initial_tenured_z_ = 1024*1024*1024,
|
|
.incr_gc_threshold_ = 16*1024,
|
|
.full_gc_threshold_ = 128*1024,
|
|
.stats_flag_ = true,
|
|
.debug_flag_ = false}));
|
|
|
|
Object::mm = gc_.get();
|
|
|
|
for (auto & x: gc_root_v_)
|
|
gc_->add_gc_root(x.ptr_address());
|
|
|
|
gc_->disable_gc();
|
|
}
|
|
|
|
std::size_t
|
|
AppState::nursery_tospace_scale() const {
|
|
std::size_t N1_to_size = gc_->nursery_before_checkpoint();
|
|
std::size_t N_to_committed = gc_->nursery_to_committed();
|
|
std::size_t N_to_incr_gc_threshold = N1_to_size + gc_->config().incr_gc_threshold_;
|
|
std::size_t N_to_scale = std::max(N_to_committed, N_to_incr_gc_threshold);
|
|
|
|
return N_to_scale;
|
|
}
|
|
|
|
std::size_t
|
|
AppState::tenured_tospace_scale() const {
|
|
std::size_t T1_to_size = gc_->tenured_before_checkpoint();
|
|
std::size_t T_to_committed = gc_->tenured_to_committed();
|
|
std::size_t T_to_full_gc_threshold = T1_to_size + gc_->config().full_gc_threshold_;
|
|
std::size_t T_to_scale = std::max(T_to_committed, T_to_full_gc_threshold);
|
|
|
|
return T_to_scale;
|
|
}
|
|
|
|
GcStateDescription
|
|
AppState::snapshot_gc_state() const {
|
|
/** NOTE: this gets invoked before GC gets opportunity to run.
|
|
* in the event that GC does run, from- and to- spaces will
|
|
* have been reversed (near beginning of GC phase)
|
|
*
|
|
* This means that nursery_to_reserved() etc. actually refer to from-space
|
|
* *during gc*
|
|
**/
|
|
|
|
// TOOD: may want to use GC::get_gc_statistics() to replace multiple round trips
|
|
|
|
return GcStateDescription(GcGenerationDescription
|
|
(generation::nursery,
|
|
"nursery",
|
|
"N",
|
|
"incremental",
|
|
gc_->nursery_polarity(),
|
|
this->nursery_tospace_scale(),
|
|
gc_->nursery_before_checkpoint(),
|
|
gc_->nursery_after_checkpoint(),
|
|
gc_->nursery_to_reserved(),
|
|
gc_->nursery_to_committed(),
|
|
gc_->nursery_before_checkpoint() + gc_->config().incr_gc_threshold_),
|
|
GcGenerationDescription
|
|
(generation::tenured,
|
|
"tenured",
|
|
"T",
|
|
"full",
|
|
gc_->tenured_polarity(),
|
|
this->tenured_tospace_scale(),
|
|
gc_->tenured_before_checkpoint(),
|
|
gc_->tenured_after_checkpoint(),
|
|
gc_->tenured_to_reserved(),
|
|
gc_->tenured_to_committed(),
|
|
gc_->tenured_before_checkpoint() + gc_->config().full_gc_threshold_),
|
|
|
|
gc_->size(),
|
|
gc_->committed(),
|
|
gc_->allocated(),
|
|
gc_->available(),
|
|
gc_->mlog_size(),
|
|
gc_->native_gc_statistics().total_promoted_,
|
|
gc_->native_gc_statistics().n_mutation_
|
|
);
|
|
}
|
|
|
|
void
|
|
AppState::generate_random_mutation() {
|
|
if (rng_() % 1000 > (5 * 1000) / 7) {
|
|
/* p=16% integer */
|
|
gc_root_v_[next_root_++] = Integer::make(gc_.get(), next_int_);
|
|
} else if (rng_() % 1000 > (3 * 1000) / 7) {
|
|
/* p=16% cons */
|
|
gp<Object> random_car = gc_root_v_.at(rng_() % gc_root_v_.size());
|
|
if (random_car.is_null())
|
|
random_car = List::nil;
|
|
|
|
/* this will always incorporate existing list as tail of new list */
|
|
gp<List> random_cdr = List::from(gc_root_v_[next_root_]);
|
|
if (random_cdr.is_null())
|
|
random_cdr = List::nil;
|
|
|
|
gp<List> random_cons = List::cons(random_car, random_cdr);
|
|
|
|
gc_root_v_[next_root_++] = random_cons;
|
|
} else if (rng_() % 1000 > (0 * 1000) / 7) {
|
|
/* p=24% mutation */
|
|
gp<List> random_list = List::from(gc_root_v_.at(rng_() % gc_root_v_.size()));
|
|
if (!random_list.is_null()) {
|
|
if (rng_() % 2 == 0) {
|
|
/* pick up some random object, assign as head */
|
|
gp<Object> random_car = gc_root_v_.at(rng_() % gc_root_v_.size());
|
|
random_list->assign_head(random_car);
|
|
} else {
|
|
/* pick up some random object; if List, assign tail as tail */
|
|
gp<List> random_cdr = List::from(gc_root_v_.at(rng_() % gc_root_v_.size()));
|
|
if (!random_cdr.is_null() && !random_cdr->is_nil())
|
|
random_list->assign_rest(random_cdr->rest());
|
|
}
|
|
}
|
|
}
|
|
if (next_root_ >= gc_root_v_.size())
|
|
this->next_root_ = 0;
|
|
}
|
|
|
|
void
|
|
AppState::generate_random_mutations() {
|
|
for (int i = 0; i < this->alloc_per_cycle_; ++i) {
|
|
this->generate_random_mutation();
|
|
}
|
|
}
|
|
|
|
/* end AppState.cpp */
|