This is an automated email from the ASF dual-hosted git repository.

nickva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb-jiffy.git

commit 5ba849569f27cb607eb0ae1289e4db43d327b072
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Tue Mar 31 00:05:17 2026 -0400

    Clean up unused code paths. Make OTP 20 the official minimum version
    
    These are based on the new coverage reports
    
     * `make_ok()` function is not used anywhere
     * `CONSUME_TIMESLICE_PRESENT` and SCHEDULE_NIF_PRESENT features are always 
present
     * `ERROR()` and `U()` macros are not used.
    
    The most "interesting" change is finding out `enif_alloc_resource()` cannot
    return `NULL` [1][2], and so `dec_new()` and its callers don't have to 
handle
    `NULL`s. Which, in turn, eliminated a bunch of `make_error()` calls. With 
some
    `make_error()`s removed, it doesn't have to be utility function, so can be
    moved to the encoder only.
    
    When moving `make_error()` to the encoder, noticed those functions along 
with
    others should really be static if they are not used from other modules.
    
    Since we removed checks for CONSUME_TIMESLICE_PRESENT, which is present 
since
    OTP 17 onwards, and to avoid users getting surprises later during C during
    compilation, make OTP 20 the official minimum OTP version (so far it's been
    unofficial only).
    
    [1] https://www.erlang.org/doc/apps/erts/erl_nif.html#enif_alloc_resource
    
    [2]
    
     - In 
[beam/erl_nif.c](https://github.com/erlang/otp/blob/639c85d7400d34c82df962547561cc1dc0a42755/erts/emulator/beam/erl_nif.c#L3121)
    it calls `bin = erts_create_magic_binary_x()`
    
     - In
     
[beam/erl_binary.h](https://github.com/erlang/otp/blob/639c85d7400d34c82df962547561cc1dc0a42755/erts/emulator/beam/erl_binary.h#L407)
     if the magic binary allocation fails it calls `erts_alloc_n_enomem()`
    
     - In
     
[beam/erl_alloc.c](https://github.com/erlang/otp/blob/639c85d7400d34c82df962547561cc1dc0a42755/erts/emulator/beam/erl_alloc.c#L2108)
     `erts_alloc_n_enomem()` calls `erts_alc_fatal_error()` which calls
     `erts_exit()` after a bunch of logging and debug dumps.
---
 c_src/decoder.c | 24 ++++++------------------
 c_src/encoder.c | 41 ++++++++++++++++++++++++-----------------
 c_src/jiffy.h   | 10 ----------
 c_src/util.c    | 26 --------------------------
 rebar.config    |  2 ++
 5 files changed, 32 insertions(+), 71 deletions(-)

diff --git a/c_src/decoder.c b/c_src/decoder.c
index 6a1a7fd..f3fcc7f 100644
--- a/c_src/decoder.c
+++ b/c_src/decoder.c
@@ -10,9 +10,6 @@
 #include "erl_nif.h"
 #include "jiffy.h"
 
-#define U(c) ((unsigned char) (c))
-#define ERROR(i, msg) make_error(st, env, msg)
-
 #define STACK_SIZE_INC 64
 #define NUM_BUF_LEN 32
 
@@ -66,17 +63,17 @@ typedef struct {
     int             st_top;
 } Decoder;
 
+// Returns an allocated resource or crashes the VM. No need to
+// check return pointer for NULL
 Decoder*
 dec_new(ErlNifEnv* env)
 {
     jiffy_st* st = (jiffy_st*) enif_priv_data(env);
+    // If enif_alloc_resource cannot allocate it crashes the VM
     Decoder* d = enif_alloc_resource(st->res_dec, sizeof(Decoder));
+    assert(d != NULL);
     int i;
 
-    if(d == NULL) {
-        return NULL;
-    }
-
     d->atoms = st;
 
     d->bytes_per_red = DEFAULT_BYTES_PER_REDUCTION;
@@ -654,10 +651,9 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM 
argv[])
         return enif_make_badarg(env);
     }
 
+    // If allocation fails VM will crash.
     d = dec_new(env);
-    if(d == NULL) {
-        return make_error(st, env, "internal_error");
-    }
+    assert(d != NULL);
 
     tmp_argv[0] = argv[0];
     tmp_argv[1] = enif_make_resource(env, d);
@@ -746,7 +742,6 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM 
argv[])
 
             bump_used_reds(env, bytes_processed, d->bytes_per_red);
 
-#if SCHEDULE_NIF_PRESENT
             return enif_schedule_nif(
                     env,
                     "nif_decode_iter",
@@ -755,13 +750,6 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM 
argv[])
                     5,
                     tmp_argv
                 );
-#else
-            return enif_make_tuple2(
-                    env,
-                    st->atom_iter,
-                    enif_make_tuple_from_array(env, tmp_argv, 5)
-                );
-#endif
         }
 
         switch(dec_curr(d)) {
diff --git a/c_src/encoder.c b/c_src/encoder.c
index 4a68c74..29ff860 100644
--- a/c_src/encoder.c
+++ b/c_src/encoder.c
@@ -66,7 +66,7 @@ static char* shifts[NUM_SHIFTS] = {
 };
 
 
-Encoder*
+static Encoder*
 enc_new(ErlNifEnv* env)
 {
     jiffy_st* st = (jiffy_st*) enif_priv_data(env);
@@ -99,7 +99,7 @@ enc_new(ErlNifEnv* env)
     return e;
 }
 
-int
+static int
 enc_init(Encoder* e, ErlNifEnv* env)
 {
     e->env = env;
@@ -116,20 +116,34 @@ enc_destroy(ErlNifEnv* env, void* obj)
     }
 }
 
-ERL_NIF_TERM
+static ERL_NIF_TERM
+make_error(jiffy_st* st, ErlNifEnv* env, const char* error)
+{
+    return enif_make_tuple2(env, st->atom_error, make_atom(env, error));
+}
+
+static ERL_NIF_TERM
 enc_error(Encoder* e, const char* msg)
 {
     //assert(0 && msg);
     return make_error(e->atoms, e->env, msg);
 }
 
-ERL_NIF_TERM
+static ERL_NIF_TERM
+make_obj_error(jiffy_st* st, ErlNifEnv* env,
+        const char* error, ERL_NIF_TERM obj)
+{
+    ERL_NIF_TERM reason = enif_make_tuple2(env, make_atom(env, error), obj);
+    return enif_make_tuple2(env, st->atom_error, reason);
+}
+
+static ERL_NIF_TERM
 enc_obj_error(Encoder* e, const char* msg, ERL_NIF_TERM obj)
 {
     return make_obj_error(e->atoms, e->env, msg, obj);
 }
 
-int
+static int
 enc_flush(Encoder* e)
 {
     ERL_NIF_TERM bin;
@@ -411,7 +425,7 @@ enc_object_key(ErlNifEnv *env, Encoder* e, ERL_NIF_TERM val)
 #define P11 100000000000L
 #define P12 1000000000000L
 
-int
+static inline int
 digits10(ErlNifUInt64 v)
 {
     if (v < P01) return 1;
@@ -435,7 +449,7 @@ digits10(ErlNifUInt64 v)
     return 12 + digits10(v / P12);
 }
 
-unsigned int
+static inline unsigned int
 u64ToAsciiTable(unsigned char *dst, ErlNifUInt64 value)
 {
     static const char digits[201] =
@@ -464,7 +478,7 @@ u64ToAsciiTable(unsigned char *dst, ErlNifUInt64 value)
     return length;
 }
 
-unsigned
+static inline unsigned
 i64ToAsciiTable(unsigned char *dst, ErlNifSInt64 value)
 {
     if (value < 0) {
@@ -595,7 +609,7 @@ enc_comma(Encoder* e)
     return 1;
 }
 
-int
+static int
 enc_map_to_ejson(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM* out)
 {
     ErlNifMapIterator iter;
@@ -743,7 +757,6 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM 
argv[])
             termstack_destroy(&stack);
             bump_used_reds(env, bytes_processed, e->bytes_per_red);
 
-#if SCHEDULE_NIF_PRESENT
             return enif_schedule_nif(
                     env,
                     "nif_encode_iter",
@@ -752,13 +765,7 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM 
argv[])
                     3,
                     tmp_argv
                 );
-#else
-            return enif_make_tuple2(
-                    env,
-                    st->atom_iter,
-                    enif_make_tuple_from_array(env, tmp_argv, 3)
-                );
-#endif
+
         }
 
         curr = termstack_pop(&stack);
