PostgreSQL Source Code  git master
jit.c File Reference
#include "postgres.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "executor/execExpr.h"
#include "fmgr.h"
#include "jit/jit.h"
#include "miscadmin.h"
#include "utils/fmgrprotos.h"
#include "utils/resowner_private.h"
Include dependency graph for jit.c:

Go to the source code of this file.

Functions

static bool provider_init (void)
 
static bool file_exists (const char *name)
 
Datum pg_jit_available (PG_FUNCTION_ARGS)
 
void jit_reset_after_error (void)
 
void jit_release_context (JitContext *context)
 
bool jit_compile_expr (struct ExprState *state)
 
void InstrJitAgg (JitInstrumentation *dst, JitInstrumentation *add)
 

Variables

bool jit_enabled = true
 
char * jit_provider = NULL
 
bool jit_debugging_support = false
 
bool jit_dump_bitcode = false
 
bool jit_expressions = true
 
bool jit_profiling_support = false
 
bool jit_tuple_deforming = true
 
double jit_above_cost = 100000
 
double jit_inline_above_cost = 500000
 
double jit_optimize_above_cost = 500000
 
static JitProviderCallbacks provider
 
static bool provider_successfully_loaded = false
 
static bool provider_failed_loading = false
 

Function Documentation

◆ file_exists()

static bool file_exists ( const char *  name)
static

Definition at line 194 of file jit.c.

References AssertArg, ereport, errcode_for_file_access(), errmsg(), ERROR, false, S_ISDIR, and stat.

Referenced by isolation_start_test(), provider_init(), and psql_start_test().

195 {
196  struct stat st;
197 
198  AssertArg(name != NULL);
199 
200  if (stat(name, &st) == 0)
201  return S_ISDIR(st.st_mode) ? false : true;
202  else if (!(errno == ENOENT || errno == ENOTDIR))
203  ereport(ERROR,
205  errmsg("could not access file \"%s\": %m", name)));
206 
207  return false;
208 }
#define false
Definition: c.h:317
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:631
#define ereport(elevel, rest)
Definition: elog.h:141
#define AssertArg(condition)
Definition: c.h:735
#define stat(a, b)
Definition: win32_port.h:255
const char * name
Definition: encode.c:521
#define S_ISDIR(m)
Definition: win32_port.h:296
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ InstrJitAgg()

◆ jit_compile_expr()

bool jit_compile_expr ( struct ExprState state)

Definition at line 153 of file jit.c.

References JitProviderCallbacks::compile_expr, EState::es_jit_flags, ExprState::parent, PGJIT_EXPR, PGJIT_PERFORM, provider_init(), and PlanState::state.

Referenced by ExecReadyExpr().

154 {
155  /*
156  * We can easily create a one-off context for functions without an
157  * associated PlanState (and thus EState). But because there's no executor
158  * shutdown callback that could deallocate the created function, they'd
159  * live to the end of the transactions, where they'd be cleaned up by the
160  * resowner machinery. That can lead to a noticeable amount of memory
161  * usage, and worse, trigger some quadratic behaviour in gdb. Therefore,
162  * at least for now, don't create a JITed function in those circumstances.
163  */
164  if (!state->parent)
165  return false;
166 
167  /* if no jitting should be performed at all */
168  if (!(state->parent->state->es_jit_flags & PGJIT_PERFORM))
169  return false;
170 
171  /* or if expressions aren't JITed */
172  if (!(state->parent->state->es_jit_flags & PGJIT_EXPR))
173  return false;
174 
175  /* this also takes !jit_enabled into account */
176  if (provider_init())
177  return provider.compile_expr(state);
178 
179  return false;
180 }
#define PGJIT_EXPR
Definition: jit.h:23
struct PlanState * parent
Definition: execnodes.h:108
EState * state
Definition: execnodes.h:942
static bool provider_init(void)
Definition: jit.c:68
static JitProviderCallbacks provider
Definition: jit.c:43
int es_jit_flags
Definition: execnodes.h:595
JitProviderCompileExprCB compile_expr
Definition: jit.h:77
#define PGJIT_PERFORM
Definition: jit.h:20

◆ jit_release_context()

void jit_release_context ( JitContext context)

Definition at line 138 of file jit.c.

References pfree(), PointerGetDatum, provider_successfully_loaded, JitProviderCallbacks::release_context, ResourceOwnerForgetJIT(), and JitContext::resowner.

Referenced by FreeExecutorState(), and ResourceOwnerReleaseInternal().

139 {
141  provider.release_context(context);
142 
143  ResourceOwnerForgetJIT(context->resowner, PointerGetDatum(context));
144  pfree(context);
145 }
#define PointerGetDatum(X)
Definition: postgres.h:556
void pfree(void *pointer)
Definition: mcxt.c:1056
static JitProviderCallbacks provider
Definition: jit.c:43
ResourceOwner resowner
Definition: jit.h:59
static bool provider_successfully_loaded
Definition: jit.c:44
void ResourceOwnerForgetJIT(ResourceOwner owner, Datum handle)
Definition: resowner.c:1343
JitProviderReleaseContextCB release_context
Definition: jit.h:76

