134 lines
5.1 KiB
C++
134 lines
5.1 KiB
C++
/** @file LocalEnv.test.cpp **/
|
|
|
|
#include "xo/interpreter/init_interpreter.hpp"
|
|
#include "xo/interpreter/LocalEnv.hpp"
|
|
#include "xo/object/Integer.hpp"
|
|
#include "xo/alloc/GC.hpp"
|
|
#include <catch2/catch.hpp>
|
|
#include <vector>
|
|
#include <cstdint>
|
|
|
|
namespace xo {
|
|
using xo::scm::LocalEnv;
|
|
using xo::obj::Integer;
|
|
using xo::gc::GC;
|
|
using xo::gc::ArenaAlloc;
|
|
using xo::gc::generation;
|
|
using xo::gc::generation_result;
|
|
using xo::reflect::TaggedPtr;
|
|
|
|
namespace ut {
|
|
static InitEvidence s_init = (InitSubsys<S_interpreter_tag>::require());
|
|
|
|
namespace {
|
|
struct Testcase_LocalEnv {
|
|
Testcase_LocalEnv(const std::vector<std::int32_t> & contents) : contents_{contents} {}
|
|
|
|
/* build xo::obj::Integer for each contents_[i], store in F[i] for new LocalEnv F */
|
|
std::vector<std::int32_t> contents_;
|
|
};
|
|
|
|
std::vector<Testcase_LocalEnv>
|
|
s_testcase_v = {
|
|
Testcase_LocalEnv({}),
|
|
Testcase_LocalEnv({}),
|
|
Testcase_LocalEnv({111}),
|
|
Testcase_LocalEnv({111, 222}),
|
|
};
|
|
}
|
|
|
|
TEST_CASE("LocalEnv", "[LocalEnv][interpreter]")
|
|
{
|
|
Subsystem::initialize_all();
|
|
|
|
constexpr bool c_debug_flag = false;
|
|
|
|
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
|
scope log(XO_DEBUG(c_debug_flag), xtag("test", "LocalEnv2"), xtag("i_tc", i_tc));
|
|
|
|
const Testcase_LocalEnv & tc = s_testcase_v[i_tc];
|
|
|
|
up<ArenaAlloc> alloc = ArenaAlloc::make("utest", 16384, c_debug_flag);
|
|
REQUIRE(alloc.get());
|
|
Object::mm = alloc.get();
|
|
|
|
std::size_t n = tc.contents_.size();
|
|
gp<LocalEnv> frame = LocalEnv::make(alloc.get(), nullptr /*parent*/, nullptr /*symtab*/, n);
|
|
|
|
TaggedPtr tp = frame->self_tp();
|
|
|
|
REQUIRE(tp.is_struct());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("LocalEnv2", "[LocalEnv][gc][interpreter]")
|
|
{
|
|
Subsystem::initialize_all();
|
|
|
|
constexpr bool c_debug_flag = false;
|
|
|
|
try {
|
|
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
|
scope log(XO_DEBUG(c_debug_flag), xtag("test", "LocalEnv2"), xtag("i_tc", i_tc));
|
|
|
|
const Testcase_LocalEnv & tc = s_testcase_v[i_tc];
|
|
|
|
up<GC> gc = GC::make(
|
|
{.initial_nursery_z_ = 16384,
|
|
.initial_tenured_z_ = 32768,
|
|
.incr_gc_threshold_ = 4096,
|
|
.full_gc_threshold_ = 4096,
|
|
.object_stats_flag_ = true,
|
|
.debug_flag_ = c_debug_flag,
|
|
});
|
|
|
|
REQUIRE(gc.get());
|
|
|
|
/* use gc for all Object allocs */
|
|
GC * mm = gc.get();
|
|
Object::mm = mm;
|
|
|
|
std::size_t n = tc.contents_.size();
|
|
|
|
gp<Integer> x = Integer::make(gc.get(), 42);
|
|
gc->add_gc_root(reinterpret_cast<Object **>(&x));
|
|
REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery);
|
|
|
|
gp<LocalEnv> frame = LocalEnv::make(gc.get(), nullptr /*parent*/, nullptr /*symtab*/, n);
|
|
LocalEnv ** frame_pp = frame.ptr_address();
|
|
gc->add_gc_root(reinterpret_cast<Object **>(frame_pp));
|
|
|
|
/* verifying allocated in N1 */
|
|
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
|
|
|
|
for (std::size_t i = 0; i < n; ++i)
|
|
(*frame)[i] = Integer::make(mm, tc.contents_.at(i));
|
|
|
|
std::size_t expected_alloc_z = frame->_shallow_size();
|
|
REQUIRE(expected_alloc_z >= sizeof(LocalEnv) + n * sizeof(gp<Object>));
|
|
|
|
gc->request_gc(generation::nursery); // <<<<<<<<< GC here <<<<<<<<<
|
|
|
|
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
|
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
|
|
|
/* verify Integer x preserved across gc */
|
|
REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery);
|
|
|
|
/* verify LocalEnv preserved across gc */
|
|
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
|
|
REQUIRE(frame->size() == n);
|
|
for (std::size_t i = 0; i < n; ++i) {
|
|
//REQUIRE(Integer::from(frame->lookup(i)).ptr());
|
|
//REQUIRE(Integer::from(frame->lookup(i))->value() == tc.contents_.at(i));
|
|
}
|
|
}
|
|
} catch (std::exception & ex) {
|
|
std::cerr << "exception: " << ex.what() << std::endl;
|
|
REQUIRE(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* end LocalEnv.test.cpp */
|