aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2018-02-19 17:06:35 +0100
committerJohn Högberg <[email protected]>2018-02-26 08:29:28 +0100
commit7fb9b59ed1fc6cbff581effaea7504fd2dc90f4e (patch)
tree829bc227637eae33badf143128508c86791f64e1 /erts/emulator/beam
parent8c3f3303f20ab5f1031731af6df5c2ef1499cd36 (diff)
downloadotp-7fb9b59ed1fc6cbff581effaea7504fd2dc90f4e.tar.gz
otp-7fb9b59ed1fc6cbff581effaea7504fd2dc90f4e.tar.bz2
otp-7fb9b59ed1fc6cbff581effaea7504fd2dc90f4e.zip
Free temporary iovecs through the tmp object list
Attaching to a ProcBin is the fastest way to delay the release of an already allocated Binary, but alloc_tmp_obj is a lot faster when starting from scratch since it usually uses temp_alloc.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/erl_nif.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 6ccf37e793..28b68c9e7d 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -3543,19 +3543,14 @@ static int create_iovec_from_slice(ErlNifEnv *env,
alloc_size = binv_offset;
alloc_size += slice->iovec_len * sizeof(Binary*);
- /* If we have an environment we'll attach the allocated data to it. The
- * GC will take care of releasing it later on. */
+ /* When the user passes an environment, we attach the iovec to it so
+ * the user won't have to bother managing it (similar to
+ * enif_inspect_binary). It'll disappear once the environment is
+ * cleaned up. */
if (env != NULL) {
- ErlNifBinary gc_bin;
-
- if (!enif_alloc_binary(alloc_size, &gc_bin)) {
- return 0;
- }
-
- alloc_base = (char*)gc_bin.data;
- enif_make_binary(env, &gc_bin);
+ alloc_base = alloc_tmp_obj(env, alloc_size, &tmp_alloc_dtor);
} else {
- alloc_base = enif_alloc(alloc_size);
+ alloc_base = erts_alloc(ERTS_ALC_T_NIF, alloc_size);
}
iovec = (ErlNifIOVec*)alloc_base;
@@ -3569,7 +3564,7 @@ static int create_iovec_from_slice(ErlNifEnv *env,
if(!fill_iovec_with_slice(env, slice, iovec)) {
if (env == NULL && !(iovec->flags & ERL_NIF_IOVEC_FLAGS_PREALLOC)) {
- enif_free(iovec);
+ erts_free(ERTS_ALC_T_NIF, iovec);
}
return 0;