/* Copyright (c) 2018 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #pragma once #include #include #include #include "runtime/object.h" namespace lean { typedef object * object_offset; class object_compactor { std::unordered_map, std::equal_to> m_obj_table; std::vector m_todo; std::vector m_tmp; void * m_begin; void * m_end; void * m_capacity; size_t capacity() const { return static_cast(m_capacity) - static_cast(m_begin); } void save(object * o, object * new_o) { lean_assert(m_begin <= new_o && new_o < m_end); m_obj_table.insert(std::make_pair(o, reinterpret_cast(reinterpret_cast(new_o) - reinterpret_cast(m_begin)))); } void * alloc(size_t sz); object_offset to_offset(object * o); void insert_terminator(object * o); object * copy_object(object * o); bool insert_constructor(object * o); bool insert_array(object * o); bool insert_thunk(object * o); bool insert_task(object * o); void insert_mpz(object * o); public: object_compactor(); object_compactor(object_compactor const &) = delete; object_compactor(object_compactor &&) = delete; ~object_compactor(); object_compactor operator=(object_compactor const &) = delete; object_compactor operator=(object_compactor &&) = delete; void operator()(object * o); size_t size() const { return static_cast(m_end) - static_cast(m_begin); } void const * data() const { return m_begin; } }; class compacted_region { void * m_begin; void * m_next; void * m_end; mpz_object * m_nested_mpzs; void move(size_t d); object * fix_object_ptr(object * o); void fix_constructor(object * o); void fix_array(object * o); void fix_thunk(object * o); void fix_mpz(object * o); public: /* Creates a compacted object region using the given region in memory. This object takes ownership of the region. */ compacted_region(size_t sz, void * data); /* Creates a compacted object region using the object_compactor current state. It creates a copy of the compacted region generated by the object compactor. */ explicit compacted_region(object_compactor const & c); compacted_region(compacted_region const &) = delete; compacted_region(compacted_region &&) = delete; ~compacted_region(); compacted_region operator=(compacted_region const &) = delete; compacted_region operator=(compacted_region &&) = delete; object * read(); }; }