diff --git a/c_src/jiffy.h b/c_src/jiffy.h
index 351749f..af755da 100644
--- a/c_src/jiffy.h
+++ b/c_src/jiffy.h
@@ -9,12 +9,6 @@
 #define DEFAULT_BYTES_PER_REDUCTION 20
 #define DEFAULT_ERLANG_REDUCTION_COUNT 2000
 
-#define CONSUME_TIMESLICE_PRESENT \
-        ((ERL_NIF_MAJOR_VERSION >= 2 && ERL_NIF_MINOR_VERSION >= 4))
-
-#define SCHEDULE_NIF_PRESENT \
-        ((ERL_NIF_MAJOR_VERSION >= 2 && ERL_NIF_MINOR_VERSION >= 7))
-
 typedef struct {
     ERL_NIF_TERM    atom_ok;
     ERL_NIF_TERM    atom_error;
@@ -49,10 +43,6 @@ typedef struct {
 } jiffy_st;
 
 ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name);
-ERL_NIF_TERM make_ok(jiffy_st* st, ErlNifEnv* env, ERL_NIF_TERM data);
-ERL_NIF_TERM make_error(jiffy_st* st, ErlNifEnv* env, const char* error);
-ERL_NIF_TERM make_obj_error(jiffy_st* st, ErlNifEnv* env, const char* error,
-        ERL_NIF_TERM obj);
 int get_bytes_per_iter(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi);
 int get_bytes_per_red(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpr);
 int get_null_term(ErlNifEnv* env, ERL_NIF_TERM val, ERL_NIF_TERM *null_term);
diff --git a/c_src/util.c b/c_src/util.c
index f6dcb68..5df4fde 100644
--- a/c_src/util.c
+++ b/c_src/util.c
@@ -14,26 +14,6 @@ make_atom(ErlNifEnv* env, const char* name)
     return enif_make_atom(env, name);
 }
 
-ERL_NIF_TERM
-make_ok(jiffy_st* st, ErlNifEnv* env, ERL_NIF_TERM value)
-{
-    return enif_make_tuple2(env, st->atom_ok, value);
-}
-
-ERL_NIF_TERM
-make_error(jiffy_st* st, ErlNifEnv* env, const char* error)
-{
-    return enif_make_tuple2(env, st->atom_error, make_atom(env, error));
-}
-
-ERL_NIF_TERM
-make_obj_error(jiffy_st* st, ErlNifEnv* env,
-        const char* error, ERL_NIF_TERM obj)
-{
-    ERL_NIF_TERM reason = enif_make_tuple2(env, make_atom(env, error), obj);
-    return enif_make_tuple2(env, st->atom_error, reason);
-}
-
 int
 get_bytes_per_iter(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi)
 {
@@ -130,7 +110,6 @@ should_yield(size_t used, size_t bytes_per_red)
 void
 bump_used_reds(ErlNifEnv* env, size_t used, size_t bytes_per_red)
 {
-#if CONSUME_TIMESLICE_PRESENT
     size_t reds_used;
     size_t pct_used;
 
@@ -144,9 +123,4 @@ bump_used_reds(ErlNifEnv* env, size_t used, size_t 
bytes_per_red)
 
         enif_consume_timeslice(env, pct_used);
     }
-#endif
-
-    (void) env;
-    (void) used;
-    (void) bytes_per_red;
 }
diff --git a/rebar.config b/rebar.config
index 6ab52c2..2cd6b3b 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,3 +1,5 @@
+{require_min_otp_vsn, "20"}.
+
 {port_specs, [
     {"priv/jiffy.so", [
         "c_src/*.c",

Reply via email to