aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-03-15 17:47:47 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-03-15 17:57:21 -0400
commit9c13e9b7ed9806d0f9774433d5e24359aff1b238 (patch)
tree5e595fd2182648e660db56b88b86f162810df8f4 /src/codegen.cpp
parent4090fe81f600afa290de5bf06a287d5fab2ea9dc (diff)
downloadzig-9c13e9b7ed9806d0f9774433d5e24359aff1b238.tar.gz
zig-9c13e9b7ed9806d0f9774433d5e24359aff1b238.zip
breaking changes to std.mem.Allocator interface API
Before, allocator implementations had to provide `allocFn`, `reallocFn`, and `freeFn`. Now, they must provide only `reallocFn` and `shrinkFn`. Reallocating from a zero length slice is allocation, and shrinking to a zero length slice is freeing. When the new memory size is less than or equal to the previous allocation size, `reallocFn` now has the option to return `error.OutOfMemory` to indicate that the allocator would not be able to take advantage of the new size. For more details see #1306. This commit closes #1306. This commit paves the way to solving #2009. This commit also introduces a memory leak to all coroutines. There is an issue where a coroutine calls the function and it frees its own stack frame, but then the return value of `shrinkFn` is a slice, which is implemented as an sret struct. Writing to the return pointer causes invalid memory write. We could work around it by having a global helper function which has a void return type and calling that instead. But instead this hack will suffice until I rework coroutines to be non-allocating. Basically coroutines are not supported right now until they are reworked as in #1194.
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index df907915bb..2de1243a66 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -5177,7 +5177,7 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
LLVMValueRef sret_ptr = LLVMBuildAlloca(g->builder, LLVMGetElementType(alloc_fn_arg_types[0]), "");
size_t next_arg = 0;
- LLVMValueRef alloc_fn_val = LLVMGetParam(fn_val, next_arg);
+ LLVMValueRef realloc_fn_val = LLVMGetParam(fn_val, next_arg);
next_arg += 1;
LLVMValueRef stack_trace_val;
@@ -5195,15 +5195,22 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
LLVMValueRef alignment_val = LLVMConstInt(g->builtin_types.entry_u29->type_ref,
get_coro_frame_align_bytes(g), false);
+ ConstExprValue *zero_array = create_const_str_lit(g, buf_create_from_str(""));
+ ConstExprValue *undef_slice_zero = create_const_slice(g, zero_array, 0, 0, false);
+ render_const_val(g, undef_slice_zero, "");
+ render_const_val_global(g, undef_slice_zero, "");
+
ZigList<LLVMValueRef> args = {};
args.append(sret_ptr);
if (g->have_err_ret_tracing) {
args.append(stack_trace_val);
}
args.append(allocator_val);
+ args.append(undef_slice_zero->global_refs->llvm_global);
+ args.append(LLVMGetUndef(g->builtin_types.entry_u29->type_ref));
args.append(coro_size);
args.append(alignment_val);
- LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, alloc_fn_val, args.items, args.length,
+ LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, realloc_fn_val, args.items, args.length,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
set_call_instr_sret(g, call_instruction);
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");
@@ -5239,14 +5246,14 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
static LLVMValueRef ir_render_coro_alloc_helper(CodeGen *g, IrExecutable *executable,
IrInstructionCoroAllocHelper *instruction)
{
- LLVMValueRef alloc_fn = ir_llvm_value(g, instruction->alloc_fn);
+ LLVMValueRef realloc_fn = ir_llvm_value(g, instruction->realloc_fn);
LLVMValueRef coro_size = ir_llvm_value(g, instruction->coro_size);
- LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(alloc_fn), instruction->alloc_fn->value.type);
+ LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(realloc_fn), instruction->realloc_fn->value.type);
size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
ZigList<LLVMValueRef> params = {};
- params.append(alloc_fn);
+ params.append(realloc_fn);
uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, g->cur_fn);
if (err_ret_trace_arg_index != UINT32_MAX) {
params.append(LLVMGetParam(g->cur_fn_val, err_ret_trace_arg_index));