diff --git a/cmake/RuntimeConfig.cmake b/cmake/RuntimeConfig.cmake index 0322459fa..46bd00fda 100644 --- a/cmake/RuntimeConfig.cmake +++ b/cmake/RuntimeConfig.cmake @@ -1,4 +1,4 @@ -set(GC_THRESHOLD 2097152 +set(GC_THRESHOLD 3 CACHE STRING "Initial Young Generation Size") set(NOT_YOUNG_OBJECT_BIT 0x10000000000000) diff --git a/config/llvm_header.inc b/config/llvm_header.inc index 0e1e7a2a3..377a0d68d 100644 --- a/config/llvm_header.inc +++ b/config/llvm_header.inc @@ -204,11 +204,6 @@ declare void @write_configuration_to_proof_trace(ptr, ptr) @gc_roots = global [256 x ptr] zeroinitializer -define void @set_gc_threshold(i64 %threshold) { - store i64 %threshold, ptr @GC_THRESHOLD - ret void -} - define i64 @get_gc_threshold() { %threshold = load i64, ptr @GC_THRESHOLD ret i64 %threshold diff --git a/include/runtime/arena.h b/include/runtime/arena.h index a8eadf3cb..1c32a0fc5 100644 --- a/include/runtime/arena.h +++ b/include/runtime/arena.h @@ -35,6 +35,10 @@ using memory_block_header = struct { #define MEM_BLOCK_START(ptr) \ ((char *)(((uintptr_t)(ptr)-1) & ~(BLOCK_SIZE - 1))) +extern bool time_for_collection; + +size_t get_gc_threshold(); + // Resets the given arena. void arena_reset(struct arena *); diff --git a/lib/codegen/Decision.cpp b/lib/codegen/Decision.cpp index 2423f7749..3f2ae9171 100644 --- a/lib/codegen/Decision.cpp +++ b/lib/codegen/Decision.cpp @@ -1003,12 +1003,11 @@ std::pair, llvm::BasicBlock *> step_function_header( module->getContext(), "checkCollect", block->getParent()); llvm::BranchInst::Create(stuck, check_collect, is_finished, block); - auto *collection = get_or_insert_function( - module, "is_collection", - llvm::FunctionType::get( - llvm::Type::getInt1Ty(module->getContext()), {}, false)); - auto *is_collection - = llvm::CallInst::Create(collection, {}, "", check_collect); + auto *collection = module->getOrInsertGlobal( + "time_for_collection", llvm::Type::getInt1Ty(module->getContext())); + auto *is_collection = new llvm::LoadInst( + llvm::Type::getInt1Ty(module->getContext()), collection, "is_collection", + check_collect); set_debug_loc(is_collection); auto *collect = llvm::BasicBlock::Create( module->getContext(), "isCollect", block->getParent()); diff --git a/runtime/alloc/arena.cpp b/runtime/alloc/arena.cpp index 3d8da2302..75a9fcf22 100644 --- a/runtime/alloc/arena.cpp +++ b/runtime/alloc/arena.cpp @@ -76,6 +76,8 @@ static void *megabyte_malloc() { return result; } +bool time_for_collection; + static void fresh_block(struct arena *arena) { char *next_block = nullptr; if (arena->block_start == nullptr) { @@ -106,8 +108,12 @@ static void fresh_block(struct arena *arena) { next_header->next_block = nullptr; next_header->semispace = arena->allocation_semispace_id; arena->num_blocks++; + time_for_collection = true; } } + if (!*(char **)next_block && arena->num_blocks >= get_gc_threshold()) { + time_for_collection = true; + } arena->block = next_block + sizeof(memory_block_header); arena->block_start = next_block; arena->block_end = next_block + BLOCK_SIZE; diff --git a/runtime/collect/collect.cpp b/runtime/collect/collect.cpp index ee0386ff1..dc8ae3b48 100644 --- a/runtime/collect/collect.cpp +++ b/runtime/collect/collect.cpp @@ -25,9 +25,6 @@ static char *last_alloc_ptr; #endif size_t numBytesLiveAtCollection[1 << AGE_WIDTH]; -void set_gc_threshold(size_t); -size_t get_gc_threshold(void); -bool youngspace_almost_full(size_t); bool during_gc() { return is_gc; @@ -285,6 +282,7 @@ void init_static_objects(void) { void kore_collect(void **roots, uint8_t nroots, layoutitem *type_info) { is_gc = true; + time_for_collection = false; collect_old = should_collect_old_gen(); MEM_LOG("Starting garbage collection\n"); #ifdef GC_DBG @@ -349,16 +347,10 @@ void kore_collect(void **roots, uint8_t nroots, layoutitem *type_info) { #endif MEM_LOG("Finishing garbage collection\n"); is_gc = false; - set_gc_threshold(youngspace_size()); } void free_all_kore_mem() { kore_collect(nullptr, 0, nullptr); kore_clear(); } - -bool is_collection() { - size_t threshold = get_gc_threshold(); - return youngspace_almost_full(threshold); -} } diff --git a/runtime/lto/alloc.cpp b/runtime/lto/alloc.cpp index 3e50a8699..86fa11dfc 100644 --- a/runtime/lto/alloc.cpp +++ b/runtime/lto/alloc.cpp @@ -45,15 +45,7 @@ size_t youngspace_size(void) { bool youngspace_almost_full(size_t threshold) { char *next_block = *(char **)youngspace.block_start; - if (next_block) { - // not on the last block, so short circuit and assume that we can keep - // allocating for now. - return false; - } - ptrdiff_t free_bytes = youngspace.block_end - youngspace.block; - size_t total_bytes - = youngspace.num_blocks * (BLOCK_SIZE - sizeof(memory_block_header)); - return (total_bytes - free_bytes) * 100 > threshold * 95; + return !next_block; } void kore_alloc_swap(bool swap_old) { diff --git a/unittests/runtime-collections/lists.cpp b/unittests/runtime-collections/lists.cpp index 96dbdafcc..381b7d90e 100644 --- a/unittests/runtime-collections/lists.cpp +++ b/unittests/runtime-collections/lists.cpp @@ -64,6 +64,9 @@ block *DUMMY1 = &D1; } bool gc_enabled; +size_t get_gc_threshold() { + return SIZE_MAX; +} BOOST_AUTO_TEST_SUITE(ListTest) diff --git a/unittests/runtime-ffi/ffi.cpp b/unittests/runtime-ffi/ffi.cpp index 5b6cbcf8f..32b9de6a4 100644 --- a/unittests/runtime-ffi/ffi.cpp +++ b/unittests/runtime-ffi/ffi.cpp @@ -82,6 +82,10 @@ bool during_gc() { return false; } +size_t get_gc_threshold() { + return SIZE_MAX; +} + void print_configuration_internal( writer *file, block *subject, char const *sort, bool, void *) { } void sfprintf(writer *, char const *, ...) { } diff --git a/unittests/runtime-io/io.cpp b/unittests/runtime-io/io.cpp index a04a9682e..7a7ec2c80 100644 --- a/unittests/runtime-io/io.cpp +++ b/unittests/runtime-io/io.cpp @@ -60,6 +60,10 @@ bool during_gc() { void add_hash64(void *, uint64_t) { } +size_t get_gc_threshold() { + return SIZE_MAX; +} + void flush_io_logs(); string *make_string(const KCHAR *, int64_t len = -1); blockheader header_err(); diff --git a/unittests/runtime-strings/stringtest.cpp b/unittests/runtime-strings/stringtest.cpp index 0c2b80cd3..b76da0ef8 100644 --- a/unittests/runtime-strings/stringtest.cpp +++ b/unittests/runtime-strings/stringtest.cpp @@ -68,6 +68,10 @@ floating *move_float(floating *i) { void add_hash64(void *, uint64_t) { } +size_t get_gc_threshold() { + return SIZE_MAX; +} + struct blockheader get_block_header_for_symbol(uint32_t tag) { return blockheader{tag}; }