v1-0001-Resolve-PL-handler-names-for-JITed-code-instead-o.patch
application/octet-stream
Filename: v1-0001-Resolve-PL-handler-names-for-JITed-code-instead-o.patch
Type: application/octet-stream
Part: 2
Patch
Format: format-patch
Series: patch v1-0001
Subject: Resolve PL handler names for JITed code instead of using const pointers
| File | + | − |
|---|---|---|
| src/backend/jit/llvm/llvmjit.c | 3 | 26 |
| src/backend/utils/fmgr/fmgr.c | 23 | 7 |
From 07c7ff996706c6f71e00d76894845c1f87956472 Mon Sep 17 00:00:00 2001
From: soumyadeep2007 <sochakraborty@pivotal.io>
Date: Sun, 27 Oct 2019 17:42:53 -0700
Subject: [PATCH v1] Resolve PL handler names for JITed code instead of using
const pointers
Using const pointers to PL handler functions prevents optimization
opportunities in JITed code. Now fmgr_symbol() resolves PL function
references to the corresponding language's handler.
llvm_function_reference() now no longer needs to create the global to
such a function.
Discussion: https://postgr.es/m/20191024224303.jvdx3hq3ak2vbit3%40alap3.anarazel.de:wq
---
src/backend/jit/llvm/llvmjit.c | 29 +++--------------------------
src/backend/utils/fmgr/fmgr.c | 30 +++++++++++++++++++++++-------
2 files changed, 26 insertions(+), 33 deletions(-)
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 82c4afb701..69a4167ac9 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -369,38 +369,15 @@ llvm_function_reference(LLVMJitContext *context,
fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
- if (modname != NULL && basename != NULL)
+ if (modname != NULL)
{
/* external function in loadable library */
funcname = psprintf("pgextern.%s.%s", modname, basename);
}
- else if (basename != NULL)
- {
- /* internal function */
- funcname = psprintf("%s", basename);
- }
else
{
- /*
- * Function we don't know to handle, return pointer. We do so by
- * creating a global constant containing a pointer to the function.
- * Makes IR more readable.
- */
- LLVMValueRef v_fn_addr;
-
- funcname = psprintf("pgoidextern.%u",
- fcinfo->flinfo->fn_oid);
- v_fn = LLVMGetNamedGlobal(mod, funcname);
- if (v_fn != 0)
- return LLVMBuildLoad(builder, v_fn, "");
-
- v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
-
- v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
- LLVMSetInitializer(v_fn, v_fn_addr);
- LLVMSetGlobalConstant(v_fn, true);
-
- return LLVMBuildLoad(builder, v_fn, "");
+ /* internal function or a PL handler */
+ funcname = psprintf("%s", basename);
}
/* check if function already has been added */
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 099ebd779b..71398bb3c1 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -265,11 +265,9 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
/*
* Return module and C function name providing implementation of functionId.
*
- * If *mod == NULL and *fn == NULL, no C symbol is known to implement
- * function.
- *
* If *mod == NULL and *fn != NULL, the function is implemented by a symbol in
- * the main binary.
+ * the main binary. If the function being looked up is not a C language
+ * function, it's language handler name is returned.
*
* If *mod != NULL and *fn !=NULL the function is implemented in an extension
* shared object.
@@ -285,6 +283,11 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
bool isnull;
Datum prosrcattr;
Datum probinattr;
+ Oid language;
+ HeapTuple languageTuple;
+ Form_pg_language languageStruct;
+ HeapTuple plHandlerProcedureTuple;
+ Form_pg_proc plHandlerProcedureStruct;
/* Otherwise we need the pg_proc entry */
procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
@@ -304,8 +307,9 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
return;
}
+ language = procedureStruct->prolang;
/* see fmgr_info_cxt_security for the individual cases */
- switch (procedureStruct->prolang)
+ switch (language)
{
case INTERNALlanguageId:
prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
@@ -342,9 +346,21 @@ fmgr_symbol(Oid functionId, char **mod, char **fn)
break;
default:
+ languageTuple = SearchSysCache1(LANGOID,
+ ObjectIdGetDatum(language));
+ if (!HeapTupleIsValid(languageTuple))
+ elog(ERROR, "cache lookup failed for language %u", language);
+ languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+ plHandlerProcedureTuple = SearchSysCache1(PROCOID,
+ ObjectIdGetDatum(
+ languageStruct->lanplcallfoid));
+ if (!HeapTupleIsValid(plHandlerProcedureTuple))
+ elog(ERROR, "cache lookup failed for function %u", functionId);
+ plHandlerProcedureStruct = (Form_pg_proc) GETSTRUCT(plHandlerProcedureTuple);
*mod = NULL;
- *fn = NULL; /* unknown, pass pointer */
- break;
+ *fn = pstrdup(NameStr(plHandlerProcedureStruct->proname));
+ ReleaseSysCache(languageTuple);
+ ReleaseSysCache(plHandlerProcedureTuple);
}
ReleaseSysCache(procedureTuple);
--
2.23.0