Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions compiler+runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ option(jank_coverage "Enable code coverage measurement" OFF)
option(jank_analyze "Enable static analysis" OFF)
option(jank_test "Enable jank's test suite" OFF)
option(jank_unity_build "Optimize translation unit compilation for the number of cores" OFF)
option(jank_debug_gc "Enable GC debug assertions" OFF)
set(jank_sanitize "none" CACHE STRING "The type of Clang sanitization to use (or none)")
set(jank_resource_dir
"../lib/jank/${CMAKE_PROJECT_VERSION}"
Expand Down
15 changes: 13 additions & 2 deletions compiler+runtime/cmake/dependency/bdwgc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,31 @@ set(CMAKE_C_FLAGS_OLD "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS_OLD "${CMAKE_CXX_FLAGS}")
set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
set(CMAKE_CXX_CLANG_TIDY_OLD ${CMAKE_CXX_CLANG_TIDY})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -DREDIRECT_MALLOC=GC_malloc_uncollectable")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -DREDIRECT_MALLOC=GC_malloc_uncollectable")
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_CXX_CLANG_TIDY "")
set(enable_cplusplus ON CACHE BOOL "Enable C++")
set(build_cord OFF CACHE BOOL "Build cord")
set(enable_docs OFF CACHE BOOL "Enable docs")
set(enable_large_config ON CACHE BOOL "Optimize for large heap or root set")
set(enable_throw_bad_alloc_library ON CACHE BOOL "Enable C++ gctba library build")
set(enable_gc_debug OFF CACHE BOOL "Support for pointer back-tracing")

if(jank_debug_gc)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGC_ASSERTIONS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGC_ASSERTIONS")
set(enable_gc_debug ON CACHE BOOL "Support for pointer back-tracing")
endif()

add_subdirectory(third-party/bdwgc EXCLUDE_FROM_ALL)

unset(enable_cplusplus)
unset(build_cord)
unset(enable_docs)
unset(enable_large_config)
unset(enable_throw_bad_alloc_library)
unset(enable_gc_debug)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_OLD}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}")
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ namespace jank::codegen
compilation_target target);
/* For this ctor, we're inheriting the context from another function, which means
* we're building a nested function. */
llvm_processor(analyze::expr::function_ref expr, std::unique_ptr<reusable_context> ctx);
llvm_processor(analyze::expr::function_ref expr, jtl::ref<reusable_context> ctx);
llvm_processor(llvm_processor const &) = delete;
llvm_processor(llvm_processor &&) noexcept = default;

Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/include/cpp/jank/read/parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace jank::read::parse
* token, we should check this list to see if there's already a form we should pull out.
* This is needed because parse iteration works one form at a time and splicing potentially
* turns one form into many. */
std::list<runtime::object_ref> pending_forms;
native_list<runtime::object_ref> pending_forms;
lex::token latest_token;
jtl::option<shorthand_function_details> shorthand;
/* Whether or not the next form is considered quoted. */
Expand Down
5 changes: 2 additions & 3 deletions compiler+runtime/include/cpp/jank/runtime/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ namespace jank::runtime
context();
context(context const &) = delete;
context(context &&) noexcept = delete;
~context();

ns_ref intern_ns(jtl::immutable_string const &);
ns_ref intern_ns(obj::symbol_ref const &);
Expand Down Expand Up @@ -161,8 +160,8 @@ namespace jank::runtime
/* Hold onto the CLI Options for use at runtime */
util::cli::options opts;

/* TODO: Remove this map. Just use the list. */
static thread_local native_unordered_map<context const *, std::list<thread_binding_frame>>
/* XXX: We can't use thread_local here, due to bdwgc not supporting it. */
static native_unordered_map<std::thread::id, native_list<thread_binding_frame>>
thread_binding_frames;

/* This must go last, since it'll try to access other bits in the runtime context during
Expand Down
27 changes: 8 additions & 19 deletions compiler+runtime/include/cpp/jank/runtime/detail/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
#include <immer/set_transient.hpp>
#include <immer/memory_policy.hpp>

#include <bpptree/bpptree.hpp>
#include <bpptree/ordered.hpp>

#include <jank/runtime/object.hpp>
#include <jank/runtime/detail/native_persistent_list.hpp>

Expand All @@ -36,15 +33,6 @@ namespace immer
jank::memory_policy>;
}

namespace bpptree::detail
{
extern template struct BppTreeSet<jank::runtime::object_ref,
jank::runtime::detail::object_ref_compare>;
extern template struct BppTreeMap<jank::runtime::object_ref,
jank::runtime::object_ref,
jank::runtime::detail::object_ref_compare>;
}

namespace jank::runtime::detail
{
using native_persistent_vector = immer::vector<object_ref, memory_policy>;
Expand All @@ -54,11 +42,10 @@ namespace jank::runtime::detail
set<object_ref, std::hash<object_ref>, std::equal_to<jank::runtime::object_ref>, memory_policy>;
using native_transient_hash_set = native_persistent_hash_set::transient_type;

/* TODO: These BppTree types will leak until we get them GC allocated. */
/* TODO: Bring in proper immutable sorted maps/sets. */
using native_persistent_sorted_set
= bpptree::BppTreeSet<object_ref, object_ref_compare>::Persistent;
using native_transient_sorted_set
= bpptree::BppTreeSet<object_ref, object_ref_compare>::Transient;
= std::set<object_ref, object_ref_compare, native_allocator<object_ref>>;
using native_transient_sorted_set = native_persistent_sorted_set;

using native_persistent_hash_map = immer::map<object_ref,
object_ref,
Expand All @@ -68,9 +55,11 @@ namespace jank::runtime::detail
using native_transient_hash_map = native_persistent_hash_map::transient_type;

using native_persistent_sorted_map
= bpptree::BppTreeMap<object_ref, object_ref, object_ref_compare>::Persistent;
using native_transient_sorted_map
= bpptree::BppTreeMap<object_ref, object_ref, object_ref_compare>::Transient;
= std::map<object_ref,
object_ref,
object_ref_compare,
native_allocator<std::pair<object_ref const, object_ref>>>;
using native_transient_sorted_map = native_persistent_sorted_map;

/* If an object requires this in its constructor, use your runtime context to intern
* it instead. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ namespace jank::runtime::obj
transient_sorted_map() = default;
transient_sorted_map(transient_sorted_map &&) noexcept = default;
transient_sorted_map(transient_sorted_map const &) = default;
transient_sorted_map(runtime::detail::native_persistent_sorted_map const &d);
transient_sorted_map(runtime::detail::native_persistent_sorted_map &&d);
transient_sorted_map(value_type const &d);
transient_sorted_map(value_type &&d);

static transient_sorted_map_ref empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ namespace jank::runtime::obj
transient_sorted_set() = default;
transient_sorted_set(transient_sorted_set &&) noexcept = default;
transient_sorted_set(transient_sorted_set const &) = default;
transient_sorted_set(runtime::detail::native_persistent_sorted_set const &d);
transient_sorted_set(runtime::detail::native_persistent_sorted_set &&d);
transient_sorted_set(value_type const &d);
transient_sorted_set(value_type &&d);

static transient_sorted_set_ref empty();
Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/include/cpp/jank/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace jank
template <typename T>
using native_list = std::list<T, native_allocator<T>>;
template <typename K, typename V>
using native_map = std::map<K, V, native_allocator<std::pair<K const, V>>>;
using native_map = std::map<K, V, std::less<K>, native_allocator<std::pair<K const, V>>>;
template <typename T>
using native_set = std::set<T, std::less<T>, native_allocator<T>>;

Expand Down
19 changes: 2 additions & 17 deletions compiler+runtime/src/cpp/jank/analyze/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1632,7 +1632,7 @@ namespace jank::analyze

native_vector<runtime::obj::symbol_ref> param_symbols;
param_symbols.reserve(params->data.size());
std::set<runtime::obj::symbol> unique_param_symbols;
native_set<runtime::obj::symbol> unique_param_symbols;

bool is_variadic{};
for(auto it(params->data.begin()); it != params->data.end(); ++it)
Expand Down Expand Up @@ -2884,27 +2884,12 @@ namespace jank::analyze
/* TODO: Detect literal and act accordingly. */
return visit_map_like(
[&](auto const typed_o) -> processor::expression_result {
using T = typename decltype(typed_o)::value_type;

native_vector<std::pair<expression_ref, expression_ref>> exprs;
exprs.reserve(typed_o->data.size());

for(auto const &kv : typed_o->data)
{
/* The two maps (hash and sorted) have slightly different iterators, so we need to
* pull out the entries differently. */
object_ref first{}, second{};
if constexpr(std::same_as<T, obj::persistent_sorted_map>)
{
auto const &entry(kv.get());
first = entry.first;
second = entry.second;
}
else
{
first = kv.first;
second = kv.second;
}
object_ref const first{ kv.first }, second{ kv.second };

auto k_expr(analyze(first, current_frame, expression_position::value, fn_ctx, true));
if(k_expr.is_err())
Expand Down
1 change: 0 additions & 1 deletion compiler+runtime/src/cpp/jank/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,6 @@ extern "C"
/* The GC needs to enabled even before arg parsing, since our native types,
* like strings, use the GC for allocations. It can still be configured later. */
GC_set_all_interior_pointers(1);
GC_enable();
GC_init();

llvm::llvm_shutdown_obj const Y{};
Expand Down
39 changes: 11 additions & 28 deletions compiler+runtime/src/cpp/jank/codegen/llvm_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace jank::codegen
compilation_target target);
/* For this ctor, we're inheriting the context from another function, which means
* we're building a nested function. */
impl(analyze::expr::function_ref expr, std::unique_ptr<reusable_context> ctx);
impl(analyze::expr::function_ref expr, jtl::ref<reusable_context> ctx);

jtl::string_result<void> gen();
llvm::Value *gen(analyze::expression_ref, analyze::expr::function_arity const &);
Expand Down Expand Up @@ -176,10 +176,9 @@ namespace jank::codegen
compilation_target target{};
analyze::expr::function_ref root_fn;
jtl::ptr<llvm::Function> llvm_fn{};
std::unique_ptr<reusable_context> ctx;
jtl::ref<reusable_context> ctx;
native_unordered_map<obj::symbol_ref, jtl::ptr<llvm::Value>> locals;
/* TODO: Use gc allocator to avoid leaks. */
std::list<deferred_init> deferred_inits{};
native_list<deferred_init> deferred_inits{};
jtl::ref<llvm::LLVMContext> llvm_ctx;
jtl::ref<llvm::Module> llvm_module;
jtl::ptr<llvm::BasicBlock> current_loop;
Expand Down Expand Up @@ -487,9 +486,8 @@ namespace jank::codegen

/* Whenever we have an object in an `alloca`, we need to load it before using. This fn only
* makes sense to use with jank objects, as opposed to native values. */
static llvm::Value *load_if_needed(std::unique_ptr<reusable_context> const &ctx,
llvm::Value *arg,
jtl::ptr<void> const type)
static llvm::Value *
load_if_needed(jtl::ref<reusable_context> const ctx, llvm::Value *arg, jtl::ptr<void> const type)
{
if(!arg)
{
Expand All @@ -503,8 +501,7 @@ namespace jank::codegen
return arg;
}

static llvm::Value *
load_if_needed(std::unique_ptr<reusable_context> const &ctx, llvm::Value * const arg)
static llvm::Value *load_if_needed(jtl::ref<reusable_context> const ctx, llvm::Value * const arg)
{
return load_if_needed(ctx, arg, cpp_util::untyped_object_ptr_type());
}
Expand Down Expand Up @@ -584,8 +581,8 @@ namespace jank::codegen
}

llvm_processor::llvm_processor(expr::function_ref const expr,
std::unique_ptr<reusable_context> ctx)
: _impl{ make_ref<impl>(expr, jtl::move(ctx)) }
jtl::ref<reusable_context> const ctx)
: _impl{ make_ref<impl>(expr, ctx) }
{
}

Expand All @@ -594,13 +591,13 @@ namespace jank::codegen
compilation_target const target)
: target{ target }
, root_fn{ expr }
, ctx{ std::make_unique<reusable_context>(module_name, std::make_unique<llvm::LLVMContext>()) }
, ctx{ make_ref<reusable_context>(module_name, std::make_unique<llvm::LLVMContext>()) }
, llvm_ctx{ extract_context(ctx->module) }
, llvm_module{ ctx->module.getModuleUnlocked() }
{
}

