xo-alloc: mutation log tracking in working state + unit test
This commit is contained in:
parent
e1d5ae46d2
commit
5d2fcf6498
25 changed files with 735 additions and 185 deletions
|
|
@ -1,37 +0,0 @@
|
|||
/* @file BooleanObj.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Aug 2025
|
||||
*/
|
||||
|
||||
#include "xo/alloc/Object.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace obj {
|
||||
/** @class BooleanObj
|
||||
* @brief Boxed wrapper for a boolean value
|
||||
**/
|
||||
class BooleanObj : public Object {
|
||||
public:
|
||||
/** @return instance representing boolean with truth-value @p x **/
|
||||
static gp<BooleanObj> boolean_obj(bool x);
|
||||
static gp<BooleanObj> true_obj();
|
||||
static gp<BooleanObj> false_obj();
|
||||
|
||||
bool value() const { return value_; }
|
||||
|
||||
// inherited from Object..
|
||||
|
||||
virtual std::size_t _shallow_size() const override;
|
||||
virtual Object * _shallow_copy() const override;
|
||||
virtual std::size_t _forward_children() override;
|
||||
|
||||
private:
|
||||
explicit BooleanObj(bool x) : value_{x} {}
|
||||
|
||||
private:
|
||||
bool value_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* end BooleanObj.hpp */
|
||||
|
|
@ -15,7 +15,12 @@ namespace xo {
|
|||
Integer() = default;
|
||||
explicit Integer(int_type x);
|
||||
|
||||
/** create instance holding integer value @p x **/
|
||||
static gp<Integer> make(int_type x);
|
||||
/** downcast from @p x iff x is actually an Integer. Otherwise nullptr **/
|
||||
static gp<Integer> from(gp<Object> x);
|
||||
|
||||
int_type value() const { return value_; }
|
||||
|
||||
// inherited from Object..
|
||||
virtual std::size_t _shallow_size() const override;
|
||||
|
|
|
|||
|
|
@ -18,14 +18,36 @@ namespace xo {
|
|||
/** @return list with first element @p car, and tail @p cdr **/
|
||||
static gp<List> cons(gp<Object> car, gp<List> cdr);
|
||||
|
||||
/** @return list with single element @p x1 **/
|
||||
template <typename T>
|
||||
static gp<List> list(T && x1) {
|
||||
return List::cons(x1, nil);
|
||||
}
|
||||
|
||||
/** @return list with elements @p x1, ..., @p rest in argument order **/
|
||||
template <typename T, typename... Rest>
|
||||
static gp<List> list(T && x1, Rest &&... rest) {
|
||||
return List::cons(x1, list(rest...));
|
||||
}
|
||||
|
||||
/** @return true iff list is empty **/
|
||||
bool is_nil() const { return this == nil.ptr(); }
|
||||
|
||||
gp<Object> head() const { return head_; }
|
||||
gp<List> tail() const { return tail_; }
|
||||
gp<List> rest() const { return rest_; }
|
||||
|
||||
/** @return first element in list; synonym for @ref head **/
|
||||
gp<Object> car() const { return head_; }
|
||||
/** @return remainder of list after first element; synonym for @ref rest **/
|
||||
gp<Object> cdr() const { return rest_; }
|
||||
|
||||
/** @return number of top-level elements in this list **/
|
||||
std::size_t size() const;
|
||||
gp<Object> list_ref(std::size_t i) const;
|
||||
|
||||
void assign_head(gp<Object> head);
|
||||
void assign_rest(gp<List> rest);
|
||||
|
||||
// inherited from Object..
|
||||
|
||||
virtual std::size_t _shallow_size() const override;
|
||||
|
|
@ -33,11 +55,11 @@ namespace xo {
|
|||
virtual std::size_t _forward_children() override;
|
||||
|
||||
private:
|
||||
List(gp<Object> head, gp<List> tail);
|
||||
List(gp<Object> head, gp<List> rest);
|
||||
|
||||
private:
|
||||
gp<Object> head_;
|
||||
gp<List> tail_;
|
||||
gp<List> rest_;
|
||||
};
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace xo {
|
|||
public:
|
||||
enum Owner { unique, shared };
|
||||
|
||||
/** donwcase from @p x iff x is actually a String. Otherwise nullptr **/
|
||||
/** donwcast from @p x iff x is actually a String. Otherwise nullptr **/
|
||||
static gp<String> from(gp<Object> x);
|
||||
|
||||
/** create copy of string @p s, using allocator @ref Object::mm **/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ namespace xo {
|
|||
return new (MMPtr(mm)) Integer(x);
|
||||
}
|
||||
|
||||
gp<Integer>
|
||||
Integer::from(gp<Object> x) {
|
||||
return dynamic_cast<Integer*>(x.ptr());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Integer::_shallow_size() const {
|
||||
return sizeof(Integer);
|
||||
|
|
@ -23,7 +28,6 @@ namespace xo {
|
|||
Object *
|
||||
Integer::_shallow_copy() const {
|
||||
Cpof cpof(this);
|
||||
|
||||
return new (cpof) Integer(*this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
**/
|
||||
|
||||
#include "List.hpp"
|
||||
#include "xo/indentlog/scope.hpp"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
namespace xo {
|
||||
namespace obj {
|
||||
List::List(gp<Object> head, gp<List> tail)
|
||||
: head_{head}, tail_{tail} {}
|
||||
List::List(gp<Object> head, gp<List> rest)
|
||||
: head_{head}, rest_{rest} {}
|
||||
|
||||
gp<List>
|
||||
List::nil = new List(nullptr, nullptr);
|
||||
|
|
@ -27,7 +28,7 @@ namespace xo {
|
|||
gp<const List> l(this);
|
||||
while (!l->is_nil()) {
|
||||
++retval;
|
||||
l = l->tail();
|
||||
l = l->rest();
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -40,7 +41,7 @@ namespace xo {
|
|||
while (i > 0) {
|
||||
assert(!(rem->is_nil()));
|
||||
|
||||
rem = rem->tail();
|
||||
rem = rem->rest();
|
||||
--i;
|
||||
}
|
||||
|
||||
|
|
@ -48,6 +49,18 @@ namespace xo {
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
List::assign_head(gp<Object> head)
|
||||
{
|
||||
Object::assign_member(this, &(this->head_), head);
|
||||
}
|
||||
|
||||
void
|
||||
List::assign_rest(gp<List> tail)
|
||||
{
|
||||
Object::assign_member(this, &(this->rest_), tail);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
List::_shallow_size() const {
|
||||
return sizeof(List);
|
||||
|
|
@ -55,6 +68,8 @@ namespace xo {
|
|||
|
||||
Object *
|
||||
List::_shallow_copy() const {
|
||||
scope log(XO_DEBUG(Object::mm->debug_flag()));
|
||||
|
||||
assert(!(this->is_nil()));
|
||||
|
||||
Cpof cpof(this);
|
||||
|
|
@ -65,7 +80,7 @@ namespace xo {
|
|||
std::size_t
|
||||
List::_forward_children() {
|
||||
Object::_forward_inplace(head_);
|
||||
Object::_forward_inplace(tail_);
|
||||
Object::_forward_inplace(rest_);
|
||||
return List::_shallow_size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,14 +31,12 @@ namespace xo {
|
|||
}
|
||||
|
||||
gp<String>
|
||||
String::from(gp<Object> x)
|
||||
{
|
||||
String::from(gp<Object> x) {
|
||||
return dynamic_cast<String*>(x.ptr());
|
||||
}
|
||||
|
||||
gp<String>
|
||||
String::copy(const char * s)
|
||||
{
|
||||
String::copy(const char * s) {
|
||||
return copy(Object::mm, s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ set(SELF_EXE utest.object)
|
|||
set(SELF_SRCS
|
||||
object_utest_main.cpp
|
||||
String.test.cpp
|
||||
List.test.cpp)
|
||||
List.test.cpp
|
||||
GC.test.cpp)
|
||||
|
||||
xo_add_utest_executable(${SELF_EXE} ${SELF_SRCS})
|
||||
xo_self_dependency(${SELF_EXE} xo_object)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace xo {
|
|||
using xo::obj::List;
|
||||
using xo::obj::String;
|
||||
using xo::gc::GC;
|
||||
using xo::gc::generation_result;
|
||||
using xo::gc::generation;
|
||||
|
||||
namespace {
|
||||
|
|
@ -117,8 +118,8 @@ namespace xo {
|
|||
REQUIRE(s.ptr());
|
||||
REQUIRE(strcmp(s->c_str(), tc.v_.at(i).at(j).c_str()) == 0);
|
||||
|
||||
REQUIRE(gc->generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation::nursery);
|
||||
REQUIRE(gc->tospace_generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation_result::nursery);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,8 +143,8 @@ namespace xo {
|
|||
REQUIRE(s.ptr());
|
||||
REQUIRE(strcmp(s->c_str(), tc.v_.at(i).at(j).c_str()) == 0);
|
||||
|
||||
REQUIRE(gc->generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation::tenured);
|
||||
REQUIRE(gc->tospace_generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation_result::tenured);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,8 +169,8 @@ namespace xo {
|
|||
REQUIRE(s.ptr());
|
||||
REQUIRE(strcmp(s->c_str(), tc.v_.at(i).at(j).c_str()) == 0);
|
||||
|
||||
REQUIRE(gc->generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation::tenured);
|
||||
REQUIRE(gc->tospace_generation_of(reinterpret_cast<std::byte*>(s.ptr()))
|
||||
== generation_result::tenured);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue