Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use intrusive reference counting #128

Merged
merged 19 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,14 @@ export(EXPORT ${PROJECT_NAME}_Targets
# Register package in the User Package Registry
export(PACKAGE trieste)

# #############################################
# # Add core Trieste tests
enable_testing()
add_subdirectory(test)

# #############################################
# # Add samples
if(TRIESTE_BUILD_SAMPLES)
enable_testing()
add_subdirectory(samples/infix)
endif()

Expand Down
51 changes: 32 additions & 19 deletions include/trieste/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
#pragma once

#include "intrusive_ptr.h"
#include "token.h"

#include <iostream>
Expand Down Expand Up @@ -33,10 +34,10 @@ namespace trieste

using Nodes = std::vector<Node>;
using NodeIt = Nodes::iterator;
using NodeSet = std::set<Node, std::owner_less<>>;
using NodeSet = std::set<Node>;

template<typename T>
using NodeMap = std::map<Node, T, std::owner_less<>>;
using NodeMap = std::map<Node, T>;

#ifdef TRIESTE_USE_CXX17
class NodeRange
Expand Down Expand Up @@ -105,7 +106,7 @@ namespace trieste
using NodeRange = std::span<Node>;
#endif

class SymtabDef
class SymtabDef final : public intrusive_refcounted<SymtabDef>
{
friend class NodeDef;

Expand Down Expand Up @@ -134,7 +135,7 @@ namespace trieste
void str(std::ostream& out, size_t level);
};

using Symtab = std::shared_ptr<SymtabDef>;
using Symtab = intrusive_ptr<SymtabDef>;

struct Index
{
Expand Down Expand Up @@ -181,7 +182,7 @@ namespace trieste
}
};

class NodeDef : public std::enable_shared_from_this<NodeDef>
class NodeDef final : public intrusive_refcounted<NodeDef>
{
private:
Token type_;
Expand All @@ -195,7 +196,7 @@ namespace trieste
: type_(type), location_(location), parent_(nullptr)
{
if (type_ & flag::symtab)
symtab_ = std::make_shared<SymtabDef>();
symtab_ = Symtab::make();
}

void add_flags()
Expand Down Expand Up @@ -291,20 +292,20 @@ namespace trieste

static Node create(const Token& type)
{
return std::shared_ptr<NodeDef>(new NodeDef(type, {nullptr, 0, 0}));
return Node(new NodeDef(type, Location{nullptr, 0, 0}));
}

static Node create(const Token& type, Location location)
{
return std::shared_ptr<NodeDef>(new NodeDef(type, location));
return Node(new NodeDef(type, location));
}

static Node create(const Token& type, NodeRange range)
{
if (range.empty())
return create(type);

return std::shared_ptr<NodeDef>(
return Node(
new NodeDef(type, range.front()->location_ * range.back()->location_));
}

Expand Down Expand Up @@ -340,7 +341,7 @@ namespace trieste
while (p)
{
if (p->type_.in(list))
return p->shared_from_this();
return p->intrusive_ptr_from_this();

p = p->parent_;
}
Expand Down Expand Up @@ -406,7 +407,7 @@ namespace trieste

auto find_first(Token token, NodeIt begin)
{
assert((*begin)->parent() == this);
assert((*begin)->parent() == this);
return std::find_if(
begin, children.end(), [token](auto& n) { return n->type() == token; });
}
Expand Down Expand Up @@ -548,7 +549,7 @@ namespace trieste

while (p)
{
auto node = p->shared_from_this();
auto node = p->intrusive_ptr_from_this();

if (node->symtab_)
return node;
Expand Down Expand Up @@ -655,7 +656,7 @@ namespace trieste
throw std::runtime_error("No symbol table");

auto& entry = st->symtab_->symbols[loc];
entry.push_back(shared_from_this());
entry.push_back(intrusive_ptr_from_this());

// If there are multiple definitions, none can be shadowing.
return (entry.size() == 1) ||
Expand All @@ -671,7 +672,7 @@ namespace trieste
if (!st)
throw std::runtime_error("No symbol table");

st->symtab_->includes.emplace_back(shared_from_this());
st->symtab_->includes.emplace_back(intrusive_ptr_from_this());
}

Location fresh(const Location& prefix = {})
Expand Down Expand Up @@ -752,10 +753,10 @@ namespace trieste

// If p and q are the same, then one is contained within the other.
if (p == q)
return p->shared_from_this();
return p->intrusive_ptr_from_this();

// Otherwise return the common parent.
return p->parent_->shared_from_this();
return p->parent_->intrusive_ptr_from_this();
}

bool precedes(Node node)
Expand All @@ -775,8 +776,8 @@ namespace trieste

// Check that p is to the left of q.
auto parent = p->parent_;
return parent->find(p->shared_from_this()) <
parent->find(q->shared_from_this());
return parent->find(p->intrusive_ptr_from_this()) <
parent->find(q->intrusive_ptr_from_this());
}

void str(std::ostream& out, size_t level = 0) const
Expand Down Expand Up @@ -846,7 +847,7 @@ namespace trieste
template<typename Pre, typename Post = NopPost>
SNMALLOC_FAST_PATH void traverse(Pre pre, Post post = NopPost())
{
Node root = shared_from_this();
Node root = intrusive_ptr_from_this();
if (!pre(root))
return;

Expand Down Expand Up @@ -936,6 +937,18 @@ namespace trieste
}
};

constexpr void
intrusive_refcounted_traits<NodeDef>::intrusive_inc_ref(NodeDef* node)
{
node->intrusive_inc_ref();
}

constexpr void
intrusive_refcounted_traits<NodeDef>::intrusive_dec_ref(NodeDef* node)
{
node->intrusive_dec_ref();
}

inline TokenDef::operator Node() const
{
return NodeDef::create(Token(*this));
Expand Down
Loading
Loading