lean4-htt/src/runtime/compact.h
Eric Wieser 6e711bf067
fix: ensure padding bytes for lean::mpz objects in olean files are zero (#11485)
This PR ensures that `Nat`s in `.olean` files use a deterministic
serialization in the case where `LEAN_USE_GMP` is not set.

This is a simplified version of
https://github.com/leanprover/lean4/pull/2908.
2025-12-09 10:59:15 +00:00

95 lines
3.6 KiB
C++

/*
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 <functional>
#include <vector>
#include "runtime/object.h"
#include "util/alloc.h"
namespace lean {
typedef lean_object * object_offset;
class LEAN_EXPORT object_compactor {
struct max_sharing_table;
friend struct max_sharing_hash;
friend struct max_sharing_eq;
lean::unordered_map<object*, object_offset, std::hash<object*>, std::equal_to<object*>> m_obj_table;
std::unique_ptr<max_sharing_table> m_max_sharing_table;
std::vector<object*> m_todo;
std::vector<object_offset> m_tmp;
// On-disk base address used for `mmap`ing compacted regions without relocations
// References within the compacted region are rewritten by subtracting `m_begin` and adding `m_base_addr`
// In the simplest case `base_addr == nullptr`, we get region-relative pointers
void * m_base_addr;
void * m_begin;
void * m_end;
void * m_capacity;
size_t capacity() const { return static_cast<char*>(m_capacity) - static_cast<char*>(m_begin); }
void save(object * o, object * new_o);
void save_max_sharing(object * o, object * new_o, size_t new_o_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);
void insert_sarray(object * o);
void insert_string(object * o);
bool insert_thunk(object * o);
bool insert_task(object * o);
bool insert_promise(object * o);
bool insert_ref(object * o);
void insert_mpz(object * o);
public:
object_compactor(void * base_addr = nullptr);
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<char*>(m_end) - static_cast<char*>(m_begin); }
void const * data() const { return m_begin; }
// Allocate `sz` bytes of zeroed memory.
void * alloc(size_t sz);
};
class LEAN_EXPORT compacted_region {
size_t m_size;
// see `object_compactor::m_base_addr`
void * m_base_addr;
bool m_is_mmap;
std::function<void()> m_free_data;
void * m_begin;
void * m_next;
void * m_end;
void move(size_t d);
void move(object * o);
object * fix_object_ptr(object * o);
void fix_constructor(object * o);
void fix_array(object * o);
void fix_thunk(object * o);
void fix_ref(object * o);
void fix_task(object * o);
void fix_promise(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, void * base_addr, bool is_mmap, std::function<void()> free_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();
bool is_memory_mapped() const { return m_is_mmap; }
size_t size() const { return m_size; }
};
}