◆ jit_reset_after_error()

void jit_reset_after_error ( void  )

Definition at line 128 of file jit.c.

References provider_successfully_loaded, and JitProviderCallbacks::reset_after_error.

Referenced by PostgresMain().

129 {
132 }
JitProviderResetAfterErrorCB reset_after_error
Definition: jit.h:75
static JitProviderCallbacks provider
Definition: jit.c:43
static bool provider_successfully_loaded
Definition: jit.c:44

◆ pg_jit_available()

Datum pg_jit_available ( PG_FUNCTION_ARGS  )

Definition at line 57 of file jit.c.

References PG_RETURN_BOOL, and provider_init().

58 {
60 }
static bool provider_init(void)
Definition: jit.c:68
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349

◆ provider_init()

static bool provider_init ( void  )
static

Definition at line 68 of file jit.c.

References DEBUG1, elog, file_exists(), init, jit_enabled, jit_provider, load_external_function(), MAXPGPATH, pkglib_path, provider_failed_loading, provider_successfully_loaded, and snprintf.

Referenced by jit_compile_expr(), and pg_jit_available().

69 {
70  char path[MAXPGPATH];
72 
73  /* don't even try to load if not enabled */
74  if (!jit_enabled)
75  return false;
76 
77  /*
78  * Don't retry loading after failing - attempting to load JIT provider
79  * isn't cheap.
80  */
82  return false;
84  return true;
85 
86  /*
87  * Check whether shared library exists. We do that check before actually
88  * attempting to load the shared library (via load_external_function()),
89  * because that'd error out in case the shlib isn't available.
90  */
91  snprintf(path, MAXPGPATH, "%s/%s%s", pkglib_path, jit_provider, DLSUFFIX);
92  elog(DEBUG1, "probing availability of JIT provider at %s", path);
93  if (!file_exists(path))
94  {
95  elog(DEBUG1,
96  "provider not available, disabling JIT for current session");
98  return false;
99  }
100 
101  /*
102  * If loading functions fails, signal failure. We do so because
103  * load_external_function() might error out despite the above check if
104  * e.g. the library's dependencies aren't installed. We want to signal
105  * ERROR in that case, so the user is notified, but we don't want to
106  * continually retry.
107  */
109 
110  /* and initialize */
111  init = (JitProviderInit)
112  load_external_function(path, "_PG_jit_provider_init", true, NULL);
113  init(&provider);
114 
116  provider_failed_loading = false;
117 
118  elog(DEBUG1, "successfully loaded JIT provider in current session");
119 
120  return true;
121 }
char * jit_provider
Definition: jit.c:33
#define DEBUG1
Definition: elog.h:25
static bool provider_failed_loading
Definition: jit.c:45
bool jit_enabled
Definition: jit.c:32
#define MAXPGPATH
static JitProviderCallbacks provider
Definition: jit.c:43
static bool file_exists(const char *name)
Definition: jit.c:194
#define init()
PGFunction load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition: dfmgr.c:107
void(* JitProviderInit)(JitProviderCallbacks *cb)
Definition: jit.h:67
static bool provider_successfully_loaded
Definition: jit.c:44
#define elog(elevel,...)
Definition: elog.h:228
#define snprintf
Definition: port.h:192
char pkglib_path[MAXPGPATH]
Definition: globals.c:73

Variable Documentation

◆ jit_above_cost

double jit_above_cost = 100000

Definition at line 39 of file jit.c.

Referenced by standard_planner().

◆ jit_debugging_support

bool jit_debugging_support = false

Definition at line 34 of file jit.c.

Referenced by llvm_session_initialize().

◆ jit_dump_bitcode

bool jit_dump_bitcode = false

Definition at line 35 of file jit.c.

Referenced by llvm_compile_module().

◆ jit_enabled

bool jit_enabled = true

Definition at line 32 of file jit.c.

Referenced by provider_init(), and standard_planner().

◆ jit_expressions

bool jit_expressions = true

Definition at line 36 of file jit.c.

Referenced by standard_planner().

◆ jit_inline_above_cost

double jit_inline_above_cost = 500000

Definition at line 40 of file jit.c.

Referenced by standard_planner().

◆ jit_optimize_above_cost

double jit_optimize_above_cost = 500000

Definition at line 41 of file jit.c.

Referenced by standard_planner().

◆ jit_profiling_support

bool jit_profiling_support = false

Definition at line 37 of file jit.c.

Referenced by llvm_session_initialize(), and llvm_shutdown().

◆ jit_provider

char* jit_provider = NULL

Definition at line 33 of file jit.c.

Referenced by provider_init().

◆ jit_tuple_deforming

bool jit_tuple_deforming = true

Definition at line 38 of file jit.c.

Referenced by standard_planner().

◆ provider

◆ provider_failed_loading

bool provider_failed_loading = false
static

Definition at line 45 of file jit.c.

Referenced by provider_init().

◆ provider_successfully_loaded

bool provider_successfully_loaded = false
static

Definition at line 44 of file jit.c.

Referenced by jit_release_context(), jit_reset_after_error(), and provider_init().