xo-expression2: DGlobalSymtab mvp implementation
This commit is contained in:
parent
017a7a092c
commit
b187f1a719
2 changed files with 109 additions and 22 deletions
|
|
@ -25,18 +25,41 @@ namespace xo {
|
||||||
public:
|
public:
|
||||||
using key_type = const DUniqueString *;
|
using key_type = const DUniqueString *;
|
||||||
using value_type = Binding;
|
using value_type = Binding;
|
||||||
|
using ArenaHashMapConfig = xo::map::ArenaHashMapConfig;
|
||||||
using repr_type = xo::map::DArenaHashMap<key_type, Binding::slot_type>;
|
using repr_type = xo::map::DArenaHashMap<key_type, Binding::slot_type>;
|
||||||
|
using ACollector = xo::mm::ACollector;
|
||||||
using AAllocator = xo::mm::AAllocator;
|
using AAllocator = xo::mm::AAllocator;
|
||||||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** @defgroup scm-globalsymtab-ctors constructors **/
|
||||||
|
///@{
|
||||||
|
|
||||||
|
DGlobalSymtab(repr_type * map, DArray * vars);
|
||||||
|
|
||||||
|
/** create instance.
|
||||||
|
* Use memory from @p fixed_mm for @ref map_.
|
||||||
|
* Use memory from @p mm for DGlobalSymtab instance.
|
||||||
|
* Hashmap configured per @p cfg.
|
||||||
|
**/
|
||||||
|
DGlobalSymtab * make(obj<AAllocator> fixed_mm,
|
||||||
|
obj<AAllocator> mm,
|
||||||
|
const ArenaHashMapConfig & cfg);
|
||||||
|
|
||||||
|
///@}
|
||||||
|
/** @defgroup scm-globalsymtab-access-methods access methods **/
|
||||||
|
///@{
|
||||||
|
|
||||||
/** visit symtab-owned memory pools; call visitor(info) for each **/
|
/** visit symtab-owned memory pools; call visitor(info) for each **/
|
||||||
void visit_pools(const MemorySizeVisitor & visitor) const;
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||||
|
|
||||||
public:
|
|
||||||
/** lookup global symbol with name @p sym **/
|
/** lookup global symbol with name @p sym **/
|
||||||
DVariable * lookup_variable(const DUniqueString * sym) const noexcept;
|
DVariable * lookup_variable(const DUniqueString * sym) const noexcept;
|
||||||
|
|
||||||
|
///@}
|
||||||
|
/** @defgroup scm-globalsymtab-general-methods general methods **/
|
||||||
|
///@{
|
||||||
|
|
||||||
/** establish binding for @p sym, with type described by @p typeref,
|
/** establish binding for @p sym, with type described by @p typeref,
|
||||||
* replacing existing global (if present) with the same name.
|
* replacing existing global (if present) with the same name.
|
||||||
* Use memory from @p mm to create variable-expr
|
* Use memory from @p mm to create variable-expr
|
||||||
|
|
@ -45,7 +68,8 @@ namespace xo {
|
||||||
const DUniqueString * sym,
|
const DUniqueString * sym,
|
||||||
TypeRef typeref);
|
TypeRef typeref);
|
||||||
|
|
||||||
/** @defgroup xo-expression2-symboltable-facet symboltable facet**/
|
///@}
|
||||||
|
/** @defgroup scm-globalsymtab-symboltable-facet symboltable facet **/
|
||||||
///@{
|
///@{
|
||||||
|
|
||||||
/** true for global symbol table **/
|
/** true for global symbol table **/
|
||||||
|
|
@ -55,13 +79,22 @@ namespace xo {
|
||||||
Binding lookup_binding(const DUniqueString * sym) const noexcept;
|
Binding lookup_binding(const DUniqueString * sym) const noexcept;
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
/** @defgroup scm-globalsymtab-gcobject-facet gcobject facet **/
|
||||||
|
///@{
|
||||||
|
|
||||||
|
std::size_t shallow_size() const noexcept;
|
||||||
|
DGlobalSymtab * shallow_copy(obj<AAllocator> mm) const noexcept;
|
||||||
|
std::size_t forward_children(obj<ACollector> gc) noexcept;
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** next binding will use this global index. See DGlobalEnv **/
|
/** map symbols -> bindings.
|
||||||
uint32_t next_binding_ix_ = 0;
|
* Minor point: storing offsets instead of Variables allows us to omit
|
||||||
|
* iterating over map elements during GC. Possible savings if map_ slots
|
||||||
/** map symbols -> bindings **/
|
* sparsely populated.
|
||||||
repr_type map_;
|
**/
|
||||||
|
repr_type * map_ = nullptr;
|
||||||
|
|
||||||
/** array of variables.
|
/** array of variables.
|
||||||
* When S is a unique-string for a global symbol, then:
|
* When S is a unique-string for a global symbol, then:
|
||||||
|
|
|
||||||
|
|
@ -7,32 +7,57 @@
|
||||||
#include "DUniqueString.hpp"
|
#include "DUniqueString.hpp"
|
||||||
#include <xo/expression2/Expression.hpp>
|
#include <xo/expression2/Expression.hpp>
|
||||||
#include <xo/expression2/Variable.hpp>
|
#include <xo/expression2/Variable.hpp>
|
||||||
|
#include <xo/object2/Array.hpp>
|
||||||
#include <xo/gc/GCObject.hpp>
|
#include <xo/gc/GCObject.hpp>
|
||||||
#include <xo/facet/FacetRegistry.hpp>
|
#include <xo/facet/FacetRegistry.hpp>
|
||||||
#include <xo/indentlog/scope.hpp>
|
#include <xo/indentlog/scope.hpp>
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
using xo::map::DArenaHashMap;
|
||||||
using xo::mm::AGCObject;
|
using xo::mm::AGCObject;
|
||||||
|
|
||||||
namespace scm {
|
namespace scm {
|
||||||
|
|
||||||
#ifdef NOT_YET
|
DGlobalSymtab::DGlobalSymtab(repr_type * map,
|
||||||
DVariable *
|
DArray * vars)
|
||||||
DGlobalSymtab::lookup_binding(Binding ix) noexcept
|
: map_{map}, vars_{vars}
|
||||||
{
|
{
|
||||||
assert(ix.i_link() == -1);
|
|
||||||
assert(ix.j_slot() >= 0);
|
|
||||||
assert(vars_);
|
|
||||||
assert(std::uint64_t(ix.j_slot()) < vars_->size());
|
|
||||||
|
|
||||||
auto var_gco = obj<AGCObject,DVariable>::from((*vars_)[ix.j_slot()]);;
|
|
||||||
auto var = var_gco.to_facet<AExpression>();
|
|
||||||
|
|
||||||
assert(var.data());
|
|
||||||
|
|
||||||
return var.data();
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
DGlobalSymtab *
|
||||||
|
DGlobalSymtab::make(obj<AAllocator> global_mm,
|
||||||
|
obj<AAllocator> mm,
|
||||||
|
const ArenaHashMapConfig & cfg)
|
||||||
|
{
|
||||||
|
repr_type * map = nullptr;
|
||||||
|
{
|
||||||
|
/** memory DGlobalSymtab::map_
|
||||||
|
* (but not counting the mmap()'s that map will make for itself)
|
||||||
|
**/
|
||||||
|
void * global_mem = global_mm.alloc_for<repr_type>();
|
||||||
|
|
||||||
|
map = new (global_mem) repr_type(cfg);
|
||||||
|
}
|
||||||
|
assert(map);
|
||||||
|
|
||||||
|
void * symtab_mem = mm.alloc_for<DGlobalSymtab>();
|
||||||
|
|
||||||
|
/* choosing same capacity for hash, vars */
|
||||||
|
DArray * vars = DArray::empty(mm, map->capacity());
|
||||||
|
assert(vars);
|
||||||
|
|
||||||
|
DGlobalSymtab * symtab = new (symtab_mem) DGlobalSymtab(map, vars);
|
||||||
|
assert(symtab);
|
||||||
|
|
||||||
|
return symtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DGlobalSymtab::visit_pools(const MemorySizeVisitor & visitor) const
|
||||||
|
{
|
||||||
|
if (map_)
|
||||||
|
map_->visit_pools(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
DVariable *
|
DVariable *
|
||||||
DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept
|
DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept
|
||||||
|
|
@ -62,6 +87,9 @@ namespace xo {
|
||||||
|
|
||||||
DArray::size_type n = vars_->size();
|
DArray::size_type n = vars_->size();
|
||||||
|
|
||||||
|
// NOTE: expansion here is moot at present (Feb 2026).
|
||||||
|
// Not implemented in ArenaHashMap
|
||||||
|
|
||||||
/** make sure vars_ has room **/
|
/** make sure vars_ has room **/
|
||||||
if (n == vars_->capacity()) {
|
if (n == vars_->capacity()) {
|
||||||
// reallocate with more capacity
|
// reallocate with more capacity
|
||||||
|
|
@ -82,7 +110,9 @@ namespace xo {
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_[sym] = binding.j_slot();
|
assert(map_->size() < map_->capacity());
|
||||||
|
|
||||||
|
(*map_)[sym] = binding.j_slot();
|
||||||
|
|
||||||
bool ok = vars_->push_back(obj<AGCObject,DVariable>(var));
|
bool ok = vars_->push_back(obj<AGCObject,DVariable>(var));
|
||||||
|
|
||||||
|
|
@ -101,14 +131,38 @@ namespace xo {
|
||||||
scope log(XO_DEBUG(true), "stub");
|
scope log(XO_DEBUG(true), "stub");
|
||||||
log && log(xtag("sym", std::string_view(*sym)));
|
log && log(xtag("sym", std::string_view(*sym)));
|
||||||
|
|
||||||
auto ix = map_.find(sym);
|
auto ix = map_->find(sym);
|
||||||
|
|
||||||
if (ix == map_.end())
|
if (ix == map_->end())
|
||||||
return Binding::null();
|
return Binding::null();
|
||||||
|
|
||||||
return Binding::global(ix->second);
|
return Binding::global(ix->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----- gcobject facet -----
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
DGlobalSymtab::shallow_size() const noexcept
|
||||||
|
{
|
||||||
|
return sizeof(DGlobalSymtab);
|
||||||
|
}
|
||||||
|
|
||||||
|
DGlobalSymtab *
|
||||||
|
DGlobalSymtab::shallow_copy(obj<AAllocator> mm) const noexcept
|
||||||
|
{
|
||||||
|
return mm.std_copy_for<DGlobalSymtab>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
DGlobalSymtab::forward_children(obj<ACollector> gc) noexcept
|
||||||
|
{
|
||||||
|
// map_ doesn't contain any gc-owned data, can skip
|
||||||
|
|
||||||
|
gc.forward_inplace(&vars_);
|
||||||
|
|
||||||
|
return this->shallow_size();
|
||||||
|
}
|
||||||
|
|
||||||
} /*namespace scm*/
|
} /*namespace scm*/
|
||||||
} /*namespace xo*/
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue