From 1f7b9b9a448521deb0d28b07ed77bb9ea7b842cd Mon Sep 17 00:00:00 2001 From: soumyadeep2007 Date: Sun, 27 Oct 2019 17:42:53 -0700 Subject: [PATCH v2] 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 | 31 +++++-------------------------- src/backend/utils/fmgr/fmgr.c | 30 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 82c4afb701..9da71a2da7 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -369,38 +369,17 @@ llvm_function_reference(LLVMJitContext *context, fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename); - if (modname != NULL && basename != NULL) + Assert(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