PostgreSQL Source Code git master
Loading...
Searching...
No Matches
jit.c
Go to the documentation of this file.
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-2026, 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"
29#include "storage/fd.h"
30#include "utils/fmgrprotos.h"
31
32/* GUCs */
33bool jit_enabled = true;
36bool jit_dump_bitcode = false;
37bool jit_expressions = true;
40double jit_above_cost = 100000;
41double jit_inline_above_cost = 500000;
43
45static bool provider_successfully_loaded = false;
46static bool provider_failed_loading = false;
47
48
49static bool provider_init(void);
50
51
52/*
53 * SQL level function returning whether JIT is available in the current
54 * backend. Will attempt to load JIT provider if necessary.
55 */
61
62
63/*
64 * Return whether a JIT provider has successfully been loaded, caching the
65 * result.
66 */
67static bool
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 */
92 elog(DEBUG1, "probing availability of JIT provider at %s", path);
93 if (!pg_file_exists(path))
94 {
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 */
112 load_external_function(path, "_PG_jit_provider_init", true, NULL);
113 init(&provider);
114
117
118 elog(DEBUG1, "successfully loaded JIT provider in current session");
119
120 return true;
121}
122
123/*
124 * Reset JIT provider's error handling. This'll be called after an error has
125 * been thrown and the main-loop has re-established control.
126 */
127void
129{
131 provider.reset_after_error();
132}
133
134/*
135 * Release resources required by one JIT context.
136 */
137void
139{
141 provider.release_context(context);
142
143 pfree(context);
144}
145
146/*
147 * Ask provider to JIT compile an expression.
148 *
149 * Returns true if successful, false if not.
150 */
151bool
153{
154 /*
155 * We can easily create a one-off context for functions without an
156 * associated PlanState (and thus EState). But because there's no executor
157 * shutdown callback that could deallocate the created function, they'd
158 * live to the end of the transactions, where they'd be cleaned up by the
159 * resowner machinery. That can lead to a noticeable amount of memory
160 * usage, and worse, trigger some quadratic behaviour in gdb. Therefore,
161 * at least for now, don't create a JITed function in those circumstances.
162 */
163 if (!state->parent)
164 return false;
165
166 /* if no jitting should be performed at all */
167 if (!(state->parent->state->es_jit_flags & PGJIT_PERFORM))
168 return false;
169
170 /* or if expressions aren't JITed */
171 if (!(state->parent->state->es_jit_flags & PGJIT_EXPR))
172 return false;
173
174 /* this also takes !jit_enabled into account */
175 if (provider_init())
176 return provider.compile_expr(state);
177
178 return false;
179}
180
181/* Aggregate JIT instrumentation information */
182void
184{
185 dst->created_functions += add->created_functions;
186 INSTR_TIME_ADD(dst->generation_counter, add->generation_counter);
187 INSTR_TIME_ADD(dst->deform_counter, add->deform_counter);
188 INSTR_TIME_ADD(dst->inlining_counter, add->inlining_counter);
189 INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter);
190 INSTR_TIME_ADD(dst->emission_counter, add->emission_counter);
191}
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition dfmgr.c:95
#define DEBUG1
Definition elog.h:30
#define elog(elevel,...)
Definition elog.h:226
bool pg_file_exists(const char *name)
Definition fd.c:504
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
char pkglib_path[MAXPGPATH]
Definition globals.c:82
#define INSTR_TIME_ADD(x, y)
Definition instr_time.h:174
void jit_reset_after_error(void)
Definition jit.c:128
double jit_optimize_above_cost
Definition jit.c:42
bool jit_dump_bitcode
Definition jit.c:36
bool jit_enabled
Definition jit.c:33
static bool provider_successfully_loaded
Definition jit.c:45
char * jit_provider
Definition jit.c:34
bool jit_expressions
Definition jit.c:37
void InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add)
Definition jit.c:183
Datum pg_jit_available(PG_FUNCTION_ARGS)
Definition jit.c:57
bool jit_compile_expr(struct ExprState *state)
Definition jit.c:152
bool jit_tuple_deforming
Definition jit.c:39
void jit_release_context(JitContext *context)
Definition jit.c:138
double jit_above_cost
Definition jit.c:40
static bool provider_failed_loading
Definition jit.c:46
double jit_inline_above_cost
Definition jit.c:41
static bool provider_init(void)
Definition jit.c:68
bool jit_profiling_support
Definition jit.c:38
bool jit_debugging_support
Definition jit.c:35
static JitProviderCallbacks provider
Definition jit.c:44
#define PGJIT_EXPR
Definition jit.h:23
void(* JitProviderInit)(JitProviderCallbacks *cb)
Definition jit.h:68
#define PGJIT_PERFORM
Definition jit.h:20
void pfree(void *pointer)
Definition mcxt.c:1616
#define MAXPGPATH
#define snprintf
Definition port.h:260
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
#define init()