Skip to content

Commit 84bd1ae

Browse files
author
Dwight Guth
authored
simplify gc code for alwaysgc roots (#1083)
When we were trying to fix the GC for `kompile -O3` on EVM, we added some logic to deal with the case where a map/list/set was a garbage collection root. Over the course of several iterations, that code evolved, and eventually became rather complex. However, it came to my attention analyzing the code that some of the complexity that was added early on was made redundant by later complexity. So we are actually able to simplify somewhat. What this PR does is remove the `is_block` boolean parameter everywhere. This was being done because we were passing a `block *` for map/list/set pointers that had been promoted from the alwaysgcspace to the youngspace. However, the new derived pointer logic we added can handle derived pointers to embedded map/list/set objects now, so this is no longer necessary. I may make further simplifications to this logic in the near future; I am considering how it may interact with changes that would make the garbage collector walk the stack. However, this is an intermediate step that I was able to write and test to ensure it didn't break anything, and since it is overall a deletion of code, I wanted to get it in first.
1 parent fa64807 commit 84bd1ae

File tree

3 files changed

+49
-121
lines changed

3 files changed

+49
-121
lines changed

include/runtime/collect.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ void migrate_rangemap(void *m);
3838
void migrate_set(void *s);
3939
void migrate_collection_node(void **node_ptr);
4040
void set_kore_memory_functions_for_gmp(void);
41-
void kore_collect(void **, uint8_t, layoutitem *, bool *);
42-
bool store_map_for_gc(void **, map *);
43-
bool store_set_for_gc(void **, set *);
44-
bool store_list_for_gc(void **, list *);
45-
bool store_rangemap_for_gc(void **, rangemap *);
46-
map *load_map_for_gc(void **, bool);
47-
set *load_set_for_gc(void **, bool);
48-
list *load_list_for_gc(void **, bool);
49-
rangemap *load_rangemap_for_gc(void **, bool);
41+
void kore_collect(void **, uint8_t, layoutitem *);
42+
void store_map_for_gc(void **, map *);
43+
void store_set_for_gc(void **, set *);
44+
void store_list_for_gc(void **, list *);
45+
void store_rangemap_for_gc(void **, rangemap *);
46+
map *load_map_for_gc(void **);
47+
set *load_set_for_gc(void **);
48+
list *load_list_for_gc(void **);
49+
rangemap *load_rangemap_for_gc(void **);
5050
}
5151

5252
#ifdef GC_DBG

lib/codegen/Decision.cpp

Lines changed: 20 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -919,12 +919,11 @@ void make_anywhere_function(
919919
// writes pointers to gc_roots prior to garbage collection
920920
static void store_ptrs_for_gc(
921921
unsigned nroots, llvm::Module *module, llvm::Type *root_ty,
922-
llvm::Constant *arr, llvm::Instruction *are_block_val,
923-
llvm::BasicBlock *collect, std::vector<llvm::Value *> const &roots,
922+
llvm::Constant *arr, llvm::BasicBlock *collect,
923+
std::vector<llvm::Value *> const &roots,
924924
std::vector<value_type> const &types,
925925
std::vector<llvm::Type *> const &ptr_types,
926-
std::vector<std::pair<llvm::Value *, llvm::Type *>> &root_ptrs,
927-
std::vector<llvm::Value *> &are_block) {
926+
std::vector<std::pair<llvm::Value *, llvm::Type *>> &root_ptrs) {
928927
auto *zero
929928
= llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 0);
930929
llvm::Type *voidptrptr = llvm::PointerType::getUnqual(
@@ -935,87 +934,48 @@ static void store_ptrs_for_gc(
935934
{zero, llvm::ConstantInt::get(
936935
llvm::Type::getInt64Ty(module->getContext()), i)},
937936
"", collect);
938-
llvm::Value *is_block = nullptr;
939-
llvm::Value *are_block_ptr = nullptr;
940937
switch (types[i].cat) {
941938
case sort_category::Map:
942-
is_block = llvm::CallInst::Create(
939+
llvm::CallInst::Create(
943940
get_or_insert_function(
944941
module, "store_map_for_gc",
945942
llvm::Type::getInt1Ty(module->getContext()), voidptrptr,
946943
ptr_types[i]),
947-
{ptr, roots[i]}, "is_block", collect);
948-
are_block_ptr = llvm::GetElementPtrInst::CreateInBounds(
949-
llvm::Type::getInt1Ty(module->getContext()), are_block_val,
950-
{llvm::ConstantInt::get(
951-
llvm::Type::getInt64Ty(module->getContext()), i)},
952-
"", collect);
953-
new llvm::StoreInst(is_block, are_block_ptr, collect);
944+
{ptr, roots[i]}, "", collect);
954945
root_ptrs.emplace_back(ptr, ptr_types[i]);
955-
are_block.push_back(is_block);
956946
break;
957947
case sort_category::RangeMap:
958-
is_block = llvm::CallInst::Create(
948+
llvm::CallInst::Create(
959949
get_or_insert_function(
960950
module, "store_rangemap_for_gc",
961951
llvm::Type::getInt1Ty(module->getContext()), voidptrptr,
962952
ptr_types[i]),
963-
{ptr, roots[i]}, "is_block", collect);
964-
are_block_ptr = llvm::GetElementPtrInst::CreateInBounds(
965-
llvm::Type::getInt1Ty(module->getContext()), are_block_val,
966-
{llvm::ConstantInt::get(
967-
llvm::Type::getInt64Ty(module->getContext()), i)},
968-
"", collect);
969-
new llvm::StoreInst(is_block, are_block_ptr, collect);
953+
{ptr, roots[i]}, "", collect);
970954
root_ptrs.emplace_back(ptr, ptr_types[i]);
971-
are_block.push_back(is_block);
972955
break;
973956
case sort_category::List:
974-
is_block = llvm::CallInst::Create(
957+
llvm::CallInst::Create(
975958
get_or_insert_function(
976959
module, "store_list_for_gc",
977960
llvm::Type::getInt1Ty(module->getContext()), voidptrptr,
978961
ptr_types[i]),
979-
{ptr, roots[i]}, "is_block", collect);
980-
are_block_ptr = llvm::GetElementPtrInst::CreateInBounds(
981-
llvm::Type::getInt1Ty(module->getContext()), are_block_val,
982-
{llvm::ConstantInt::get(
983-
llvm::Type::getInt64Ty(module->getContext()), i)},
984-
"", collect);
985-
new llvm::StoreInst(is_block, are_block_ptr, collect);
962+
{ptr, roots[i]}, "", collect);
986963
root_ptrs.emplace_back(ptr, ptr_types[i]);
987-
are_block.push_back(is_block);
988964
break;
989965
case sort_category::Set:
990-
is_block = llvm::CallInst::Create(
966+
llvm::CallInst::Create(
991967
get_or_insert_function(
992968
module, "store_set_for_gc",
993969
llvm::Type::getInt1Ty(module->getContext()), voidptrptr,
994970
ptr_types[i]),
995-
{ptr, roots[i]}, "is_block", collect);
996-
are_block_ptr = llvm::GetElementPtrInst::CreateInBounds(
997-
llvm::Type::getInt1Ty(module->getContext()), are_block_val,
998-
{llvm::ConstantInt::get(
999-
llvm::Type::getInt64Ty(module->getContext()), i)},
1000-
"", collect);
1001-
new llvm::StoreInst(is_block, are_block_ptr, "", collect);
971+
{ptr, roots[i]}, "", collect);
1002972
root_ptrs.emplace_back(ptr, ptr_types[i]);
1003-
are_block.push_back(is_block);
1004973
break;
1005974
default:
1006975
auto *casted = new llvm::BitCastInst(
1007976
ptr, llvm::PointerType::getUnqual(ptr_types[i]), "", collect);
1008977
new llvm::StoreInst(roots[i], casted, collect);
1009-
are_block_ptr = llvm::GetElementPtrInst::CreateInBounds(
1010-
llvm::Type::getInt1Ty(module->getContext()), are_block_val,
1011-
{llvm::ConstantInt::get(
1012-
llvm::Type::getInt64Ty(module->getContext()), i)},
1013-
"", collect);
1014-
new llvm::StoreInst(
1015-
llvm::ConstantInt::getFalse(module->getContext()), are_block_ptr, "",
1016-
collect);
1017978
root_ptrs.emplace_back(casted, ptr_types[i]);
1018-
are_block.push_back(nullptr);
1019979
break;
1020980
}
1021981
}
@@ -1028,8 +988,7 @@ static void load_ptrs_for_gc(
1028988
llvm::BasicBlock *collect, llvm::BasicBlock *merge,
1029989
std::vector<llvm::Value *> &phis, std::vector<llvm::Value *> const &roots,
1030990
std::vector<std::pair<llvm::Value *, llvm::Type *>> const &root_ptrs,
1031-
std::vector<value_type> const &types,
1032-
std::vector<llvm::Value *> const &are_block) {
991+
std::vector<value_type> const &types) {
1033992
llvm::Type *voidptrptr = llvm::PointerType::getUnqual(
1034993
llvm::PointerType::getUnqual(module->getContext()));
1035994
unsigned i = 0;
@@ -1041,28 +1000,28 @@ static void load_ptrs_for_gc(
10411000
get_or_insert_function(
10421001
module, "load_map_for_gc", pointee_ty, voidptrptr,
10431002
llvm::Type::getInt1Ty(module->getContext())),
1044-
{ptr, are_block[i]}, "", collect);
1003+
{ptr}, "", collect);
10451004
break;
10461005
case sort_category::RangeMap:
10471006
loaded = llvm::CallInst::Create(
10481007
get_or_insert_function(
10491008
module, "load_rangemap_for_gc", pointee_ty, voidptrptr,
10501009
llvm::Type::getInt1Ty(module->getContext())),
1051-
{ptr, are_block[i]}, "", collect);
1010+
{ptr}, "", collect);
10521011
break;
10531012
case sort_category::List:
10541013
loaded = llvm::CallInst::Create(
10551014
get_or_insert_function(
10561015
module, "load_list_for_gc", pointee_ty, voidptrptr,
10571016
llvm::Type::getInt1Ty(module->getContext())),
1058-
{ptr, are_block[i]}, "", collect);
1017+
{ptr}, "", collect);
10591018
break;
10601019
case sort_category::Set:
10611020
loaded = llvm::CallInst::Create(
10621021
get_or_insert_function(
10631022
module, "load_set_for_gc", pointee_ty, voidptrptr,
10641023
llvm::Type::getInt1Ty(module->getContext())),
1065-
{ptr, are_block[i]}, "", collect);
1024+
{ptr}, "", collect);
10661025
break;
10671026
default: loaded = new llvm::LoadInst(pointee_ty, ptr, "", collect);
10681027
}
@@ -1133,18 +1092,10 @@ std::pair<std::vector<llvm::Value *>, llvm::BasicBlock *> step_function_header(
11331092
llvm::PointerType::getUnqual(module->getContext()), 256);
11341093
auto *arr = module->getOrInsertGlobal("gc_roots", root_ty);
11351094
std::vector<std::pair<llvm::Value *, llvm::Type *>> root_ptrs;
1136-
std::vector<llvm::Value *> are_block;
1137-
auto *are_block_val = create_malloc(
1138-
collect, llvm::Type::getInt64Ty(block->getContext()),
1139-
llvm::Type::getInt1Ty(module->getContext()),
1140-
llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 1),
1141-
llvm::ConstantInt::get(
1142-
llvm::Type::getInt64Ty(module->getContext()), nroots),
1143-
nullptr);
11441095

11451096
store_ptrs_for_gc(
1146-
nroots, module, root_ty, arr, are_block_val, collect, roots, types,
1147-
ptr_types, root_ptrs, are_block);
1097+
nroots, module, root_ty, arr, collect, roots, types, ptr_types,
1098+
root_ptrs);
11481099
std::vector<llvm::Constant *> elements;
11491100
i = 0;
11501101
for (auto cat : types) {
@@ -1199,13 +1150,12 @@ std::pair<std::vector<llvm::Value *>, llvm::BasicBlock *> step_function_header(
11991150
{arr,
12001151
llvm::ConstantInt::get(
12011152
llvm::Type::getInt8Ty(module->getContext()), nroots),
1202-
llvm::ConstantExpr::getBitCast(layout, ptr_ty), are_block_val},
1153+
llvm::ConstantExpr::getBitCast(layout, ptr_ty)},
12031154
"", collect);
12041155
set_debug_loc(call);
12051156
std::vector<llvm::Value *> phis;
12061157
load_ptrs_for_gc(
1207-
module, check_collect, collect, merge, phis, roots, root_ptrs, types,
1208-
are_block);
1158+
module, check_collect, collect, merge, phis, roots, root_ptrs, types);
12091159
llvm::BranchInst::Create(merge, collect);
12101160
i = 0;
12111161
unsigned root_idx = 0;

