LCOV - differential code coverage report
Current view: top level - src/backend/jit - jit.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 60.0 % 50 30 20 2 28 3 6
Current Date: 2024-04-14 14:21:10 Functions: 66.7 % 6 4 1 1 2 2 1
Baseline: 16@8cea358b128 Branches: 53.8 % 26 14 1 11 1 13
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (60,120] days: 100.0 % 1 1 1
(180,240] days: 100.0 % 1 1 1
(240..) days: 58.3 % 48 28 20 28
Function coverage date bins:
(240..) days: 66.7 % 6 4 1 1 2 2
Branch coverage date bins:
(60,120] days: 50.0 % 2 1 1 1
(240..) days: 54.2 % 24 13 11 13

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * jit.c
                                  4                 :                :  *    Provider independent JIT infrastructure.
                                  5                 :                :  *
                                  6                 :                :  * Code related to loading JIT providers, redirecting calls into JIT providers
                                  7                 :                :  * and error handling.  No code specific to a specific JIT implementation
                                  8                 :                :  * should end up here.
                                  9                 :                :  *
                                 10                 :                :  *
                                 11                 :                :  * Copyright (c) 2016-2024, PostgreSQL Global Development Group
                                 12                 :                :  *
                                 13                 :                :  * IDENTIFICATION
                                 14                 :                :  *    src/backend/jit/jit.c
                                 15                 :                :  *
                                 16                 :                :  *-------------------------------------------------------------------------
                                 17                 :                :  */
                                 18                 :                : #include "postgres.h"
                                 19                 :                : 
                                 20                 :                : #include <sys/types.h>
                                 21                 :                : #include <sys/stat.h>
                                 22                 :                : #include <unistd.h>
                                 23                 :                : 
                                 24                 :                : #include "fmgr.h"
                                 25                 :                : #include "jit/jit.h"
                                 26                 :                : #include "miscadmin.h"
                                 27                 :                : #include "nodes/execnodes.h"
                                 28                 :                : #include "portability/instr_time.h"
                                 29                 :                : #include "utils/fmgrprotos.h"
                                 30                 :                : 
                                 31                 :                : /* GUCs */
                                 32                 :                : bool        jit_enabled = true;
                                 33                 :                : char       *jit_provider = NULL;
                                 34                 :                : bool        jit_debugging_support = false;
                                 35                 :                : bool        jit_dump_bitcode = false;
                                 36                 :                : bool        jit_expressions = true;
                                 37                 :                : bool        jit_profiling_support = false;
                                 38                 :                : bool        jit_tuple_deforming = true;
                                 39                 :                : double      jit_above_cost = 100000;
                                 40                 :                : double      jit_inline_above_cost = 500000;
                                 41                 :                : double      jit_optimize_above_cost = 500000;
                                 42                 :                : 
                                 43                 :                : static JitProviderCallbacks provider;
                                 44                 :                : static bool provider_successfully_loaded = false;
                                 45                 :                : static bool provider_failed_loading = false;
                                 46                 :                : 
                                 47                 :                : 
                                 48                 :                : static bool provider_init(void);
                                 49                 :                : 
                                 50                 :                : 
                                 51                 :                : /*
                                 52                 :                :  * SQL level function returning whether JIT is available in the current
                                 53                 :                :  * backend. Will attempt to load JIT provider if necessary.
                                 54                 :                :  */
                                 55                 :                : Datum
 2216 andres@anarazel.de         56                 :UBC           0 : pg_jit_available(PG_FUNCTION_ARGS)
                                 57                 :                : {
                                 58                 :              0 :     PG_RETURN_BOOL(provider_init());
                                 59                 :                : }
                                 60                 :                : 
                                 61                 :                : 
                                 62                 :                : /*
                                 63                 :                :  * Return whether a JIT provider has successfully been loaded, caching the
                                 64                 :                :  * result.
                                 65                 :                :  */
                                 66                 :                : static bool
 2216 andres@anarazel.de         67                 :CBC        5462 : provider_init(void)
                                 68                 :                : {
                                 69                 :                :     char        path[MAXPGPATH];
                                 70                 :                :     JitProviderInit init;
                                 71                 :                : 
                                 72                 :                :     /* don't even try to load if not enabled */
                                 73         [ -  + ]:           5462 :     if (!jit_enabled)
 2216 andres@anarazel.de         74                 :UBC           0 :         return false;
                                 75                 :                : 
                                 76                 :                :     /*
                                 77                 :                :      * Don't retry loading after failing - attempting to load JIT provider
                                 78                 :                :      * isn't cheap.
                                 79                 :                :      */
 2216 andres@anarazel.de         80         [ +  + ]:CBC        5462 :     if (provider_failed_loading)
                                 81                 :           5065 :         return false;
                                 82         [ -  + ]:            397 :     if (provider_successfully_loaded)
 2216 andres@anarazel.de         83                 :UBC           0 :         return true;
                                 84                 :                : 
                                 85                 :                :     /*
                                 86                 :                :      * Check whether shared library exists. We do that check before actually
                                 87                 :                :      * attempting to load the shared library (via load_external_function()),
                                 88                 :                :      * because that'd error out in case the shlib isn't available.
                                 89                 :                :      */
 2216 andres@anarazel.de         90                 :CBC         397 :     snprintf(path, MAXPGPATH, "%s/%s%s", pkglib_path, jit_provider, DLSUFFIX);
                                 91         [ -  + ]:            397 :     elog(DEBUG1, "probing availability of JIT provider at %s", path);
   93 michael@paquier.xyz        92         [ +  - ]:GNC         397 :     if (!pg_file_exists(path))
                                 93                 :                :     {
 2216 andres@anarazel.de         94         [ -  + ]:CBC         397 :         elog(DEBUG1,
                                 95                 :                :              "provider not available, disabling JIT for current session");
                                 96                 :            397 :         provider_failed_loading = true;
                                 97                 :            397 :         return false;
                                 98                 :                :     }
                                 99                 :                : 
                                100                 :                :     /*
                                101                 :                :      * If loading functions fails, signal failure. We do so because
                                102                 :                :      * load_external_function() might error out despite the above check if
                                103                 :                :      * e.g. the library's dependencies aren't installed. We want to signal
                                104                 :                :      * ERROR in that case, so the user is notified, but we don't want to
                                105                 :                :      * continually retry.
                                106                 :                :      */
 2216 andres@anarazel.de        107                 :UBC           0 :     provider_failed_loading = true;
                                108                 :                : 
                                109                 :                :     /* and initialize */
                                110                 :              0 :     init = (JitProviderInit)
                                111                 :              0 :         load_external_function(path, "_PG_jit_provider_init", true, NULL);
                                112                 :              0 :     init(&provider);
                                113                 :                : 
                                114                 :              0 :     provider_successfully_loaded = true;
                                115                 :              0 :     provider_failed_loading = false;
                                116                 :                : 
                                117         [ #  # ]:              0 :     elog(DEBUG1, "successfully loaded JIT provider in current session");
                                118                 :                : 
                                119                 :              0 :     return true;
                                120                 :                : }
                                121                 :                : 
                                122                 :                : /*
                                123                 :                :  * Reset JIT provider's error handling. This'll be called after an error has
                                124                 :                :  * been thrown and the main-loop has re-established control.
                                125                 :                :  */
                                126                 :                : void
 2216 andres@anarazel.de        127                 :CBC       19971 : jit_reset_after_error(void)
                                128                 :                : {
                                129         [ -  + ]:          19971 :     if (provider_successfully_loaded)
 2216 andres@anarazel.de        130                 :UBC           0 :         provider.reset_after_error();
 2216 andres@anarazel.de        131                 :CBC       19971 : }
                                132                 :                : 
                                133                 :                : /*
                                134                 :                :  * Release resources required by one JIT context.
                                135                 :                :  */
                                136                 :                : void
 2216 andres@anarazel.de        137                 :UBC           0 : jit_release_context(JitContext *context)
                                138                 :                : {
                                139         [ #  # ]:              0 :     if (provider_successfully_loaded)
                                140                 :              0 :         provider.release_context(context);
                                141                 :                : 
                                142                 :              0 :     pfree(context);
                                143                 :              0 : }
                                144                 :                : 
                                145                 :                : /*
                                146                 :                :  * Ask provider to JIT compile an expression.
                                147                 :                :  *
                                148                 :                :  * Returns true if successful, false if not.
                                149                 :                :  */
                                150                 :                : bool
 2217 andres@anarazel.de        151                 :CBC     1122611 : jit_compile_expr(struct ExprState *state)
                                152                 :                : {
                                153                 :                :     /*
                                154                 :                :      * We can easily create a one-off context for functions without an
                                155                 :                :      * associated PlanState (and thus EState). But because there's no executor
                                156                 :                :      * shutdown callback that could deallocate the created function, they'd
                                157                 :                :      * live to the end of the transactions, where they'd be cleaned up by the
                                158                 :                :      * resowner machinery. That can lead to a noticeable amount of memory
                                159                 :                :      * usage, and worse, trigger some quadratic behaviour in gdb. Therefore,
                                160                 :                :      * at least for now, don't create a JITed function in those circumstances.
                                161                 :                :      */
                                162         [ +  + ]:        1122611 :     if (!state->parent)
                                163                 :         327330 :         return false;
                                164                 :                : 
                                165                 :                :     /* if no jitting should be performed at all */
                                166         [ +  + ]:         795281 :     if (!(state->parent->state->es_jit_flags & PGJIT_PERFORM))
                                167                 :         789819 :         return false;
                                168                 :                : 
                                169                 :                :     /* or if expressions aren't JITed */
                                170         [ -  + ]:           5462 :     if (!(state->parent->state->es_jit_flags & PGJIT_EXPR))
 2217 andres@anarazel.de        171                 :UBC           0 :         return false;
                                172                 :                : 
                                173                 :                :     /* this also takes !jit_enabled into account */
 2217 andres@anarazel.de        174         [ -  + ]:CBC        5462 :     if (provider_init())
 2217 andres@anarazel.de        175                 :UBC           0 :         return provider.compile_expr(state);
                                176                 :                : 
 2217 andres@anarazel.de        177                 :CBC        5462 :     return false;
                                178                 :                : }
                                179                 :                : 
                                180                 :                : /* Aggregate JIT instrumentation information */
                                181                 :                : void
 2028                           182                 :             36 : InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add)
                                183                 :                : {
                                184                 :             36 :     dst->created_functions += add->created_functions;
                                185                 :             36 :     INSTR_TIME_ADD(dst->generation_counter, add->generation_counter);
  219 dgustafsson@postgres      186                 :GNC          36 :     INSTR_TIME_ADD(dst->deform_counter, add->deform_counter);
 2028 andres@anarazel.de        187                 :CBC          36 :     INSTR_TIME_ADD(dst->inlining_counter, add->inlining_counter);
                                188                 :             36 :     INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter);
                                189                 :             36 :     INSTR_TIME_ADD(dst->emission_counter, add->emission_counter);
                                190                 :             36 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622