This PR changes the closure allocator to use the general allocator instead of the small object one. This is because users may create closures with a gigantic amount of closed variables which in turn boost the size of the closure beyond the small object threshold. This issue was uncovered by #10979. Detecting that the small object threshold is at fault requires building mimalloc in debug mode at which point it yields: ``` mimalloc: assertion failed: at "/home/henrik/lean4/build/debug/mimalloc/src/mimalloc/src/alloc.c":132, mi_heap_malloc_small_zero assertion: "size <= MI_SMALL_SIZE_MAX" ``` The generated code at fault here looks as follows: ```c LEAN_EXPORT lean_object* l_initExec___at___00res_spec__0(lean_object* x_1) { _start: { lean_object* x_2; lean_object* x_3; lean_object* x_4; lean_object* x_5; lean_object* x_6; lean_object* x_7; lean_object* x_8; lean_object* x_9; lean_object* x_10; lean_object* x_11; lean_object* x_12; lean_object* x_13; lean_object* x_14; x_2 = lean_alloc_closure((void*)(l_initializer_ext___at___00initExec___at___00res_spec__0_spec__0___lam__0___boxed), 3, 0); x_3 = l_initExec___redArg___closed__0; x_4 = l_initExec___redArg___closed__1; x_5 = l_instMonadLiftNonDetT___closed__0; x_6 = l_initExec___redArg___closed__2; x_7 = l_initExec___at___00res_spec__0___closed__0; lean_inc_ref(x_2); x_8 = lean_alloc_closure((void*)(l_initExec___at___00res_spec__0___lam__29___boxed), 213, 212); lean_closure_set(x_8, 0, x_3); lean_closure_set(x_8, 1, x_2); lean_closure_set(x_8, 2, x_4); lean_closure_set(x_8, 3, x_3); lean_closure_set(x_8, 4, x_4); lean_closure_set(x_8, 5, x_3); lean_closure_set(x_8, 6, x_4); lean_closure_set(x_8, 7, x_3); lean_closure_set(x_8, 8, x_4); lean_closure_set(x_8, 9, x_3); lean_closure_set(x_8, 10, x_4); lean_closure_set(x_8, 11, x_3); lean_closure_set(x_8, 12, x_4); lean_closure_set(x_8, 13, x_3); lean_closure_set(x_8, 14, x_4); lean_closure_set(x_8, 15, x_5); lean_closure_set(x_8, 16, x_6); lean_closure_set(x_8, 17, x_5); lean_closure_set(x_8, 18, x_5); lean_closure_set(x_8, 19, x_5); lean_closure_set(x_8, 20, x_5); lean_closure_set(x_8, 21, x_5); lean_closure_set(x_8, 22, x_5); ... ``` With the crash happening in `lean_alloc_closure` where we unconditionally invoke the small allocator which cannot cope with closures this large. Hopefully changing this to the general purpose allocator doesn't have too much of an impact on performance. Closes: #10979 |
||
|---|---|---|
| .. | ||
| foreign | ||
| .gitignore | ||
| 534.lean | ||
| 534.lean.expected.out | ||
| append.lean | ||
| append.lean.expected.out | ||
| array.lean | ||
| array.lean.expected.out | ||
| array_test.lean | ||
| array_test.lean.expected.out | ||
| array_test2.lean | ||
| array_test2.lean.expected.out | ||
| arrayMk.lean | ||
| arrayMk.lean.expected.out | ||
| bigctor.lean | ||
| bigctor.lean.expected.out | ||
| bytearray_bug.lean | ||
| bytearray_bug.lean.expected.out | ||
| closure_bug1.lean | ||
| closure_bug1.lean.expected.out | ||
| closure_bug2.lean | ||
| closure_bug2.lean.expected.out | ||
| closure_bug3.lean | ||
| closure_bug3.lean.expected.out | ||
| closure_bug4.lean | ||
| closure_bug4.lean.expected.out | ||
| closure_bug5.lean | ||
| closure_bug5.lean.expected.out | ||
| closure_bug6.lean | ||
| closure_bug6.lean.expected.out | ||
| closure_bug7.lean | ||
| closure_bug7.lean.expected.out | ||
| closure_bug8.lean | ||
| closure_bug8.lean.expected.out | ||
| computedFieldsExtern.lean.no_interpreter | ||
| escape.lean | ||
| escape.lean.expected.out | ||
| expr.lean | ||
| expr.lean.expected.out | ||
| extractClosedMutualBlock.lean | ||
| extractClosedMutualBlock.lean.expected.out | ||
| float.lean | ||
| float.lean.expected.out | ||
| float_cases_bug.lean | ||
| float_cases_bug.lean.expected.out | ||
| init.lean | ||
| init.lean.expected.out | ||
| init.lean.no_interpreter | ||
| initUnboxed.lean | ||
| initUnboxed.lean.expected.out | ||
| initUnboxed.lean.no_interpreter | ||
| large_closure_bug.lean | ||
| large_closure_bug.lean.expected.out | ||
| lazylist.lean | ||
| lazylist.lean.expected.out | ||
| lazylist.lean.no_interpreter | ||
| link_lake.lean | ||
| link_lake.lean.expected.out | ||
| map_big.lean | ||
| map_big.lean.expected.out | ||
| map_big.lean.no_interpreter | ||
| nat_shiftr.lean | ||
| nat_shiftr.lean.expected.out | ||
| overflow1.lean | ||
| overflow1.lean.expected.out | ||
| overflow2.lean | ||
| overflow2.lean.expected.out | ||
| overflow3.lean | ||
| overflow3.lean.expected.out | ||
| partial.lean | ||
| partial.lean.expected.out | ||
| phashmap.lean | ||
| phashmap.lean.expected.out | ||
| phashmap2.lean | ||
| phashmap2.lean.expected.out | ||
| phashmap3.lean | ||
| phashmap3.lean.expected.out | ||
| print_error.lean | ||
| print_error.lean.expected.out | ||
| print_error.lean.expected.ret | ||
| qsortBadLt.lean | ||
| qsortBadLt.lean.expected.out | ||
| rbmap_library.lean | ||
| rbmap_library.lean.expected.out | ||
| reusebug.lean | ||
| reusebug.lean.expected.out | ||
| StackOverflow.lean | ||
| StackOverflow.lean.expected.out | ||
| StackOverflow.lean.expected.ret | ||
| StackOverflow.lean.no_interpreter | ||
| StackOverflowTask.lean | ||
| StackOverflowTask.lean.expected.out | ||
| StackOverflowTask.lean.expected.ret | ||
| StackOverflowTask.lean.no_interpreter | ||
| str.lean | ||
| str.lean.expected.out | ||
| strictAndOr.lean | ||
| strictAndOr.lean.expected.out | ||
| strictOrSimp.lean.expected.out | ||
| t1.lean | ||
| t1.lean.expected.out | ||
| t2.lean | ||
| t2.lean.expected.out | ||
| t4.lean | ||
| t4.lean.expected.out | ||
| test_single.sh | ||
| test_single_interpret.sh | ||
| thunk.lean | ||
| thunk.lean.expected.out | ||
| trie.lean | ||
| trie.lean.expected.out | ||
| trigraphs.lean | ||
| trigraphs.lean.expected.out | ||
| tuple.lean | ||
| tuple.lean.expected.out | ||
| typeFormerPolymorphism.lean | ||
| typeFormerPolymorphism.lean.expected.out | ||
| uint_fold.lean | ||
| uint_fold.lean.expected.out | ||
| unreachable.lean | ||
| unreachable.lean.expected.out | ||
| uset.lean | ||
| uset.lean.expected.out | ||
| utf8Path.lean | ||
| utf8Path.lean.expected.out | ||
| wait_dedicated.lean | ||
| wait_dedicated.lean.expected.out | ||