llvm_processor::impl::impl(expr::function_ref const expr, std::unique_ptr<reusable_context> ctx)
llvm_processor::impl::impl(expr::function_ref const expr, jtl::ref<reusable_context> ctx)
: target{ compilation_target::function }
, root_fn{ expr }
, ctx{ std::move(ctx) }
Expand Down Expand Up @@ -1175,28 +1172,14 @@ namespace jank::codegen
{
llvm::IRBuilder<>::InsertPointGuard const guard{ *ctx->builder };

llvm_processor nested{ expr, std::move(ctx) };

/* We need to make sure to transfer ownership of the context back, even if an exception
* is thrown. */
util::scope_exit const finally{ [&]() {
if(nested._impl->ctx)
{
ctx = std::move(nested._impl->ctx);
}
} };

llvm_processor const nested{ expr, ctx };
auto const res{ nested.gen() };
if(res.is_err())
{
/* TODO: Return error. */
res.expect_ok();
}

/* This is covered by finally, but clang-tidy can't figure that out, so we have
* to make this more clear. */
ctx = std::move(nested._impl->ctx);

global_rtti.insert(nested._impl->global_rtti.begin(), nested._impl->global_rtti.end());
}

Expand Down
2 changes: 1 addition & 1 deletion compiler+runtime/src/cpp/jank/read/lex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ namespace jank::read::lex
return error::lex_invalid_number(
util::format(
"Characters '{}' are invalid for a base {} number.",
jtl::immutable_string_view{ invalid_digits.begin(), invalid_digits.end() },
jtl::immutable_string_view{ invalid_digits.data(), invalid_digits.size() },
radix),
{ token_start, pos });
}
Expand Down
12 changes: 6 additions & 6 deletions compiler+runtime/src/cpp/jank/read/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ namespace jank::read::parse

parsed_keys.insert({ key.ptr, key });

if constexpr(std::same_as<T, runtime::detail::native_array_map>)
if constexpr(jtl::is_same<T, runtime::detail::native_array_map>)
{
map.insert_or_assign(key.ptr, value.unwrap().ptr);
}
Expand All @@ -435,7 +435,7 @@ namespace jank::read::parse

return object_source_info{ make_box<obj::persistent_array_map>(
source_to_meta(start_token.start, latest_token.end),
std::move(map)),
jtl::move(map)),
start_token,
latest_token };
}
Expand All @@ -453,7 +453,7 @@ namespace jank::read::parse

return object_source_info{ make_box<obj::persistent_hash_map>(
source_to_meta(start_token.start, latest_token.end),
std::move(map)),
jtl::move(map)),
start_token,
latest_token };
}
Expand Down Expand Up @@ -538,7 +538,7 @@ namespace jank::read::parse
auto meta_result(visit_object(
[&](auto const typed_val) -> processor::object_result {
using T = typename decltype(typed_val)::value_type;
if constexpr(std::same_as<T, obj::keyword>)
if constexpr(jtl::is_same<T, obj::keyword>)
{
return object_source_info{ obj::persistent_array_map::create_unique(typed_val, jank_true),
start_token,
Expand Down Expand Up @@ -683,7 +683,7 @@ namespace jank::read::parse
expected_closer = prev_expected_closer;
return object_source_info{ make_box<obj::persistent_hash_set>(
source_to_meta(start_token.start, latest_token.end),
std::move(ret).persistent()),
jtl::move(ret).persistent()),
start_token,
latest_token };
}
Expand Down Expand Up @@ -1314,7 +1314,7 @@ namespace jank::read::parse
[&](auto const typed_form) -> jtl::result<object_ref, error_ref> {
using T = typename decltype(typed_form)::value_type;

if constexpr(std::same_as<T, obj::persistent_vector>)
if constexpr(jtl::is_same<T, obj::persistent_vector>)
{
auto const seq(typed_form->seq());
if(seq.is_nil())
Expand Down
Loading
Loading