1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Basic JIT provider and error handling infrastructure.

This commit introduces:

1) JIT provider abstraction, which allows JIT functionality to be
   implemented in separate shared libraries. That's desirable because
   it allows to install JIT support as a separate package, and because
   it allows experimentation with different forms of JITing.
2) JITContexts which can be, using functions introduced in follow up
   commits, used to emit JITed functions, and have them be cleaned up
   on error.
3) The outline of a LLVM JIT provider, which will be fleshed out in
   subsequent commits.

Documentation for GUCs added, and for JIT in general, will be added in
later commits.

Author: Andres Freund, with architectural input from Jeff Davis
Discussion: https://postgr.es/m/20170901064131.tazjxwus3k2w3ybh@alap3.anarazel.de
This commit is contained in:
Andres Freund
2018-03-21 19:28:28 -07:00
parent 4317cc68a2
commit 432bb9e04d
18 changed files with 679 additions and 2 deletions

View File

@ -0,0 +1,113 @@
/*-------------------------------------------------------------------------
*
* llvmjit.c
* Core part of the LLVM JIT provider.
*
* Copyright (c) 2016-2018, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/jit/llvm/llvmjit.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "jit/llvmjit.h"
#include "miscadmin.h"
#include "utils/memutils.h"
#include "utils/resowner_private.h"
#include "storage/ipc.h"
#include <llvm-c/Target.h>
static bool llvm_session_initialized = false;
static void llvm_release_context(JitContext *context);
static void llvm_session_initialize(void);
static void llvm_shutdown(int code, Datum arg);
PG_MODULE_MAGIC;
/*
* Initialize LLVM JIT provider.
*/
void
_PG_jit_provider_init(JitProviderCallbacks *cb)
{
cb->reset_after_error = llvm_reset_after_error;
cb->release_context = llvm_release_context;
}
/*
* Create a context for JITing work.
*
* The context, including subsidiary resources, will be cleaned up either when
* the context is explicitly released, or when the lifetime of
* CurrentResourceOwner ends (usually the end of the current [sub]xact).
*/
LLVMJitContext *
llvm_create_context(int jitFlags)
{
LLVMJitContext *context;
llvm_assert_in_fatal_section();
llvm_session_initialize();
ResourceOwnerEnlargeJIT(CurrentResourceOwner);
context = MemoryContextAllocZero(TopMemoryContext,
sizeof(LLVMJitContext));
context->base.flags = jitFlags;
/* ensure cleanup */
context->base.resowner = CurrentResourceOwner;
ResourceOwnerRememberJIT(CurrentResourceOwner, PointerGetDatum(context));
return context;
}
/*
* Release resources required by one llvm context.
*/
static void
llvm_release_context(JitContext *context)
{
}
/*
* Per session initialization.
*/
static void
llvm_session_initialize(void)
{
MemoryContext oldcontext;
if (llvm_session_initialized)
return;
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMInitializeNativeAsmParser();
before_shmem_exit(llvm_shutdown, 0);
llvm_session_initialized = true;
MemoryContextSwitchTo(oldcontext);
}
static void
llvm_shutdown(int code, Datum arg)
{
}