runtime/collect/collect.cpp

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,9 @@ migrate_child(void *curr_block, layoutitem *args, unsigned i, bool ptr) {
228228
}
229229
}
230230

231-
static void
232-
migrate_root(void *curr_block, layoutitem *args, unsigned i, bool is_block) {
231+
static void migrate_root(void *curr_block, layoutitem *args, unsigned i) {
233232
layoutitem *arg_data = args + i;
234233
void *arg = ((char *)curr_block) + arg_data->offset;
235-
if (is_block) {
236-
migrate((block **)arg);
237-
return;
238-
}
239234
switch (arg_data->cat) {
240235
case MAP_LAYOUT:
241236
case RANGEMAP_LAYOUT:
@@ -288,8 +283,7 @@ void init_static_objects(void) {
288283
set_kore_memory_functions_for_gmp();
289284
}
290285

291-
void kore_collect(
292-
void **roots, uint8_t nroots, layoutitem *type_info, bool *are_block) {
286+
void kore_collect(void **roots, uint8_t nroots, layoutitem *type_info) {
293287
is_gc = true;
294288
collect_old = should_collect_old_gen();
295289
MEM_LOG("Starting garbage collection\n");
@@ -307,7 +301,7 @@ void kore_collect(
307301
#endif
308302
char *previous_oldspace_alloc_ptr = *old_alloc_ptr();
309303
for (int i = 0; i < nroots; i++) {
310-
migrate_root(roots, type_info, i, are_block[i]);
304+
migrate_root(roots, type_info, i);
311305
}
312306
migrate_static_roots();
313307
char *scan_ptr = youngspace_ptr();
@@ -359,18 +353,18 @@ void kore_collect(
359353
}
360354

361355
void free_all_kore_mem() {
362-
kore_collect(nullptr, 0, nullptr, nullptr);
356+
kore_collect(nullptr, 0, nullptr);
363357
}
364358

365359
bool is_collection() {
366360
size_t threshold = get_gc_threshold();
367361
return youngspace_almost_full(threshold);
368362
}
369363

370-
bool store_map_for_gc(void **roots, map *ptr) {
364+
void store_map_for_gc(void **roots, map *ptr) {
371365
if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) {
372366
*roots = ptr;
373-
return false;
367+
return;
374368
}
375369
void *mem = kore_alloc(sizeof(blockheader) + sizeof(map) + sizeof(uint64_t));
376370
auto *hdr = (blockheader *)mem;
@@ -380,14 +374,13 @@ bool store_map_for_gc(void **roots, map *ptr) {
380374
*offset = 16;
381375
auto *child = (map *)(hdr + 2);
382376
*child = std::move(*ptr);
383-
*roots = mem;
384-
return true;
377+
*roots = child;
385378
}
386379

387-
bool store_set_for_gc(void **roots, set *ptr) {
380+
void store_set_for_gc(void **roots, set *ptr) {
388381
if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) {
389382
*roots = ptr;
390-
return false;
383+
return;
391384
}
392385
void *mem = kore_alloc(sizeof(blockheader) + sizeof(set) + sizeof(uint64_t));
393386
auto *hdr = (blockheader *)mem;
@@ -397,14 +390,13 @@ bool store_set_for_gc(void **roots, set *ptr) {
397390
*offset = 16;
398391
auto *child = (set *)(hdr + 2);
399392
*child = std::move(*ptr);
400-
*roots = mem;
401-
return true;
393+
*roots = child;
402394
}
403395

404-
bool store_list_for_gc(void **roots, list *ptr) {
396+
void store_list_for_gc(void **roots, list *ptr) {
405397
if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) {
406398
*roots = ptr;
407-
return false;
399+
return;
408400
}
409401
void *mem = kore_alloc(sizeof(blockheader) + sizeof(list) + sizeof(uint64_t));
410402
auto *hdr = (blockheader *)mem;
@@ -414,14 +406,13 @@ bool store_list_for_gc(void **roots, list *ptr) {
414406
*offset = 16;
415407
auto *child = (list *)(hdr + 2);
416408
*child = std::move(*ptr);
417-
*roots = mem;
418-
return true;
409+
*roots = child;
419410
}
420411

421-
bool store_rangemap_for_gc(void **roots, rangemap *ptr) {
412+
void store_rangemap_for_gc(void **roots, rangemap *ptr) {
422413
if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) {
423414
*roots = ptr;
424-
return false;
415+
return;
425416
}
426417
void *mem
427418
= kore_alloc(sizeof(blockheader) + sizeof(rangemap) + sizeof(uint64_t));
@@ -432,39 +423,26 @@ bool store_rangemap_for_gc(void **roots, rangemap *ptr) {
432423
*offset = 16;
433424
auto *child = (rangemap *)(hdr + 2);
434425
*child = std::move(*ptr);
435-
*roots = mem;
436-
return true;
426+
*roots = child;
437427
}
438428

439-
map *load_map_for_gc(void **roots, bool is_block) {
429+
map *load_map_for_gc(void **roots) {
440430
void *mem = *roots;
441-
if (is_block) {
442-
return (map *)(((char *)mem) + sizeof(blockheader) + sizeof(uint64_t));
443-
}
444431
return (map *)mem;
445432
}
446433

447-
set *load_set_for_gc(void **roots, bool is_block) {
434+
set *load_set_for_gc(void **roots) {
448435
void *mem = *roots;
449-
if (is_block) {
450-
return (set *)(((char *)mem) + sizeof(blockheader) + sizeof(uint64_t));
451-
}
452436
return (set *)mem;
453437
}
454438

455-
list *load_list_for_gc(void **roots, bool is_block) {
439+
list *load_list_for_gc(void **roots) {
456440
void *mem = *roots;
457-
if (is_block) {
458-
return (list *)(((char *)mem) + sizeof(blockheader) + sizeof(uint64_t));
459-
}
460441
return (list *)mem;
461442
}
462443

463-
rangemap *load_rangemap_for_gc(void **roots, bool is_block) {
444+
rangemap *load_rangemap_for_gc(void **roots) {
464445
void *mem = *roots;
465-
if (is_block) {
466-
return (rangemap *)(((char *)mem) + sizeof(blockheader) + sizeof(uint64_t));
467-
}
468446
return (rangemap *)mem;
469447
}
470448
}

0 commit comments

Comments
 (0)